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

headache with 2 process state machine

Altera_Forum
Honored Contributor II
2,155 Views

Hi everyone, 

 

below is the code from a state machine. It is a intended emulate one part of a system to test the other part, so all it is doing is sending rows and columns of data (and looking for some special cases while its at it) to the system downstream 

 

nearly all of the signals are reported as having unsafe behaviour, and, although it builds, it doesn't work 

(as well as unsafe behavior, it is throwing up inferred latches all over the place) 

I think this is probably relatively elementary to those who are wiser than me in this field,  

Am I trying to do too much in each of the states, should I be creating some other code to do the donkey work? 

 

 

Hope one of you can steer me back on right path- I think I have been here before, but was a simpler system 

 

I have tried changing to a one process machine, but that didn't especially help 

 

Regards 

 

Pete B 

 

(code attached) 

 

 

process (nReset,Clock50) 

begin 

if (nReset ='0') then  

CurrentState <= InReset; 

elsif (rising_edge (Clock50)) then 

CurrentState <= NextState; 

end if; 

end process; 

 

 

 

process (CurrentState) 

begin 

 

 

case CurrentState is 

------------------------ 

when InReset =>  

 

CurrentFreqBin<="00000"; 

TargetBin<="00000"; 

TargBinInt<=0; 

index <= 0; 

InterFrameDelay<="000000000000000000000000"; 

---------------------- 

NextState <= StartCol; 

 

------------------------ 

------------------------ 

when StartCol =>  

 

TargBinInt<=FreqTable(index); 

