Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

Sync reset with push-button not reliable

Altera_Forum
Honored Contributor II
3,101 Views

I'm using Quartus II 9.1 Web Edition with a DE1 (Cyclone II Starter Kit) board and I have some problems with resetting my tiny design that I can't figure out. When I have all my flops reset synchronously, my design will reset improperly maybe 1 out 10 times. For example, I have some registers that are driven by the following block: 

always @ (posedge CLOCK_50) if (!rst_n) begin a3 <= 4'b0; a2 <= 4'b0; a1 <= 4'b0; a0 <= 4'b0; end else if (trigger & !done & ms_timeout) begin a3 <= a3_next; a2 <= a2_next; a1 <= a1_next; a0 <= a0_next; end  

When my reset signal, rst_n, is tied directly to KEY[0], I get traces like the attached (generated from the SignalTap II Logic Analyzer), showing a0 changing from 0 to 1 although the reset is deasserted and "trigger" is low throughout the trace. 

 

If I make all the flops reset asynchronously, everything works fine. But what really puzzles me: If I synchronize the rst_n signal like this: 

reg rst_n; always @ (posedge CLOCK_50 or negedge KEY) if (!KEY) rst_n <= 1'b0; else rst_n <= 1'b1;  

instead of just having it be wired directly to KEY[0], everything works even when all the flops are reset synchronously again. With my admittedly not very extensive knowledge on reset techniques, the purpose of synchronizing a reset like above is to avoid meta-stability on deassertion of aync resets. However, if that was the problem, why did the code then *work* with async reset and *not* work with sync reset? 

 

I'm sure I'm missing something here. Can anybody tell me what it is? 

 

Sebastian
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
1,679 Views

always @ (posedge CLOCK_50) if (!rst_n) begin a3 <= 4'b0; a2 <= 4'b0; a1 <= 4'b0; a0 <= 4'b0; end else if (trigger & !done & ms_timeout) begin a3 <= a3_next; a2 <= a2_next; a1 <= a1_next; a0 <= a0_next; end  

 

You have stated that above code implies synchronous reset. 

but is your reset signal itself synchronised from origin? 

Synchronous reset is true only if it is sourced synchronously. Applying it synchronously is not enough by itself. It may for example bounce at the key in your case. 

 

Also mak sure that timing is not violated and you may delete your signaltap file and restart fresh.
0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

Hi Sebastian, 

 

both the direct synchronous as well as asynchronous can have problems with metastability. This means the acceptance or not of your reset near the rising edge of your clock signal. This can be misinterpreted by different flip-flops in your FPGA, giving the results that you describe. 

 

Please refer to thread: http://www.alteraforum.com/forum/showthread.php?t=4281 which has a nice paper explaining how to make a good reset circuit in general and for Altera in particular. 

 

Hope this clarifies a little,
0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

I think, it's misleading to use the term "metastability" for trivial cases of timing violation caused by unrelated input signals. But synchronizing the input signal (in this case rst_n) to the clock is the appropriate means anyway.

0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

Hi FvM, 

 

when using an external button or switch for reset, the reset signal is unrelated to the clock. Of course it depends on the delay paths from your reset button to the flip-flops where it is being used and of course the relationship to the clock edge where the reset signal is used. So depending on when you reset in relation to your clock edge, even with synchronized resets, the chances are very real that this transition of the reset signal comes at the moment of the clock edge. Or that some paths of the (synchronous) reset signal may arrive earlier and other later than the clock edge. This is not usually what you want and it can mean that your system does not synchronously reset all flip flops at the same time. It is not difficult to make such a system, even with synchronous resets (from a button or switch) as you mention. 

 

I (mis)use the term metastable to indicate that we are in such cases operating on the border of what has to be recognized in one way or another, as the -synchronous- reset signal can arrive from the unrelated button input at nearly the same time (or before or after) the clock edge. 

 

To make real synchronized reset signals the method of 

 

always @(posedge clock) if (!rst_n) ... blah blah blah  

 

is not reliable enough when using switches or buttons, because the chance that the transition happens very near to the clock edge is very likely (Giving the results of the first poster). 

 

In order not to repeat things, I only wanted to refer to an excellent white paper in a previous thread of the forum. 

 

Hope this clarifies my abuse of metastability... 

 

 

 

 

 

--- Quote Start ---  

I think, it's misleading to use the term "metastability" for trivial cases of timing violation caused by unrelated input signals. But synchronizing the input signal (in this case rst_n) to the clock is the appropriate means anyway. 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

I completely agree with your explanation of the problem that rst_n is "misinterpreted by different flip-flops", if the "transition of the reset signal comes at the moment of the clock edge". But as you said, that's not metastability. 

 

The solution is synchronization of the unrelated signal to CLOCK_50: 

