Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > State Machine with single cycle pulsed outputs?

Reply
Thread Tools

State Machine with single cycle pulsed outputs?

 
 
Analog_Guy
Guest
Posts: n/a
 
      09-24-2008
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.
 
Reply With Quote
 
 
 
 
KJ
Guest
Posts: n/a
 
      09-24-2008
On Sep 24, 12:42*pm, Analog_Guy <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
 
M. Norton
Guest
Posts: n/a
 
      09-24-2008
On Sep 24, 9:42*am, Analog_Guy <(E-Mail Removed)> 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
 
Reply With Quote
 
spam@oxfordbromley.plus.com
Guest
Posts: n/a
 
      09-25-2008
On Sep 24, 5:42 pm, Analog_Guy <(E-Mail Removed)> 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
 
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      09-25-2008
Hi
Please study the Toogle_button3 code at this site:
http://www.jjmk.dk/MMMI/Logic_Problems/No04_StopWatch/
it will give you some ideas.

Jeppe
 
Reply With Quote
 
gramador
Guest
Posts: n/a
 
      09-25-2008
On 25 Sep., 08:07, (E-Mail Removed) wrote:
> On Sep 24, 5:42 pm, Analog_Guy <(E-Mail Removed)> 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
 
Reply With Quote
 
Jan Decaluwe
Guest
Posts: n/a
 
      09-25-2008
gramador wrote:
> On 25 Sep., 08:07, (E-Mail Removed) wrote:
>> On Sep 24, 5:42 pm, Analog_Guy <(E-Mail Removed)> 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
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      09-25-2008
On Sep 25, 2:07*am, (E-Mail Removed) wrote:
> On Sep 24, 5:42 pm, Analog_Guy <(E-Mail Removed)> 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
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      09-25-2008
On Sep 25, 7:02*am, Jan Decaluwe <(E-Mail Removed)> 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
 
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      09-25-2008
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
State machine - Vending machine - strange behaviour fenster VHDL 3 12-23-2011 09:53 AM
Pulsed Event? me C++ 8 10-08-2004 02:30 PM
What is the state of state machine after power-up without reset conditions Weng Tianxiang VHDL 7 11-25-2003 06:24 PM
State machine: how to stay in a state? David Lamb VHDL 1 09-15-2003 05:24 PM



Advertisments