Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > (newbie) writing a state machine

Reply
Thread Tools

(newbie) writing a state machine

 
 
Max
Guest
Posts: n/a
 
      08-29-2003
I must write a state machine that depend also on number o events that
occurs in any state.

for example:

I have this ports:
Port ( clk : in std_logic;
din : in std_logic;
sclk : out std_logic);

I need to wait 2 falling edge of din (state 0), then 4 rising edge of
clk (state 1), and finally I can set sclk to 1 as long as 3 falling
edge of clk (state 3). Then it restart from state 0.

I tried varius solution but any of them works.

could you help me?

thanks
 
Reply With Quote
 
 
 
 
Jonathan Bromley
Guest
Posts: n/a
 
      08-29-2003
"Max" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> I must write a state machine that depend also on number o events that
> occurs in any state.
>
> for example:
>
> I have this ports:
> Port ( clk : in std_logic;
> din : in std_logic;
> sclk : out std_logic);
>
> I need to wait 2 falling edge of din (state 0), then 4 rising edge of
> clk (state 1), and finally I can set sclk to 1 as long as 3 falling
> edge of clk (state 3). Then it restart from state 0.


Various ideas:

To detect falling edge on din, use a piece of logic OUTSIDE the
state machine that takes a copy of din on every clock. Then
falling_edge = (din = '0') and (din_delayed = '1'). Or something
like that.

To count off clocks or whatever, have a counter that's preset to
some value on entry to a state, and decrements on each clock when
in that state; then when the counter reaches zero, it's time to
move on to the next state.

Or alternatively, split each state into several sub-states and
advance from one sub-state to the next unconditionally on
the clock. This approach is probably easier to understand
and code, but is less flexible.

> I tried varius solution but any of them works.


Strange. I can think of lots of solutions that would work.
Can you share your failed solutions with us?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: http://www.velocityreviews.com/forums/(E-Mail Removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.



 
Reply With Quote
 
 
 
 
Ralf Hildebrandt
Guest
Posts: n/a
 
      08-29-2003
Hi Max!



> I have this ports:
> Port ( clk : in std_logic;
> din : in std_logic;
> sclk : out std_logic);
>
> I need to wait 2 falling edge of din (state 0)


Write a counter, that counts from 0 to 2 every falling_edge(din).
If it has reached 2, hold the counter.


> , then 4 rising edge of
> clk (state 1),


Write a counter, that counts from 0 to 4 every rising_edge(clk), iff the
first counter has reached 2. If it has reached 4, hold the counter.


> and finally I can set sclk to 1 as long as 3 falling
> edge of clk (state 3).


If sclk can be set and reset with falling_edge(clk), try this:
Test every falling_edge(clk), if the second counter has reached 4. If it
has reached 4, set sclk to 1 and count from 0 to 3 with every
falling_edge(clk). Reset sclk, while counting from 2 to 3.

Prevent the 3rd counter from running with a test of counter 2: if
coutner 2 is not equal to 4, do nothing with counter 3.


> Then it restart from state 0.


Apply a rest-signal for the first and second counter, that is set, when
the third counter has reached 2, and reset, when the 3rd counter has
reached 3.



Your question is not about a "normal" state machine. "Normal" state
machines in VHDL act on one edge of one clock. My solution for your
problem is a 3-state-machine - solution, where every state machine is a
simple counter.


Ralf

 
Reply With Quote
 
Max
Guest
Posts: n/a
 
      09-01-2003
Ralf Hildebrandt <(E-Mail Removed)> wrote in message news:<bipii8$bjvt8$(E-Mail Removed)-berlin.de>...

> > I have this ports:
> > Port ( clk : in std_logic;
> > din : in std_logic;
> > sclk : out std_logic);
> >
> > I need to wait 2 falling edge of din (state 0)

>
> Write a counter, that counts from 0 to 2 every falling_edge(din).
> If it has reached 2, hold the counter.
>
>
> > , then 4 rising edge of
> > clk (state 1),

>
> Write a counter, that counts from 0 to 4 every rising_edge(clk), iff the
> first counter has reached 2. If it has reached 4, hold the counter.
>
>
> > and finally I can set sclk to 1 as long as 3 falling
> > edge of clk (state 3).

>
> If sclk can be set and reset with falling_edge(clk), try this:
> Test every falling_edge(clk), if the second counter has reached 4. If it
> has reached 4, set sclk to 1 and count from 0 to 3 with every
> falling_edge(clk). Reset sclk, while counting from 2 to 3.
>
> Prevent the 3rd counter from running with a test of counter 2: if
> coutner 2 is not equal to 4, do nothing with counter 3.

I tried something like this but it was not synthetizable....

>
>
> > Then it restart from state 0.

>
> Apply a rest-signal for the first and second counter, that is set, when
> the third counter has reached 2, and reset, when the 3rd counter has
> reached 3.
>
>
>
> Your question is not about a "normal" state machine. "Normal" state
> machines in VHDL act on one edge of one clock. My solution for your
> problem is a 3-state-machine - solution, where every state machine is a
> simple counter.

what is a "3-state-machine"
could you write me a simple example?

I tried to make all couters as process, using a some enable signals,
but it was not synthetizable.

I tried this:
----8<----------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity main is
Port ( clk : in std_logic;
din : in std_logic;
sclk : out std_logic);
end main;

architecture Behavioral of main is

type state_type is (ST0, ST1, ST2);
signal state: state_type;

--signal cnt : integer range 0 to 10;

begin

sclk <= '0' when state /= ST2 else '1';

transition: process (state, clk, din)
variable cnt : integer range 0 to 10;
begin
case state is
when ST0 =>
if falling_edge(din) then
if cnt < 2 then
cnt := cnt + 1;
else
state <= ST1;
cnt := 0;
end if;
end if;
when ST1 =>
if rising_edge(clk) then
if cnt < 4 then
cnt := cnt + 1;
else
cnt := 0;
state <= ST2;
end if;
end if;
when ST2 =>
if falling_edge(clk) then
if cnt < 3 then
cnt := cnt + 1;
else
cnt := 0;
state <= ST0;
end if;
end if;
end case;
end process;


end Behavioral;
----8<----------------
but it is not synthetizable, neithe if cnt is variable nor it is
signal.
the error is:

ERROR:Xst:827 - main.vhd line 28: Signal cnt cannot be synthesized,
bad synchronous description.

I don't know why.

could you help me?

thanks
 
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
How to print a state flow graph for a state machine using Xilinx ISE or ModelSim Weng Tianxiang VHDL 3 07-25-2006 01:19 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