State Machine with single cycle pulsed outputs?

A

Analog_Guy

Is there an easy method of creating a state machine to output control
signals that are only one clock cylce wide (i.e. upon entering a
state), no matter how long the state machine resides in that single
state? I like to use pulsed "start" and "stop" commands to control
functionality in other processes.

Any help would be greatly appreciated.
 
K

KJ

Is there an easy method of creating a state machine to output control
signals that are only one clock cylce wide (i.e. upon entering a
state), no matter how long the state machine resides in that single
state?  I like to use pulsed "start" and "stop" commands to control
functionality in other processes.

Any help would be greatly appreciated.

One approach is when transitioning into the state generate the pulse
and shut it off at the next state.

if rising_edge(clock) then
case Current_State is
when Prior_To_Some_State =>
if (... state change condition goes here) then
Current_State <= Some_State;
Gazouta <= '1'; -- Pulse it
end if;
when Some_State =>
Gazouta <= '0';
...
end case;
end if;

Another approach is to save the current state and then compare current
state with previous state. If they are different then this is the
first time in that state.

if rising_edge(clock) then
Previous_State <= Current_State;
case Current_State is
when Some_State =>
if (Previous_State /= Current_State) then
Gazouta <= '1'; -- Pulse it
else
Gazouta <= '0';
end if;
...
end case;
end if;

Other ways are possible that will depend on just exactly when you need
the pulse to occur.

KJ
 
M

M. Norton

Is there an easy method of creating a state machine to output control
signals that are only one clock cylce wide (i.e. upon entering a
state), no matter how long the state machine resides in that single
state?  I like to use pulsed "start" and "stop" commands to control
functionality in other processes.

Any help would be greatly appreciated.

Well, easy is in the eye of the beholder. However one way that comes
immediately to mind is to make each output the function of a two bit
vector, such that you could have:

signal start_edge : std_logic_vector(1 downto 0);
signal start_pulse : std_logic;

....

case state is
...
when UNIT_A =>
start_edge <= start_edge(0) & '1';
if (start_edge = "01") then
start_pulse <= '1';
else
start_pulse <= '0';
end if;

Naturally, you have to make sure your little "*_edge" signal gets set
to something appropriate, but the basic idea is there. It'll give you
a pulse one clock cycle in duration when the state is entered (to be
specific, one clock cycle after entering the state as it will take a
clock cycle to go from "00" to "01") and won't repeat.

There may be other more clever ways of handling it, but maybe this is
a start.

Best regards,
Mark Norton
 
G

Guest

Is there an easy method of creating a state machine to output control
signals that are only one clock cylce wide (i.e. upon entering a
state), no matter how long the state machine resides in that single
state? I like to use pulsed "start" and "stop" commands to control
functionality in other processes.

This is another reason for using a state variable: this kind of thing
is elegant and easy to code. Here's a very simple FSM with 2 states.
There's an idle (do-nothing) state, and a Run state.
When in Idle you stay there until you see the Go input
asserted; then transition to Run. At this point you would like
a Start output asserted for just one clock, but you also have
a Running output that remains asserted all the time you're in Run.
You then wait until Go becomes false; at this point you transition
back to Idle and assert a Stop signal for one cycle. Here's the
code (many declarations missing):

process (Clock) is
variable state: state_type; -- enum (Idle, Run)
begin
if rising_edge(Clock) then
if Synch_Reset='1' then
state := Idle;
Start <= '0';
Stop <= '0';
Running <= '0';
else
-- All outputs are defaulted here.
Start <= '0';
Stop <= '0';
Running <= '0';
-- Transition actions, compute next-state
-- and single-clock (edge detect) outputs
case state is
when Idle =>
if Go = '1' then
state := Run;
Start <= '1'; -- asserted for 1 clock only
end if;
when Run =>
if Go = '0' then
state := Idle;
Stop <= '0'; -- asserted for 1 clock only
end if;
end case;
-- Now "state" contains the next-state value,
-- use it to compute Moore (state-dependent) outputs
case state is
when Run =>
Running <= '1';
when others =>
null;
end case;
end if;
end if;
end process;

No edge detectors, no extra states, just a clear
distinction between things that happen on a
state transition and things that happen when
you're in a certain state.

It works for me; YMMV.
 
