state machine problem in vhdl

Discussion in 'VHDL' started by anupam, Sep 22, 2004.

  1. anupam

    anupam Guest

    Hi alls,
    I am facing problem with the following process.
    state machine from state "0001" goes to state "0011" instead of "0010"
    when the wr signal is low.
    Can u suggest something ?

    Regards,

    Anupam


    PROCESS (rst, extclk) --PROCESS no 01

    BEGIN
    IF rst = '0' THEN
    temp_w <= "0000";
    wrpointer_tx <= (OTHERS => (OTHERS => '0'));
    wren_txram <= '0';
    wraddress_txram <= (OTHERS => '0');
    ELSIF rising_edge(extclk) THEN
    case temp_w is
    when "0000" =>
    wren_txram <= '0';
    IF cs = '0' AND offset < "100000" THEN
    temp_w <= "0001";
    else temp_w <= "0000";
    end if;
    when "0001" =>
    wren_txram <= '0';
    wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
    data2txram <= datain;
    if wr = '0' then
    temp_w <= "0010";
    elsif rd = '0' then
    temp_w <= "0000";
    else temp_w <= "0001";
    end if;
    when "0010" =>
    temp_w <= "0100";
    wren_txram <= '1';
    wrpointer_tx(conv_integer(ch_no)) <=
    wrpointer_tx(conv_integer(ch_no)) + 1;
    when "0100" =>
    wren_txram <= '1';
    IF cs = '1' OR wr = '1' THEN
    temp_w <= "0000";

    ELSE
    temp_w <= "0100";
    END IF;

    when others => null;
    end case;
    IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
    datain(bit_XRES) = '1' THEN
    wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
    END IF;
    END IF;
    END PROCESS;
     
    anupam, Sep 22, 2004
    #1
    1. Advertising

  2. anupam

    Vince Guest

    Try to change this

    ----------------------------
    if wr = '0' then
    temp_w <= "0010"
    elsif rd = '0' then
    temp_w <= "0000";
    else temp_w <= "0001";
    end if;

    ---------------------------------------
    ****(if+ elsif + else) i hate this code....

    by this:

    ---------------------------------
    temp_w <= "0001";
    if wr = '0' then
    temp_w <= "0010"
    elsif rd = '0' then
    temp_w <= "0000";
    end if;
    ---------------------------------


    "anupam" <> a écrit dans le message de
    news:...
    > Hi alls,
    > I am facing problem with the following process.
    > state machine from state "0001" goes to state "0011" instead of "0010"
    > when the wr signal is low.
    > Can u suggest something ?
    >
    > Regards,
    >
    > Anupam
    >
    >
    > PROCESS (rst, extclk) --PROCESS no 01
    >
    > BEGIN
    > IF rst = '0' THEN
    > temp_w <= "0000";
    > wrpointer_tx <= (OTHERS => (OTHERS => '0'));
    > wren_txram <= '0';
    > wraddress_txram <= (OTHERS => '0');
    > ELSIF rising_edge(extclk) THEN
    > case temp_w is
    > when "0000" =>
    > wren_txram <= '0';
    > IF cs = '0' AND offset < "100000" THEN
    > temp_w <= "0001";
    > else temp_w <= "0000";
    > end if;
    > when "0001" =>
    > wren_txram <= '0';
    > wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
    > data2txram <= datain;
    > if wr = '0' then
    > temp_w <= "0010";
    > elsif rd = '0' then
    > temp_w <= "0000";
    > else temp_w <= "0001";
    > end if;
    > when "0010" =>
    > temp_w <= "0100";
    > wren_txram <= '1';
    > wrpointer_tx(conv_integer(ch_no)) <=
    > wrpointer_tx(conv_integer(ch_no)) + 1;
    > when "0100" =>
    > wren_txram <= '1';
    > IF cs = '1' OR wr = '1' THEN
    > temp_w <= "0000";
    >
    > ELSE
    > temp_w <= "0100";
    > END IF;
    >
    > when others => null;
    > end case;
    > IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
    > datain(bit_XRES) = '1' THEN
    > wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
    > END IF;
    > END IF;
    > END PROCESS;
    >
     
    Vince, Sep 22, 2004
    #2
    1. Advertising

  3. Vince a écrit:
    > Try to change this
    > ----------------------------
    > if wr = '0' then
    > temp_w <= "0010"
    > elsif rd = '0' then
    > temp_w <= "0000";
    > else temp_w <= "0001";
    > end if;
    > ---------------------------------------
    > ****(if+ elsif + else) i hate this code....
    > by this:
    > ---------------------------------
    > temp_w <= "0001";
    > if wr = '0' then
    > temp_w <= "0010"
    > elsif rd = '0' then
    > temp_w <= "0000";
    > end if;
    > ---------------------------------


    Strictly equivalent, this won't change anything.
    I think the problem comes from wr which is probably asynchronous, or
    badly resynchronized.


    --
    ____ _ __ ___
    | _ \_)/ _|/ _ \ Adresse de retour invalide: retirez le -
    | | | | | (_| |_| | Invalid return address: remove the -
    |_| |_|_|\__|\___/
     
    Nicolas Matringe, Sep 22, 2004
    #3
  4. Nicolas Matringe wrote:

    > I think the problem comes from wr which is probably asynchronous, or
    > badly resynchronized.


    I agree. Find all the inputs not synchronous with extclk,
    and fix them something like this:

    http://groups.google.com/groups?q=test_dqdq

    Your code looks good otherwise.

    -- Mike Treseler
     
    Mike Treseler, Sep 22, 2004
    #4
  5. anupam

    rickman Guest

    Mike Treseler wrote:
    >
    > Nicolas Matringe wrote:
    >
    > > I think the problem comes from wr which is probably asynchronous, or
    > > badly resynchronized.

    >
    > I agree. Find all the inputs not synchronous with extclk,
    > and fix them something like this:
    >
    > http://groups.google.com/groups?q=test_dqdq
    >
    > Your code looks good otherwise.


    I think the code will work, but it looks like he is trying to use
    one-hot encoding, but I don't think this is going to work. Plus I see
    one possible error. He is using four states, 0000, 0001, 0010 and
    0100. The msb never changes. I think the states should be 0001, 0010,
    0100 and 1000. Plus the way he has coded this, unless the compiler is
    very smart about recognizing one-hit encoding, it will still generate
    logic to decode all four bits on each transition.

    To use one-hot encoding, typically an enumerated type is used and an
    attribute is added to indicate one-hot encoding. I don't like this
    myself since I am not sure it is fully portable. So I construct my
    one-hot FSM by describing the various bits separately. temp_w(0) <=
    f(...). Then the optimal logic is easily obtained.

    --

    Rick "rickman" Collins


    Ignore the reply address. To email me use the above address with the XY
    removed.

    Arius - A Signal Processing Solutions Company
    Specializing in DSP and FPGA design URL http://www.arius.com
    4 King Ave 301-682-7772 Voice
    Frederick, MD 21701-3110 301-682-7666 FAX
     
    rickman, Sep 22, 2004
    #5
  6. > So I construct my
    > one-hot FSM by describing the various bits separately. temp_w(0) <=
    > f(...). Then the optimal logic is easily obtained.
    >


    I did'nt understand the way you said in the last line. Can I get an
    example it clarify myself.

    Thanks.

    Mohammed A.khader.
     
    Mohammed A.khader, Sep 23, 2004
    #6
  7. anupam

    jandc Guest

    > Hi alls,
    > I am facing problem with the following process.
    > state machine from state "0001" goes to state "0011" instead of "0010"
    > when the wr signal is low.
    > Can u suggest something ?
    >
    > Regards,
    >
    > Anupam
    >
    >
    > PROCESS (rst, extclk) --PROCESS no 01
    >
    > BEGIN
    > IF rst = '0' THEN
    > temp_w <= "0000";
    > wrpointer_tx <= (OTHERS => (OTHERS => '0'));
    > wren_txram <= '0';
    > wraddress_txram <= (OTHERS => '0');
    > ELSIF rising_edge(extclk) THEN
    > case temp_w is
    > when "0000" =>
    > wren_txram <= '0';
    > IF cs = '0' AND offset < "100000" THEN
    > temp_w <= "0001";
    > else temp_w <= "0000";
    > end if;
    > when "0001" =>
    > wren_txram <= '0';
    > wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
    > data2txram <= datain;
    > if wr = '0' then
    > temp_w <= "0010";
    > elsif rd = '0' then
    > temp_w <= "0000";
    > else temp_w <= "0001";
    > end if;
    > when "0010" =>
    > temp_w <= "0100";
    > wren_txram <= '1';
    > wrpointer_tx(conv_integer(ch_no)) <=
    > wrpointer_tx(conv_integer(ch_no)) + 1;
    > when "0100" =>
    > wren_txram <= '1';
    > IF cs = '1' OR wr = '1' THEN
    > temp_w <= "0000";
    >
    > ELSE
    > temp_w <= "0100";
    > END IF;
    >
    > when others => null;
    > end case;
    > IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
    > datain(bit_XRES) = '1' THEN
    > wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
    > END IF;
    > END IF;
    > END PROCESS;
    >


    Euhm... first of all: using a seperate process for the statemachine
    (which calculates nextstate) and a register to store state itself is a
    very good idea...

    Is it possible thet wr is a 'weak low' signal? This means that wr is 'L'
    and nog '0'. So in simulation this check will be false...
    If this is true change
    if wr = '0' then
    to
    if wr /= '1' then
    or
    if to_X01(wr) = '0' then
     
    jandc, Sep 23, 2004
    #7
  8. anupam

    Raghavendra Guest

    HI,
    I saw your code.there is something fishy.No where in the code you are
    state to 0011 & how can this problem arise.

    Regards,
    Raghavendra.

    "anupam" <> wrote in message news:<>...
    > Hi alls,
    > I am facing problem with the following process.
    > state machine from state "0001" goes to state "0011" instead of "0010"
    > when the wr signal is low.
    > Can u suggest something ?
    >
    > Regards,
    >
    > Anupam
    >
    >
    > PROCESS (rst, extclk) --PROCESS no 01
    >
    > BEGIN
    > IF rst = '0' THEN
    > temp_w <= "0000";
    > wrpointer_tx <= (OTHERS => (OTHERS => '0'));
    > wren_txram <= '0';
    > wraddress_txram <= (OTHERS => '0');
    > ELSIF rising_edge(extclk) THEN
    > case temp_w is
    > when "0000" =>
    > wren_txram <= '0';
    > IF cs = '0' AND offset < "100000" THEN
    > temp_w <= "0001";
    > else temp_w <= "0000";
    > end if;
    > when "0001" =>
    > wren_txram <= '0';
    > wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
    > data2txram <= datain;
    > if wr = '0' then
    > temp_w <= "0010";
    > elsif rd = '0' then
    > temp_w <= "0000";
    > else temp_w <= "0001";
    > end if;
    > when "0010" =>
    > temp_w <= "0100";
    > wren_txram <= '1';
    > wrpointer_tx(conv_integer(ch_no)) <=
    > wrpointer_tx(conv_integer(ch_no)) + 1;
    > when "0100" =>
    > wren_txram <= '1';
    > IF cs = '1' OR wr = '1' THEN
    > temp_w <= "0000";
    >
    > ELSE
    > temp_w <= "0100";
    > END IF;
    >
    > when others => null;
    > end case;
    > IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
    > datain(bit_XRES) = '1' THEN
    > wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
    > END IF;
    > END IF;
    > END PROCESS;
     
    Raghavendra, Sep 24, 2004
    #8
  9. anupam

    rickman Guest

    "Mohammed A.khader" wrote:
    >
    > > So I construct my
    > > one-hot FSM by describing the various bits separately. temp_w(0) <=
    > > f(...). Then the optimal logic is easily obtained.
    > >

    >
    > I did'nt understand the way you said in the last line. Can I get an
    > example it clarify myself.
    >
    > Thanks.
    >
    > Mohammed A.khader.


    BTW, it is a good idea to include a line showing who you are quoting. I
    sort my newsgroup listings by date, so I don't see the threads unless I
    change that. I almost missed replying to this message because I did not
    see my name as the person you were quoting.

    One hot encoding, in theory, reduces the width (depth) of logic by
    allowing the encoding for a given state to be represented by a single
    bit rather than by a large number of bits as is the case with binary.
    If you had an FSM with 17 states, you would need 5 bits for binary
    encoding and all five bits would be examined to decode a single state.

    With one-hot encoding, it will require 17 bits to encode all the states,
    but only one needs to be considered to determin if the machine is in a
    single state. Assume part of your machine looks like this...

    start speedup halt -resume
    -----> IDLE -----> RUNSLOW -----> RUNFAST -----> WAIT ----->
    ^ |
    | resume |
    +----------------------------+

    If we use one hot encoding, each state will have its own bit. The
    inputs to the logic for a given state function "f(...)" will only
    include those states that have the given state as one of its next
    states. The input function for RUNFAST will be f(RUNSLOW, RUNFAST,
    speedup, halt). No other states need be considered. The state RUNSLOW
    will be a bit more complex with f(IDLE, RUNSLOW, WAIT, start, speedup,
    resume). The input function for WAIT will be very simple with
    f(RUNFAST, halt).

    Some of these state functions can be encoded in a single LUT and many
    can be done in just two. But when the FSM has many transitions so that
    most states have transitions from more than 4 functions, the equations
    can depend on so many states, that a binary encoding might be more
    efficient. But once the number of states gets much above 8 it seems
    that one-hot encoding is most often the most efficent.

    --

    Rick "rickman" Collins


    Ignore the reply address. To email me use the above address with the XY
    removed.

    Arius - A Signal Processing Solutions Company
    Specializing in DSP and FPGA design URL http://www.arius.com
    4 King Ave 301-682-7772 Voice
    Frederick, MD 21701-3110 301-682-7666 FAX
     
    rickman, Sep 24, 2004
    #9
    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:
    682
  2. Weng Tianxiang
    Replies:
    7
    Views:
    1,109
    Mike Treseler
    Nov 25, 2003
  3. Weng Tianxiang
    Replies:
    3
    Views:
    1,407
    Weng Tianxiang
    Jul 25, 2006
  4. Grumps
    Replies:
    2
    Views:
    690
    Grumps
    Feb 13, 2008
  5. fenster
    Replies:
    3
    Views:
    1,162
    jeppe
    Dec 23, 2011
Loading...

Share This Page