Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16606 Discussions

State machine counter problems

Altera_Forum
Honored Contributor II
1,162 Views

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;
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
424 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
424 Views

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 ---  

0 Kudos
Altera_Forum
Honored Contributor II
424 Views

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.
0 Kudos
Reply