(newbie) writing a state machine

M

Max

Guest
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
 
"Max" <cialdi@firenze.net> wrote in message
news:8e077568.0308290219.36bff1a9@posting.google.com...
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: jonathan.bromley@doulos.com
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.
 
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
 
Ralf Hildebrandt <Ralf-Hildebrandt@gmx.de> wrote in message news:<bipii8$bjvt8$3@ID-8609.news.uni-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
 

Welcome to EDABoard.com

Sponsor

Back
Top