(newbie) writing a state machine

Discussion in 'VHDL' started by Max, Aug 29, 2003.

  1. Max

    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, Aug 29, 2003
    #1
    1. Advertising

  2. "Max" <> wrote in message
    news:...
    > 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:
    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.
     
    Jonathan Bromley, Aug 29, 2003
    #2
    1. Advertising

  3. 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, Aug 29, 2003
    #3
  4. Max

    Max Guest

    Ralf Hildebrandt <> wrote in message news:<bipii8$bjvt8$-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
     
    Max, Sep 1, 2003
    #4
    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. David Lamb
    Replies:
    1
    Views:
    694
  2. Weng Tianxiang
    Replies:
    7
    Views:
    1,130
    Mike Treseler
    Nov 25, 2003
  3. Weng Tianxiang
    Replies:
    3
    Views:
    1,460
    Weng Tianxiang
    Jul 25, 2006
  4. Grumps
    Replies:
    2
    Views:
    710
    Grumps
    Feb 13, 2008
  5. fenster
    Replies:
    3
    Views:
    1,173
    jeppe
    Dec 23, 2011
Loading...

Share This Page