State Machine with single cycle pulsed outputs?

Discussion in 'VHDL' started by Analog_Guy, Sep 24, 2008.

  1. Analog_Guy

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

    Any help would be greatly appreciated.
    Analog_Guy, Sep 24, 2008
    #1
    1. Advertising

  2. Analog_Guy

    KJ Guest

    On Sep 24, 12:42 pm, Analog_Guy <> wrote:
    > 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
    KJ, Sep 24, 2008
    #2
    1. Advertising

  3. Analog_Guy

    M. Norton Guest

    On Sep 24, 9:42 am, Analog_Guy <> wrote:
    > 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
    M. Norton, Sep 24, 2008
    #3
  4. Analog_Guy

    Guest

    On Sep 24, 5:42 pm, Analog_Guy <> wrote:
    > 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.
    --
    Jonathan Bromley
    , Sep 25, 2008
    #4
  5. Analog_Guy

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    jeppe, Sep 25, 2008
    #5
  6. Analog_Guy

    gramador Guest

    On 25 Sep., 08:07, wrote:
    > On Sep 24, 5:42 pm, Analog_Guy <> wrote:
    >
    > > 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.
    > --
    > Jonathan Bromley


    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
    gramador, Sep 25, 2008
    #6
  7. Analog_Guy

    Jan Decaluwe Guest

    gramador wrote:
    > On 25 Sep., 08:07, wrote:
    >> On Sep 24, 5:42 pm, Analog_Guy <> wrote:
    >>
    >>> 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.
    >> --
    >> Jonathan Bromley

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

    --
    Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
    Kaboutermansstraat 97, B-3000 Leuven, Belgium
    From Python to silicon:
    http://myhdl.jandecaluwe.com
    Jan Decaluwe, Sep 25, 2008
    #7
  8. Analog_Guy

    KJ Guest

    On Sep 25, 2:07 am, wrote:
    > On Sep 24, 5:42 pm, Analog_Guy <> wrote:
    >
    > > 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.  


    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
    KJ, Sep 25, 2008
    #8
  9. Analog_Guy

    KJ Guest

    On Sep 25, 7:02 am, Jan Decaluwe <> wrote:
    >
    > 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
    KJ, Sep 25, 2008
    #9
  10. Analog_Guy

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    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
    jeppe, Sep 25, 2008
    #10
  11. Analog_Guy

    Dave Guest

    On Sep 25, 8:48 am, KJ <> wrote:
    > On Sep 25, 7:02 am, Jan Decaluwe <> wrote:
    >
    >
    >
    > > 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


    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
    Dave, Sep 25, 2008
    #11
  12. Analog_Guy

    Guest

    On Sep 25, 1:44 pm, KJ <> wrote:

    > 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
    --
    Jonathan Bromley
    , Sep 25, 2008
    #12
  13. Analog_Guy

    KJ Guest

    On Sep 25, 12:17 pm, Dave <> wrote:
    > On Sep 25, 8:48 am, KJ <> wrote:
    >
    > > On Sep 25, 7:02 am, Jan Decaluwe <> wrote:

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

    >
    > 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
    KJ, Sep 25, 2008
    #13
  14. Analog_Guy

    M. Norton Guest

    On Sep 25, 10:05 am, wrote:
    > > 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.


    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
    M. Norton, Sep 25, 2008
    #14
  15. Analog_Guy

    Guest

    On Sep 25, 6:14 pm, KJ <> wrote:

    > 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
    --
    Jonathan Bromley
    , Sep 25, 2008
    #15
  16. Analog_Guy

    KJ Guest

    On Sep 25, 1:05 pm, wrote:
    > On Sep 25, 1:44 pm, KJ <> wrote:
    >
    >
    > > 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)


    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.

    > > 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,


    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.

    > > In any case, your example is at least 30-40% more verbose* than it
    > > needs to be,

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

    > > 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 :)
    >


    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.

    > > 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 :)
    >


    Yep, thanks!

    Kevin Jennings
    KJ, Sep 25, 2008
    #16
  17. Analog_Guy

    M. Norton Guest

    On Sep 25, 11:00 am, KJ <> wrote:
    > 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
    M. Norton, Sep 25, 2008
    #17
  18. Analog_Guy

    KJ Guest

    On Sep 25, 2:22 pm, "M. Norton" <> wrote:
    > On Sep 25, 11:00 am, KJ <> wrote:
    > > 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'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
    KJ, Sep 25, 2008
    #18
  19. Analog_Guy

    Guest

    On Sep 25, 7:00 pm, KJ <> wrote:

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

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


    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.

    [...]
    > > 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.


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

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


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

    > > > In any case, your example is at least 30-40% more verbose* than it
    > > > needs to be,

    >
    > > That doesn't much bother me.

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

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


    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.
    --
    Jonathan Bromley
    , Sep 25, 2008
    #19
  20. Analog_Guy

    KJ Guest

    On Sep 25, 3:24 pm, wrote:
    > On Sep 25, 7:00 pm, KJ <> wrote:
    > > 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).
    >


    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.

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


    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.

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


    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.

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


    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
    KJ, Sep 25, 2008
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. me

    Pulsed Event?

    me, Oct 7, 2004, in forum: C++
    Replies:
    8
    Views:
    496
    Mike Wahler
    Oct 8, 2004
  2. john
    Replies:
    15
    Views:
    662
  3. john sun
    Replies:
    2
    Views:
    384
    Tim Mackey
    Jan 23, 2007
  4. raven
    Replies:
    0
    Views:
    303
    raven
    Jul 12, 2007
  5. Grumps
    Replies:
    2
    Views:
    669
    Grumps
    Feb 13, 2008
Loading...

Share This Page