(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. Advertisements

  2. 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.
    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. Advertisements

  3. Hi Max!


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

    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.

    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.

    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

    I tried something like this but it was not synthetizable....
    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. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.