On Jan 11, 4:29 pm, Dave Pollum <vze24...@verizon.net> wrote:
> On Jan 10, 3:39 am, Ponceludon de Malavoy <neeraj2...@gmail.com>
> wrote:
>
>
>
> > 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
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