Release asynchrounous resets synchronously

  • Thread starter William Wallace
  • Start date
W

William Wallace

Guest
THE IMPORTANCE OF PROVIDING A RESET THAT LEAVES THE RESET
SYNCHRONOUSLY EVEN IF IT DRIVES THE ASYNCHRONOUS RESET:

Consider a simple one hot state machine that cycles through 3 states:

S001: 001
S010: 010
S100: 100
S001: 001
S010: 010
S011: 100

This is a simple, trivial state machine, but it will serve the purpose
of highlighting why you should leave reset synchronously.

What happens if the asynchronous reset comes at a time and has delays
such that two of the flops to see clock N as the first clock, but the
third flop to see clock N+1 as the first clock. Your state machine
might end up running like so:

S001: 001
Invalid: 011
Invalid: 110
Invalid: 101
Invalid: 011
Invalid: 110
Invalid: 101

Two flip flops are hot. This is bad.

You could get around this by treating your one hot as a binary encoded
state machine, and treating all other states other than {001, 010,
100} as dead end states that must transition to one of the valid
states, but in doing so, you loose the advantages of a one hot state
machine (specifically, the combinatorial logic required to protect
against these dead end states may make it harder to meet timing, and
may chew up more resources than you want).

A different approach would be to process your reset into the FPGA such
that the entire design is reset asynchronously, but the majority of
the design leaves reset synchronously (though under control of the
asynchronous reset input)

E.g., (and not syntax checked):

process(clk,iReset)
begin
if(iReset='1') then
ResetSR="00";
elsif(clk'event and clk = '1') then
ResetSR(0) <= '1';
ResetSR(1) <= ResetSR(0);
end if;
end process;

RESET <= ResetSR(1);

simplesm : process(clk,RESET)
begin
if(Reset = '1') then -- NOTE, this is not iReset
state <= S001;
elsif(clk'event and clk='1') then
case state is =>
when S001 =>
state <= S010;
when S010 =>
state <= S100;
when S100 =>
state <= S001;
end case
end if
end process simplesm;


Here, if the path delays on the internal signal RESET are less than
the clock period, all three registers used to implement the state
machine will see the same first clock after reset.

Any thoughts? (Probably pretty obvious to some who have actually
encountered problems due to different registers in a design seeing
different first clocks, but it wasn't so obvious to me until somebody
recently recommended this practice to me, since I never had a problem
that I traced back to this type of issue.)

But for this to work, static timing analysis tools should check path
delays on the internal RESET signal to make sure it makes it to all
the registers asynchronous resets before the clock after it was
generated.

Do static timing analysis tools do this?
 
On 5 Mar 2004 22:15:43 -0800, msm30@yahoo.com (William Wallace) wrote:

THE IMPORTANCE OF PROVIDING A RESET THAT LEAVES THE RESET
SYNCHRONOUSLY EVEN IF IT DRIVES THE ASYNCHRONOUS RESET:

....

But for this to work, static timing analysis tools should check path
delays on the internal RESET signal to make sure it makes it to all
the registers asynchronous resets before the clock after it was
generated.

Do static timing analysis tools do this?
Yes; for DFF cells there is a parameter called Reset Recovery Time on
the reset input which is similar to setup parameter for D input. If
you release the reset synchronously to the clock input, STA tools can
time the reset path too.
 
William Wallace wrote:
THE IMPORTANCE OF PROVIDING A RESET THAT LEAVES THE RESET
SYNCHRONOUSLY EVEN IF IT DRIVES THE ASYNCHRONOUS RESET...
You cannot rely on async reset at startup for initializing one hot state
machines and the like. You need to do something like generate your own
sync reset from some flip flops at startup as in your code example. If
you are using DLLs you also might want to factor the lock output into
your synch reset. This has been discussed here before, you might search
the ng archive. I have been burnt by this bug before, i.e. state
machines starting up 0-hot. This works for me:

-- synchronous part of state machine
process(clk,asynch_rst)
begin
if asynch_rst = '1' then -- the startup global async reset.
state <= idle;
elsif rising_edge(clk) then
if synch_rst = '1' then -- my own synch reset signal.
state <= idle;
else
state <= next_state; -- from combinatorial part of s.m.
end if;
end if;
end process;


-JC
 
Jeff Cunningham wrote:
William Wallace wrote:
THE IMPORTANCE OF PROVIDING A RESET THAT LEAVES THE RESET
SYNCHRONOUSLY EVEN IF IT DRIVES THE ASYNCHRONOUS RESET...

You cannot rely on async reset at startup for initializing one hot state
machines and the like. You need to do something like generate your own
sync reset from some flip flops at startup as in your code example. If
you are using DLLs you also might want to factor the lock output into
your synch reset. This has been discussed here before, you might search
the ng archive. I have been burnt by this bug before, i.e. state
machines starting up 0-hot. This works for me:

-- synchronous part of state machine
process(clk,asynch_rst)
begin
if asynch_rst = '1' then -- the startup global async reset.
state <= idle;
elsif rising_edge(clk) then
if synch_rst = '1' then -- my own synch reset signal.
state <= idle;
else
state <= next_state; -- from combinatorial part of s.m.
end if;
end if;
end process;
This is correct. The async global reset is not designed to be fast. So
you have to make sure that your design will work if the FFs come out of
reset on different clock cycles. There are other ways to do this than
using a sync reset. If your design is large, a sync reset may be hard
to route to all the FFs that need it within a single clock cycle as
well.

For state machines, you can use a few prior states to assure that the
reset has been released before the FSM gets to "critical" states. For
example, if your machine is one hot, you can use a few states that are
not one hot, e.g. 000 -> 100 -> 110 -> 111 before your FSM can operate
(any gray code will do). Of course, this is really the same as having a
"local" sync reset which is another way of doing this.

Or if your logic does not have an immediate transition then you don't
need to do anything. For example, if your FSM depends on an external
signal such as a write strobe, if you have time before the write strobe
comes along to let the global reset settle, a separate sync reset is not
needed.

--

Rick "rickman" Collins

rick.collins@XYarius.com
Ignore the reply address. To email me use the above address with the XY
removed.

Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design URL http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX
 

Welcome to EDABoard.com

Sponsor

Back
Top