G

gramador

This is another reason for using a state variable: this kind of thing
is elegant and easy to code.  Here's a very simple FSM with 2 states.
There's an idle (do-nothing) state, and a Run state.
When in Idle you stay there until you see the Go input
asserted; then transition to Run.  At this point you would like
a Start output asserted for just one clock, but you also have
a Running output that remains asserted all the time you're in Run.
You then wait until Go becomes false; at this point you transition
back to Idle and assert a Stop signal for one cycle.  Here's the
code (many declarations missing):

  process (Clock) is
    variable state: state_type; -- enum (Idle, Run)
  begin
    if rising_edge(Clock) then
      if Synch_Reset='1' then
        state := Idle;
        Start <= '0';
        Stop <= '0';
        Running <= '0';
      else
        -- All outputs are defaulted here.
        Start <= '0';
        Stop <= '0';
        Running <= '0';
        -- Transition actions, compute next-state
        -- and single-clock (edge detect) outputs
        case state is
          when Idle =>
            if Go = '1' then
              state := Run;
              Start <= '1'; -- asserted for 1 clock only
            end if;
          when Run =>
            if Go = '0' then
              state := Idle;
              Stop <= '0'; -- asserted for 1 clock only
            end if;
        end case;
        -- Now "state" contains the next-state value,
        -- use it to compute Moore (state-dependent) outputs
        case state is
          when Run =>
            Running <= '1';
          when others =>
            null;
        end case;
      end if;
    end if;
  end process;

No edge detectors, no extra states, just a clear
distinction between things that happen on a
state transition and things that happen when
you're in a certain state.

It works for me; YMMV.

Hi Jonathan.

Where do you see the point in prefering a state variables instead of a
state signals?
At least in Modelsim they are more difficult to observe (if using the
"log -r /*" command to have all signals in available for watching in
wave window).

And a good design does not incorporate a number of state machines in
one design unit (IMHO). So you don't get a namespace problem.

Regards
Torsten
 
J

Jan Decaluwe

gramador said:
Hi Jonathan.

Where do you see the point in prefering a state variables instead of a
state signals?

In the semantics of course. THE SEMANTICS.

Variables have behavior that you can't easily duplicate
with signals. (Just try it on the example above.)

Jan
 
K

KJ

This is another reason for using a state variable: this kind of thing
is elegant and easy to code.  

A signal would work just as nicely...more later.
Here's a very simple FSM with 2 states.
There's an idle (do-nothing) state, and a Run state.
When in Idle you stay there until you see the Go input
asserted; then transition to Run.  At this point you would like
a Start output asserted for just one clock, but you also have
a Running output that remains asserted all the time you're in Run.

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.
You then wait until Go becomes false; at this point you transition
back to Idle and assert a Stop signal for one cycle.  Here's the
code (many declarations missing):

  process (Clock) is
    variable state: state_type; -- enum (Idle, Run)
  begin
    if rising_edge(Clock) then
      if Synch_Reset='1' then
        state := Idle;
        Start <= '0';
        Stop <= '0';
        Running <= '0';
      else
        -- All outputs are defaulted here.
        Start <= '0';
        Stop <= '0';
        Running <= '0';
        -- Transition actions, compute next-state
        -- and single-clock (edge detect) outputs
        case state is
          when Idle =>
            if Go = '1' then
              state := Run;
              Start <= '1'; -- asserted for 1 clock only
            end if;
          when Run =>
            if Go = '0' then
              state := Idle;
              Stop <= '0'; -- asserted for 1 clock only
I think you meant to set Stop to '1' above
            end if;
        end case;
        -- Now "state" contains the next-state value,
        -- use it to compute Moore (state-dependent) outputs
        case state is
          when Run =>
            Running <= '1';
          when others =>
            null;
        end case;
      end if;
    end if;
  end process;

No edge detectors, no extra states, just a clear
distinction between things that happen on a
state transition and things that happen when
you're in a certain state.

It works for me; YMMV.

I don't think you've met the definition of a 'clear distinction
between...'. 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' 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.

