Working on an FSM

Discussion in 'VHDL' started by laserbeak43, Dec 31, 2010.

  1. laserbeak43

    laserbeak43 Guest

    Hello,
    I'm learning about FSMs and I'm having a hard time getting my code to
    run correctly.
    I'm getting errors that say the registers for my states won't hold
    outside of the clock edge, and another set of errors saying that i
    have multiple constant drivers that can't be resolved.

    Does anyone think that they could help me out with this code? I've
    truncated the switch, the full
    source can be found here http://paste.org/pastebin/view/26824

    Thanks
    Malik

    ****************************************************************************************************************

    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;

    entity part1take2 is
    port(
    CLOCK_50 : in std_logic;
    SW : in unsigned(1 downto 0);
    LEDR : out unsigned(8 downto 0)
    );
    end part1take2;

    architecture behavioral of part1take2 is

    type statet is ( A, B, C, D, E, F, G, H, I );
    constant FMil: integer := 50000000;

    signal count : unsigned(25 downto 0);
    signal CLK : std_logic;
    signal cstate, nstate : statet;
    signal lstate : unsigned(8 downto 0);

    begin

    LEDR <= lstate;

    process(CLK, SW, cstate)
    begin

    nstate <= cstate;
    LEDR <= to_unsigned(0, 9);

    if(SW(0) = '1') then
    nstate <= A;
    else
    if(rising_edge(CLK)) then
    case cstate is
    when A =>
    lstate <= to_unsigned(000000001, 9);
    if(SW(1) = '1') then
    nstate <= F;
    else
    nstate <= B;
    end if;
    when B =>
    lstate <= to_unsigned(000000010, 9);
    if(SW(1) = '1') then
    nstate <= F;
    else
    nstate <= C;
    end if;
    t--truncated
    end case;
    end if;
    end if;
    end process;

    process(CLOCK_50) begin

    if rising_edge(CLOCK_50) then
    if(count = FMil) then
    CLK <= (not CLK);
    if(CLK = '1') then
    cstate <= nstate;
    end if;
    else
    count <= count + 1;
    end if;
    end if;

    end process;

    end behavioral;
     
    laserbeak43, Dec 31, 2010
    #1
    1. Advertising

  2. laserbeak43

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Hi

    Try this instead - your next-state logic should be pure combinatorial

    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;
    
    entity part1take2 is
     port( 
      CLOCK_50 : in std_logic;
      SW   : in unsigned(1 downto 0);
      LEDR  : out unsigned(8 downto 0)
     );
    end part1take2;
    
    architecture behavioral of part1take2 is 
     
     type statet is ( A, B, C, D, E, F, G, H, I );
     constant FMil: integer := 50000000;
     
     signal count : unsigned(25 downto 0);
     signal CLK  : std_logic;
     signal cstate, nstate : statet;
     signal lstate : unsigned(8 downto 0);
     
    begin
     
     LEDR <= lstate;
     
     process(CLK, SW, cstate) 
     begin
      
      nstate <= cstate;
      LEDR <= to_unsigned(0, 9);
      
      if(SW(0) = '1') then
       nstate <= A;
      else 
       -- not needed for combinatorial logic  => if(rising_edge(CLK)) then
        case cstate is
         when A =>
          lstate <= to_unsigned(000000001, 9);
          if(SW(1) = '1') then
           nstate <= F;
          else
           nstate <= B;
          end if;
         when B =>
          lstate <= to_unsigned(000000010, 9);
          if(SW(1) = '1') then
           nstate <= F;
          else
           nstate <= C;
          end if;
         when C =>
          lstate <= to_unsigned(000000100, 9);
          if(SW(1) = '1') then
           nstate <= F;
          else
           nstate <= D;
          end if;
         when D =>
          lstate <= to_unsigned(000001000, 9);
          if(SW(1) = '1') then
           nstate <= F;
          else
           nstate <= E;
          end if;
         when E =>
          lstate <= to_unsigned(000010000, 9);
          if(SW(1) = '1') then
           nstate <= F;
          else
           nstate <= E;
          end if;
         when F =>
          lstate <= to_unsigned(000100000, 9);
          if(SW(1) = '1') then
           nstate <= G;
          else
           nstate <= B;
          end if;
         when G =>
          lstate <= to_unsigned(001000000, 9);
          if(SW(1) = '1') then
           nstate <= H;
          else
           nstate <= B;
          end if;
         when H =>
          lstate <= to_unsigned(010000000, 9);
          if(SW(1) = '1') then
           nstate <= I;
          else
           nstate <= B;
          end if;
         when I =>
          lstate <= to_unsigned(100000000, 9);
          if(SW(1) = '1') then
           nstate <= I;
          else
           nstate <= B;
          end if;
        end case;
       ------------------- to be deleted  => end if;
      end if;
     end process;
     
     process(CLOCK_50) begin
    
      if rising_edge(CLOCK_50) then
       if(count = FMil) then
        CLK <= (not CLK);
        cstate <= nstate;
        count <= (others=>'0'); 
       else 
        count <= count + 1;
       end if;
      end if;
     
     end process;
     
    end behavioral;
     
    jeppe, Dec 31, 2010
    #2
    1. Advertising

  3. On 12/31/2010 12:07 AM, laserbeak43 wrote:
    > Hello,
    > I'm learning about FSMs and I'm having a hard time getting my code to
    > run correctly.
    > I'm getting errors that say the registers for my states won't hold
    > outside of the clock edge, and another set of errors saying that i
    > have multiple constant drivers that can't be resolved.


    I use a single process (reset, clock)
    This would fix most of your problems.

    -- Mike Treseler
     
    Mike Treseler, Dec 31, 2010
    #3
  4. laserbeak43

    eliascm

    Joined:
    Jan 30, 2009
    Messages:
    42
    FSM Problem

    It would help if you described what you are trying to do with the FSM and the counter.
     
    eliascm, Jan 3, 2011
    #4
  5. laserbeak43

    JimLewis Guest

    Hi Malik,
    1)
    You have multiple drivers on LEDR.
    One outside the process and one in the process.
    For every signal assigned in a separate process
    (and think of a concurrent assignment as a separate
    process), a separate piece of hardware is created.
    If you have more than one piece of hardware, you are
    connecting outputs directly together in a bad way.

    2)
    You probably do not want derived clocks. Instead
    use enables - you are kind of doing this with CLK in
    the process that includes CLOCK_50. I suspect you do
    not need the "rising_edge(CLK)" in the other process.

    3)
    You need to work on your logic revolving around count.
    Does count ever go back to 0? Otherwise the condition,
    count = FMil will only be true once.

    You could probably evolve it to something that captures
    the nstate when count = 2*FMil and resets count to 0,
    and otherwise increments count.

    4)
    You need to simulate before you synthesize.


    5)
    Although Mike hates using more than one process to code
    a statemachine, I prefer using two.

    6)
    The assignment "nstate <= cstate;" is called a default
    assignment and can help you take short-cuts in some
    statemachines, but looking at the rest of your statemachine,
    you are neither using it nor would you benefit from it
    (except in state E - and I am not going to use a default
    assignment to help only in one state).

    Good luck. Try the simulator.

    Best,
    Jim Lewis
     
    JimLewis, Jan 3, 2011
    #5
  6. laserbeak43

    rickman Guest

    On Dec 31 2010, 3:07 am, laserbeak43 <> wrote:
    > Hello,
    > I'm learning about FSMs and I'm having a hard time getting my code to
    > run correctly.
    > I'm getting errors that say the registers for my states won't hold
    > outside of the clock edge, and another set of errors saying that i
    > have multiple constant drivers that can't be resolved.
    >
    > Does anyone think that they could help me out with this code? I've
    > truncated the switch, the full
    > source can be found herehttp://paste.org/pastebin/view/26824
    >
    > Thanks
    > Malik
    >
    > ****************************************************************************************************************
    >
    > LIBRARY ieee;
    > USE ieee.std_logic_1164.all;
    > USE ieee.numeric_std.all;
    >
    > entity part1take2 is
    >         port(
    >                 CLOCK_50        : in std_logic;
    >                 SW                      : in unsigned(1 downto 0);
    >                 LEDR            : out unsigned(8 downto 0)
    >         );
    > end part1take2;
    >
    > architecture behavioral of part1take2 is
    >
    >         type statet is ( A, B, C, D, E, F, G, H, I );
    >         constant FMil: integer := 50000000;
    >
    >         signal count    : unsigned(25 downto 0);
    >         signal CLK              : std_logic;
    >         signal cstate, nstate : statet;
    >         signal lstate   : unsigned(8 downto 0);
    >
    > begin
    >
    >         LEDR <= lstate;
    >
    >         process(CLK, SW, cstate)


    In a clocked process only the clock and any async inputs should be in
    the sensitivity list. This can make your simulation differ from the
    synthesized logic. Remove cstate.

    >         begin
    >
    >                 nstate <= cstate;
    >                 LEDR <= to_unsigned(0, 9);
    >


    These two lines are outside of the conditional clauses. That means
    they are executed anytime any of the signals in the sensitivity list
    change. There is no reasonable synthesizable logic that will match
    this description. What are you trying to do with these two lines?
    They are the ones giving the error.


    >                 if(SW(0) = '1') then
    >                         nstate <= A;
    >                 else
    >                         if(rising_edge(CLK)) then
    >                                 case cstate is
    >                                         when A =>
    >                                                 lstate <= to_unsigned(000000001, 9);
    >                                                 if(SW(1) = '1') then
    >                                                         nstate <= F;
    >                                                 else
    >                                                         nstate <= B;
    >                                                 end if;
    >                                         when B =>
    >                                                 lstate <= to_unsigned(000000010, 9);
    >                                                 if(SW(1) = '1') then
    >                                                         nstate <= F;
    >                                                 else
    >                                                         nstate <= C;
    >                                                 end if;
    >                                         t--truncated
    >                                 end case;
    >                         end if;
    >                 end if;
    >         end process;
    >
    >         process(CLOCK_50) begin
    >
    >                 if rising_edge(CLOCK_50) then
    >                         if(count = FMil) then
    >                                 CLK <= (not CLK);
    >                                 if(CLK = '1') then
    >                                         cstate <= nstate;
    >                                 end if;
    >                         else
    >                                 count <= count + 1;
    >                         end if;
    >                 end if;
    >
    >         end process;
    >
    > end behavioral;


    I also don't understand what you are trying to acheive with the two
    processes. The second process synthesizes a clock for the first. The
    values of cstate and nstate run through BOTH clocks, two registers!
    One is clocked by the rising edge of CLK while the other is clocked by
    the rising edget of CLOCK_50, but enabled when CLK is high which
    roughly corresponds to the falling edge of CLK. Is that what you
    intend?

    BTW, to get the CLK <= not CLK; line to simulate you need to
    initialize CLK in a reset statement or in the signal declaration. The
    former will be synthesized while the latter may or may not be.

    Rick
     
    rickman, Jan 3, 2011
    #6
  7. laserbeak43

    d_s_klein Guest

    On Jan 3, 2:35 pm, rickman <> wrote:
    >
    > In a clocked process only the clock and any async inputs should be in
    > the sensitivity list.  This can make your simulation differ from the
    > synthesized logic.  Remove cstate.
    >
    > Rick


    I suggest that only 'clock' and 'reset' be on the sensitivity list of
    a clocked process.

    RK
     
    d_s_klein, Jan 5, 2011
    #7
  8. d_s_klein <> writes:

    > On Jan 3, 2:35 pm, rickman <> wrote:
    >>
    >> In a clocked process only the clock and any async inputs should be in
    >> the sensitivity list.  This can make your simulation differ from the
    >> synthesized logic.  Remove cstate.
    >>
    >> Rick

    >
    > I suggest that only 'clock' and 'reset' be on the sensitivity list of
    > a clocked process.


    Good suggestion iff reset is an async input.

    When using synchronous resets, then *only* clock should be in the
    sensitivity list.

    Cheers,
    Martin

    --

    TRW Conekt - Consultancy in Engineering, Knowledge and Technology
    http://www.conekt.co.uk/capabilities/39-electronic-hardware
     
    Martin Thompson, Jan 6, 2011
    #8
  9. laserbeak43

    d_s_klein Guest

    On Jan 6, 6:06 am, Martin Thompson <> wrote:
    >
    > Good suggestion iff reset is an async input.  
    >


    You are correct; all of the synthesis tools I have used behave exactly
    as you describe.

    I wonder how many understand that 'iff' is not a typo.

    RK
     
    d_s_klein, Jan 6, 2011
    #9
  10. d_s_klein <> writes:

    > On Jan 6, 6:06 am, Martin Thompson <> wrote:
    >>
    >> Good suggestion iff reset is an async input.  
    >>

    >
    > You are correct; all of the synthesis tools I have used behave exactly
    > as you describe.


    And the simulators I hope - it's the way the language is specified!

    [aside]
    Of course, if you omit reset from the sensitivity list and then use it
    in an "asynchronous" way in the process (outside of the "clocked" part),
    all bets are off synthesis-behaviour-wise:

    process (clk)
    begin
    if asyncreset = '1' then
    -- do stuff on both clock edges when asyncreset is high!
    elsif rising_edge(clk) then
    -- do stuff on rising edges when syncreset is low...
    end if;
    end;

    Some (all?) synthesisers will assume you meant to include reset in the
    sensitivity list and synth an async reset. Whereas the simulator will
    execute the reset clause on *every* clock edge, but the "normal"
    clocked part on the rising edges.

    I'm sure no-one would ever write code like that though :)

    >
    > I wonder how many understand that 'iff' is not a typo.
    >


    I have to admit I wondered that as I wrote it...

    Cheers,
    Martin

    --

    TRW Conekt - Consultancy in Engineering, Knowledge and Technology
    http://www.conekt.co.uk/capabilities/39-electronic-hardware
     
    Martin Thompson, Jan 7, 2011
    #10
    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. E. Backhus
    Replies:
    2
    Views:
    7,122
    Alain
    Jul 25, 2003
  2. Ingmar Seifert

    tool to draw FSM bubble diagram

    Ingmar Seifert, Jul 31, 2003, in forum: VHDL
    Replies:
    5
    Views:
    23,371
    Pedro Claro
    Aug 1, 2003
  3. Charlie

    FSM Problem

    Charlie, Dec 28, 2003, in forum: VHDL
    Replies:
    5
    Views:
    802
    Charles M. Elias
    Dec 31, 2003
  4. Nic

    One Hot FSM stuck !!

    Nic, Feb 26, 2004, in forum: VHDL
    Replies:
    5
    Views:
    1,200
    FGreen
    Mar 2, 2004
  5. Tony Smith
    Replies:
    0
    Views:
    826
    Tony Smith
    Apr 28, 2004
Loading...

Share This Page