Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

State machine counter problems

I do not understand why my state machine does absolutely nothing. Can anyone identify why? It seems simple enough to me, 4 states that have three possibilities based on two inputs (2 state changes and 1 no state change), and upon changing states increment or decrement one of 8 counters (variables) then assign these variables to out ports. The simulation outputs nothing. This is the first state machine I have written.

Thanks so much!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity pmodcounter is
      Port (Ain, Bin        : in  STD_LOGIC;
          reset             : in  STD_LOGIC;
          out12, out23, out34, out41, out43, out32, out21, out 14     : out  unsigned(25 downto 0));
                
end pmodcounter;
architecture Behavioral of pmodcounter is
type states is (st1, st2, st3, st4);
signal present_state, next_state: states;
begin
process (reset,clk)
begin
if (reset='1') then
    present_state <= st1;
    elsif rising_edge(clk) then
        present_state <= next_state;
end if;
end process;
process (Ain, Bin, present_state)
-- Counting variables
variable c12, c23, c34, c41, c43, c32, c21, c14: unsigned(25 downto 0):="01000000000000000000000000";
begin
    case present_state is
    
        when st1=>
        if (Ain='0' and Bin='1') then
        c12:=c12+1;
        next_state <= st2;
        elsif (Ain='1' and Bin='0') then
        c14:=c14-1;
        next_state <= st4;
        else 
        end if;
        
        when st2=>
        if (Ain='1' and Bin='1') then
        c23:=c23+1;
        next_state <= st3;
        elsif (Ain='0' and Bin='0') then
        c21:=c21-1;
        next_state <= st1;
        else 
        end if;
        
        when st3=>
        if (Ain='1' and Bin='0') then
        c34:=c34+1;
        next_state <= st4;
        elsif (Ain='0' and Bin='1') then
        c32:=c32-1;
        next_state <= st2;
        else 
        end if;
        
        when st4=>
        if (Ain='0' and Bin='0') then
        c41:=c41+1;
        next_state <= st1;
        elsif (Ain='1' and Bin='1') then
        c43:=c43-1;
        next_state <= st3;
        else 
        end if;
        
    end case;
    
        out12<=c12;
    out23<=c23;
    out34<=c34;
    out41<=c41;
    out43<=c43;
    out32<=c32;
    out21<=c21;
    out14<=c14;
    
end process;
end behavioral;

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    There are several things wrong here:

    1. Because of the way VHDL works, your outputs will only change when Ain, Bin or present_state actually change. Be warned - the way you have your circuit will mean that the code will behave differently to hardware.

    2. How would you expect the counters to work. Your code implies that the counters should add one when conditions are met - but they will keep adding 1 in a feedback loop. You need to move the counters to a clocked process to actually work as expected.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you, this gives me material to think about for sure. Given my signal I thought it would trigger counts and restrict any loop counts. I changed the code to change states on edges of my signal, but now my variables depend on multiple clock edges. My signal will always look like what is shown, two square waves with a 90 degree phase difference (50% duty cycle, varying period, and process can reverse in time). This is a piece of scientific instrumentation that is fundamentally asynchronous so it would be nice to avoid a master clock and only depend on these two inputs (blasphemous or not).

    https://alteraforum.com/forum/attachment.php?attachmentid=14226&stc=1

    
    process (Ain, Bin, present_state)
    -- Counting variables
    variable c12, c23, c34, c41, c43, c32, c21, c14: unsigned(25 downto 0):="01000000000000000000000000";
    begin
        case present_state is
        
            when st1=>
            if (rising_edge(Bin)) then
            c12:=c12+1;
            next_state <= st2;
            elsif (rising_edge(Ain)) then
            c14:=c14-1;
            next_state <= st4;
            else 
            next_state <= st1;
            end if;
            
            when st2=>
            if (rising_edge(Ain)) then
            c23:=c23+1;
            next_state <= st3;
            elsif (falling_edge(Bin)) then
            c21:=c21-1;
            next_state <= st1;
            else 
            next_state <= st2;
            end if;
            
            when st3=>
            if (falling_edge(Ain)) then
            c34:=c34+1;
            next_state <= st4;
            elsif (falling_edge(Bin)) then
            c32:=c32-1;
            next_state <= st2;
            else 
            next_state <= st3;
            end if;
            
            when st4=>
            if (falling_edge(Ain)) then
            c41:=c41+1;
            next_state <= st1;
            elsif (rising_edge(Bin)) then
            c43:=c43-1;
            next_state <= st3;
            else 
            next_state <= st4;
            end if;
            
        end case;
        
        out12<=c12;
        out23<=c23;
        out34<=c34;
        out41<=c41;
        out43<=c43;
        out32<=c32;
        out21<=c21;
        out14<=c14;
        
    end process;
    

    --- Quote Start ---

    There are several things wrong here:

    1. Because of the way VHDL works, your outputs will only change when Ain, Bin or present_state actually change. Be warned - the way you have your circuit will mean that the code will behave differently to hardware.

    2. How would you expect the counters to work. Your code implies that the counters should add one when conditions are met - but they will keep adding 1 in a feedback loop. You need to move the counters to a clocked process to actually work as expected.

    --- Quote End ---

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Your code will not compile. Apart from 2 clocks, they are not the outermost part of the process.

    You really need to do 2 things. First of all, draw your circuit out on paper. Without knowing what your circuit should be, you shouldn't be writing HDL.

    Second, using that circuit, read up on how to code those components.