In any case, your example is at least 30-40% more verbose* than it
needs to be, it's not any clearer for that extra typing, it didn't
demonstrate some of the things you claimed (i.e. "another reason for
using a state variable" and "clear distinction between..."). Although
your example did show "No edge detectors, no extra states"...nobody
posted anything showing 'extra states' to begin with.

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.

Kevin Jennings

* 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.

-- Start of code
A_Block : block
signal state: state_type; -- enum (Idle, Run)
process (Clock) is
begin
if rising_edge(Clock) then
-- All outputs are defaulted here.
Start <= '0';
Stop <= '0';
if Synch_Reset='1' then
state <= Idle;
else
-- Transition actions, compute next-state
-- and single-clock (edge detect) outputs
case state is
when Idle =>
if Go = '1' then
state <= Run;
Start <= '1'; -- asserted for 1 clock only
end if;
when Run =>
if Go = '0' then
state <= Idle;
Stop <= '1'; -- asserted for 1 clock only
end if;
end case;
end if;
end if;
end process;
Running <= to_std_logic(state = Run);
end block A_Block;
-- End of code
 
K

KJ

Variables have behavior that you can't easily duplicate
with signals. (Just try it on the example above.)

That's true, but Jonathon's example was not a good demonstrator of
this difference.

KJ
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
Ok

HOW ABOUT - Shared variables - they can be seen by the simulator and acts as "normal" variables and can be used as input by more the one process.
BUT only driven from one process.

Jeppe
 
D

Dave

That's true, but Jonathon's example was not a good demonstrator of
this difference.

KJ

I think I can see two differences that favor Jonathan's code

1. The 'running' output is asserted all of the cycles that the state
machine is in 'Run' state, and none that it is in the 'Idle' state.
Brian's code produces a 1-cycle delayed running output, since it is
based on the current-state logic, not the next-state.

2. The 'runing' output is registered, which might be important for
large state machines.

I am curious, though, what Jonathan sees as being all of these other
reasons for using a state variable.

Dave
 
G

Guest

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
 
K

KJ

I think I can see two differences that favor Jonathan's code

1. The 'running' output is asserted all of the cycles that the state
machine is in 'Run' state, and none that it is in the 'Idle' state.
Brian's code produces a 1-cycle delayed running output, since it is
based on the current-state logic, not the next-state.

Take a look at my reply to Jonathon's post in this thread and see if
you still think your point is valid compared to that code...or more
broadly, if you see any advantages to Jonathon's code versus the code
that I posted.
2. The 'runing' output is registered, which might be important for
large state machines.

If the synthesis tool chooses to use one-hot encoding for 'state',
then the code I posted in reply to JB will be a register also. If I
wanted to insure that 'Running' was really a register I would move it
into the case statement as shown in the following snippet.

when Idle =>
if Go = '1' then
state <= Run;
Start <= '1'; -- asserted for 1 clock only
Running <= '1';
end if;
when Run =>
if Go = '0' then
state <= Idle;
Stop <= '1'; -- asserted for 1 clock only
Running <= '0';
end if;
I am curious, though, what Jonathan sees as being all of these other
reasons for using a state variable.

That could launch another variables vs. concurrent signal assignments
skirmish.

For what it's worth, I find it awkward to see code like the following
(which mimics JB's code) where the identifier 'state' in the two case
statements is referring to two logically different things.

case state is
....Do stuff that also happens to modify 'state'.
end case;
case state is
....Do other stuff
end case;

It would've been clearer if the first case statement produced a
variable named 'next_state' and the second case statement be on
'next_state' (i.e. a different identifier). The second case statement
is really basing things on what the 'next' state of the state machine
is going to be, but you can only know that by first seeing that the
earlier case statement modified the variable called 'state'.

So even if the section you're interested in analyzing at the moment is
in the second case statement, you still have to have prior analysis of
everything leading up to that case statement because of the use of
variables. When using signals you don't have that issue, you can
analyze the second case statement independently of the first. When
processes get a bit long (i.e. they don't fit on a screen without
scrolling) that can be a problem unless this is your code and it's all
still fresh in your mind at that time...and you remember it correctly.

KJ
 
M

M. Norton

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.

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
 
G

Guest

It would've been clearer if the first case statement produced a
variable named 'next_state' and the second case statement be on
'next_state' (i.e. a different identifier). The second case statement
is really basing things on what the 'next' state of the state machine
is going to be, but you can only know that by first seeing that the
earlier case statement modified the variable called 'state'.

That's entirely true, and I can see that it might make things
clearer to use two variables (or a next-state variable and a
current-state signal) as you suggest. On the other hand, you
then have to be absolutely sure that you remember to update the
state from the next-state variable, which comes free in the
style I used.

Thanks
 
K

KJ

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)

There is no rationale for defaulting all the outputs to anything at
the top of the process since this is a synchronous process. You say
'often a good idea' but as I'll get to later in this case it's not a
good idea.
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.

But there is no real distinction between outputs that happen to be
there for one clock cycle versus one that are there for more. All
outputs must perform the logic function that is required for them,
classifying them and structuring your code differently by how many
clock cycles they need to be asserted or whether they are asserted on
a state transition or not is a pointless exercise.
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,

Darn right. Had you not defaulted 'Running' to '0' at the top of the
process which you did only because you often find it to be a good
idea, the relevant section of code would be

when Idle =>
if Go = '1' then
state <= Run;
Start <= '1'; -- asserted for 1 clock only
Running <= '1';
end if;
when Run =>
if Go = '0' then
state <= Idle;
Stop <= '1'; -- asserted for 1 clock only
Running <= '0';
end if;

If you have no problem with 'Start' and 'Stop' being where they are in
your code, then there should be no problem with having 'Running' being
assigned right along with them (and of course in the 'reset' section).
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.

So maybe now you won't be blindly assigning default values at the top
of the process then huh? If one assigns such an output on reset and
then only specifies transitions you're good to go as well...in other
words, the form is just like the way the state gets assigned.
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.

And as I've shown it can be specified in a manner that it would be a
registered output.
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.

I'll take your word on it breaking the one-to-one mapping from state
transition diagram to code since I don't use such diagrams or much
care whether the code I'm writing is Mealy or Moore. Dare I ask
though what implications there are to such a breaking on the mapping?
Function, and performance fitting within the design constraints are
the big ones where I work.
Since I still
find state transition diagrams a useful thinking tool, that
matters to me very much.

OK.


That doesn't much bother me.

It costs you though. (time=money and all that).
  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.

It's your choice to limit yourself to a single process though.
Concurrent statements and functions do the same thing for basically
the same amount of effort. Without having this morph off into the
'scope of variables' clash, I'll just say that the "in a single
process" clause in your statement is a self imposed and needless
straight jacket.
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 :)

