Why a 'Running' output? The OP asked for a method to generate one
clock cycle wide pulses to start and stop other things. There isn't
necessarily a need for anything outside of the state machine to know
when things are 'running' and the state machine doesn't need any
additional signal to indicate to itself that it is running.
Oh puh-leeze! I just wanted a very simple example of an
output that is a pure function of state, to contrast it
with the outputs that get asserted only for one cycle on
state transitions. Yes, of course it's redundant.
[...]
I think you meant to set Stop to '1' above
Indeed I did. Whoops.
Your example shows two case statements, you set output
signals in each one but there is no rationale for why the output that
you came up with called 'Running' should not be set in the first case
statement along with the other outputs 'Start' and 'Stop'
Yes there is! That's the whole point! Given that I've defaulted
all the outputs to false at the top of the process (often a good
idea, because in my experience FSMs tend to have fairly sparse
outputs) the outputs that are written in the "transition" case
statement will be asserted for one clock on the transition, and
the outputs that are written in the second case statement will
be asserted for the whole time the FSM is in the chosen state.
or in fact
why it is even inside the clocked process at all since it is simply a
decode of being in the 'Run' state. Do you have a justification for
why 'Running' is treated differently than 'Start' and 'Stop'? Even if
'Running' was more than a simple state decode, it would've been more
appropriate to assign it inside the 'if' statements along with 'Start'
and 'Stop' than totally separate as you've shown.
Wrong. If I were to assert Running in the transition case
statement, I would need to find some way to keep it asserted
throughout the Run state:
Start <= '0';
Stop <= '0';
Running <= '0';
case state is
when Idle =>
if Go then
state <= Run;
Start <= '1'; -- one-shot
Running <= '1'; -- sticky
end if;
when Run =>
if Go = '0' then
state <= Idle;
Stop <= '1';
else
Running <= '1';
end if;
end case;
That's messy, and introduces a disconnect between the code
and a state transition diagram. It's also very verbose in
non-trivial FSMs, because I need to set the output variable
on EVERY state transition into each state for which the
output is asserted; sometimes there are many such
transitions, from all over the state machine, and it
gets tedious and hard to maintain.
If the state variable were a signal, I could easily have
made "Running" be a combinational decode of state. But I wanted
it registered, and I like my FSMs to be in a single process.
Getting registered Moore-style (pure function of state) outputs
in a single-process FSM with a state SIGNAL requires you to set
those outputs on state transitions, which breaks the one-to-one
mapping from state transition diagram to code. Since I still
find state transition diagrams a useful thinking tool, that
matters to me very much.
In any case, your example is at least 30-40% more verbose* than it
needs to be,
That doesn't much bother me.
it's not any clearer for that extra typing,
If I thought you were right, then that most certainly
would bother me. But I disagree.
it didn't
demonstrate some of the things you claimed (i.e. "another reason for
using a state variable"
OK, I exaggerated. It's the same old reason for using a
variable in a clocked process: the only one that really
makes a difference, and the one that lets me do all manner
of things that would be tedious otherwise:
A variable in a clocked process gives you access to the
NEXT-state value of the flops, which is impossible any
other way in a single process.
and "clear distinction between...").
What could be a clearer distinction than this:
outputs assigned in the first case statement
are asserted for only one clock, outputs
assigned in the second case statement are
asserted throughout the chosen state. I'd
love to know what definition of "distinction"
I'd need to meet if that doesn't satisfy you
your example did show "No edge detectors, no extra states"...nobody
posted anything showing 'extra states' to begin with.
No, but extra states is an obvious possible solution
and one that I have sometimes seen.
I don't have any particular issue with code that is different from how
I might write it, that is a good thing. When claims are made that are
not backed up by anything though it's worth asking what the reasoning
behind it is.
You asked, I answered
* Verbosity was determined from your posted code (39 lines of text)
versus my version which is functionally identical that takes 30 lines
of code (or 28 if you remove the block statements and assume the
signal declaration is moved up into the signal declarations for the
architecture. My code posted below.
The key difference is that your "Running" output is not registered.
(I know it will in this case be exactly the state flop, but in general
there's some decode logic in the way). Sometimes that matters.
I completely agree that the two implementations are functionally
equivalent.
Thanks