Xilinx XST and a State Machine - A Mystery

D

Darol Klawetter

Guest
I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing. I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.



parameter [3:0]
S1 = 4'b0000,
S2 = 4'b0001,
S3 = 4'b0010,
S4 = 4'b0011,
S5 = 4'b0100,
S6 = 4'b0101,
S7 = 4'b0110,
S8 = 4'b0111,
S9 = 4'b1000,
S10 = 4'b1001,
S11 = 4'b1010,
S12 = 4'b1011,
S13 = 4'b1100,
S14 = 4'b1101,
S15 = 4'b1110,
S16 = 4'b1111;

always @(posedge rst or posedge clk)
begin
if (rst) // 'rst' is asserted
and deasserted synchronously to 'clk'
begin
rfd <= 1'b0;
phaseRamWE <= 1'b0;
phaseRamWriteAdr <= 0;
phaseRamReadAdr <= 0;
phaseAccum <= 0;
state <= S1;
end
else
begin
case (state)
S1:
begin
if (pipeFill == 1'b1) // 'pipeFill' is
asynchronous to 'clk'
begin
phaseRamWE <= 1'b1;
state <= S2;
end
end

S2:
begin
phaseRamReadAdr <= phaseRamReadAdr + 1;
state <= S3;
end


S3:
begin
phaseRamReadAdr <= phaseRamReadAdr + 1;
state <= S4;
end

S4:
begin
phaseRamWriteAdr <= phaseRamWriteAdr + 1;
phaseRamReadAdr <= phaseRamReadAdr + 1;
state <= S5;
end

S5:
begin
phaseRamWriteAdr <= phaseRamWriteAdr + 1;
phaseRamReadAdr <= phaseRamReadAdr + 1;
state <= S6;
end

S6:
begin
rfd <= 1'b1;
phaseRamReadAdr <= phaseRamReadAdr + 1;
phaseRamWriteAdr <= phaseRamWriteAdr + 1;
if (start == 1'b0) // 'start' is
synchronous
begin
state <= S7;
end
else
begin
state <= S8;
end
end


S7:
begin
if (start == 1'b0) // 'start' is
synchronous
begin
state <= S7;
end
else
begin
state <= S8;
phaseRamReadAdr <= phaseRamReadAdr + 1;
phaseRamWriteAdr <= phaseRamWriteAdr + 1;
end
end


S8:
begin
if (start == 1'b0) // 'start' is
synchronous
begin
state <= S9;
phaseRamWE <= 1'b0;
phaseAccum <= 0;
rfd <= 1'b0;
phaseRamReadAdr <= 0;
phaseRamWriteAdr <= 0;
end
else
begin
state <= S8;
phaseRamReadAdr <= phaseRamReadAdr + 1;
phaseRamWriteAdr <= phaseRamWriteAdr + 1;
end
end

S9: state <= S10;
S10: state <= S11;
S11: state <= S12;
S12: state <= S13;
S13: state <= S14;
S14: state <= S15;
S15: state <= S16;
S16: state <= S1;

endcase

end
end
 
Darol Klawetter wrote:

I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing. I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.
I have seen similar behaviour with Altera Quartus. It was the same problem:
asynchronous inputs changed the state machine and sometimes it hangs. I
think it is possible that the state machine is internally implemented with
some more bits and it is possible that it hangs, if there are some timing
violations or meta stability conditions, because then there is an invalid
state encoded and everything can happen with optimized gates. The fix was
easy: Creating an input latch (or even two, if you are paranoid) for each
asynchronous signal to make it synchronous.

--
Frank Buss, http://www.frank-buss.de
piano and more: http://www.youtube.com/user/frankbuss
 
On Mon, 20 Sep 2010 08:52:16 -0700 (PDT), Darol Klawetter
<darol.klawetter@l-3com.com> wrote:

I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing. I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.
Try adding a (* safe_implementation = "yes" *) to your state register
and see if that gets rid of the problem.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
On Sep 20, 10:52 am, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:
I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing.  I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.
<snip>

I only skimmed the code, but this bit jumped out at me:

if (pipeFill == 1'b1) // 'pipeFill' is
asynchronous to 'clk'

If pipeFill is really asynchronous to the clock that is running your
state machine, using it without synchronizing it first is going to
cause you problems. Probably not because of metastability, but
because of coherency problems. If pipeFill is changing near the clock
edge, some FFs will see the new value, and some the old. This can
cause weird and flaky behaviour.

Regards,

John McCaskill
www.FasterTechnology.com
 
On Sep 20, 11:00 am, Frank Buss <f...@frank-buss.de> wrote:
Darol Klawetter wrote:
I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing.  I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.

I have seen similar behaviour with Altera Quartus. It was the same problem:
asynchronous inputs changed the state machine and sometimes it hangs. I
think it is possible that the state machine is internally implemented with
some more bits and it is possible that it hangs, if there are some timing
violations or meta stability conditions, because then there is an invalid
state encoded and everything can happen with optimized gates. The fix was
easy: Creating an input latch (or even two, if you are paranoid) for each
asynchronous signal to make it synchronous.

--
Frank Buss,http://www.frank-buss.de
piano and more:http://www.youtube.com/user/frankbuss
I thought the same thing, especially because XST often uses one-hot
encoding internally, and that introduces more state bits. Even though
I exhaustively defined all states, this may not be the case in the
post-synthesis result.
 
On Sep 20, 11:05 am, John McCaskill <jhmccask...@gmail.com> wrote:
On Sep 20, 10:52 am, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing.  I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.

snip

I only skimmed the code, but this bit jumped out at me:

            if (pipeFill == 1'b1)                     // 'pipeFill' is
asynchronous to 'clk'

If pipeFill is really asynchronous to the clock that is running your
state machine,  using it without synchronizing it first is going to
cause you problems.  Probably not because of metastability, but
because of coherency problems. If pipeFill is changing near the clock
edge, some FFs will see the new value, and some the old.  This can
cause weird and flaky behaviour.

Regards,

John McCaskillwww.FasterTechnology.com
Agreed, but the state machine should recover, right? All states are
defined.
 
On Sep 20, 11:05 am, John McCaskill <jhmccask...@gmail.com> wrote:
On Sep 20, 10:52 am, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing.  I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.

snip

I only skimmed the code, but this bit jumped out at me:

            if (pipeFill == 1'b1)                     // 'pipeFill' is
asynchronous to 'clk'

If pipeFill is really asynchronous to the clock that is running your
state machine,  using it without synchronizing it first is going to
cause you problems.  Probably not because of metastability, but
because of coherency problems. If pipeFill is changing near the clock
edge, some FFs will see the new value, and some the old.  This can
cause weird and flaky behaviour.

Regards,

John McCaskillwww.FasterTechnology.com
I think I just found the source of the problem, and it's not a bug in
XST. In state S1, if 'state' is updated while 'phaseRamWE' is not,
then it would produce the symptoms I saw. Early on, I had considered
synchronizing pipeFill to the 'clk" domain, but I thought I would just
handle it in the robustness of the state machine - my mistake.
 
On Sep 20, 11:12 am, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:
On Sep 20, 11:05 am, John McCaskill <jhmccask...@gmail.com> wrote:



On Sep 20, 10:52 am, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing.  I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me..

snip

I only skimmed the code, but this bit jumped out at me:

            if (pipeFill == 1'b1)                     // 'pipeFill' is
asynchronous to 'clk'

If pipeFill is really asynchronous to the clock that is running your
state machine,  using it without synchronizing it first is going to
cause you problems.  Probably not because of metastability, but
because of coherency problems. If pipeFill is changing near the clock
edge, some FFs will see the new value, and some the old.  This can
cause weird and flaky behaviour.

Regards,

John McCaskillwww.FasterTechnology.com

Agreed, but the state machine should recover, right? All states are
defined.
Hello Darol,

While you may have specified all the possible states for the width of
state variable that you used, unless you tell XST otherwise, it will
choose which ever encoding style that it feels is optimal. That is
usually a one hot encoding for a state machine the size of yours. By
default, XST will assume that states that you do not explicitly have a
transition to are truly unreachable and will not worry about them, and
will ignore default or when others cases of your case statement.

You can change the default behavior. You can force the tools to use an
encoding of your choice, and you can use the safe state machine
constraint to cause the tools to be more conservative in their
assumptions about unreachable states. Doing that will come at a cost
that the tools will choose a different encoding that will probably be
slower and bigger.

I think that you are much better off to always synchronize an
asynchronous signal at the boundary of your design.

Regards,

John McCaskill
www.FasterTechnology.com
 
On Sep 20, 11:55 am, John McCaskill <jhmccask...@gmail.com> wrote:
On Sep 20, 11:12 am, Darol Klawetter <darol.klawet...@l-3com.com
wrote:



On Sep 20, 11:05 am, John McCaskill <jhmccask...@gmail.com> wrote:

On Sep 20, 10:52 am, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

I recently fixed a problem with one of my state machines, and I think
that the cause could be a bug in Xilinx XST. Below is the code that
produced the failure. The state-machine worked most of the time,
though occasionally the 'phaseRamWE' signal would be stuck low, even
though I could see 'phaseRamReadAdr' and 'phaseRamWriteAdr'
incrementing.  I fixed it by explicitly declaring the desired value of
'phaseRamWE' in every state. Notice that all states are defined so it
should recover from any conditions introduced by asynchronous inputs.

Have any of you seen similar behavior? Appears to be an XST bug to me.

snip

I only skimmed the code, but this bit jumped out at me:

            if (pipeFill == 1'b1)                     // 'pipeFill' is
asynchronous to 'clk'

If pipeFill is really asynchronous to the clock that is running your
state machine,  using it without synchronizing it first is going to
cause you problems.  Probably not because of metastability, but
because of coherency problems. If pipeFill is changing near the clock
edge, some FFs will see the new value, and some the old.  This can
cause weird and flaky behaviour.

Regards,

John McCaskillwww.FasterTechnology.com

Agreed, but the state machine should recover, right? All states are
defined.

Hello Darol,

While you may have specified all the possible states for the width of
state variable that you used, unless you tell XST otherwise, it will
choose which ever encoding style that it feels is optimal. That is
usually a one hot encoding for a state machine the size of yours.  By
default, XST will assume that states that you do not explicitly have a
transition to are truly unreachable and will not worry about them, and
will ignore default or when others cases of your case statement.

You can change the default behavior. You can force the tools to use an
encoding of your choice, and you can use the safe state machine
constraint to cause the tools to be more conservative in their
assumptions about unreachable states. Doing that will come at a cost
that the tools will choose a different encoding that will probably be
slower and bigger.

I think that you are much better off to always synchronize an
asynchronous signal at the boundary of your design.

Regards,

John McCaskillwww.FasterTechnology.com
Thanks for the response, John. Yes, I realized that the Xilinx tools
could use different state encoding than that specified by the user,
but it seemed reasonable to assume that functionality would be matched
(wrong assumption). Anyway, you may have noticed, from a previous post
to this thread, that my problem was caused by my own error and was not
tool related.

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).
 
In comp.arch.fpga,
Gabor <gabor@alacron.com> wrote:
In practice, Gray code is not very useful for state machines that have
many
branch possibilities. Remember that you need to make sure that any
possible transition only changes one state bit. This is easy for any
linear or loop state logic like a counter, but most control logic
state
machines will have multiple-way branching from many of the states.
So unless you add intermediate states to prevent more than two-way
branching from any node you can still run into problems with
asynchronous inputs to the Gray coded machine. The added states
would give the same delay as a synchronizer flop on the input signal.
Did that many years ago for a CPLD design! Draw a big Karnaugh map,
try put in your states with the minimum possible dummy states and
only single bit changes. Great fun, better than cross-words. :)

But agreed, wouldn't do that now (although, I might ...), and back
then it only worked if the machine was not too complex.

--
Stef (remove caps, dashes and .invalid from e-mail address to reply by mail)

Most public domain software is free, at least at first glance.
 
On Sep 20, 2:02 pm, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -
The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than one state.

KJ
 
I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -
The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ
 
On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:
I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ
I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.
 
On Sep 20, 5:01 pm, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:
On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ

I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.
In practice, Gray code is not very useful for state machines that have
many
branch possibilities. Remember that you need to make sure that any
possible transition only changes one state bit. This is easy for any
linear or loop state logic like a counter, but most control logic
state
machines will have multiple-way branching from many of the states.
So unless you add intermediate states to prevent more than two-way
branching from any node you can still run into problems with
asynchronous inputs to the Gray coded machine. The added states
would give the same delay as a synchronizer flop on the input signal.
 
On Sep 20, 2:01 pm, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:
On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ

I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.
This is not a rule that "should be generally followed". It is rule
that must ALWAYS be followed!

If a signal from a "foreign" clock domain is used in a conditional
inside a state machine, the state machine will fail (eventually).

This is NOT a metastability problem. It is because the time to decode
the D inputs of the state bits is different for each D input, and if
the "foreign clock" signal is used in a conditional it will go to more
than one D input. There is no way to ensure that the D inputs are all
valid at the same time, and when the clock happens while one is valid
and the other is not state machine gets corrupted. This syndrome is
independent of the coding method of the state variable.

Synchronizing all inputs to a state machine to the state machines
clock will prevent that.

Not optional. Sorry.

RK
 
On Sep 20, 4:31 pm, d_s_klein <d_s_kl...@yahoo.com> wrote:
On Sep 20, 2:01 pm, Darol Klawetter <darol.klawet...@l-3com.com
wrote:





On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ

I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.

This is not a rule that "should be generally followed".  It is rule
that must ALWAYS be followed!

If a signal from a "foreign" clock domain is used in a conditional
inside a state machine, the state machine will fail (eventually).

This is NOT a metastability problem.  It is because the time to decode
the D inputs of the state bits is different for each D input, and if
the "foreign clock" signal is used in a conditional it will go to more
than one D input.  There is no way to ensure that the D inputs are all
valid at the same time, and when the clock happens while one is valid
and the other is not state machine gets corrupted.  This syndrome is
independent of the coding method of the state variable.

Synchronizing all inputs to a state machine to the state machines
clock will prevent that.

Not optional.  Sorry.

RK
RK,

You'll have to convince me that the rule "must ALWAYS" be followed,
independent of state encoding. It still seems to me that gray coding
could work - the machine either stays in the current state or
transitions to the next state because only one bit is transitioning.
If the input to this bit's register meets timing, then the machine
goes to the next state; if timing is not met, it either goes to the
next state or stays at the current one. The other bits are static.
 
Darol Klawetter <darol.klawetter@l-3com.com> wrote:
(snip, someone wrote)

This condition occurs for any state machine with more than flip flop
used to implement the state.
(snip)

This is not a rule that "should be generally followed".  It is rule
that must ALWAYS be followed!

If a signal from a "foreign" clock domain is used in a conditional
inside a state machine, the state machine will fail (eventually).
(snip)

Synchronizing all inputs to a state machine to the state machines
clock will prevent that.
(snip)

You'll have to convince me that the rule "must ALWAYS" be followed,
independent of state encoding. It still seems to me that gray coding
could work - the machine either stays in the current state or
transitions to the next state because only one bit is transitioning.
If the input to this bit's register meets timing, then the machine
goes to the next state; if timing is not met, it either goes to the
next state or stays at the current one. The other bits are static.
For a gray code state machine, and only one unsynchronized input,
maybe it can work. Assuming that there are more than two
states, you have to ask about the interaction with other inputs,
and the possible state transitions. If it is already going
from state 1 to state 3, and the unsynchronized input goes from
state 1 to state 0, then it seems possible that you might end
up in state 2.

So, for each synchronous state transition, you have to figure
out what transition occurs if the unsynchronized input changes
just before or just after the clock. For more than one,
you have to figure out the transition for all combinations of
inputs changing just before or just after the clock, even
if there is supposed to be an order.

I suppose if you do that, then I believe that it can work.

-- glen
 
On Sep 20, 9:04 pm, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:
On Sep 20, 4:31 pm, d_s_klein <d_s_kl...@yahoo.com> wrote:



On Sep 20, 2:01 pm, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ

I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.

This is not a rule that "should be generally followed".  It is rule
that must ALWAYS be followed!

If a signal from a "foreign" clock domain is used in a conditional
inside a state machine, the state machine will fail (eventually).

This is NOT a metastability problem.  It is because the time to decode
the D inputs of the state bits is different for each D input, and if
the "foreign clock" signal is used in a conditional it will go to more
than one D input.  There is no way to ensure that the D inputs are all
valid at the same time, and when the clock happens while one is valid
and the other is not state machine gets corrupted.  This syndrome is
independent of the coding method of the state variable.

Synchronizing all inputs to a state machine to the state machines
clock will prevent that.

Not optional.  Sorry.

RK

RK,

You'll have to convince me that the rule "must ALWAYS" be followed,
independent of state encoding. It still seems to me that gray coding
could work - the machine either stays in the current state or
transitions to the next state because only one bit is transitioning.
If the input to this bit's register meets timing, then the machine
goes to the next state; if timing is not met, it either goes to the
next state or stays at the current one. The other bits are static.
Must always is too strong. Your Gray coding example is valid and deals
with the issue of coherency, since only one FF changes state based on
the asynchronous signal. It does not address the issue of
metastability, but that is becoming much less of an issue because of
how fast the FFs have become. There have been post by either Austin
or Peter that they have a problem even trying to make it happen so
that they can measure it.

What I would say is that unless you have a very good reason not to,
you want to just use a synchronizing circuit before you do anything
else with an asynchronous signal. The cost is usually low, and the
consequences of doing it another way and getting it wrong are high. I
have debugged this sort of problem before, and it is a painful
process. FPGAs and their tools assume that you are using synchronous
techniques, and can work against you if you deviate from that path.
They can take your carefully coded Gray state machine and change it to
one hot if you don't have the proper constraints, or they might
replicate state registers if they have a high enough fan out and you
did not turn off that option.

Regards,

John McCaskill
www.FasterTechnology.com
 
On Sep 20, 7:04 pm, Darol Klawetter <darol.klawet...@l-3com.com>
wrote:
On Sep 20, 4:31 pm, d_s_klein <d_s_kl...@yahoo.com> wrote:





On Sep 20, 2:01 pm, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ

I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.

This is not a rule that "should be generally followed".  It is rule
that must ALWAYS be followed!

If a signal from a "foreign" clock domain is used in a conditional
inside a state machine, the state machine will fail (eventually).

This is NOT a metastability problem.  It is because the time to decode
the D inputs of the state bits is different for each D input, and if
the "foreign clock" signal is used in a conditional it will go to more
than one D input.  There is no way to ensure that the D inputs are all
valid at the same time, and when the clock happens while one is valid
and the other is not state machine gets corrupted.  This syndrome is
independent of the coding method of the state variable.

Synchronizing all inputs to a state machine to the state machines
clock will prevent that.

Not optional.  Sorry.

RK

RK,

You'll have to convince me that the rule "must ALWAYS" be followed,
independent of state encoding. It still seems to me that gray coding
could work - the machine either stays in the current state or
transitions to the next state because only one bit is transitioning.
If the input to this bit's register meets timing, then the machine
goes to the next state; if timing is not met, it either goes to the
next state or stays at the current one. The other bits are static.
It is more basic than that:
When the asynchronous input drives the D of asingle flip-flop, there
can be no problem. The flip-flop either changes or does not.
When, however the asynchronous input drives the D of more than one
flip-flop, then inevitably there will come the moment where one gets
set and the other one gets reset. Usually, this is a disaster, and can
and should be avoided by synchronizing all data inputs.
There might be special designs that can tolerate this ambiguity, but
the best practice is to synchronize.

I have been preaching this for over 40 years, but there are always new
designers who fall into the old trap...
Peter Alfke
 
On Sep 20, 7:38 pm, Peter Alfke <al...@sbcglobal.net> wrote:
On Sep 20, 7:04 pm, Darol Klawetter <darol.klawet...@l-3com.com
wrote:





On Sep 20, 4:31 pm, d_s_klein <d_s_kl...@yahoo.com> wrote:

On Sep 20, 2:01 pm, Darol Klawetter <darol.klawet...@l-3com.com
wrote:

On Sep 20, 3:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

I agree with your last paragraph. It's typically better to use a
couple of flops on an asynchronous control signal than trying to
handle it within the state machine (especially if the tool is going to
take encoding liberties).- Hide quoted text -

The rule is that any time there is a logic path from an asynchronous
input to more than one device that samples the signal(s), you must
first synchronize the signal before feeding it into any logic path.

This condition occurs for any state machine with more than flip flop
used to implement the state.

KJ

I agree that this is a rule that should be generally followed, but
there are exceptions. For example, a gray-coded state machine is
sometimes used to tolerate an asynchronous control input. If timing is
violated on any of the flops, the machine will stay at the current
state or transition to the next state.

This is not a rule that "should be generally followed".  It is rule
that must ALWAYS be followed!

If a signal from a "foreign" clock domain is used in a conditional
inside a state machine, the state machine will fail (eventually).

This is NOT a metastability problem.  It is because the time to decode
the D inputs of the state bits is different for each D input, and if
the "foreign clock" signal is used in a conditional it will go to more
than one D input.  There is no way to ensure that the D inputs are all
valid at the same time, and when the clock happens while one is valid
and the other is not state machine gets corrupted.  This syndrome is
independent of the coding method of the state variable.

Synchronizing all inputs to a state machine to the state machines
clock will prevent that.

Not optional.  Sorry.

RK

RK,

You'll have to convince me that the rule "must ALWAYS" be followed,
independent of state encoding. It still seems to me that gray coding
could work - the machine either stays in the current state or
transitions to the next state because only one bit is transitioning.
If the input to this bit's register meets timing, then the machine
goes to the next state; if timing is not met, it either goes to the
next state or stays at the current one. The other bits are static.

It is more basic than that:
When the asynchronous input drives the D of asingle flip-flop, there
can be no problem. The flip-flop either changes or does not.
When, however the asynchronous input drives the D of more than one
flip-flop, then inevitably there will come the moment where one gets
set and the other one gets reset. Usually, this is a disaster, and can
and should be avoided by synchronizing all data inputs.
There might be special designs that can tolerate this ambiguity, but
the best practice is to synchronize.

I have been preaching this for over 40 years, but there are always new
designers who fall into the old trap...
Peter Alfke
Well, and then there is the rare case of metastability, where even a
single flip-flop driven with an asynchronous D input, can change its Q
output asynchronously, perhaps moving up and down within a few ns.
Peter Alfke
 

Welcome to EDABoard.com

Sponsor

Back
Top