I see no need to have any distinction between any of the outputs.
They are outputs, they do whatever it is they are functionally
supposed to be doing. If that means they are asserted for one clock,
two clocks or whenever we're in a state or a function of other inputs
and state does not matter to me. Outputs are just signals...just like
the state of the state machine.
You asked, I answered :)

Yep, thanks!

Kevin Jennings
 
M

M. Norton

Darn right.  Had you not defaulted 'Running' to '0' at the top of the
process which you did only because you often find it to be a good
idea, the relevant section of code would be

when Idle =>
  if Go = '1' then
    state <= Run;
    Start <= '1'; -- asserted for 1 clock only
    Running <= '1';
  end if;
when Run =>
  if Go = '0' then
    state <= Idle;
    Stop <= '1'; -- asserted for 1 clock only
    Running <= '0';
  end if;

If you have no problem with 'Start' and 'Stop' being where they are in
your code, then there should be no problem with having 'Running' being
assigned right along with them (and of course in the 'reset' section).

However, if I'm following along correctly, this no longer works for
start and stop, unless you are going to explicitly turn them off in
the relevant states? I know I've had to do that before (I don't
typically use the "default at the top" but can see both sides of the
story here.)

And, I'd still like to know if the variable/signal distinction mixed
together in a process is valid RTL semantics.

Best regards,
Mark Norton
 
K

KJ

However, if I'm following along correctly, this no longer works for
start and stop, unless you are going to explicitly turn them off in
the relevant states?  

I'm not sure what you mean by not working for start and stop, but the
logic that Jonathon has for for start and stop would remain as he had
it. I was simply showing where you would assign to the signal
'running' inside the case statement to get it to function in the same
manner and to guarantee that you get a register.

