Reading enumerated state variables

Discussion in 'VHDL' started by cristian, Oct 11, 2004.

  1. cristian

    cristian Guest

    I have done the following declaration as part of my state machine
    code:

    type states is (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_write);
    attribute syn_enum_encoding: string;
    attribute syn_enum_encoding of states : type is "000 001 011 111 110
    101 100";
    SIGNAL state, nxt_state : states;

    For different reasons I do need to be able to 'read' the value of the
    state variables of my enumerated type to do something like this:

    oe_rst <= sv(1) and not sv(2) and not sv(3);

    int_req <= ((not r_cmd(3) and not r_cmd(2) and r_cmd(1) and sv(1) and
    not sv(2) and sv(3)) or (sv(1) and not sv(2) and not sv(3));

    start_timer <= ((sv(1) and not sv(2) and not sv(3)) or (sv(1) and not
    sv(2) and sv(3)));

    where 'sv' is the state variable of the enumerated type defined in the
    respective VHDL statement.

    I do know that this is not the best way of doing output assignments in
    an State Machine. But, I need to follow some directions.

    So, in concrete, is there any way to use the value of the state
    variables of a declared enumerated type ?

    thanks,

    cristian
    cristian, Oct 11, 2004
    #1
    1. Advertising

  2. cristian wrote:
    > I have done the following declaration as part of my state machine
    > code:
    >
    > type states is (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_write);
    > attribute syn_enum_encoding: string;
    > attribute syn_enum_encoding of states : type is "000 001 011 111 110
    > 101 100";
    > SIGNAL state, nxt_state : states;
    >
    > For different reasons I do need to be able to 'read' the value of the
    > state variables of my enumerated type to do something like this:
    >
    > oe_rst <= sv(1) and not sv(2) and not sv(3);
    >
    > int_req <= ((not r_cmd(3) and not r_cmd(2) and r_cmd(1) and sv(1) and
    > not sv(2) and sv(3)) or (sv(1) and not sv(2) and not sv(3));
    >
    > start_timer <= ((sv(1) and not sv(2) and not sv(3)) or (sv(1) and not
    > sv(2) and sv(3)));
    >
    > where 'sv' is the state variable of the enumerated type defined in the
    > respective VHDL statement.
    >
    > I do know that this is not the best way of doing output assignments in
    > an State Machine. But, I need to follow some directions.
    >
    > So, in concrete, is there any way to use the value of the state
    > variables of a declared enumerated type ?


    I still do not understand why you must do it this way, but if you insist
    you should declare sv a std_logic_vector and create constants (of type
    std_logic_vector) for the state values. Use these constants in your FSM
    code and use the the bits of sv (as above) in the decoding.

    Paul.
    Paul Uiterlinden, Oct 12, 2004
    #2
    1. Advertising

  3. cristian

    Alan Fitch Guest

    "cristian" <> wrote in message
    news:...
    > I have done the following declaration as part of my state machine
    > code:
    >
    > type states is

    (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_w
    rite);
    > attribute syn_enum_encoding: string;
    > attribute syn_enum_encoding of states : type is "000 001 011 111 110
    > 101 100";
    > SIGNAL state, nxt_state : states;
    >
    > For different reasons I do need to be able to 'read' the value of

    the
    > state variables of my enumerated type to do something like this:
    >
    > oe_rst <= sv(1) and not sv(2) and not sv(3);
    >
    > int_req <= ((not r_cmd(3) and not r_cmd(2) and r_cmd(1) and sv(1)

    and
    > not sv(2) and sv(3)) or (sv(1) and not sv(2) and not sv(3));
    >
    > start_timer <= ((sv(1) and not sv(2) and not sv(3)) or (sv(1) and

    not
    > sv(2) and sv(3)));
    >
    > where 'sv' is the state variable of the enumerated type defined in

    the
    > respective VHDL statement.
    >
    > I do know that this is not the best way of doing output assignments

    in
    > an State Machine. But, I need to follow some directions.
    >
    > So, in concrete, is there any way to use the value of the state
    > variables of a declared enumerated type ?
    >


    Hi Cristian,
    in theory you could do it by getting the position number
    of the enumerated values using 'POS and converting to a
    std_logic_vector,
    but it would not be synthesisable!

    You might be better to start by using a set of constants rather than
    an
    enumerated type, e.g.

    constant b_busy : std_logic_vector := "000";

    and so on. Then you have "complete control". However synthesis tools
    may
    not recognise this as a state machine, which means you won't
    necessarily
    get any clever optimisations - but then I guess you don't want clever
    optimisations if you are relying on the coding of the states,

    regards

    Alan


    --
    Alan Fitch
    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.
    Alan Fitch, Oct 12, 2004
    #3
  4. cristian

    rickman Guest

    cristian wrote:
    >
    > I have done the following declaration as part of my state machine
    > code:
    >
    > type states is (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_write);
    > attribute syn_enum_encoding: string;
    > attribute syn_enum_encoding of states : type is "000 001 011 111 110
    > 101 100";
    > SIGNAL state, nxt_state : states;
    >
    > For different reasons I do need to be able to 'read' the value of the
    > state variables of my enumerated type to do something like this:
    >
    > oe_rst <= sv(1) and not sv(2) and not sv(3);
    >
    > int_req <= ((not r_cmd(3) and not r_cmd(2) and r_cmd(1) and sv(1) and
    > not sv(2) and sv(3)) or (sv(1) and not sv(2) and not sv(3));
    >
    > start_timer <= ((sv(1) and not sv(2) and not sv(3)) or (sv(1) and not
    > sv(2) and sv(3)));
    >
    > where 'sv' is the state variable of the enumerated type defined in the
    > respective VHDL statement.
    >
    > I do know that this is not the best way of doing output assignments in
    > an State Machine. But, I need to follow some directions.
    >
    > So, in concrete, is there any way to use the value of the state
    > variables of a declared enumerated type ?


    It sounds like you are trying to optimize the coding of your state
    machine so that a given output potentially does not depend on all of the
    state variable bits. If that is not the case, then I don't think you
    will find this added complexity will add much to your design. I guess
    your hard coding of the output functions might save a bit of logic, but
    typically the optimizer will be pretty good.

    If you were one-hot encoding, then you might get the best results by
    hand decoding the states.

    One way to get the state variable bits is to define an slv that maps to
    the states of the machine using a case statement in a non-clocked
    process...

    process (state) begin
    case (state) of
    b_busy => slv_state <= "000";
    backoff => slv_state <= "001";
    rickman, Oct 13, 2004
    #4
  5. cristian

    cristian Guest

    rickman <> wrote in message news:<>...
    > cristian wrote:
    > >
    > > I have done the following declaration as part of my state machine
    > > code:
    > >
    > > type states is (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_write);
    > > attribute syn_enum_encoding: string;
    > > attribute syn_enum_encoding of states : type is "000 001 011 111 110
    > > 101 100";
    > > SIGNAL state, nxt_state : states;
    > >
    > > For different reasons I do need to be able to 'read' the value of the
    > > state variables of my enumerated type to do something like this:
    > >
    > > oe_rst <= sv(1) and not sv(2) and not sv(3);
    > >
    > > int_req <= ((not r_cmd(3) and not r_cmd(2) and r_cmd(1) and sv(1) and
    > > not sv(2) and sv(3)) or (sv(1) and not sv(2) and not sv(3));
    > >
    > > start_timer <= ((sv(1) and not sv(2) and not sv(3)) or (sv(1) and not
    > > sv(2) and sv(3)));
    > >
    > > where 'sv' is the state variable of the enumerated type defined in the
    > > respective VHDL statement.
    > >
    > > I do know that this is not the best way of doing output assignments in
    > > an State Machine. But, I need to follow some directions.
    > >
    > > So, in concrete, is there any way to use the value of the state
    > > variables of a declared enumerated type ?

    >
    > It sounds like you are trying to optimize the coding of your state
    > machine so that a given output potentially does not depend on all of the
    > state variable bits. If that is not the case, then I don't think you
    > will find this added complexity will add much to your design. I guess
    > your hard coding of the output functions might save a bit of logic, but
    > typically the optimizer will be pretty good.
    >
    > If you were one-hot encoding, then you might get the best results by
    > hand decoding the states.
    >
    > One way to get the state variable bits is to define an slv that maps to
    > the states of the machine using a case statement in a non-clocked
    > process...
    >
    > process (state) begin
    > case (state) of
    > b_busy => slv_state <= "000";
    > backoff => slv_state <= "001";
    > .
    > .
    > .
    > end case;
    > end process;
    >
    > I don't bother to remember details of syntax so I don't know that it is
    > correct for the above code, but you get the idea.
    >
    >
    > --
    >
    > 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


    Thanks very much for all your feedback. Though, it seems to me that I
    did not get the right answer yet.

    First, Alan's answer regarding using 'POS, even though is not
    synthesisable, it would not help since I have other than binary/seq
    kind of encoding. On the other side, the problem of declaring an
    std_logic_vector constant with the specific encoding (same solution
    that Paul brought out and close to the Rick's point); this approach
    will create one constant per each state of the SM. Therefore, there
    will not be a 'common' state variable for all the states. Remember, I
    need to something like this:
    oe_rst <= sv(1) and not sv(2) and not sv(3);
    So, I need to have access to the 'common' state variables.

    I investigated a little further and found an intersting posting in
    this group associated with the 'POS. Search the following string in
    the VHDL group:

    non-constant 'pos, or other method of state debugging

    Though, the solution is just suitable for binary encoding.

    Thanks,

    cristian
    cristian, Oct 13, 2004
    #5
  6. cristian

    rickman Guest

    cristian wrote:
    >
    > Thanks very much for all your feedback. Though, it seems to me that I
    > did not get the right answer yet.
    >
    > First, Alan's answer regarding using 'POS, even though is not
    > synthesisable, it would not help since I have other than binary/seq
    > kind of encoding. On the other side, the problem of declaring an
    > std_logic_vector constant with the specific encoding (same solution
    > that Paul brought out and close to the Rick's point); this approach
    > will create one constant per each state of the SM. Therefore, there
    > will not be a 'common' state variable for all the states. Remember, I
    > need to something like this:
    > oe_rst <= sv(1) and not sv(2) and not sv(3);
    > So, I need to have access to the 'common' state variables.
    >
    > I investigated a little further and found an intersting posting in
    > this group associated with the 'POS. Search the following string in
    > the VHDL group:
    >
    > non-constant 'pos, or other method of state debugging
    >
    > Though, the solution is just suitable for binary encoding.


    Two points, first if you are not trying to optimize the decoding of your
    outputs, I don't understand why you need separate access to the bits in
    your state variable. But I will ignore my lack of understanding.

    The second point is that using an SLV will give you *exactly* what you
    are asking for. You can either use the SLV as the state variable in the
    FSM description, or as I suggested, you can use your enumerated signal
    in the FSM and assign an SLV to the value of the state variable. In
    either case you can then access the bits individually. The fact that
    you use constants to define the SLV values does not prevent you from
    accessing the individual bits.

    type states is
    (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_write);
    attribute syn_enum_encoding: string;
    attribute syn_enum_encoding of states : type is "000 001 011 111 110 101
    100";
    SIGNAL state_enum : states;
    signal state_slv : std_logic_vector(2 downto 0);

    process (clk, reset) begin
    case (state_enum) is
    when b_busy =>
    if input_a = '0' then
    state_enum <= backoff;
    end if;
    when backoff =>
    state_enum <= b_busy;
    end case;
    end process;

    process (state) begin
    case (state) of
    b_busy => state_slv <= "000";
    backoff => state_slv <= "001";
    rickman, Oct 13, 2004
    #6
  7. How about defining a function which accepts a state variable and a
    bit-index as arguments, and returns the selected bit?
    ie
    function myfunc(signal sv : states; index : natural)
    return std_logic is
    variable x : std_logic_vector(2 downto 0);
    begin
    case sv of
    b_busy => x <= "000";
    ... etc
    default => x <= "XXX"; -- broken!
    end case;
    return x(index);
    end myfunc;

    You would probably want to add asserts on the range of "index", etc.,
    but you get the idea.
    Now you can write
    oe_rst <= myfunc(sv,1) and not myfunc(sv,2) ...

    rickman <> wrote:

    :cristian wrote:
    :>
    :> I have done the following declaration as part of my state machine
    :> code:
    :>
    :> type states is (b_busy,backoff,base_address,card_present,timer_dat,timer_read,timer_write);
    :> attribute syn_enum_encoding: string;
    :> attribute syn_enum_encoding of states : type is "000 001 011 111 110
    :> 101 100";
    :> SIGNAL state, nxt_state : states;
    :>
    :> For different reasons I do need to be able to 'read' the value of the
    :> state variables of my enumerated type to do something like this:
    :>
    :> oe_rst <= sv(1) and not sv(2) and not sv(3);
    :>
    :> int_req <= ((not r_cmd(3) and not r_cmd(2) and r_cmd(1) and sv(1) and
    :> not sv(2) and sv(3)) or (sv(1) and not sv(2) and not sv(3));
    :>
    :> start_timer <= ((sv(1) and not sv(2) and not sv(3)) or (sv(1) and not
    :> sv(2) and sv(3)));
    :>
    :> where 'sv' is the state variable of the enumerated type defined in the
    :> respective VHDL statement.
    :>
    :> I do know that this is not the best way of doing output assignments in
    :> an State Machine. But, I need to follow some directions.
    :>
    :> So, in concrete, is there any way to use the value of the state
    :> variables of a declared enumerated type ?
    :
    :It sounds like you are trying to optimize the coding of your state
    :machine so that a given output potentially does not depend on all of the
    :state variable bits. If that is not the case, then I don't think you
    :will find this added complexity will add much to your design. I guess
    :your hard coding of the output functions might save a bit of logic, but
    :typically the optimizer will be pretty good.
    :
    :If you were one-hot encoding, then you might get the best results by
    :hand decoding the states.
    :
    :One way to get the state variable bits is to define an slv that maps to
    :the states of the machine using a case statement in a non-clocked
    :process...
    :
    :process (state) begin
    : case (state) of
    : b_busy => slv_state <= "000";
    : backoff => slv_state <= "001";
    : .
    : .
    : .
    : end case;
    :end process;
    :
    :I don't bother to remember details of syntax so I don't know that it is
    :correct for the above code, but you get the idea.
    David R Brooks, Oct 13, 2004
    #7
    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. Marek Ponca

    Enumerated Type in assertion ?

    Marek Ponca, Jan 10, 2005, in forum: VHDL
    Replies:
    2
    Views:
    3,211
    Jonathan Bromley
    Jan 10, 2005
  2. rfractal30
    Replies:
    6
    Views:
    470
    rfractal30
    Feb 25, 2005
  3. Alastair Cameron
    Replies:
    1
    Views:
    1,575
    Colin Mackenzie
    Jul 4, 2003
  4. David R. Throop
    Replies:
    0
    Views:
    403
    David R. Throop
    May 6, 2005
  5. Replies:
    3
    Views:
    383
Loading...

Share This Page