custom types in process sensitivity list

Discussion in 'VHDL' started by Roger Dahl, Sep 29, 2003.

  1. Roger Dahl

    Roger Dahl Guest

    Hi all,

    I've just started playing around with VHDL and I'm having trouble
    solving a particular problem.

    I have two FSMs. FSM A is clocked at a slow speed and FSM B is clocked
    at a fast speed. I would like FSM B to cycle through all its states
    each time FSM A changes state. The states for each FSM is declared as
    a type.

    Is there a standard solution to this kind of problem?

    One solution that I have been trying to implement involves having a
    third process that sets a signal when FSM A changes state and clears
    the signal when FSM B changes state. That signal would be used for
    telling FSM B to start going.

    I have tried to implement that process like this:

    process(CurrentFSM_A_State, CurrentFSM_B_State)
    begin
    [if triggered by A, set signal. if triggered by B, clear signal]...
    end process;

    However, I am unable to determine within the process if it was
    triggered by CurrentFSM_A_State or CurrentFSM_B_State. rising_edge()
    etc doesn't work since the signals are types, not single signals.

    Any help would be greatly appreciated.

    Roger Dahl
     
    Roger Dahl, Sep 29, 2003
    #1
    1. Advertising

  2. Roger Dahl

    Ian Poole Guest

    Hi Roger

    Is this intended for hardware, or just for simulation? If it is just for
    simulation, then the simple answer is use the 'event attribute -

    process(FSM_A_State , FSM_B_State)
    begin
    if (FSM_A_State'event) then

    elsif (FSM_B_State'event) then

    end if;
    end process;

    However, if you ever want to build hardware, then this will not work - could
    you draw the schematic resulting from the above code? There are various
    ideas for solving your problem -

    Clock both FSMs at the faster clock, but use a clock enable to only activate
    the slower FSM once per cycle of the faster one. I haven't tested the
    following, but it should illustrate my idea -
    type FSM_A_States is (FSM_A_State1 , FSM_A_State2 , FSM_A_State3 ,
    Do_Cycle_Of_B)
    type FSM_B_States is (FSM_B_State1 , FSM_B_State2 , FSM_B_State3)

    and in your fsms:
    process(Clock , Reset)
    begin
    if (Reset = 1) then
    State_A = FSM_A_State1;
    State_B = FSM_B_State1;
    elsif (Rising_Edge(Clock)) then
    if (State_A = Do_Cycle_Of_B) then
    State_B <= Next_State_B;
    end if;

    State_A <= Next_State_A;
    end if;
    end process;

    There are various horrible async. solutions, such as deriving the clock for
    the slower FSM from some part of the faster FSM, but that would be truely
    horrible... Try and keep everything synchrounous to a single clock.

    HTH

    Ian

    --
    Ian Poole, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services


    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.


    "Roger Dahl" <> wrote in message
    news:...
    > Hi all,
    >
    > I've just started playing around with VHDL and I'm having trouble
    > solving a particular problem.
    >
    > I have two FSMs. FSM A is clocked at a slow speed and FSM B is clocked
    > at a fast speed. I would like FSM B to cycle through all its states
    > each time FSM A changes state. The states for each FSM is declared as
    > a type.
    >
    > Is there a standard solution to this kind of problem?
    >
    > One solution that I have been trying to implement involves having a
    > third process that sets a signal when FSM A changes state and clears
    > the signal when FSM B changes state. That signal would be used for
    > telling FSM B to start going.
    >
    > I have tried to implement that process like this:
    >
    > process(CurrentFSM_A_State, CurrentFSM_B_State)
    > begin
    > [if triggered by A, set signal. if triggered by B, clear signal]...
    > end process;
    >
    > However, I am unable to determine within the process if it was
    > triggered by CurrentFSM_A_State or CurrentFSM_B_State. rising_edge()
    > etc doesn't work since the signals are types, not single signals.
    >
    > Any help would be greatly appreciated.
    >
    > Roger Dahl
     
    Ian Poole, Sep 29, 2003
    #2
    1. Advertising

  3. Roger Dahl wrote:

    > I have two FSMs. FSM A is clocked at a slow speed and FSM B is clocked
    > at a fast speed. I would like FSM B to cycle through all its states
    > each time FSM A changes state. The states for each FSM is declared as
    > a type.


    Consider designing a single machine at the fast speed,
    and adding synchronizers for the slow inputs.

    -- Mike Treseler
     
    Mike Treseler, Sep 29, 2003
    #3
  4. Roger Dahl

    Roger Dahl Guest

    Ian,

    Thank you for taking the time to answer. I really appreciate it.

    This is intended for hardware.

    I hadn't considered that you can clock one FSM from another so this
    was exactly the kind of insight I was looking for. However, your
    solution doesn't bring me all the way there. I would like the fast FSM
    to run on 1MHz and the slow one to run on 1Hz. So, I need to somehow
    get rid of 999,995 cycles if I want to clock the slow FSM from the
    fast one (which has 5 states). I was thinking of attempting to do that
    by adding states that "loop" that many cycles. Would that be a good
    way of doing it?

    > Is this intended for hardware, or just for simulation? If it is just for
    > simulation, then the simple answer is use the 'event attribute -
    >
    > process(FSM_A_State , FSM_B_State)
    > begin
    > if (FSM_A_State'event) then
    >
    > elsif (FSM_B_State'event) then
    >
    > end if;
    > end process;
    >
    > However, if you ever want to build hardware, then this will not work - could
    > you draw the schematic resulting from the above code?


    That is a good point but some magic must already be going on in the
    background here as the synthesizer somehow includes circuitry that
    detects changes in the state types (which consist of multiple signals)
    to trigger the process. It seems to me that the synthesizer might also
    be able to generate circuitry to tell me which signal changed?

    Thank you again for your advice,

    Roger
     
    Roger Dahl, Sep 30, 2003
    #4
  5. Roger Dahl

    Roger Dahl Guest

    Mike,

    Thank you for your reply.

    If FSM A and FSM B have 5 states each, would the design you're
    suggesting cause the single FSM to have 5 x 5 = 25 states? If not,
    could you describe the design more closely? After reading your reply,
    I researched synchronizers, but I am unsure how they can help in this
    design.

    Thanks again,

    Roger

    Mike Treseler <> wrote in message news:<>...
    > Roger Dahl wrote:
    >
    > > I have two FSMs. FSM A is clocked at a slow speed and FSM B is clocked
    > > at a fast speed. I would like FSM B to cycle through all its states
    > > each time FSM A changes state. The states for each FSM is declared as
    > > a type.

    >
    > Consider designing a single machine at the fast speed,
    > and adding synchronizers for the slow inputs.
    >
    > -- Mike Treseler
     
    Roger Dahl, Oct 1, 2003
    #5
  6. Roger Dahl

    Jim Wu Guest

    > process(CurrentFSM_A_State, CurrentFSM_B_State)
    > begin
    > [if triggered by A, set signal. if triggered by B, clear signal]...
    > end process;
    >


    I would use two separate processes for the two state machines and check
    state change of the slow FSM (A) in the fast FSM(B)

    process (CurrentFSM_B)
    case CurrentFSM_B_State is
    when WAIT_FOR_A_CHANGE =>
    if (PreFSM_A_State_In_B_Clk /= CurFSM_A_STATE_In_B_CLk) then
    NextFSM_B <= FSM_B_STATE1;
    else
    NextFSM_B <= Current_FSM_B_State;
    end if;

    When FSM_B_STATE1 =>
    NextFSM_B <= FSM_B_STATE2;
    ......
    When FSM_B_STATE5 =>
    NextFSM_B <= WAIT_FOR_A_CHANGE;
    end case;

    Jim Wu
    (remove capital letters)
    http://www.geocities.com/jimwu88/chips
     
    Jim Wu, Oct 1, 2003
    #6
  7. Roger Dahl wrote:
    > Mike,
    >
    > Thank you for your reply.
    >
    > If FSM A and FSM B have 5 states each, would the design you're
    > suggesting cause the single FSM to have 5 x 5 = 25 states? If not,
    > could you describe the design more closely?


    Yes, but I visualize it as a process with two
    local variables. If one variable is a counter,
    I would declare it as unsigned. If it is
    pure state, I would declare a type enumeration.

    After reading your reply,
    > I researched synchronizers, but I am unsure how they can help in this
    > design.



    A three bit (two register) shift register is
    standard practice for any input not already
    synchronized to the system clock.

    -- Mike Treseler
     
    Mike Treseler, Oct 1, 2003
    #7
  8. Roger Dahl

    Roger Dahl Guest

    Jim,

    I have implemented your excellent suggestion and it works beautifully.
    The resulting code became very clean and simple with a basic structure
    like the one I was trying to create.

    Thank you,

    Roger


    "Jim Wu" <> wrote in message news:<Ihqeb.14517$>...
    > > process(CurrentFSM_A_State, CurrentFSM_B_State)
    > > begin
    > > [if triggered by A, set signal. if triggered by B, clear signal]...
    > > end process;
    > >

    >
    > I would use two separate processes for the two state machines and check
    > state change of the slow FSM (A) in the fast FSM(B)
    >
    > process (CurrentFSM_B)
    > case CurrentFSM_B_State is
    > when WAIT_FOR_A_CHANGE =>
    > if (PreFSM_A_State_In_B_Clk /= CurFSM_A_STATE_In_B_CLk) then
    > NextFSM_B <= FSM_B_STATE1;
    > else
    > NextFSM_B <= Current_FSM_B_State;
    > end if;
    >
    > When FSM_B_STATE1 =>
    > NextFSM_B <= FSM_B_STATE2;
    > ......
    > When FSM_B_STATE5 =>
    > NextFSM_B <= WAIT_FOR_A_CHANGE;
    > end case;
    >
    > Jim Wu
    > (remove capital letters)
    > http://www.geocities.com/jimwu88/chips
     
    Roger Dahl, Oct 3, 2003
    #8
  9. Roger Dahl

    Roger Dahl Guest

    Mike,

    I'm curious about your solution. It looks like you have something in
    mind where you code a 25 state FSM but simplify it using the local
    variables and enumerations you mention? I would be interested in
    seeing such a solution since seeing different solutions to the same
    problem would help me gain perspective on the language.

    Thanks,

    Roger

    Mike Treseler <> wrote in message news:<>...
    > Roger Dahl wrote:
    > > Mike,
    > >
    > > Thank you for your reply.
    > >
    > > If FSM A and FSM B have 5 states each, would the design you're
    > > suggesting cause the single FSM to have 5 x 5 = 25 states? If not,
    > > could you describe the design more closely?

    >
    > Yes, but I visualize it as a process with two
    > local variables. If one variable is a counter,
    > I would declare it as unsigned. If it is
    > pure state, I would declare a type enumeration.
    >
    > After reading your reply,
    > > I researched synchronizers, but I am unsure how they can help in this
    > > design.

    >
    >
    > A three bit (two register) shift register is
    > standard practice for any input not already
    > synchronized to the system clock.
    >
    > -- Mike Treseler
     
    Roger Dahl, Oct 3, 2003
    #9
  10. Roger Dahl wrote:
    > Mike,
    >
    > I'm curious about your solution. It looks like you have something in
    > mind where you code a 25 state FSM but simplify it using the local
    > variables and enumerations you mention? I would be interested in
    > seeing such a solution since seeing different solutions to the same
    > problem would help me gain perspective on the language.


    I'll bite.
    A state machine that cycles through all states
    without other output is a counter to me.
    So here's an example of two synchronous
    counters, one that counts every tick
    and one that counts every 5th tick:

    -- Mike Treseler


    -- Fast and slow counters on the same clock
    -- Mike Treseler Fri Oct 3 13:03:22 2003

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity two_counters is
    generic (len : natural := 3; -- vector length
    max : natural := 4); -- max count
    port (
    clk : in std_ulogic;
    rst : in std_ulogic;
    fast : out unsigned(len-1 downto 0);
    slow : out unsigned(len-1 downto 0)
    );
    end two_counters;

    architecture synth of two_counters is
    subtype count_t is unsigned(len-1 downto 0);
    constant init : unsigned := (count_t'range => '0');
    begin
    clked:process (clk, rst)
    variable fast_v : count_t;
    variable slow_v : count_t;
    begin
    values:if rst = '1' then
    fast_v := init;
    slow_v := init;
    elsif rising_edge(clk) then
    fast_v := fast_v + 1; -- fast counts every tick.
    if fast_v > max then -- slow counts every 5 ticks
    fast_v := init;
    slow_v := slow_v + 1;
    if slow_v > max then
    slow_v := init;
    end if;
    end if;
    end if values;
    fast <= fast_v;
    slow <= slow_v;
    end process clked;
    end synth;
     
    Mike Treseler, Oct 3, 2003
    #10
  11. -- rev 0.1 improved outputs

    -- Fast and slow counters on the same clock
    -- outputs corrected
    -- Mike Treseler Fri Oct 3 13:58:00 2003
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity two_counters is
    generic (len : natural := 3; -- vector length
    max : natural := 4); -- max count
    port (
    clk : in std_ulogic;
    rst : in std_ulogic;
    fast : out unsigned(len-1 downto 0);
    slow : out unsigned(len-1 downto 0)
    );
    end two_counters;

    architecture synth of two_counters is
    subtype count_t is unsigned(len-1 downto 0);
    constant init : unsigned := (count_t'range => '0');
    begin
    clked:process (clk, rst)
    variable fast_v : count_t;
    variable slow_v : count_t;
    begin
    values:if rst = '1' then
    fast_v := init;
    slow_v := init;
    fast <= fast_v;
    slow <= slow_v;
    elsif rising_edge(clk) then
    fast <= fast_v;
    slow <= slow_v;
    fast_v := fast_v + 1; -- fast counts every tick.
    if fast_v > max then -- slow counts every 5 ticks
    fast_v := init;
    slow_v := slow_v + 1;
    if slow_v > max then
    slow_v := init;
    end if;
    end if;
    end if values;
    end process clked;
    end synth;
     
    Mike Treseler, Oct 3, 2003
    #11
    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. walala
    Replies:
    3
    Views:
    746
    Allan Herriman
    Sep 9, 2003
  2. antonio bergnoli
    Replies:
    5
    Views:
    4,466
    Mike Treseler
    Dec 18, 2005
  3. Steven Kauffmann
    Replies:
    21
    Views:
    2,652
    Ponceludon de Malavoy
    Jan 9, 2008
  4. neilmac
    Replies:
    2
    Views:
    648
    mcdjnaja
    Feb 7, 2008
  5. ferrari

    Process sensitivity list

    ferrari, Jun 19, 2008, in forum: VHDL
    Replies:
    8
    Views:
    1,267
    ferrari
    Jun 24, 2008
Loading...

Share This Page