Safe FSM

On Tue, 31 Mar 2015 18:40:24 -0400, rickman wrote:

On 3/31/2015 3:31 PM, KJ wrote:

If you then take the above code and add 'when others=> Current_State <=
Idle' to the case statement as a method to cover those 'impossible'
states, synthesis tools will generally ignore it because I have already
covered all of the possible cases in an earlier 'when ...'.

This is exactly my point. Don't code like this. Code the one hot
states independently and the tool won't be able to see it as one large
FSM. Instead each state will appear as a separate FSM with nothing to
be optimized out. Error detection will consist of adding the state bits
and if the count is not exactly one, go to a safe state, a signal that
sets all the separate state bits to the appropriate value. I supplied
code for this earlier, but here is a version I like better based on the
transition specification rather than the present state value.

FSM : process (Clk, Rst)
begin
if ('1' = Rst) then
StateA <= '1';
StateB <= '0';
StateC <= '0';
StateD <= '0';
.
.
.
StateZ <= '0';

I see where you're going with this, making every bit of every state
assignment explicit.

You could do the same without the clutter, by declaring State to be an
array of bits, indexed by A to Z, and then:

-------------------------------------------------------------
type State_Index is (A,B,C,...Z);
type State_Type is array (State_Index) of bit;

signal State : State_Type;
constant State_A : State_Type is (A => '1', others => '0');
....
constant State_Z : State_Type is (Z => '1', others => '0');
-------------------------------------------------------------
All boiler plate, hide it in a package.

But now your state machine is written as:
-------------------------------------------------------------
FSM : process (Clk, Rst)
begin
if ('1' = Rst) then
State <= State_A;
elsif Rising_Edge(Clk) then ...
-------------------------------------------------------------
all completely compatible with the traditional way of writing a state
machine. In other words, we can retrofit your approach to any existing
state machine - without any rewrite to them - simply by replacing its
State_Type (an enumeration) declaration with the (packaged) declarations
above.

-- Brian
 
On 4/1/2015 7:02 AM, Brian Drummond wrote:
On Tue, 31 Mar 2015 18:40:24 -0400, rickman wrote:

On 3/31/2015 3:31 PM, KJ wrote:

If you then take the above code and add 'when others=> Current_State <=
Idle' to the case statement as a method to cover those 'impossible'
states, synthesis tools will generally ignore it because I have already
covered all of the possible cases in an earlier 'when ...'.

This is exactly my point. Don't code like this. Code the one hot
states independently and the tool won't be able to see it as one large
FSM. Instead each state will appear as a separate FSM with nothing to
be optimized out. Error detection will consist of adding the state bits
and if the count is not exactly one, go to a safe state, a signal that
sets all the separate state bits to the appropriate value. I supplied
code for this earlier, but here is a version I like better based on the
transition specification rather than the present state value.

FSM : process (Clk, Rst)
begin
if ('1' = Rst) then
StateA <= '1';
StateB <= '0';
StateC <= '0';
StateD <= '0';
.
.
.
StateZ <= '0';

I see where you're going with this, making every bit of every state
assignment explicit.

You could do the same without the clutter, by declaring State to be an
array of bits, indexed by A to Z, and then:

-------------------------------------------------------------
type State_Index is (A,B,C,...Z);
type State_Type is array (State_Index) of bit;

signal State : State_Type;
constant State_A : State_Type is (A => '1', others => '0');
...
constant State_Z : State_Type is (Z => '1', others => '0');
-------------------------------------------------------------
All boiler plate, hide it in a package.

But now your state machine is written as:
-------------------------------------------------------------
FSM : process (Clk, Rst)
begin
if ('1' = Rst) then
State <= State_A;
elsif Rising_Edge(Clk) then ...
-------------------------------------------------------------
all completely compatible with the traditional way of writing a state
machine. In other words, we can retrofit your approach to any existing
state machine - without any rewrite to them - simply by replacing its
State_Type (an enumeration) declaration with the (packaged) declarations
above.

I was never a fan of the "traditional" way of describing a state
machien. But my concern would be that your method would not get around
the FSM recognition by the tools. You are still using one signal for
the state variable, it just happens to have N bits just like any other
state variable with more than two bits.

--

Rick
 

Welcome to EDABoard.com

Sponsor

Back
Top