I was wondering if somebody could give me some advice. I am trying to design a module that takes 8 inputs (buttons). These buttons determine if the state is active or not. Then on the rising edge of the clock it sequentially moves forwards or backwards through the active states, skipping the inactive clock states.
for example:
If the inputs are 11111111. It counts 00000001, 00000010, 00000100, 00001000, 00010000, 00100000, 01000000, 10000000. continuously
If the inputs are 00001111. It counts 00000001, 00000010, 00000100, 00001000. continuously.
If the inputs are 00000011. It counts 00000001, 00000010. continuously.
I am new to VHDL and fpga. I have tried a few different approaches. All of them have had problems. But this state machine i have written is working the way i want. It basically starts at state 0, checks which direction its moving then checks for the next active state in that directon and moves to it.
for example:
if in state 0 and moving forwards it checks input 2, if backwards it checks input 8. If they are not active it checks input 3 and input 7. if they are active it moves to that state and goes through the process again. But this time because we are in a different state it starts the check from this new state. If we are in state 2. It checks input 3 if forward and input 1 if backwards. If active it moves to that state.
Its a bit long with a lot of repeating code and is very much like C code. I would like to get away from this if I can. But as I said my knowledge is limited and I would like to know if there is a better way to achieving the function I need. Any help and guidance would be appreciated and I thank you in advance.
Here is the code for the module.
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY state_machine IS
PORT(
clk : IN STD_LOGIC;
a : IN STD_LOGIC; -- state0 Active '1'
b : IN STD_LOGIC; -- state1 Active '1'
c : IN STD_LOGIC; -- state2 Active '1'
d : IN STD_LOGIC; -- state3 Active '1'
e : IN STD_LOGIC; -- state4 Active '1'
f : IN STD_LOGIC; -- state5 Active '1'
g : IN STD_LOGIC; -- state6 Active '1'
h : IN STD_LOGIC; -- state7 Active '1'
dir : IN STD_LOGIC; -- direction
reset : IN STD_LOGIC;
output : OUT STD_LOGIC_VECTOR(2 downto 0));
END state_machine;
ARCHITECTURE behaviour OF state_machine IS
TYPE STATE_TYPE IS (s0, s1, s2, s3, s4, s5, s6, s7);
SIGNAL state : STATE_TYPE;
BEGIN
sequence: PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
state <= s0;
ELSIF (rising_edge (clk)) THEN
CASE state IS
WHEN s0=> -- When in state 0
IF (dir = '1') THEN -- if direction is forwards
IF b = '1' THEN state <= s1; -- If b is 1 go to state 1...if not
elsif c = '1' then state <= s2; -- if c is 1 go to state 2...if not
elsif d = '1' then state <= s3; -- if d is 1 go to state 3...if not
elsif e = '1' then state <= s4; -- if e is 1 go to state 4...if not
elsif f = '1' then state <= s5; -- if f is 1 go to state 5...if not
elsif g = '1' then state <= s6; -- if g is 1 go to state 6...if not
elsif h = '1' then state <= s7; -- if h is 1 go to state 7...if not
elsif a = '1' then state <= s0; -- if a is 1 go to state 0
END IF;
ELSE -- if direction is backwards
IF h = '1' THEN state <= s7; -- If h is 1 go to state 1...if not
elsif g = '1' then state <= s6; -- if g is 1 go to state 2...if not
elsif f = '1' then state <= s5; -- if f is 1 go to state 3...if not
elsif e = '1' then state <= s4; -- if e is 1 go to state 4...if not
elsif d = '1' then state <= s3; -- if d is 1 go to state 5...if not
elsif c = '1' then state <= s2; -- if c is 1 go to state 6...if not
elsif b = '1' then state <= s1; -- if b is 1 go to state 7...if not
elsif a = '1' then state <= s0; -- if a is 1 go to state 0...if not
END IF;
END IF;
WHEN s1=>
IF (dir = '1') THEN
IF c = '1' THEN state <= s2;
elsif d = '1' then state <= s3;
elsif e = '1' then state <= s4;
elsif f = '1' then state <= s5;
elsif g = '1' then state <= s6;
elsif h = '1' then state <= s7;
elsif a = '1' then state <= s0;
elsif b = '1' THEN state <= s1;
END IF;
ELSE
IF a = '1' THEN state <= s0;
elsif h = '1' then state <= s7;
elsif g = '1' then state <= s6;
elsif f = '1' then state <= s5;
elsif e = '1' then state <= s4;
elsif d = '1' then state <= s3;
elsif c = '1' then state <= s2;
elsif b = '1' then state <= s1;
END IF;
END IF;
WHEN s2=>
IF (dir = '1') THEN
IF d = '1' THEN state <= s3;
elsif e = '1' then state <= s4;
elsif f = '1' then state <= s5;
elsif g = '1' then state <= s6;
elsif h = '1' then state <= s7;
elsif a = '1' then state <= s0;
elsif b = '1' then state <= s1;
elsif c = '1' then state <= s2;
END IF;
ELSE
IF b = '1' THEN state <= s1;
elsif a = '1' then state <= s0;
elsif h = '1' then state <= s7;
elsif g = '1' then state <= s6;
elsif f = '1' then state <= s5;
elsif e = '1' then state <= s4;
elsif d = '1' then state <= s3;
elsif c = '1' then state <= s2;
END IF;
END IF;
WHEN s3=>
IF (dir = '1') THEN
IF e = '1' THEN state <= s4;
elsif f = '1' then state <= s5;
elsif g = '1' then state <= s6;
elsif h = '1' then state <= s7;
elsif a = '1' then state <= s0;
elsif b = '1' then state <= s1;
elsif c = '1' then state <= s2;
elsif d = '1' then state <= s3;
END IF;
ELSE
IF c = '1' THEN state <= s2;
elsif b = '1' then state <= s1;
elsif a = '1' then state <= s0;
elsif h = '1' then state <= s7;
elsif g = '1' then state <= s6;
elsif f = '1' then state <= s5;
elsif e = '1' then state <= s4;
elsif d = '1' then state <= s3;
END IF;
END IF;
WHEN s4=>
IF (dir = '1') THEN
IF f = '1' THEN state <= s5;
elsif g = '1' then state <= s6;
elsif h = '1' then state <= s7;
elsif a = '1' then state <= s0;
elsif b = '1' then state <= s1;
elsif c = '1' then state <= s2;
elsif d = '1' then state <= s3;
elsif e = '1' then state <= s4;
END IF;
ELSE
IF d = '1' THEN state <= s3;
elsif c = '1' then state <= s2;
elsif b = '1' then state <= s1;
elsif a = '1' then state <= s0;
elsif h = '1' then state <= s7;
elsif g = '1' then state <= s6;
elsif f = '1' then state <= s5;
elsif e = '1' then state <= s4;
END IF;
END IF;
WHEN s5=>
IF (dir = '1') THEN
IF g = '1' THEN state <= s6;
elsif h = '1' then state <= s7;
elsif a = '1' then state <= s0;
elsif b = '1' then state <= s1;
elsif c = '1' then state <= s2;
elsif d = '1' then state <= s3;
elsif e = '1' then state <= s4;
elsif e = '1' then state <= s5;
END IF;
ELSE
IF e = '1' THEN state <= s4;
elsif d = '1' then state <= s3;
elsif c = '1' then state <= s2;
elsif b = '1' then state <= s1;
elsif a = '1' then state <= s0;
elsif h = '1' then state <= s7;
elsif g = '1' then state <= s6;
elsif f = '1' then state <= s5;
END IF;
END IF;
WHEN s6=>
IF (dir = '1') THEN
IF h = '1' THEN state <= s7;
elsif a = '1' then state <= s0;
elsif b = '1' then state <= s1;
elsif c = '1' then state <= s2;
elsif d = '1' then state <= s3;
elsif e = '1' then state <= s4;
elsif f = '1' then state <= s5;
elsif g = '1' then state <= s6;
END IF;
ELSE
IF f = '1' THEN state <= s5;
elsif e = '1' then state <= s4;
elsif d = '1' then state <= s3;
elsif c = '1' then state <= s2;
elsif b = '1' then state <= s1;
elsif a = '1' then state <= s0;
elsif h = '1' then state <= s7;
elsif g = '1' then state <= s6;
END IF;
END IF;
WHEN s7=>
IF (dir = '1') THEN
IF a = '1' THEN state <= s0;
elsif b = '1' then state <= s1;
elsif c = '1' then state <= s2;
elsif d = '1' then state <= s3;
elsif e = '1' then state <= s4;
elsif f = '1' then state <= s5;
elsif g = '1' then state <= s6;
elsif h = '1' then state <= s7;
END IF;
ELSE
IF g = '1' THEN state <= s6;
elsif f = '1' then state <= s5;
elsif e = '1' then state <= s4;
elsif d = '1' then state <= s3;
elsif c = '1' then state <= s2;
elsif b = '1' then state <= s1;
elsif a = '1' then state <= s0;
elsif h = '1' then state <= s7;
END IF;
END IF;
END CASE;
END IF;
END PROCESS;
PROCESS (state)
BEGIN
CASE state IS
WHEN s0 =>
output <= "000";
WHEN s1 =>
output <= "001";
WHEN s2 =>
output <= "010";
WHEN s3 =>
output <= "011";
WHEN s4 =>
output <= "100";
WHEN s5 =>
output <= "101";
WHEN s6 =>
output <= "110";
WHEN s7 =>
output <= "111";
END CASE;
END PROCESS;
END behaviour;
here is the testbench:
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
entity state_machine_tb is
end;
architecture bench of state_machine_tb is
component state_machine
PORT(
clk : IN STD_LOGIC;
a : IN STD_LOGIC;
b : IN STD_LOGIC;
c : IN STD_LOGIC;
d : IN STD_LOGIC;
e : IN STD_LOGIC;
f : IN STD_LOGIC;
g : IN STD_LOGIC;
h : IN STD_LOGIC;
dir : IN STD_LOGIC;
reset : IN STD_LOGIC;
output : OUT STD_LOGIC_VECTOR(2 downto 0));
end component;
signal clk : STD_LOGIC;
signal a : STD_LOGIC;
signal b : STD_LOGIC;
signal c : STD_LOGIC;
signal d : STD_LOGIC;
signal e : STD_LOGIC;
signal f : STD_LOGIC;
signal g : STD_LOGIC;
signal h : STD_LOGIC;
signal dir : STD_LOGIC;
signal reset : STD_LOGIC;
signal output : STD_LOGIC_VECTOR(2 downto 0);
constant clock_period: time := 10 ns;
begin
uut: state_machine port map ( clk => clk,
a => a,
b => b,
c => c,
d => d,
e => e,
f => f,
g => g,
h => h,
dir => dir,
reset => reset,
output => output);
stimulus: process
begin
reset <= '1';
dir <= '1';
a <= '1';
b <= '1';
c <= '1';
d <= '1';
e <= '1';
f <= '1';
g <= '1';
h <= '1';
wait for clock_period;
reset <= '0';
wait for clock_period *15;
dir <= '0';
a <= '1';
b <= '1';
c <= '1';
d <= '1';
e <= '1';
f <= '1';
g <= '1';
h <= '1';
wait for clock_period *16;
dir <= '1';
a <= '1';
b <= '1';
c <= '1';
d <= '1';
e <= '0';
f <= '0';
g <= '0';
h <= '0';
wait for clock_period *16;
dir <= '0';
a <= '1';
b <= '1';
c <= '1';
d <= '1';
e <= '0';
f <= '0';
g <= '0';
h <= '0';
wait for clock_period *16;
dir <= '1';
a <= '1';
b <= '0';
c <= '1';
d <= '0';
e <= '1';
f <= '0';
g <= '1';
h <= '0';
wait for clock_period *16;
a <= '1';
b <= '1';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
g <= '0';
h <= '0';
wait for clock_period *16;
a <= '1';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
g <= '0';
h <= '0';
wait for clock_period *4;
dir <= '0';
wait;
end process;
clocking: process
begin
clk <= '0';
wait for clock_period / 2;
clk <= '1';
wait for clock_period / 2;
end process;
end;
Aucun commentaire:
Enregistrer un commentaire