# VHDL Algorithm state machine output

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ASM is
port(clk, rst, A, B: in std_logic;
Z:buffer std_logic_vector(1 downto 0));
end ASM;

architecture asm1 of ASM is
type t_state is(T0,T1,T2,T3);
signal current_state, next_state:t_state;

begin
memory:process(clk,rst)
begin
if(rst='1')then
current_state<=T0;
elsif(clk'event and clk='1') then
current_state<=next_state;
end if;
end process;

next_state_decoder:process(current_state)
begin
case current_state is
when T0=>if(A='1' and B='0')then
next_state<=T1;
else
next_state<=T0;
end if;

when T1=>if(A='1'and B='1')then
next_state<=T2;
else
next_state<=T3;
end if;

when T2=> next_state<=T0;

when T3=> next_state<=T0;

when others=> NULL;
end case;
end process;

output_decoder:process(clk,A,B,Z)
begin
if (clk'event and clk='1')then
case(current_state) is
when T0=> if(A='1'and B='0')then
Z<="00";
end if;

when T1=> if(A='1'and B='1')then
Z<="10";
else
Z<="11";
end if;

when T2=> Z<="10";

when T3=> Z<="11";

end case;
end if;
end process;
end asm1;


Hi, i'm trying to display the output waveform in modelsim, but with this code, I wasn't able to get the output of Z, the output of Z shows nothing.

Testbench code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ASM_tb is
end ASM_tb;

architecture behave of ASM_tb is
component ASM is
port(clk, rst, A, B: in std_logic;
Z:buffer std_logic_vector(1 downto 0));
end component;

signal clk: std_logic :='0';
signal rst : std_logic;
signal A,B: std_logic;
signal Z: std_logic_vector(1 downto 0);
constant clk_period: time := 40ns;

begin
uut: ASM port map (clk,rst,A,B);

clk_process:process
begin
clk<='0';
wait for clk_period/2;
clk<='1';
wait for clk_period/2;
end process;

-- Stimulus process
stimulus: process
begin
A<='0';
B<='0';
wait for 20 ns;
A<='0';
B<='1';
wait for 20 ns;
A<='1';
B<='0';
wait for 20 ns;
A<='1';
B<='1';
wait for 20 ns;
A<='1';
B<='1';
wait for 20 ns;
A<='1';
B<='0';
wait for 20 ns;
end process;

end behave;

• Do you see any warnings in the modelsim log about uut being unbounded? You are compiling both files? – user2913869 Mar 13 '18 at 12:45
• Hint : rewrite the port map using named association ... carefully. – Brian Drummond Mar 13 '18 at 12:46

1) Testbench: You are not initializing the reset signal or driving it to a valid state during the simulation. Fix this.

2) Testbench: Your clock period is 40 ns but your testbench waits for 20 ns to change the inputs. This is faster than the system can respond to changes. Probably not what you want to do for basic behavior checks. I suggest changing your wait 20ns statements to "wait until rising_edge(clk); wait for 1 ps;"

3) ASM Code: Next decoder process needs to have A, B, and current_state in the sensitivity list. Generally, if it's an unclocked process, you want to have all input stimulus in the sensitivity list, else you are creating transparent latches. If you need registers (which you don't in this case), make it a clocked process.

4) ASM Code: In your output decoder process, the only thing you need in the sensitivity list is the clock signal. In general, if it's a clocked process, you only need the clock in the sensitivity list (maybe a reset signal as well if you desire an asynchronous reset, but I avoid asynchronous resets unless absolutely necessary). I believe this is not absolutely necessary, but more of a stylistic thing.

5) ASM Code: Generally, you would want to initialize all output signals to SOMETHING. I suggest creating an internal signal for your output Z port, initializing it in the declaration area, use the signal everywhere you are using Z, and then add a line to the bottom of the file that assigns Ztmp to Z.

6) ASM Code: Also, what asdfex said: Initialize your current_state signal.

Hope that helps.

• For (3) and (4) : the sensitivity list is not a stylistic thing. Combinatorial processes must have all inputs in a sensitivity list (unless 'wait on' statements are used) for correct simulation. Synthesis tools may let you get away with this but ModelSim will not. Clocked processes just use CLK and RST, as you say. Incidentally, synchronous vs asynchronous reset is not a preferential thing, it depends on the technology you're targeting. Many FPGAs and most CPLDs use fewer gates for asynchronous resets. Refer to the logic structure in the datasheet. – TonyM Mar 13 '18 at 14:18
• Vendors of modern "large" FPGAs suggest not to use global asynchronous resets. There are other reasons to consider instead of just fewer gates. However, this would be a whole new topic discussion, and it's been discussed to death. – user2913869 Mar 13 '18 at 14:51
• I dunno about all the "discussed to death" stuff: you chose to advocate in your post and I questioned it. Modern "large" FPGAs aren't much of the PLD population. Looking at the datasheet and understanding how to choose a technique has to be a better policy. I had commented on several things, good chance to improve your answer... – TonyM Mar 13 '18 at 15:20
• I tried everything as you listed but the output is still NULL – Yap YiXien Mar 14 '18 at 10:35
• Did you see Brian Drummond's comment? He's hinting that you need to add Z to your uut instantiation's port map in your testbench. You basically declared signal Z in your test bench, never initialized it, and never drove it. – user2913869 Mar 14 '18 at 17:17