I am implementing a state machine in a FPGA using VHDL. Several states are determined by 4 external event inputs (falling edge) which occur asynchronously to the 25MHz FPGA clock (I might need to increase to 50MHz). The events occur at random intervals of 10us or more.
I have a couple questions which someone may be able to guide me on:
1) Should I have a synchroniser (2-stage shift reg) at each of the 4 event inputs before being sampled by the state machine to avoid meta-stability problems?
2) I'm using the following VHDL code to detect a falling edge on the event inputs. Is there a better way?
begin if (reset = '1') then -- reset the event states prev_ev1 := event; got_ev1 := false; elsif (rising_edge(clk)) then if (event = '0') then -- event signal is low if (prev_ev1 = '1') then got_ev1 := true; -- falling edge detected end if; prev_ev1 = '0' else prev_ev1 = '1'; end if;
end if; end process; Any advice welcome! Thanks Dave
Yes, absolutely, unless you have an astonishingly cunning state machine design...
AARGH, no, that's not the reason.
Saddle-up the old warhorse, and back in to battle once again...
Most people who *think* they have a problem with metastability, don't. Instead they probably have a problem with input hazards.
OK, so what's an input hazard? It's any situation where an asynchronous input can affect more than one flip-flop.
If this asynch input should change painfully close to a clock edge, you will of course get setup/hold violations on the flops. This in itself rarely causes a problem, because each flop individually will either respond to the changed input or it won't. The problem happens when one of the flops DOES respond, and the other DOESN'T. When this happens you get an internal state change that was not expected. It will almost certainly screw up the sequencing of your state machine, and it will quite likely send it off into the weeds.
Note that, in describing this problem, I have made no appeal whatever to the idea of metastability. Each flip-flop individually is behaving quite perfectly; it's just that the collection of two flip-flops appears to behave inconsistently because of the asynchronous input.
The problem is completely (yes, I really mean completely) solved by registering the offending input in just one flip-flop. The output of this resynchronising flop is then fed to your state machine. Given that the input is asynchronous, a one- clock delay in responding to it is unlikely to be a show- stopper.
If you are both clever and lucky, you may be able to design your state machine so that only one of its state bits is affected by any input change. However, it is brain- numbingly difficult to do this in the face of complicated changes to the state machine as its design evolves, and when synthesis tools are inclined to re-code state vector values arbitrarily as an "optimisation". So it's almost always better, in practice, to register the asynchronous inputs before they get anywhere near your state machine. Especially when you have multiple asynch inputs to worry about.
Metastability is a much less likely culprit. Metastability means that one individual flop misbehaves because its D input changes at an inopportune moment, so that the internal logic of the flop gets confused about whether to settle at
1 or 0. The flop's clock-to-output delay then becomes much longer than its specified value. This effect, of course, CAN happen on my single resynchronising flop, and CAN cause trouble if its clock-to-output delay is thereby pushed out to about a clock period; should this happen, the supposedly resynchronised signal can itself appear to be asynchronous and can therefore cause an input hazard on the state machine. A second resynch flip-flop will dramatically reduce the risk of this problem, at the expense of one more cycle of latency. Figures published here by Peter Alfke and others suggest that in your case, with a slow-ish clock and relatively infrequent transitions of the asynchronous input, the risk of this genuine metastability is so small that you can ignore it - but you MUST either do the sums, or else be just a little paranoid and add the extra flop in any case.
Oh flippin' 'eck, what are you doing putting asynch inputs into the sensitivity list of a clocked process?
Yeah, something like that. Don't reset the flags inside the state machine. Reset them at the top of the clocked process, so that they become purely combinational flags. Effectively you've created a shift register with an and gate sensing a change across its final stage.
It's sometimes easier to roll this edge detection into the state machine (don't go into your "wait for fall" state until you've detected "input high"). Depends on what you're doing in the state machine. Once again, given that you have multiple inputs, I suspect the scheme you outline is as good as you'll get - and it's easy to understand.
Finally, please DON'T do anything that depends on simultaneity of two or more of the external asynchronous inputs - you simply can't rely on that, given that they are asynchronous relative to your clock. The best you can do is to identify when two or more inputs change within one or two sampling clocks of each other. Alternatively, if you're very lucky you may have an external signal that indicates when the four inputs are stable and therefore it's safe to sample them.
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how
Yes, you should use a resynchronizer, and avoid using the "greedy path". That is, the signal 'event' in your code above should be the output of a two-flop synchronizer; not the output of a single synchronization flop.
Jonathan's comments about metastability being of little concern to you are accurate, but the danger is finite. The liklihood of a single synchronizer flop being metastable at the next clock edge is very small, but if it does go metastable it will eat into the setup time. If the path connected to the output takes up most of the period, then there is no margin for any excess clk->out time. If latency isn't an issue and flops are plentiful, then having extra synchronizer flops is a prudent idea. It is true though that a more common mistake is to synchronize a multibit bus without realizing that this will result in invalid values except in the case of Gray-coded logic.
Do you want your circuit to work all of the time or is most of the time good enough?
There are tricks to building reliable circuits without the classic pair of FFs to synchronize an async input. But they are asking for troubles. The main problem is that the typical tool package doesn't support checking to make sure you get it right and don't break something with an innocent change sometime later on.
The suespammers.org mail server is located in California. So are all my
other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited
At 25 or even 50 MHz, the likelihood of a metastability event on the output of the first synchronizer stage lasting into the setup time of the next clock edge is very low. BUT at least put the asynchronous inputs through one flip-flop. That way the various flip-flops inferred by your state logic will see the same value on the same clock edge. Not doing this is the classic way to create a "zero-hot" or "multiple-hot" condition in a one-hot state machine. If you are worried about that small chance of metastability, by all means use two flip-flops to reduce the chance to near zero (as in not likely to happen in our lifetimes at 25 MHz).
In this case without the input synchronizer, your danger is for prev_ev1 to go active because it saw an event at some clock edge, but got_ev1 staying false because it didn't see the event on the same edge. This way you would miss an event. After a single stage synchronizer this would only happen if the event caused metastability on the output of the synchronizer flip flop lasting into the setup time to the next clock edge, nearly a full cycle of 25 MHz. This is an extremely unlikely event for most FPGA processes, but as I mentioned above you can add one more input stage and reduce the risk further.
Thanks to everyone who responded to my original "Asynchronous Inputs Question", the answers have been very informative. As you can tell, I'm new to FPGAs/VHDL but I should have known better than to connect asynchronous inputs to a state machine!
Does anyone have a suggestion for a practical book (Horowitz & Hill style) or links, papers, etc. for VHDL, especially synthesis for FPGAs ? The books I've come across are a bit lacking in this respect.
Lastly, I get "Unable to retrieve message ..." when clicking on the post follow-up button. Am I doing something wrong?
Have you seen these? Both of them press the right buttons for me: Rushton, A: VHDL for Logic Synthesis (Wiley) Zwolinski, M: Digital System Design using VHDL (Prentice-Hall)
No idea. There are so many newsreader tools around. I use the free version of Forte Agent and never have any trouble like that (although the free version lacks a few features that some people would probably miss, such as cross-posting).
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how