always @ (posedge CLOCK_50) rst_n_sync <= rst_n; if (!rst_n_sync) begin a3 <= 4'b0; a2 <= 4'b0; a1 <= 4'b0; a0 <= 4'b0; end else if (trigger & !done & ms_timeout) begin a3 <= a3_next; a2 <= a2_next; a1 <= a1_next; a0 <= a0_next; end 

I should be mentioned, that if other signals, e.g. trigger would be unrelated to CLOCK_50, they also need to be synchronized. 

 

Metastability describes the (very unlikely, but still existing) case, that rst_n_sync hasn't reached a defined logic state after one cycle of CLOCK_50. Quartus has a metastability advisor, that calculates the likelihood of metastable states for particular synchronizers. If the possible faulty behaviour due to metastability is a risk for the application, a multistage synchronizer can reduce the likelihood to effectively zero. 

 

In the present case, I guess, that the lifetime of a the mechanical switch would be exceeded before metastability induces MTBF is reached. But if the signal to be synchronized is switching very often, e.g. it's a MBPS serial signal, a metastable event can be expected in a very finite period of time.
0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

Hi sanmao, 

 

Thanks for the pointer to the tech note. The general discussion looks like a verbatim copy of Cummings' and Mills' paper (indeed my synchronization was taken from there), but I'll be sure to revisit it for FPGA specific hints when I start implementing more complicated designs. 

 

As for the overall discussion, I now realize my original question was not clear: The question was not why I'm getting reset problems when using synchronous resetting without synchronizing the reset signal (although I'm frankly baffled at the frequency of errors), but rather why I'm not seeing the same problems with asynchronous reset (without synchronizing the reset signal). As such, my question is about understanding the underlying problem I'm seeing, not how to work around it. 

 

Since I'm pulling reset with the touch of my finger, reset is pulled for 100's or 1000's of cycles, so any non-determinism (label it meta-stability or anything else you want) at the assertion of reset should be irrelevant. Indeed, the reset state is perfectly fine *during* reset. Neither "trigger" nor "ms_timeout" will change for 1000's of cycles after reset, so they shouldn't be able to cause any issues and should make it impossible for a0_next to "get to" a0 anytime around reset. By the same reasoning, I don't see any reason why glitches on the reset signal would cause any trouble once the reset state is set. 

 

Overall, I would expect synchronous reset to be *more* robust than asynchronous reset, not less, without any synchronization. The case against sync reset, as I read it, is about gate count and therefore setup time, not robustness. 

 

Thanks for all the responses so far, I really appreciate them! 

Sebastian
0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

 

--- Quote Start ---  

Overall, I would expect synchronous reset to be *more* robust than asynchronous reset, not less, without any synchronization. 

--- Quote End ---  

 

Both are unreliable without any synchronization. The specific behaviour depends on the design details, that haven't been shown in the present case. I don't want to guess, why the synchronous example appears less realiable to you. Because both need synchronization, I won't suggest to use synchronous constructs for the general design reset. The asynchronous variant has the important advantage to achieve defined output states without applying a clock, which is mandatory in many designs. Because it uses dedicated clear inputs of the FPGA registers, it saves resources compared to the synchronous solution. 

 

 

--- Quote Start ---  

As such, my question is about understanding the underlying problem I'm seeing, not how to work around it. 

--- Quote End ---  

Synchronization of unrelated signals in not a workaround. It's simply required, for both reset variants.
0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

This is an example of misnomers and misleading wording of available literature. 

 

synchronous (for any signal) is wrongly perceived as the case of applying it at the input to registers but we should make distinction between "applying it" and "synchronising it at origin". 

 

in your case I am not surprised that asynchronous application was safer because it bypassed the clk edge. 

 

Thus asynchronous reset is far more superior to the so called synchronous provided it is pre-synchronised which should be done in any case. There is no extra cost on resource when you use the dedicated port. 

 

Another unrelated example of bad wording that put me in trouble was this: 

 

-- combinatorial assignment 

a <= b; -- means a is wired to b 

 

It was written in a MentorGraphics paper(1998). I will keep you guessing what is wrong with it...
0 Kudos
Altera_Forum
Honored Contributor II
1,679 Views

 

--- Quote Start ---  

in your case I am not surprised that asynchronous application was safer because it bypassed the clk edge. 

--- Quote End ---  

 

 

Well, it only bypasses the clock edge on assertion, not deassertion, hence the need for a synchronizer. Which, again, was why I was confused as the problem seemed to be introduced on deassertion, where async reset is even more picky than sync reset. 

 

I finally took a deep breath and untangled the result of synthesis, and the behavior was indeed coming from a race condition on reset deassertion introduced by modeling the RTL 

always @ (posedge clk) if (!rst_n) A <= 1'b0; else if (trigger) A <= B;  

by the resource with 

clk = clk; D = rst_n & B; ena = !rst_n | trigger;  

 

So, I get the wrong reset state when the deassertion of rst_n is seen on the data path a cycle before the enable. The synthesis result for the asynchronous case just uses the sclr port and so has no race condition. Mystery solved.
0 Kudos
Reply