I wrote some code in VHDL that is expected to look at a rotory switch and feed back to me what position it is in.
When it gets turned it will read in the greycode from the rotor dial and switch states to the corresponding greycode state.
The act of changing states tells me which way the rotor is being twisted so I can indicate either an up or down state on a counter module later in the circuit.
If the state changes it should trigger a pulse on Mag
and triger either a 1 or 0 on up_dwn
.
It doesn't work when I simulate it. I get an occassional blip on Mag
but no up_dwn
change.
I suspect it's stuck in theSTART
state.
Anyone care to look and tell me what I've done wrong?
[Ed: Using Quartus II Version 9 ]
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY EncoderV2 IS
PORT(
CH_AB : IN STD_LOGIC_VECTOR (1 downto 0);
clk : IN STD_LOGIC;
nReset : IN STD_LOGIC;
up_dwn, Mag : OUT STD_LOGIC);
END EncoderV2;
ARCHITECTURE a OF EncoderV2 IS --
TYPE STATE_TYPE IS ( START, s00, s01, s11, s10);
SIGNAL state: STATE_TYPE;
BEGIN
PROCESS (clk, nReset)
BEGIN
IF nReset = '0' THEN -- asynch Reset to zero
state <= START;
ELSIF clk'EVENT AND clk = '1' THEN -- triggers on PGT
CASE state IS
WHEN START =>
IF CH_AB ="00" THEN
state <= s00;
Mag <='0';
ELSIF CH_AB="01" THEN
state <= s01;
Mag <='0';
ELSIF CH_AB= "11" THEN
state <= s11;
Mag <='0';
ELSIF CH_AB= "10" THEN
state <= s10;
Mag <='0';
ELSE state <= START;
END IF;
WHEN s00 => -- S10 <- S00 -> S01
IF CH_AB= "00" THEN
state <= s00;
Mag <='0';
ELSIF CH_AB= "10" THEN
state <= s10;
up_dwn <= '0';
Mag <='1';
ELSIF CH_AB= "01" THEN
state <= s01;
up_dwn <='1';
Mag <='1';
ELSE state <= START;
END IF;
WHEN s01 => -- S00 <- S01 -> S11
IF CH_AB= "01" THEN
state <= s01;
Mag <='0';
ELSIF CH_AB= "00" THEN
state <= s00;
up_dwn <= '0';
Mag <='1';
ELSIF CH_AB= "11" THEN
state <= s11;
up_dwn <='1';
Mag <='1';
ELSE state <= START;
END IF;
WHEN s11 => -- S01 <- S11 ->S10
IF CH_AB= "11" THEN
state <= s11;
Mag <='0';
ELSIF CH_AB= "01" THEN
state <= s01;
up_dwn <= '0';
Mag <='1';
ELSIF CH_AB= "10" THEN
state <= s10;
up_dwn <='1';
Mag <='1';
ELSE state <= START;
END IF;
WHEN s10 => -- S11 <- S10 -> S00
IF CH_AB= "10" THEN
state <= s10;
Mag <='0';
ELSIF CH_AB= "11" THEN
state <= s11;
up_dwn <= '0';
Mag <='1';
ELSIF CH_AB= "00" THEN
state <= s00;
up_dwn <='1';
Mag <='1';
ELSE state <= START;
END IF;
END CASE;
END IF;
END PROCESS;
END a;