I am writing the code for the state diagram below but not sure why I get the output Y that is 0 even I followed the correct sequence? I tested and change the value of output Y for the 1st transition S0 to S1 to 1 for testing purposes, the 1st transition did not work, what did I consider wrongly?
VHDL
library ieee;
use IEEE.STD_LOGIC_1164.all;
entity seqdet is
port(
RST,CLK : in STD_LOGIC;
X1,X0: in STD_LOGIC;
Y: out STD_LOGIC
);
end seqdet;
architecture BHV of seqdet is
type state is (S0,S1,S2,S3,S4,S5);
signal presentstate, nextstate:state;
begin
CLK_PULSE:process(CLK,RST)
begin
if rising_edge(CLK) then
if(RST='1') then
presentstate<=S0;
elsif(RST='0') then
presentstate<=nextstate;
end if;
end if;
end process;
state_process:process(presentstate,X1,X0)
begin
if(presentstate<=S0) then
Y<='0';
if(X1='0' and X0='0') then
nextstate<=S1;
else
nextstate<=S0;
end if;
elsif(nextstate<=S1 ) then
Y<='0';
if(X1='0' and X0='0') then
nextstate<=S2;
else
nextstate<=S0;
end if;
elsif(presentstate<=S2 ) then
Y<='0';
if(X1='0' and X0='0') then
nextstate<=S2;
elsif(X1='0' and X0='1') then
nextstate<=S3;
else
nextstate<=S0;
end if;
elsif(presentstate<=S3 ) then
Y<='0';
if(X1='1' and X0='1') then
nextstate<=S4;
else
nextstate<=S0;
end if;
elsif(presentstate<=S4 ) then
Y<='0';
if(X1='0' and X0='0') then
nextstate<=S5;
else
nextstate<=S0;
end if;
elsif(presentstate<=S5 ) then
if(X1='0' and X0='0') then
Y<='0';
nextstate<=S2;
elsif(X1='1' and X0='0' ) then
Y<='1';
nextstate<=S0;
else
Y<='0';
nextstate<=S0;
end if;
end if;
end process;
end BHV;
Testbench
library ieee;
use IEEE.STD_LOGIC_1164.all;
entity seqdetest is
end seqdetest;
architecture seqdetest_arch of seqdetest is
signal CLK: std_logic:='0';
signal RST: std_logic;
signal X1,X0: std_logic;
signal Y: std_logic;
BEGIN
uut: entity work.seqdet
port map (
CLK=>CLK,
RST => RST,
X1 => X1,
X0 => X0,
Y => Y
);
CLK_proc: process
begin
CLK<= '1';
wait for 50 ns;
CLK <= '0';
wait for 50 ns;
end process CLK_proc;
sim_proc:process
begin
RST<='1';
wait for 100 ns;
RST<='0';
X1<='0';X0<='0';
wait for 100 ns;
X1<='0';X0<='0';
wait for 100 ns;
X1<='0';X0<='1';
wait for 100 ns;
X1<='1';X0<='1';
wait for 100 ns;
X1<='0';X0<='0';
wait for 100 ns;
X1<='1';X0<='0';
wait for 100 ns;
end process sim_proc;
END seqdetest_arch ;
To enhance readability white space has been added and superfluous parentheses have been removed. All the changes made to get Y = '1' are shown:
state_process:
process (presentstate, X1, X0)
begin
if presentstate = S0 then -- CHANGED = WAS <=
Y <= '0';
if X1 = '0' and X0 = '0' then
nextstate <= S1;
else
nextstate <= S0;
end if;
elsif presentstate = S1 then -- CHANGED presentstate WAS nextstate
-- CHANGED = WAS <=
Y <= '0';
if X1 = '0' and X0 = '0' then
nextstate <= S2;
else
nextstate <= S0;
end if;
elsif presentstate = S2 then -- CHANGED = WAS <=
Y <= '0';
if X1 = '0' and X0 = '0' then
nextstate <= S2;
elsif X1 = '0' and X0 = '1' then
nextstate <= S3;
else
nextstate <= S0;
end if;
elsif presentstate = S3 then -- CHANGED = WAS <=
Y <= '0';
if X1 = '1' and X0 = '1' then
nextstate <= S4;
else
nextstate <= S0;
end if;
elsif presentstate = S4 then -- CHANGED = WAS <=
Y <= '0';
if X1 = '0' and X0 = '0' then
nextstate <= S5;
else
nextstate <= S0;
end if;
elsif presentstate = S5 then -- CHANGED = WAS <=
if X1 = '0' and X0 = '0' then
Y <= '0';
nextstate <= S2;
elsif X1 = '1' and X0 = '0' then
Y <= '1';
nextstate <= S0;
else
Y <= '0';
nextstate <= S0;
end if;
end if;
end process;
There was one place where elsif nextstate = S1 then
should have evaluated presentstate
which doesn't have the scheduled update to S1
. There are no intervening wait statements. Signal updates don't occur when any process statement is executing. This would likely have caused your branching error.
All six state evaluations used less than or equal to (<=
) which is incorrect. Enumerated types are scalar types and are ordered. Using less than or equal to is dependent on condition evaluation order in the outer if statement (which could be replaced with a case statement).
With these 7 changes you get Y = '1':
The first mentioned change reflects a typographic error. The following six are commonly described as thinkos.
I found the branching notation in your state diagram almost incomprehensible and took the VHDL as the notional documentation of the state diagram and assumed errors were present. VHDL is intended to document design descriptions.
The testbench does not test the S5
to S2
branch nor all the to S0
branches.