CASE statement & LOOP

N

Niv

Guest
I have a state machine which goes through a regular stepping process
for a lot of states (35), to produce a short clock burst (and other
control signals) so I was wondering if its possible to put a loop
inside a case statement!!

e.g. could I change this:

CASE state IS
WHEN s0 => next_state s1;
WHEN s1 => next_state s1;
WHEN s2 => next_state s1;

....
....

WHEN s34 => next_state s35;
WHEN OTHERS => reset_state; -- capture errors
END CASE;

to this:

CASE state IS
FOR i IN 0 TO 34 LOOP
WHEN s(i) => next_state s(i+1);
END LOOP;
WHEN OTHERS => reset_state; -- capture errors
END CASE;

Obviously the state type declaration will need modifying as well
(somehow).
Is any of this possible, just occurred to me & haven't got time right
now to try.
Just wondering, as it might be a tad neater.
 
Niv wrote:

I have a state machine which goes through a regular stepping process
for a lot of states (35), to produce a short clock burst (and other
control signals) so I was wondering if its possible to put a loop
inside a case statement!!

e.g. could I change this:

CASE state IS
WHEN s0 => next_state s1;
WHEN s1 => next_state s1;
WHEN s2 => next_state s1;

....
....

WHEN s34 => next_state s35;
WHEN OTHERS => reset_state; -- capture errors
END CASE;
This piece of code is incomplete. Do you want something like

WHEN s0 => next_state<=s1;

or what is your purpose? The OTHERS-clause if also incomplete.


CASE state IS
FOR i IN 0 TO 34 LOOP
WHEN s(i) => next_state s(i+1);
END LOOP;
WHEN OTHERS => reset_state; -- capture errors
END CASE;
From one state you want to go to exactly one other state - with no
branches included? Am I right? If yes - use a counter. A counter jumps
also to only one next state without branches.


Is any of this possible, just occurred to me & haven't got time right
now to try.
But we shall have the time?

Ralf
 
Ralf Hildebrandt wrote:
Niv wrote:

I have a state machine which goes through a regular stepping process
for a lot of states (35), to produce a short clock burst (and other
control signals) so I was wondering if its possible to put a loop
inside a case statement!!

e.g. could I change this:

CASE state IS
WHEN s0 => next_state s1;
WHEN s1 => next_state s1;
WHEN s2 => next_state s1;

....
....

WHEN s34 => next_state s35;
WHEN OTHERS => reset_state; -- capture errors
END CASE;

This piece of code is incomplete. Do you want something like

WHEN s0 => next_state<=s1;

or what is your purpose? The OTHERS-clause if also incomplete.


CASE state IS
FOR i IN 0 TO 34 LOOP
WHEN s(i) => next_state s(i+1);
END LOOP;
WHEN OTHERS => reset_state; -- capture errors
END CASE;

From one state you want to go to exactly one other state - with no
branches included? Am I right? If yes - use a counter. A counter jumps
also to only one next state without branches.


Is any of this possible, just occurred to me & haven't got time right
now to try.

But we shall have the time?

Ralf
I wasn't expecting anyone to "try" anything, just pass on their
knowledge if thry knew whether or not it was possible.
The state machine has 64 states in total, but 35 of them follow on from
one another, the rest are not so sequential, hence the original
question.

Niv
 
You could write:
case state is
when s0 to s30 => next_state <=
state_type'val(state_type'pos(state) + 1);
when s31 => next_state <= s17; -- for example
...

Maybe some synthetizer do not handle that however :-(

JD.
 
john Doef a écrit :
You could write:
case state is
when s0 to s30 => next_state <> state_type'val(state_type'pos(state) + 1);
maybe even shorter :
when s0 to s30 => next_state <= state_type'succ(state);

when s31 => next_state <= s17; -- for example
...