--my_slv <= std_logic_vector(to_unsigned(my_integer, my_slv'length)); -- if  

TargetBin <= std_logic_vector(to_unsigned(TargBinInt,5)); 

----------------------- 

NextState <= WriteFreq; 

 

 

 

 

------------------------ 

------------------------ 

when WriteFreq =>  

 

FreqSlot<=CurrentFreqBin; 

if (CurrentFreqBin=TargetBin) then 

Amplitude<="11111111"; 

else  

Amplitude<="00000000"; 

end if; 

Strobe<='1'; 

---------------------- 

NextState <= StrobeOff; 

 

 

------------------------ 

------------------------ 

when StrobeOff =>  

 

Strobe<='0'; 

CurrentFreqBin<=CurrentFreqBin+1; 

if (CurrentFreqBin="00000") then 

NextState <= ColumnFinished; 

else 

NextState <= WriteFreq; 

end if; 

 

 

 

 

------------------------ 

------------------------ 

when ColumnFinished => 

 

ColumnDone<='1'; 

index<=index+1; 

NextState <= ColFinStrobeOff; 

 

 

 

 

------------------------ 

 

------------------------ 

when ColFinStrobeOff =>  

 

if (index = 256) then 

NextState <= AllDone; 

InterFrameDelay <="000001111010000100100000"; 

else  

NextState <=StartCol; 

ColumnDone<='0'; 

end if; 

 

 

------------------------ 

 

------------------------ 

when AllDone =>  

ColumnDone<='1'; 

NextState <= AllDoneLoop; 

 

 

 

------------------------ 

------------------------ 

when AllDoneLoop =>  

ColumnDone<='0'; 

InterFrameDelay <=InterFrameDelay-1; 

if (InterFrameDelay < "000000000000000000000010") then 

NextState <= AllDone; 

else 

NextState <= AllDoneLoop; 

end if;  

 

 

------------------------ 

 

 

end case; 

 

end process;
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
610 Views

The latch issue is brought up by assigning other signals than NextState in the asynchronous process, and assigning them only in some of the states. Besides generating a lot of warnings, you can be rather sure that constructs like "index<=index+1;" will never work based on latches. 

 

A simple solution, although not usually suggested in the text books is to change the design to a single synchronous process state machine, simply merging both processes.
0 Kudos
Altera_Forum
Honored Contributor II
610 Views

you might want to restrict your async process for only state transition. for the rest of the stuffs, write them under clocked process.

0 Kudos
Altera_Forum
Honored Contributor II
610 Views

Thanks to you both for replying, 

 

FvM - I had tried single process solution, but will revisit this, perhaps also moving some functionality outside  

 

jacklsw86 - this additional clocked process, would this be the same clock as drives the state changer (or, indeed, somewhat blasphemous, the falling edge of the same clock) or should it be something else altogether? 

 

thanks again for your help, will advise how I get on
0 Kudos
Altera_Forum
Honored Contributor II
610 Views

you could write another process with the same clock edge. 

 

besides that, you might wanna look for more example codes to get familiar with other people's coding style.
0 Kudos
Altera_Forum
Honored Contributor II
610 Views

Hi jacklsw and FvM 

 

so this is working (sufficiently for my purpose) 

 

I went down jacklsw route (mostly because in my post I did ask 

'Am I trying to do too much in each of the states, should I be creating some other code to do the donkey work?' :rolleyes: s 

 

but I do think FvM is (part of) the more formal way to write this sort of stuff,  

 

So I guess, my working code (below-- yes, is still a bit scruffy, but its not getting released into the wild, its my test) might be called a three process state machine? Or is it really two process, as the third is doing work rather than managing?  

 

Any comments on the code are welcome, and indeed gratefully recieved, if you have the time to look,  

 

(note added InterFrameDelay to sensitivity list - Im pretty sure that just a simulation thing, and it would work 'in the real world' without it 

 

Thanks so much (again) 

 

Pete B 

 

 

 

 

begin 

process (nReset,Clock50) 

begin 

if (nReset ='0') then  

CurrentState <= InReset; 

elsif (rising_edge (Clock50)) then 

CurrentState <= NextState; 

end if; 

end process; 

 

process (CurrentState,InterFrameDelay) 

 

begin 

case CurrentState is 

 

when InReset =>  

NextState <= StartCol; 

 

when StartCol =>  

NextState <= WriteFreq; 

 

when WriteFreq =>  

NextState <= StrobeOff; 

 

when StrobeOff =>  

if (CurrentFreqBin="00000") then 

NextState <= ColumnFinished; 

else 

NextState <= WriteFreq; 

end if; 

 

when ColumnFinished => 

NextState <= ColFinStrobeOff;  

 

when ColFinStrobeOff =>  

if (index = 256) then 

NextState <= AllDone; 

else  

NextState <=StartCol; 

end if;  

 

when AllDone =>  

NextState <= AllDoneLoop; 

 

when AllDoneLoop =>  

if interFrameDelay<"000000000000000000000010")  

then 

NextState <= AllDone; 

else 

NextState <= AllDoneLoop; 

end if;  

 

end case; 

 

end process; 

 

---------------------------------------------------------------------------  

process (CurrentState,Clock50) 

 

begin 

if (Rising_edge (Clock50)) then 

 

case CurrentState is 

 

when InReset =>  

CurrentFreqBin<="00000"; 

TargetBin<="00000"; 

TargBinInt<=0; 

index <= 0; 

InterFrameDelay<="000000000000000000000000"; 

------------------------ 

when StartCol =>  

TargBinInt<=FreqTable(index); 

TargetBin <= std_logic_vector(to_unsigned(TargBinInt,5)); 

----------------------- 

when WriteFreq =>  

 

FreqSlot<=CurrentFreqBin; 

if (CurrentFreqBin=TargetBin) then 

Amplitude<="11111111"; 

else  

Amplitude<="00000000"; 

end if; 

Strobe<='1'; 

---------------------- 

when StrobeOff =>  

 

Strobe<='0'; 

CurrentFreqBin<=CurrentFreqBin+1; 

------------------------ 

when ColumnFinished => 

ColumnDone<='1'; 

index<=index+1; 

------------------------ 

when ColFinStrobeOff =>  

if (index = 256) then  

ColumnDone<='1'; 

else  

ColumnDone<='0'; 

end if; 

------------------------ 

when AllDone =>  

InterFrameDelay <="000000000000000000100000";  

ColumnDone<='1'; 

------------------------ 

when AllDoneLoop =>  

ColumnDone<='0'; 

InterFrameDelay <=InterFrameDelay-'1'; 

------------- 

end case; 

end if; 

 

end process;
0 Kudos
Altera_Forum
Honored Contributor II
610 Views

Thanks,  

looks like our postings crossed!  

but I did use same clock edge 

Thanks again
0 Kudos
Altera_Forum
Honored Contributor II
610 Views

your asynchronous process' sensitivity list isn't complete either. you got to put all signals which affects the outcome in the sensitivity list, usually the signals in if-else statement. 

 

for synchronous process, usually it is sufficient to put just clock signal in the sensitivity list. unless you want to add some async signal in it. 

 

eg. registers with async reset 

 

process (clk, reset) if (reset = '1') then ... elsif rising_edge(clk) .. end process;
0 Kudos
Reply