Reading enumerated state variables

C

cristian

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
 
P

Paul Uiterlinden

cristian said:
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.
 
A

Alan Fitch

cristian said:
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:
(e-mail address removed)
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.
 
R

rickman

cristian said:
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";
 
C

cristian

rickman said:
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

(e-mail address removed)
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
 
R

rickman

cristian said:
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";
 
D

David R Brooks

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) ...


: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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top