Combinational elements in Global Reset Trees

  • Thread starter Ponceludon de Malavoy
  • Start date
P

Ponceludon de Malavoy

Hi,
I wanted to know if it is advisable to insert combinational elements
into Reset trees. I realize that inserting logic into clock paths is a
nightmare for timing. Is it that bad for reset paths too?

I'll explain how I got here. I have a flop (I'll call it FF1) in my
design that has an asynchronous reset (I'll call this async reset
input of the flop, reset_n). The async reset is generated by logic
(I'll call this signal FF1_async_reset) driven by other flops. All the
other flops also have async resets with the difference that they're
all driven by the global reset (I'll call this global_reset). Now, I
don't want to leave FF1 out of the global reset path either. So, I was
thinking of something along these lines:

reset_n <= global_reset when global_reset = '1' else --connect either
the global or the local reset to FF1
FF1_async_reset;

Obviously, I'm messing with the reset path to FF1. Is this going to
create problems?

Thank you for your help.
 
K

KJ

Ponceludon de Malavoy said:
Hi,
I wanted to know if it is advisable to insert combinational elements
into Reset trees. I realize that inserting logic into clock paths is a
nightmare for timing. Is it that bad for reset paths too?

It is bad for asynchronous resets in FPGAs. Remember that FPGAs use memory
look up tables to generate their outputs. These can glitch depending on
your reset logic. A glitch on an asynchronous reset signal will cause some
of the FFs in a design to get reset, others maybe not.

The solution is either of the following....
1. Clock the reset signal so that it is no longer the result of a
combinatorial logic path. Generally speaking, it really doesn't matter if a
flip flop gets reset on 'this' clock cycle or 'this+1'.


2. Use only synchronous resets on your FFs.
I'll explain how I got here. I have a flop (I'll call it FF1) in my
design that has an asynchronous reset (I'll call this async reset
input of the flop, reset_n). The async reset is generated by logic
(I'll call this signal FF1_async_reset) driven by other flops. All the
other flops also have async resets with the difference that they're
all driven by the global reset (I'll call this global_reset). Now, I
don't want to leave FF1 out of the global reset path either. So, I was
thinking of something along these lines:

reset_n <= global_reset when global_reset = '1' else --connect either
the global or the local reset to FF1
FF1_async_reset;

Obviously, I'm messing with the reset path to FF1. Is this going to
create problems?

Probably. Even worse it might appear to work for you at first and lead you
to believe that this technique is OK but some time later it will start
failing and take a long time to debug down to the root cause. Make the
'reset_n' signal (and any other signals that are used to asynchronously set
or reset any flip flops) be the output of a flip flop....flip flop outputs
don't glitch.

Kevin Jennings
 
D

Dave Pollum

Hi,
I wanted to know if it is advisable to insert combinational elements
into Reset trees. I realize that inserting logic into clock paths is a
nightmare for timing. Is it that bad for reset paths too?

I'll explain how I got here. I have a flop (I'll call it FF1) in my
design that has an asynchronous reset (I'll call this async reset
input of the flop, reset_n). The async reset is generated by logic
(I'll call this signal FF1_async_reset) driven by other flops. All the
other flops also have async resets with the difference that they're
all driven by the global reset (I'll call this global_reset). Now, I
don't want to leave FF1 out of the global reset path either. So, I was
thinking of something along these lines:

reset_n <= global_reset when global_reset = '1' else --connect either
the global or the local reset to FF1
FF1_async_reset;

Obviously, I'm messing with the reset path to FF1. Is this going to
create problems?

Thank you for your help.

From what I've read, if you have an asynchronous reset, the preferred
method is to feed that async reset into a 2 or 3 stage synchronizer.
When the async reset is de-asserted, it is sync'd to the clock. So,
async reset in, synch'd reset out to all FF's that need to be reset.

-Dave Pollum
 
K

kennheinrich

From what I've read, if you have an asynchronous reset, the preferred
method is to feed that async reset into a 2 or 3 stage synchronizer.
When the async reset is de-asserted, it is sync'd to the clock. So,
async reset in, synch'd reset out to all FF's that need to be reset.

-Dave Pollum

It also depends what you need the reset to do. If the reset has to be
a clock-accurate reset with well-defined behaviour in the immediate
next cycle (say a reset of a functional unit before the next work item
is to be precessed) then you should go fully synchronous, both with
the reset generator and with the logic that uses the reset.

If, on the other hand, the reset has to just get your logic into some
known state after a brownout or PLL unlock or power-up, then you can
often get away with sloppier async resets. However, this is easier
said than done. There are two common mistakes that people make when
doing this.

Mistake 1 is to forget that when the reset drives clocked logic, that
you have to guarantee that the reset *de-asserts* synchronously to
clock edge to prevent different flops from seeing the reset complete
on different clock edges due to skew, etc. This is what Dave Pollum's
solution helps you achieve. Having an async reset is often an
invitation for race conditions coming out of reset; many people will
ignore FPGA PAR timing errors around the reset line. thinking "it's
OK, it's supposed to be asynchronous" :-(

Mistake 2 is to assume that clocks are stable during reset; in
brownout or PLL unlock conditions, this may not always be true. This
would prevent the simple synchronizer from working properly, you might
actually delay your reset assertion unwantedly until clocks recover.
For example, some PLL gating logic may hold the clock solid low until
the PLL is locked.

A more robust solution is to use an multi-flop synchronizer chain
where all flops get asynchronously reset by the global reset (ensuring
immediate response), then starts clocking through a "valid" (reset
done, clock valid, or conjunction of both). The "valid" (ie reset de-
assert) will come out 2 or 3 clocks after the initial condition
clears. This will ensure that when the reset condition eventually
clears, then your output reset line gets de-asserted on a known good
clock edge (required to avoid race conditions), and that some small
number of known good clocks have elapsed before reset de-asserts
(required when the reset is used to do a synchronous reset of block
that are not implemented with async resets).

There are, as always, many more options. But these two mistakes are
aspects that I've seen hurt designs in the past; you should consider
these when you think about modifying your reset tree.

Cheers,

- Kenn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,084
Latest member
HansGeorgi

Latest Threads

Top