The "running <= '0'" statement (not shown in the snippet I posted)
would be moved from where Jonathon had it (where it would be
encountered on every clock) into the "if reset = '1' then" (where it
would be assigned to only at reset to get it initialized to the
correct value).
I know I've had to do that before (I don't
typically use the "default at the top" but can see both sides of the
story here.)

Default at the top is handy when 'most of the time' you want that
default value to be used and there are only a few specific cases where
you don't. In the case that the OP asked about for creating a single
clock cycle pulse, this is a good technique since it cuts down on
typing and errors.

In the case that Jonathon brought up with his new signal called
'running' he still likes the default at the top although I do not.
And, I'd still like to know if the variable/signal distinction mixed
together in a process is valid RTL semantics.

It is valid to use both signals and variables. Personally I haven't
had any synthesis problems with variables but I use them rather
sparingly compared to others in this group. There have been reports
of people having troubles with variables with certain tools, but to be
fair there can be reports of all kinds of bad things and I think even
the heavy variable users generally have no trouble with them
either...but hold out for posts from those like Treseler or Andy (the
biggest variable proponents that seem to haunt these halls) who use
them more frequently than I do for more info on which tools they
believe do and don't work well with variables.

KJ
 
G

Guest

There is no rationale for defaulting all the outputs to anything at
the top of the process since this is a synchronous process. You say
'often a good idea' but as I'll get to later in this case it's not a
good idea.

In a state machine with many states, an output that is asserted
in only one or two states is most conveniently expressed by
a default followed by assertion in the chosen state(s).
But there is no real distinction between outputs that happen to be
there for one clock cycle versus one that are there for more. All
outputs must perform the logic function that is required for them,
classifying them and structuring your code differently by how many
clock cycles they need to be asserted or whether they are asserted on
a state transition or not is a pointless exercise.

Eh? The OP asked how he could do the single-clock thing.
I showed a coding form that makes it very obvious which
outputs are asserted for a single cycle on a transition.
Now you're telling me that there's no difference. I don't
understand.

[...]
So maybe now you won't be blindly assigning default values at the top
of the process then huh? If one assigns such an output on reset and
then only specifies transitions you're good to go as well...in other
words, the form is just like the way the state gets assigned.

With respect I think you're being deliberately obtuse here.
Consider an FSM with four states A,B,C,D. Some output F
must be asserted in state D, and must be registered. There
are conditional transitions from all three statest A, B, C
to D. In the form you suggest, I must assert F in at least
THREE different places - all three transitions - just to
get the signal asserted during state D. That can easily
be made to work, but it seems to me to defeat the point
of using the FSM design paradigm (and that, of course,
is a whole different discussion; maybe FSMs have had their
day, maybe not).
And as I've shown it can be specified in a manner that it would be a
registered output.

I'm not for a moment disputing that you *can* so describe it.
But I *like* to use state transition diagrams as an intermediate
thinking step between specification and code, and therefore I
don't want to have to do the one-cycle lookahead - possibly
from several different "source" states - that your scheme
requires.
I'll take your word on it breaking the one-to-one mapping from state
transition diagram to code since I don't use such diagrams

So hang on, you're saying that you move straight from spec
to code? I can see that being possible and even perhaps a
good idea, but it's not what the OP was talking about and
it's not what works for me.
or much
care whether the code I'm writing is Mealy or Moore.

Me neither - for years I couldn't even remember which was
which. The names are just shorthand.
Dare I ask
though what implications there are to such a breaking on the mapping?

It kicks away a useful intellectual prop. I am not ashamed
that I need such.
Function, and performance fitting within the design constraints are
the big ones where I work.

Fair enough. There's no doubt that some synth tools do a
sub-optimal job on the FSM coding scheme I outlined; you
get working hardware, but it may be bigger or slower than
you might wish. In practice this doesn't bother me because
not only is the FSM usually a rather small part of the design,
but it's rarely on the critical timing path - especially if
all its outputs are registered.....
It costs you though. (time=money and all that).

Phooey. I spend a tiny fraction of my life writing code;
much more time is spent reading it and reasoning about it.
Clarity is all. If you can show me that I could write the
code more clearly at the expense of a few extra lines,
I'll do it. Case in point: your suggestion that I make my
next-state variable explicit. I may well start to do that.
It's your choice to limit yourself to a single process though.
Concurrent statements and functions do the same thing for basically
the same amount of effort. Without having this morph off into the
'scope of variables' clash, I'll just say that the "in a single
process" clause in your statement is a self imposed and needless
straight jacket.