Maybe some synthetizer do not handle that however :-(

JD.

maybe
 
Or, remove states 0 through 34 and have a single state that waits for a
counter to expire. All synthesizers can handle this.
 
I cannot remove any states, I must have 2^n states (e.g. 64), and use
binary encoding rather than one-hot. This helps eliminate unwanted
possible states due to errors (SEU etc), which could cause a one hot to
go to some strange state. My state m/c actually needs 34 states, so I
have an extra 30 reset states which are only passed through during
reset and then sits in the idle state until initiated, where it cycle
round the 34 states.
If I used one hot, there would be 2^64 - 34 possible unwanted states,
rather more than 30! This is the way we code for some safety related
apps.
Of course, there be better ways, but this is our (currently) standard
way of coding for safety related apps.
 
I don't mean to sound pessimistic, but protection against SEU in this way
isn't really going to help... (Statistically) AFAIR only about 1% of SEU
actually leads to data corruption, of the reminder about 90% have no visible
effect, and 9% change the function of a circuit. The probability of an SEU
effecting data or function at ground level for a typical FPGA is around the
same as the component randomly failing due to lifetime (MTBF/FIT).

But then maybe you're having an issue with electronics near radiation
sources, or something for high altitude?

So my question becomes - why do things by hand like this? why not just go
the whole hog and use TMR?

Just my 2p.
Ben


"Niv" <kev.parsons@mbda.co.uk> wrote in message
news:1151392041.511673.170410@x69g2000cwx.googlegroups.com...
I cannot remove any states, I must have 2^n states (e.g. 64), and use
binary encoding rather than one-hot. This helps eliminate unwanted
possible states due to errors (SEU etc), which could cause a one hot to
go to some strange state. My state m/c actually needs 34 states, so I
have an extra 30 reset states which are only passed through during
reset and then sits in the idle state until initiated, where it cycle
round the 34 states.
If I used one hot, there would be 2^64 - 34 possible unwanted states,
rather more than 30! This is the way we code for some safety related
apps.
Of course, there be better ways, but this is our (currently) standard
way of coding for safety related apps.
 
Niv wrote:

I cannot remove any states, I must have 2^n states (e.g. 64)
All state machines have this problem, because you can only use a
flipflop or not for state encoding. Therefore every time 2^n states are
included.


, and use
binary encoding rather than one-hot.
The encoding is stuff for the synthesis tool. With area or speed
constraints or forced encoding types you get the desired encoding type.


This helps eliminate unwanted
possible states due to errors (SEU etc), which could cause a one hot to
go to some strange state.
A lot of synthesis tools are "smart" enough to see, that the impossible
state encodings are never reached and remove them! So verify if you
really get the results that you expect.


My state m/c actually needs 34 states
Sometimes its impossible, but maybe you can remove 2 states...


, so I
have an extra 30 reset states which are only passed through during
reset and then sits in the idle state until initiated, where it cycle
round the 34 states.
Ok, that is a workaround to prevent the synthesis tool to optimize the
filled state encodings away.


Ralf
 
Hi Niv,

"Niv" <kev.parsons@mbda.co.uk> writes:

I cannot remove any states, I must have 2^n states (e.g. 64), and use
binary encoding rather than one-hot. This helps eliminate unwanted
possible states due to errors (SEU etc), which could cause a one hot to
go to some strange state. My state m/c actually needs 34 states, so I
have an extra 30 reset states which are only passed through during
reset and then sits in the idle state until initiated, where it cycle
round the 34 states.
If I used one hot, there would be 2^64 - 34 possible unwanted states,
rather more than 30! This is the way we code for some safety related
apps.
OTOH, with one-hot (or even coding-schemes with parity/ECC), you have
a higher chance of actually detecting that something went wrong.

With a binary encoding a flipped bit will almost certainly hit a valid
state. How do you determine whether the state is valid in the current
context?

In other words, you really want these "unwanted possible states".

Regards,
Marcus

--
The Germans have inherited a filthy Saxon culture and no more need be
said about them.
-- Mark Ballard, The Register
 
Another technique for illegal state recovery is to use binary encoding,
but ensure that all reachable states are at least a hamming distance of
3 from each other (i.e. 3 bits would have to change to get from one
reachable state to another). Then insert transition logic from all of
the unreachable states to their nearest reachable state. You have to
disable fsm optimization or it will get rid of the
unreachable/redundant states. This is usually more efficient than TMR,
with the same benefits (seu recovery).

case state is
when idle | idle1 | idle2 => -- idle1 and idle2 are nearest to idle
state := idle; -- default assignment back to idle
do_idle_stuff_here; -- normal actions for idle state
when go | go1 | go2 => -- go1 and go2 are nearest to go
state := go; -- default assignment back to go
do_go_stuff_here; -- normal actions for go state
end case;

You could use a concurrent asssertion with a function to ensure that
your reachable states have hamming distances of 3 or more between them.
This can come in handy when trying to specify 9 or more states with
hamming separations of 3 or more.

From my observations, 2 states take 3 bits (=tmr), 3-4 states take 5
bits, 5-8 states take 6 bits. With TMR, 3-4 states take 6 bits, 5-8
states take 9 bits.

Andy
 
Hi,

Marcus Harnisch schrieb:
OTOH, with one-hot (or even coding-schemes with parity/ECC), you have
a higher chance of actually detecting that something went wrong.
But you need either a lot of logic to recover from all possible illegal
states or get your designs hang up until next power on.
For a good designed fsm a SEU[1] will cause one error but recovers
without external help.
This may be not acceptable for some designs, but a lot of designs could
accept, that an error leads to a limited number of wrong outputs, when
self recovery is garanteed within a given time.
Your car could tolerate, that an error cause a delay of several us
until your brake reacts, but it will not be acceptable that your brake
stops working until next restart of your motor.
Of course you do not want your airbag to be deployed due to an error so
you just have to inspect which errors yould be acceptable.

With a binary encoding a flipped bit will almost certainly hit a valid
state. How do you determine whether the state is valid in the current
context?

In other words, you really want these "unwanted possible states".
As long as an unwanted possible state is only a delay, there is no harm
done for several designs.
bye Thomas

[1] Single Event Upset in a more generell way it makes no difference
wheter you have a data corruption due to radition, spikes on clock or
temperature effects.
 
Hi,

Benjamin Todd schrieb:
But then maybe you're having an issue with electronics near radiation
sources, or something for high altitude?

So my question becomes - why do things by hand like this? why not just go
the whole hog and use TMR?
Even when using TMR your not 100% safe. So it is common practice to use
all 2^n states.
Unfortunately there are synthesis tools like Synplify removing the
logic of
when others => state <= init_state;
If your design didn't walk through the states during "normal" function.


bye Thomas
 
"Thomas Stanka" <usenet_10@stanka-web.de> writes:

Benjamin Todd schrieb:
But then maybe you're having an issue with electronics near radiation
sources, or something for high altitude?

So my question becomes - why do things by hand like this? why not just go
the whole hog and use TMR?

Even when using TMR your not 100% safe. So it is common practice to use
all 2^n states.
Unfortunately there are synthesis tools like Synplify removing the
logic of
when others => state <= init_state;
If your design didn't walk through the states during "normal" function.
I specify the normally unused states in the enumeration type, and
then "count" through these after a reset, ending up at the idle
state. IIRC the original poster said something like this as well.

I got that method from this very newsgroup, and I think it is a
pretty safe way to disallow the synthesis tool to remove these
states. If that still doesn't help, one could maybe bring out the
state signal to a port and then don't flatten the hierarchy, so that
it doesn't know that the port is not used.

This wasn't needed for us, I "injected" such SEU errors in gatelevel
simulation (with the force/deposit feature of the simulator), and
the design recovered as expected.

Cheers,
Colin
 
Hi Thomas,

"Thomas Stanka" <usenet_10@stanka-web.de> writes:
But you need either a lot of logic to recover from all possible illegal
states or get your designs hang up until next power on.
Safety comes at a price.

will cause one error but recovers
without external help.
This is often true. But a spurious invalid transition from one valid
state (normal) to another valid state (maintenance), due to fully
encoded state variables can hardly be called `self recovery'.

case state is
when normal => -- do stuff

when maintenance => -- disable all safety measures and sit until
-- power-cycle
end case


Best regards,
Marcus
 
The only issue with always jumping to the init state is that, while the
FSM keeps running, it may now be out of sync with whatever it was
controlling (handshakes, etc.), and the _system_ may lock up.

What is needed is a state mapping where it is unambiguous which legal
state is nearest (fewest bits flopped) from _any_ illegal state. Then
the state machine should treat any illegal state just like its nearest
legal neighbor, and scrub it (set it to the legal state) at the same
time.

TMR does this automatically, but at a cost of significantly more
resources than the approach I outlined elsewhere in this thread
(defining legal states with hamming distance of at least 3 between
them).

No approach is 100% safe, but both TMR and the approach I have proposed
are 100% safe for SEUs. If you have multiple-bit, simultaneous
errors, all bets are off. You could increase the hamming distances
between legal states to some arbitrary value... Or implement PMR
(5-way) or SMR (7-way) or ...

Andy


Colin Marquardt wrote:
"Thomas Stanka" <usenet_10@stanka-web.de> writes:

Benjamin Todd schrieb:
But then maybe you're having an issue with electronics near radiation
sources, or something for high altitude?

So my question becomes - why do things by hand like this? why not just go
the whole hog and use TMR?

Even when using TMR your not 100% safe. So it is common practice to use
all 2^n states.
Unfortunately there are synthesis tools like Synplify removing the
logic of
when others => state <= init_state;
If your design didn't walk through the states during "normal" function.

I specify the normally unused states in the enumeration type, and
then "count" through these after a reset, ending up at the idle
state. IIRC the original poster said something like this as well.

I got that method from this very newsgroup, and I think it is a
pretty safe way to disallow the synthesis tool to remove these
states. If that still doesn't help, one could maybe bring out the
state signal to a port and then don't flatten the hierarchy, so that
it doesn't know that the port is not used.

This wasn't needed for us, I "injected" such SEU errors in gatelevel
simulation (with the force/deposit feature of the simulator), and
the design recovered as expected.

Cheers,
Colin
 
Well, to guarantee 100% cover of any number of multiple errors I might
need IMR (infinite module redundancy), not sure this is in Xilinx
device roadmap (yet!)

Kev P.
 

Welcome to EDABoard.com

Sponsor

Back
Top