Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > A general rule for State Machines?

Reply
Thread Tools

A general rule for State Machines?

 
 
Dave Dean
Guest
Posts: n/a
 
      09-12-2006
Hi all,
I've got a question about some alternate ways to implement a state
machine - in particular, when you may be in a state for several cycles -
I'll use a deserializer as my example here.

First, suppose a boring deserializer that needs to grab just one bit:

entity test is
port (
data_in : in std_logic;
clk : in std_logic
);
end test;

architecture one_bit of test is

type states is (idle, get_data);
signal state : states;
signal data : std_logic;

begin
process(clk)
begin
if (rising_edge(clk)) then
case state is
when idle => if (go='1') then state <= get_data; end if;
when get_data => data <= data_in;
state <= idle;
end case;
end if;
end process;
end one_bit;
---------------------------------
very simple. Now, suppose we need to deserialize TWO bits. Here's two
different changes to the SM that will do this:

architecture two_bits1 of test is

type states is (idle, get_data1, get_data2);
signal state : states;
signal data : std_logic_vector(1 downto 0);

begin
process(clk)
begin
if (rising_edge(clk)) then
case state is
when idle => if (go='1') then state <= get_data1; end if;
when get_data1 => data <= data(0) & data_in;
state <= get_data2;
when get_data2 => data <= data(0) & data_in;
state <= idle;
end case;
end if;
end process;
end imp;
--------------------------------------
architecture two_bits2 of test is

type states is (idle, get_data);
signal state : states;
signal data : std_logic_vector(1 downto 0);
signal counter : std_logic;

begin
process(clk)
begin
if (rising_edge(clk)) then
case state is
when idle => if (go='1') then
state <= get_data;
counter <= '0';
end if;
when get_data => data <= data(0) & data_in;
counter <= counter + 1;
if (counter='1') then
state <= idle;
end if;
end case;
end if;
end process;
end imp;
----------------------------
In the first example, I added a second "get_data" state to allow me to get 2
bits. In the second, I added a counter, so I could stay in the one
"get_data" state for two cycles. In this small example, I'm not sure which
implementation is better.
However, when you start getting significantly larger, like this 16-bit
example:

architecture 16bits of test is

type states is (idle, get_data);
signal state : states;
signal data : std_logic_vector(15 downto 0);
signal counter : std_logic_vector(3 downto 0);

begin
process(clk)
begin
if (rising_edge(clk)) then
case state is
when idle => if (go='1') then
state <= get_data;
counter <= (others => '0');
end if;
when get_data => data <= data(14 downto 0) & data_in;
counter <= counter + 1;
if (counter="1111") then
state <= idle;
end if;
end case;
end if;
end process;
end 16bits;
----------------------------------
Here, I think a counter will be better than adding 16 extra states. If you
use one-hot encoding, you'll be using a lot of extra resources with the
additional states (right?).

Anyway, this is a fairly simple example that I hope illustrates the larger
point. Does anyone have a good rule of thumb of when to use a counter and
when to add extra states? I suppose it can depend on the particular
situation (the extra states will usually be faster) but the counter is
certainly more flexible and elegent.

Thanks,
Dave


 
Reply With Quote
 
 
 
 
Paul Uiterlinden
Guest
Posts: n/a
 
      09-12-2006
Dave Dean wrote:

> Anyway, this is a fairly simple example that I hope illustrates the
> larger
> point. Does anyone have a good rule of thumb of when to use a
> counter and
> when to add extra states?


My opinion: go for the implementation that shows the least code
duplication. This makes it more robust against introduction of bugs
when the implementation is changed. Using a counter certainly would
have my preference. It just makes the code easier to maintain.

--
Paul.

 
Reply With Quote
 
 
 
 
Andy
Guest
Posts: n/a
 
      09-12-2006
Anytime I need to delay more than 3 or 4 clocks, I prefer to use a
counter. Plus, the length of the delay counter can be parameterized.

case state is
when start =>
state := waiting;
delay_cnt := WAIT_DELAY;
when waiting =>
if delay_cnt - 1 < 0 then -- for integer counters only!
state := go;
else
delay_cnt := delay_cnt - 1;
end if;
when ...
end case;

Andy


Paul Uiterlinden wrote:
> Dave Dean wrote:
>
> > Anyway, this is a fairly simple example that I hope illustrates the
> > larger
> > point. Does anyone have a good rule of thumb of when to use a
> > counter and
> > when to add extra states?

>
> My opinion: go for the implementation that shows the least code
> duplication. This makes it more robust against introduction of bugs
> when the implementation is changed. Using a counter certainly would
> have my preference. It just makes the code easier to maintain.
>
> --
> Paul.


 
Reply With Quote
 
homoalteraiensis
Guest
Posts: n/a
 
      09-14-2006
If there is no demand for hot encoded states due to speed problems, I
prefer counters, since they can be reused in more than one area of a
complex state machine. Also a counter realy indicates "wait" where
states can do anything (using 2 fsm where actions and clocking are
separated, you will have to check the state transistion part if there
are really nothing else than transions without conditions.

 
Reply With Quote
 
Andy Peters
Guest
Posts: n/a
 
      09-18-2006
Paul Uiterlinden wrote:
> Dave Dean wrote:
>
> > Anyway, this is a fairly simple example that I hope illustrates the
> > larger
> > point. Does anyone have a good rule of thumb of when to use a
> > counter and
> > when to add extra states?

>
> My opinion: go for the implementation that shows the least code
> duplication. This makes it more robust against introduction of bugs
> when the implementation is changed. Using a counter certainly would
> have my preference. It just makes the code easier to maintain.


Agreed. As a bonus, you can generalize the code by using a generic to
set the number of bits.

-a

 
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
General....very general.... no important for u forever hi Python 0 03-18-2009 08:21 AM
General rule for constructors pek Java 12 08-16-2008 10:15 AM
General "previous page" feature saving state Jeff ASP .Net 1 01-22-2007 10:01 AM
how to add validation rule for url in the validation-rule.xml ,I added some thing like this but......... shailajabtech@gmail.com Java 0 10-12-2006 08:36 AM
Unable to serialize the session state. Please note that non-serializable objects or MarshalByRef objects are not permitted when session state mode is 'StateServer' or 'SQLServer'. Mike Larkin ASP .Net 1 05-23-2005 12:33 PM



Advertisments