Well, I think we're in personal-taste territory there. But I
would like to point out that as I get older my jackets are less
and less straight; strait-jackets, though, I will always avoid :)
I see no need to have any distinction between any of the outputs.
They are outputs, they do whatever it is they are functionally
supposed to be doing. If that means they are asserted for one clock,
two clocks or whenever we're in a state or a function of other inputs
and state does not matter to me. Outputs are just signals...just like
the state of the state machine.

Design patterns are still useful, though... and I offered a
design pattern that allows you to code, easily, the common
requirements "signal asserted for one cycle on entry to a
state" and "signal asserted for the duration of a state".
Of course you can re-invent those every time you need them.
Your choice.
 
K

KJ

In a state machine with many states, an output that is asserted
in only one or two states is most conveniently expressed by
a default followed by assertion in the chosen state(s).

I agree, but your example with the signal 'running' the use of
defaults at the top doesn't help with clarity although we apparently
disagree on that. With 'start' and 'stop' the defaults do help the
clarity of design intent.
Eh?  The OP asked how he could do the single-clock thing.
I showed a coding form that makes it very obvious which
outputs are asserted for a single cycle on a transition.
Now you're telling me that there's no difference. I don't
understand.

I agree that we both presented methods that met the OP's wish to code
single clock cycle pulses, you also went beyond the call of duty and
showed how you would code up an additional unrequested registered
output signal that was a function of state.

All I'm saying is that the physical placement of the source code for
setting the signal should not depend on whether or not it is a one
clock cycle pulse or not. Maybe it's just a style thing.
With respect I think you're being deliberately obtuse here.

Not trying to be.
Consider an FSM with four states A,B,C,D.  Some output F
must be asserted in state D, and must be registered.  There
are conditional transitions from all three statest A, B, C
to D.  In the form you suggest, I must assert F in at least
THREE different places - all three transitions - just to
get the signal asserted during state D.  

There would be a situation where use of variables would be good
because it would actually cut down and clarify the code and likely
make it easier to maintain.

But I'd also suggest that such a state machine occurs more often when
the overall design has not been thought out enough and subdivided into
reasonable sized pieces. It seems to come up when folks like to have
*the state machine* (with way more than the four states that you
mentioned) that does some *big* function but a bit more thought would
have led to a design with several smaller state machines perhaps
organized in some form of pipeline, or maybe as a master/slave
arrangement, depending on what the needs are. What I've found is that
the smaller, more numerous collection that has a standardized
signalling interface is easier to design, debug and get working,
generally requires less logic and runs faster than the large
monolithic approach.

Lastly, I'm not trying to suggest that the four state machine that you
described should be sub-divided just that I haven't found the
situation that you described to be all that common...if nothing else,
many times that signal can be asserted one tick later and be just
fine. By not needing to depend on 'next state' information,
performance is usually improved, so it should only be used when really
needed.
So hang on, you're saying that you move straight from spec
to code?  I can see that being possible and even perhaps a
good idea, but it's not what the OP was talking about and
it's not what works for me.

I'd go from requirements spec as input to functional spec for the
thing that I'm working on to code. The widget I work on needs to be
documented and as I flush out the details of how I would go about
doing it, that info gets into the functional spec. The code is
written somewhat in parallel with the creation of that spec mainly
because as I work out the overall design details and get them into the
spec and notes what seemed like a good idea at first might not be
later on. I try to move the 'later on' up sooner by writing code and
update the functional spec as required. For the most part though,
after the functional spec that I write (based on the requirements
spec) is somewhat 'done' I jump to code/board design/whatever design.
Design patterns are still useful, though...  and I offered a
design pattern that allows you to code, easily, the common
requirements "signal asserted for one cycle on entry to a
state" and "signal asserted for the duration of a state".
Of course you can re-invent those every time you need them.
Your choice.

Fair enough...I have enough to keep straight without having to think
to myself what is the design pattern for a single clock cycle pulse
versus something else since I know in my head what overall function
I'm trying to accomplish. But based on the OP, obviously it's not
clear to all and since you're in the training world you would see more
of that then I.

KJ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top