- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you might want to restrict your async process for only state transition. for the rest of the stuffs, write them under clocked process.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks,
looks like our postings crossed! but I did use same clock edge Thanks again- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page