02-24-2012 04:29 AM
Hallo,
I would like to know if there is any significant difference in performance/resources use between these two coding styles for FSMs. Also, if there is any specific applications for each one of them or if it is irrelevant to use one-process or two-process state machines.
Thank you in advance.
02-24-2012 07:04 AM - edited 02-24-2012 07:04 AM
It's just good coding style (IMO) to split up combinational and sequential logic. If designed properly, the results should be the same.
02-24-2012 01:04 PM
@bwiec wrote:
It's just good coding style (IMO) to split up combinational and sequential logic. If designed properly, the results should be the same.
It seems to be the consensus among many experienced designers on this forum that it is not good
design practice to split FSM's into multiple processes. Many problems arise when combinatorial
processes don't have complete coverage causing latches or even unsynthesizable sequential
logic. While it may be good to separate truly combinatorial from sequential logic, the outputs
and state variables of an FSM are not combinatorial. You could argue that every LUT in front
of a flip-flop is "combinatorial," but generally the logic for such functions are written in clocked
processes.
-- Gabor
02-24-2012 01:19 PM
Thanks for the comments Gabor, I will certainly refer to your expertise on the subject as the authority.
I guess, my statement was under the assumption that the user also follow standard practices of using 'else'/'default's so that unintended latches are not inferred. Coding this way also allows the tools to tell you when you're designing latches, which could help you avoid them if you're aware of these pitfalls. If everything is in one clocked process and you forget your 'else', the tools will infer a register, no questions asked, right?
I was thinking more from a readability standpoint as well. It seems to be more obvious what the designer is trying to get the tools to infer when they are separated.
Thanks for your advice!
02-24-2012 01:27 PM - edited 02-24-2012 01:33 PM
It's just good coding style (IMO) to split up combinational and sequential logic.
I find that it is easier to design -- and MUCH easier to debug -- a state machine implemented in one process rather than two.
If designed properly, the results should be the same.
No, not entirely. Either design style can be successful, but there are noteworthy differences.
In a single clocked process, all the process outputs are aligned (in time, by clock cycle). Using the two-process style, the combinatorial outputs are a single clock cycle offset from the clocked outputs. For designs of any complexity -- and especially for beginners in logic design -- this complicates the implementation and debugging steps, and the resulting code is less readable (and, therefore, less maintainable).
Gabor and I have over 200 years of combined experience with logic design (OK, a slight exaggeration), and our many years of experience have led both of us to the same conclusion on this subject. There are other experienced designers participating in these forums -- folks who might otherwise go to great lengths to present contrary opinions -- who have also professed the same advice: Keep It Simple, Sir (KISS), and use single-process state machines.
I was thinking more from a readability standpoint as well. It seems to be more obvious what the designer is trying to get the tools to infer when they are separated.
I find that reading and understanding (and making changes to) state machine code is much easier when all the logic for a given state is gathered together in a single process, in a single section of code. It is much easier to maintain consistent use of logic when editing a single section of code rather than two or more sections of code.
Here is my generalisation of the day:
-- Bob Elkind
02-24-2012 01:37 PM
I'm still waiting for Bassman59 to weigh in on this topic, but in the meantime you
might find some interesting reading here:
http://forums.xilinx.com/t5/Synthesis/PAR-1018-for-a-reset-button/td-p/131740
-- Gabor
02-24-2012 01:45 PM - edited 02-24-2012 01:51 PM
I'm still waiting for Bassman59 to weigh in on this topic
And when he does, it won't take long to figure out where he stands on any particular question, in spite of his shy and introspective demeanour.
Here's a 3-post thread, where both bassman and eilert weigh in. Bassman replies with his usual affinity for concise statements.
-- Bob Elkind
02-24-2012 02:16 PM
Thanks again for sharing your knowledge, it's great discussion and learning experience. I'll defer to the expert opinions stated above instead of my own.
I would like to point out that the mentioned instances involve poor coding style anyway. I wouldn't think it's exactly fair to cite those instances as drawbacks of 2-process style. Since the original question was somewhat vague, I was thinking under the assumption that proper coding style is used (I realize this is not necessarily a good assumption).
Though point is certainly taken that, for those who don't realize they are creating latches, a single clocked process will eliminate latches for the user. But wouldn't this would mask a bigger problem that next_state equations are not covering, for example?
02-24-2012 02:31 PM
But wouldn't this would mask a bigger problem that next_state equations are not covering, for example?
There is no separate "next_state" variable in a single-process FSM. If there is no assignment
to the "state" variable in any state of the FSM, then "state" will not change and the machine will hang.
Sometimes this is done intentionally. For example I have a flash memory storage system that works
like a DVR and when the flash is "full" the state logic hangs until reset to prevent unintentional
overwriting (trashing) existing data.
In addition to warnings about latches, XST will give warnings for FSM's where states are not
reachable.
Anyway the original question was about resource usage. There are subtle differences in
the two methods for the position of LUTs and registers. For example, it is typical of a two-process
FSM to have the outputs encoded from the state. This means there are LUT's after the
state variable flops. If these go off-chip, you would need to turn on register balancing to
get the LUTs before the register so the output registers could be pushed into the IOB.
In the single-state case, the registers are all after the LUTs. XST probably does a good
job of building efficient hardware from either design, and with register balancing fully enabled
you probably couldn't tell the difference.
-- Gabor
02-25-2012 08:13 AM - edited 02-25-2012 09:16 AM
If I may add a few years of experience to the already excellent answers...
My grief against the 2-or-more-process FSM is that some "people" will always want to decode the combinatorial state, and worst, mix and match the registered and combinatorial state in their process --> even writing this is confusing. <edit> The bottom line issue is that the performance/operating frequency drops like a stone and the FSM becomes harder to optimize if the debug wasn't already difficult enough.</edit>
None of this happens with 1-process FSM (in which, by definition, you can decode only one state, the _registered_ state).
02-27-2012 03:17 AM
04-23-2016 04:59 AM
@eteam00, @gszakacs, @rcingham
I'd like to add a little twist to this very helpful and stimulating thread.
For Moore fsm it is a matter of style and taste whether one used one or two processes. Technically they can be expressed as one sequential process.
For Mealy fsm's it is different, one technically needs at least two processes because the combinatoric path from input to output can't be in the sequential process which describes the state register. In that case I found it better to have next state and output logic in the combinatorial process because this way all the logic is in one place.
And there can be, imho, good reasons for a Mealy fsm. For example when a larger fsm is broken up into several tightly coupled smaller ones because the overall state can somehow be factored into several parts. One can express this either as several Moore fsm with an additional combinatorial logic, or as several Mealy fsm. I found the second approach gave clearer and denser code, but that of course depends much on the structure of the problem.
08-31-2016 11:33 AM - edited 08-31-2016 11:35 AM
Am I the only person who treats state machines as little programs? The state variable is a program counter of sorts. I've written thousands of them by now, and I can't tell you if any were Mealy, Moore, Sneezy, Bashful, Sleepy, Grumpy or Doc style. Sometimes they're Dopey, but eventually I find the bug. ;-)
I first write them out as pseudocode on paper, and then convert directly to a single process state machine. They compile quickly and generally run at the limits of the FPGA's speed. Forcing them to meet some sort of precise definition or splitting it into combinational and sequential sections is just an unnecessary complication. Maybe the synthesis tools required that at one point, and the style get perpetuated for some reason?