Alright, I've been following this because typically for RTL I rarely
use variables. I have had, in the past, issues where I want signals
asserted at state transitions and, using signals, it requires some
jiggerypokery and has never been as entirely clear as I liked. So
this is interesting stuff to see the difference. I knew there had to
be something more clever than my edge detect ;-).
So I can see that we get the pulse asserted on the rising clock edge
for one cycle, and running also starts on the rising clock edge,
everything seems nicely synchronous.
My only question is, do synthesizers respect this distinction between
variable and signal updates and generate appropriately?
Best regards,
Mark Norton
I appreciate JB's two-case-statement approach, and for some complex
state machines, it would be very beneficial. I have from time to time,
to make the cycle-based timing work out, needed to specify an output
in every transition to a given state, and on large/complex FSMs, JB's
example is a better way, while still having registered outputs.
As to the synthesis tool's treatment of the differences between
variable and signal update behavior, yes, most tools handle it fine. I
use Synplify for most of my work, and have had only one problem, a
couple of years ago, that was quickly fixed. The way I see it, a
synthesis tool's job is to create hardware that will, on a clock cycle
basis, replicate the behavior of the RTL code. Most tools ignore the
impact of sensitivity lists, but other than that, do a pretty good
job.
To me, variables represent the most flexible way to represent cycle-
based behavior. If the behavior has a clock cycle delay, then the
hardware will too (by using a register). If not, it won't. We
typically think of any signal assigned in a clocked process as being
registered. With variables, it is the reference to the variable,
relative to when it was last written, that determines a registered or
combinatorial implementation. In JB's example, the first case
statement's reference to 'state' is registered, since state was not
previously assigned in that clock cycle (forcing storage of previous
value, accomplished with the register). References to state in the
second case statement are combinatorial, because state may have been
updated, and at least a mux is required to choose between the input
and output of the state register. Note that even in those situations
where state is not explicitly assigned in the first case statement,
the second case statement uses the same next state logic (feedback
mux) that was implemented for the first case statement.
Andy