State Machine prblem in VHDL

Discussion in 'VHDL' started by fpgawizz, Mar 14, 2005.

  1. fpgawizz

    fpgawizz Guest

    I have this state machine where in reset state , I assign four signals (8
    bit stdlogic vecs) values..and then in the next state i try to read their
    values and pass it on to a display..for some reason, i get all zeros..i
    used modelsim to simulate and it looked good..

    here is the snippet..

    case current_state is
    when RESET =>
    R0 <= "11110001";
    R1 <= "01010101";
    R2 <= "10111100";
    R3 <= "11001101";
    next_state <= IDLE;
    when IDLE =>
    sd0 <= R0(3 downto 0);
    sd1 <= R0(7 downto 4);
    sd2 <= R1(3 downto 0);
    sd3 <= R1(7 downto 4);
    if BTN0 = '1' then
    next_state <= ChkOp;
    else
    next_state <= IDLE;
    end if;
    when ChkOp =>
    yada yada yada.....

    sd0,sd1,sd2 and sd3 are connected to my display which is running at 1KHz.
    My state machine is running at abot 250 Hz. Any ideas why my 4 outputs are
    at zero and not displaying the correct values.

    thanks
    fpgawizz, Mar 14, 2005
    #1
    1. Advertising

  2. fpgawizz

    Neo Guest

    It is difficult to say with what you have posted. If you can, put the
    complete code or atleast the complete process where the case statement
    resides.
    Neo, Mar 14, 2005
    #2
    1. Advertising

  3. fpgawizz

    Guest

    The code you posted looks good. Try the change below. It should not
    be necessary, but I have had to do similar changes to make a certain
    compiler synthesize my code properly.

    when IDLE =>
    sd0(3 downto 0) <= R0(3 downto 0);
    sd1(3 downto 0) <= R0(7 downto 4);
    sd2(3 downto 0) <= R1(3 downto 0);
    sd3(3 downto 0) <= R1(7 downto 4);
    if BTN0 = '1' then
    next_state <= ChkOp;
    else
    next_state <= IDLE;
    end if;
    , Mar 14, 2005
    #3
  4. fpgawizz

    fpgawizz Guest

    Neo,
    Here is the complete code.

    State_Memory:process(fsmclk,Reset,BTN0,BTN1,BTN2)
    begin
    if reset = '1' then
    current_State <= RST;
    elsif BTN0 = '1' then
    current_State <= ChkOp;
    elsif BTN1 = '1' then
    current_State <= ReadSel;
    elsif BTN2 = '1' then
    current_state <= ShowR2R3;
    elsif fsmclk'event and fsmclk = '1' then
    current_state <= next_state;
    internal_databus <= Databus;
    end if;
    end process State_Memory;

    Next_State_Logic:
    Process(current_state,BTN0,BTN1,BTN2)

    begin

    case current_state is
    when RST =>
    R0 <= "00000000";
    R1 <= "00000001";
    R2 <= "00000010";
    R3 <= "00000011";
    LD7 <= '1';
    LD0 <= '0';
    LD6 <= '0';
    next_state <= IDLE;
    when IDLE =>
    SramAddr2 <= "00000000"; CE2 <= '1';
    CE1 <= '0';
    UB <= '1';
    LB <= '0';
    OE <= '1';
    WE <= '1';
    DataBus <= "ZZZZZZZZ";
    LD0 <= '1';
    LD6 <= '1';
    LD7 <= '0';
    sd0 <= R0(3 downto 0);
    sd1 <= R0(7 downto 4);
    sd2 <= R1(3 downto 0);
    sd3 <= R1(7 downto 4);
    if BTN0 = '1' then
    next_state <= Chkop;
    else
    next_state <= IDLE;
    end if;
    when ChkOp =>
    instruction <= InSel;
    case Instruction(7 downto 4) is
    when "0001" =>
    next_state <= ADD;
    when "0010" =>
    next_State <= SUB;
    when "0011" =>
    next_state <= MUL;
    when "0100" =>
    next_State <= SHR;
    when "0101" =>
    next_State <= SHL;
    when "1010" =>
    next_state <= LD;
    when "1111" =>
    next_state <= ST;
    when others =>
    next_State <= IDLE;
    end case;

    when ADD =>
    LD7 <= '1';
    when SUB =>
    case Instruction(3 downto 0) is
    when "0000" =>
    R0 <= R0 - R0;
    when "0100" =>
    R0 <= R1 - R0;
    when "1000" =>
    R0 <= R2 - R0;
    when "1100" =>
    R0 <= R3 - R0;
    when "0001" =>
    R1 <= R0 - R1;
    when "0101" =>
    R1 <= R1 - R1;
    when "1001" =>
    R1 <= R2 - R1;
    when "1101" =>
    R1 <= R3 - R1;
    when others =>
    R0 <= R0;
    R1 <= R1;
    R2 <= R2;
    R3 <= R3;
    end case;
    next_state <= IDLE;
    when MUL =>
    when SHR =>
    case Instruction(3 downto 2) is
    when "00" =>
    R0 <= '0' & R0(7 downto 1);
    when "01" =>
    R1 <= '0' & R1(7 downto 1);
    when "10" =>
    R2 <= '0' & R2(7 downto 1);
    when "11" =>
    R3 <= '0' & R3(7 downto 1);
    when others =>
    R0 <= R0;
    R1 <= R1;
    R2 <= R2;
    R3 <= R3;
    end case;
    next_state <= IDLE;

    when SHL =>
    case Instruction(3 downto 2) is
    when "00" =>
    R0 <= R0(6 downto 0) &'0';
    when "01" =>
    R1 <= R1(6 downto 0) & '0';
    when "10" =>
    R2 <= R2(6 downto 0) & '0';
    when "11" =>
    R3 <= R3(6 downto 0) & '0';
    when others =>
    R0 <= R0;
    R1 <= R1;
    R2 <= R2;
    R3 <= R3;
    end case;
    next_state <= IDLE;

    when LD =>
    when ST =>

    when SetupRead =>
    when Read =>
    when SetupWrite =>

    when Write =>

    when ReadSel =>

    when SetupSelRead =>

    when SelRead =>

    when ShowR2R3 =>


    end case;

    end process Next_State_Logic;
    end Behavioral;
    fpgawizz, Mar 14, 2005
    #4
  5. fpgawizz wrote:


    > Next_State_Logic:
    > Process(current_state,BTN0,BTN1,BTN2)
    >
    > begin
    >
    > case current_state is
    > when RST =>
    > R0 <= "00000000";
    > R1 <= "00000001";
    > R2 <= "00000010";
    > R3 <= "00000011";
    > LD7 <= '1';
    > LD0 <= '0';
    > LD6 <= '0';
    > next_state <= IDLE;
    > when IDLE =>
    > SramAddr2 <= "00000000"; CE2 <= '1';
    > CE1 <= '0';
    > UB <= '1';
    > LB <= '0';
    > OE <= '1';
    > WE <= '1';
    > DataBus <= "ZZZZZZZZ";
    > LD0 <= '1';
    > LD6 <= '1';
    > LD7 <= '0';
    > sd0 <= R0(3 downto 0);
    > sd1 <= R0(7 downto 4);
    > sd2 <= R1(3 downto 0);
    > sd3 <= R1(7 downto 4);
    > if BTN0 = '1' then
    > next_state <= Chkop;
    > else
    > next_state <= IDLE;
    > end if;
    > when ChkOp =>

    ....
    > when SUB =>
    > case Instruction(3 downto 0) is
    > when "0000" =>
    > R0 <= R0 - R0;

    ....

    So R0 to R3 are latches and I guess you are confronted with the "muxed
    latch problem". I guess so especially because you are writing in more
    than one case-branch to the signals (which is not forbidden but can lead
    to this problem.

    Let me explain:
    The latches are enabled if some conditions are met (current_state = RST
    or current_state = SUB...). Now, if the state changes, the enable
    signals change with a delay. The same holds for the latch-inputs and for
    the muxes that select which data have to be stored. Therefore your
    latches may be enabled a little bit longer than the latch-inputs and the
    muxes are stable and therefore some faulty data may be stored.

    For FPGAs the solution is simple: Don't use latches - take flipflops!
    You got a lot of them and power dissipation is not the main fact. ;-)
    Otherwise make shure that the latch-enable-signals are inactive before
    the muxes and therefore the latch-inputs change their value.


    Ralf
    Ralf Hildebrandt, Mar 14, 2005
    #5
  6. fpgawizz

    Guest

    I think you are confusing what goes into what process.

    Everything that is intended to be a latch, that is, something that will
    hold the current state of your logic until the next clock cycle, should
    be set in the clock process (State_Memory). Things that are decodes of
    latches or primary inputs should be in separate,
    combinational_logic_type processes. Combinational logic processes have
    these characteristics:
    1. Any signal that appears on the right-hand side of an expression
    should be in the sensitivity list.
    2. Any signal that is on the left-hand side of an assigment statement
    must be set to the desired value by every possible path through that
    process's logic. Otherwise you will get an unexpected implied latch.

    In your case, it looks like you are trying to do *way* too much in the
    Next_State_Logic process. I would suggest you use this process just to
    compute what the next_state should be, based on the current state and
    various input conditions.

    Are R0, R1, R2, and R3 supposed to be registers? If so, you shouldn't
    be setting them in the Next_State process. They should be set in the
    clock process. Notice how you are setting them in some states of the
    Next_State process, but not in others. This will create implied
    latches, clocked by ???, that won't necessarily change on the rising
    edge of fsmclk like you expect.

    Are you trying to use sd0 ... sd3 to monitor the state of the R0 and R1
    registers? If so, I would suggest moving the
    sd0 <= R0(3 downto 0);
    sd1 <= R0(7 downto 4);
    sd2 <= R1(3 downto 0);
    sd3 <= R1(7 downto 4);
    statements out of the Next_State process and let them be stand-alone
    concurrent assignment statements.

    Charles Bailey
    , Mar 14, 2005
    #6
  7. fpgawizz

    fpgawizz Guest

    Charles
    Thanks. I will see if I can have just one process statement for my state
    machine.
    R0,R1,R2 and R3 need to be 4, 8-bit registers initialized to 00,01,02 and
    03H.I am not sure how i can put this in the State_Memory process coz I
    tried putting them under fsmclk'event and fsmclk='1' but i will be
    overwriting them every clock cycle with 00,01,02and 03H. I only want them
    to have these values at power up and if an asynchrounous reset happens.
    Coz I need to do arithmetic ops on these 4 registers ( if you see my
    states, i have add,sub..etc etc..)

    sd0,sd1,sd2 and sd3 are 4 bit signals that port map to a display module
    that displays them to 4 digits on a seven segment display. I could have
    put those 4 statements outside then process but I also have an
    asynchronous input called "BTN1", when pressed i must display contents of
    R2 and R3. If i have a concurrent statement with sd0,sd1,sd2 and sd3
    outside the process and then i try to assign them inside the process in a
    state called ShowR2R3 when BTN1 = '1' I would get multisource errors on
    sd0,sd1,sd2 and sd3 right?

    The way sd0, sd1,sd2 and sd3 must work is at a default state they must
    carry R0,R1 information and if asynchrounous input BTN1 = '1' then they
    must carry R2,R3 info and go back to default state after BTN1 goes to
    zero. Thats what I am trying to set in IDLE state bny making sd0,sd1,sd2
    and sd3 display R0 and R1 contents.

    comments??
    fpgawizz, Mar 14, 2005
    #7
  8. fpgawizz

    Guest

    >R0,R1,R2 and R3 need to be 4, 8-bit registers initialized to 00,01,02
    and
    >03H.I am not sure how i can put this in the State_Memory process coz I


    >tried putting them under fsmclk'event and fsmclk='1' but i will be
    >overwriting them every clock cycle with 00,01,02and 03H. I only want

    them
    >to have these values at power up and if an asynchrounous reset

    happens.
    >Coz I need to do arithmetic ops on these 4 registers ( if you see my
    >states, i have add,sub..etc etc..)

    Consider this type of approach:

    State_Memory:process(fsmclk,Reset)
    begin
    if reset = '1' then
    current_State <= RST;
    R0 <= "00000000";
    R1 <= "00000001";
    R2 <= "00000010";
    R3 <= "00000011";
    elsif fsmclk'event and fsmclk = '1' then
    case current_state is
    when ...
    when SUB =>
    case Instruction(3 downto 0) is
    when "0000" => -- "XXYY" XX - Source, YY - DEST
    R0 <= R0 - R0;
    when "0100" =>
    R0 <= R1 - R0;
    when "1000" =>
    R0 <= R2 - R0;
    when "1100" =>
    R0 <= R3 - R0;
    when "0001" =>
    R1 <= R0 - R1;
    when "0101" =>
    R1 <= R1 - R1;
    when "1001" =>
    R1 <= R2 - R1;
    when "1101" =>
    R1 <= R3 - R1;
    end case;
    when ...
    end case;
    current_state <= next_state;
    internal_databus <= Databus;
    end if;
    end process State_Memory;


    >The way sd0, sd1,sd2 and sd3 must work is at a default state they must


    >carry R0,R1 information and if asynchrounous input BTN1 = '1' then

    they
    >must carry R2,R3 info and go back to default state after BTN1 goes to
    >zero. Thats what I am trying to set in IDLE state bny making

    sd0,sd1,sd2
    >and sd3 display R0 and R1 contents.


    sd_proc: process(R0, R1, R2, R3, BTN1)
    begin
    If BTN1='1' then
    sd0 <= R0(3 downto 0);
    sd1 <= R0(7 downto 4);
    sd2 <= R1(3 downto 0);
    sd3 <= R1(7 downto 4);
    else
    sd0 <= R2(3 downto 0);
    sd1 <= R2(7 downto 4);
    sd2 <= R3(3 downto 0);
    sd3 <= R3(7 downto 4);
    end if;
    end process;


    Charles Bailey
    , Mar 14, 2005
    #8
  9. fpgawizz

    fpgawizz Guest

    thanks charles.once i made my state machine synchronous w the clock, most
    of my problems went away.
    fpgawizz, Mar 15, 2005
    #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:
    679
  2. Weng Tianxiang
    Replies:
    7
    Views:
    1,103
    Mike Treseler
    Nov 25, 2003
  3. Weng Tianxiang
    Replies:
    3
    Views:
    1,397
    Weng Tianxiang
    Jul 25, 2006
  4. Sagaert Johan

    Masterpages and Response.Write prblem

    Sagaert Johan, Feb 5, 2008, in forum: ASP .Net
    Replies:
    4
    Views:
    397
    Sagaert Johan
    Feb 5, 2008
  5. fenster
    Replies:
    3
    Views:
    1,159
    jeppe
    Dec 23, 2011
Loading...

Share This Page