Why is this an issue?
Mixing both synchronous and asynchronous resets within the same reset domain can lead to several complications:
- Timing Complexity
-
Reset Synchronization: Asynchronous resets must be synchronized if they are to be distributed across clock
domains or if they might interact with synchronous logic, leading to potential setup and hold time violations.
-
Clock Skew: Synchronous resets depend on the clock, and any skew in clock distribution could result in
different parts of the circuit entering reset at different times, whereas asynchronous resets would not wait for
the clock edge.
- Functional Ambiguity
-
Reset Recovery: If both types of reset are active, it's unclear when the system should start
recovering from reset. An asynchronous reset might override a synchronous reset, or vice versa, leading to
unpredictable behavior.
-
State Recovery: When moving out of reset, the timing of when registers start to accept new data
can be non-deterministic, causing issues in state machines or sequential logic where timing is critical.
- Increased Design Complexity
-
Verification Difficulty: Testing all possible scenarios where resets might overlap or interact
becomes more complex, making verification and debugging harder.
-
Reset Distribution: Managing how the reset signal is distributed, whether it's asynchronous or
needs to be synchronized, adds to the complexity of the design.
- Potential for Glitches
-
Glitch Generation: If an asynchronous reset deactivates just before a clock edge, it might
interact with the synchronous reset, potentially causing brief glitches or meta-stability issues in the logic.
- Synthesis and Implementation Challenges
- Tool Handling: Different synthesis tools might handle mixed reset strategies inconsistently,
leading to potential differences in timing closure or even in the synthesized netlist.
- Area and Performance: Using both reset styles might not optimize the design for area or
performance as well as using one consistent strategy.
In conclusion, while there might be specific scenarios where using both reset strategies could seem advantageous,
the combination generally introduces unnecessary complexity, timing ambiguities, and verification challenges. It's
often better to choose one strategy that fits the design's requirements for all elements within a reset domain to
maintain clarity, consistency, and reliability in the design.
How to fix it
Code examples
Noncompliant code example
architecture rtl of top is
begin
A: process (clk) is
begin
if rising_edge(clk) then
s1 <= '1';
if rst = '1' then -- Synchronous reset
s1 <= '0';
end if;
end if;
end process;
B: process(clk, rst) is
begin
if rst = '1' then -- Asynchronous reset
s2 <= '0';
elsif rising_edge(clk) then
s2 <= '1';
end if;
end process;
end architecture;
Compliant solution
architecture rtl of top is
begin
A: process (clk) is
begin
if rising_edge(clk) then
s1 <= '1';
if rst = '1' then -- Synchronous reset
s1 <= '0';
end if;
end if;
end process;
B: process (clk) is
begin
if rising_edge(clk) then
s2 <= '1';
if rst = '1' then -- Synchronous reset
s2 <= '0';
end if;
end if;
end process;
end architecture;