From: Dave on
On Apr 23, 11:34 am, Muzaffer Kal <k...(a)dspia.com> wrote:
> On Wed, 23 Apr 2008 15:25:33 GMT, Muzaffer Kal <k...(a)dspia.com> wrote:
> >On Wed, 23 Apr 2008 02:33:32 -0700 (PDT), ee_ether
> ><xjjzdv...(a)sneakemail.com> wrote:
>
> >>Hi,
>
> >>A colleague and I are having a friendly debate on coding state
> >>machines in Verilog, targeting synthesis for FPGAs. Comments are very
> >>appreciated. I am NOT trying to start a holy war here regarding
> >>syntax style (one process vs. two process, etc).
>
> >>Crux of the matter: Do you need to define values for outputs of your
> >>state machine in EVERY state, or do you only need to define values for
> >>outputs in states where you want the output to update/change?
>
> >In either one process or two process designs, you only need to write
> >to the next state when you need to change it. In one process, the
> >registers by definition remember their state so there is no chance of
> >getting a latch. In two states, you assign the next state to the
>
> this should say "in two process implementation..." of course
>
> >current state at the top of the process so if they don't get written
> >again later, they keep their current state so no latches either.
>
> here are some example for my points:
>
> always@(posedge clk)
> if (enable)
> count <= count+1;
>
> in this case there is no need for
> else
> count <= count;
>
> because if not enable counter registers remember their state so in a
> state machine, there is no reason to write to states/outputs which
> don't need changing.
>
> In two process design, you say
> always @(*)
> begin
> next_state = state;
> case (state)
> foo: next_state = bar;
> bar: output_x = 6; // no state change
> ...
> end
>
> in this case the first line always assigns next_state so if later not
> reassigned it remembers that value so there is no latch for
> next_state, strictly combinational of off state.

I think what Kevin was getting at was that in the two-process style,
every output signal in the asynchronous process needs to be assigned
for every case. The fact that there is a default assignment doesn't
change this - every output is defined for every possible case. Even if
there is a default assignment, you still need to specify the output
when the output differs from the default, which is different from
saying that the output needs to be specified only when it changes. You
could omit the output assignment for a case, and it might still change
from a non-default value to the default value. The default assignment
does not imply memory, it's just a shorthand notation to keep the code
more readable.

Dave
From: Eric Crabill on
Hi,

> Crux of the matter: Do you need to define values for outputs of your
> state machine in EVERY state, or do you only need to define values
> for outputs in states where you want the output to update/change?

It depends on the type of output. If the output is a combinational function
of the current state, or a combinational function of the current state and
the inputs, then you must describe the output values for all possible
conditions. This is how you model combinational logic; it doesn't matter if
it is part of an FSM or not.

On the other hand, if you have outputs which are a registered function of
the current state, or a registered function of the current state and the
inputs, then you do not need to describe the output values for all possible
conditions. Since you will be modeling these assignments to something that
maintains state in a clocked process, using a reg datatype, the absence of
an assignment for a given condition implies "retain the previous value".

Here's a short presentation on a "textbook" FSM:
http://www.engr.sjsu.edu/crabill/vlogfsm.pdf

To paraphrase what someone else wrote, if it solves the problem -- it's
correct. However, I think it's a good practice to fully understand what you
are creating when you write the code solve a given problem.

If you look at the code you provided in the context of a "textbook" FSM, I
would suggest that your FSM state variable is actually more than just
"state". It's
{ackb,cpu_lw_read,cpu_hw_read,cpu_lw_write,cpu_hw_write,state} and by way of
what is a custom state assignment implemented in the next state logic, you
are able to use certain bits of the state directly as outputs (Moore type
outputs) with no combinational decoding logic required to generate those
outputs.

Eric


From: Muzaffer Kal on
On Wed, 23 Apr 2008 08:54:24 -0700 (PDT), Dave <dhschetz(a)gmail.com>
wrote:

> The default assignment
>does not imply memory, it's just a shorthand notation to keep the code
>more readable.

Isn't the whole idea of a combinatorial process to avoid memory? In
the two process model, the non-clocked process is supposed to be fully
combinational. You can imagine the default assignment as the branch of
a mux coming from the output of the memory directly and the other
branch which is actually calculated next state. If there is no
calculated next state the current state gets loaded again.
From: KJ on
On Apr 24, 11:55 am, Muzaffer Kal <k...(a)dspia.com> wrote:
> On Wed, 23 Apr 2008 08:54:24 -0700 (PDT), Dave <dhsch...(a)gmail.com>
> wrote:
>
> > The default assignment
> >does not imply memory, it's just a shorthand notation to keep the code
> >more readable.
>
> Isn't the whole idea of a combinatorial process to avoid memory?

Yes...the memory is 'supposed to' be implemented in a separate clocked
process (for the two process design approach).

> In
> the two process model, the non-clocked process is supposed to be fully
> combinational.

But there is nothing preventing the designer from inadvertantly
creating a latch in this process. The two process approach presents
no advantages and has several disadvantages as compared to the one
process approach.

> You can imagine the default assignment as the branch of
> a mux coming from the output of the memory directly and the other
> branch which is actually calculated next state. If there is no
> calculated next state the current state gets loaded again.

If there is no 'calculated next state' in the combinatorial process
then you have a design error because you've just created a transparent
latch that will come up and bite you at the most inopportune time.
This latch is the 'unwanted memory' that is being created which should
not exist when using the two process form. All this unpleasantness is
completely avoided by simply using a one process design approach.

KJ
From: Kevin Neilson on
ee_ether wrote:
> Hi,
>
> A colleague and I are having a friendly debate on coding state
> machines in Verilog, targeting synthesis for FPGAs. Comments are very
> appreciated. I am NOT trying to start a holy war here regarding
> syntax style (one process vs. two process, etc).
>
> Crux of the matter: Do you need to define values for outputs of your
> state machine in EVERY state, or do you only need to define values for
> outputs in states where you want the output to update/change?
>

You shouldn't need to specify output values for states in which the
output doesn't change. However, this sometimes makes it hard to debug
something like a flag because you have to make sure that you deassert
the signal in all states that can follow the state in which you asserted it.

For things like flags that are only to be asserted on a few states, I
like to do this:

always@(posedge clk)
begin
flag <= 0; // set the default value
case (state)
state0: state <= state1;
state1: state <= state2;
state2: flag <= 1;
state3: state <= state0;
endcase
end

You can see that for state2, the value of flag is set twice: once to 0
and then later to 1. In a clocked process which uses nonblocking
signals, the assignment made last is the one that is used. (Sometimes
order *is* important with nonblocking assignments.) This ensures that
flag is assigned to 0 in every other state. If the synthesizer has
state machine extraction, it might just implement the logic to assert
flag's clock enable in the two states (state2 and state3) where it
actually changes. An explicit synthesis would update flag on every
cycle but only assign it to 1 on state2. If the machine is one-hot, it
wouldn't matter too much either way.
-Kevin