Why is this an issue?
An issue is raised when multiple reset domains are used within the same process (VHDL) or always block
(Verilog).
Using two reset domains for the same process or always block can lead to several issues:
-
Synchronization Problems: If the two reset signals come from different clock domains or are
asynchronous to each other, you might encounter metastability issues. This means that the state of one reset might
be sampled incorrectly due to setup or hold time violations when both resets are changing.
-
Design Complexity and Unpredictability: The logic becomes more complex to understand and simulate.
With two resets, it's harder to predict the behavior of
the circuit, especially during reset transitions. This can lead to race conditions where the order in which resets
are
applied can affect the final state of the registers.
-
Reset Priority and Order: There's ambiguity in which reset has priority if both are active
simultaneously or if their edges overlap. This can lead to inconsistent behavior across different synthesis tools or
hardware implementations unless explicitly defined.
-
Timing Closure Issues The timing analysis becomes more complicated, especially if the resets are
not perfectly synchronous. This can affect the ability to close timing in the design, leading to potential timing
violations.
-
Increased Power Consumption: Having two reset paths might increase the power consumption,
especially if one reset is toggling frequently. This could lead to additional power management challenges in the
design.
-
Synthesis and Implementation Challenges: Synthesis tools might not optimize the reset logic as
effectively when dealing with multiple reset sources. This could result in suboptimal hardware, possibly increasing
area, power, or delay.
Best Practices:
- Use only one reset per always block unless absolutely necessary.
- If two resets must be used, ensure they are synchronized or one is clearly subordinate to the other in terms of
priority.
- Consider using reset synchronizers if resets are coming from different clock domains.
If you really need to use two resets for a specific reason, make sure to document why this is necessary and how
conflicts are resolved, and test thoroughly to ensure the behavior is as expected.
How to fix it
Code examples
Noncompliant code example
A: process (clk) is -- Noncompliant: Two reset domains (rst1 and rst2)
begin
if rising_edge(clk) then
if rst1 = '1' then
o1 <= '0';
else
o1 <= i1;
end if;
end if;
if rising_edge(clk) then
if rst2 = '0' then
o2 <= '1';
else
o2 <= i2;
end if;
end if;
end process;
Compliant solution
A: process (clk) is -- Compliant: One-single reset (rst1)
begin
if rising_edge(clk) then
if rst1 = '1' then
o1 <= '0';
else
o1 <= i1;
end if;
end if;
end process;
B: process (clk) is -- Compliant: One-single reset (rst2)
if rising_edge(clk) then
if rst2 = '0' then
o2 <= '1';
else
o2 <= i2;
end if;
end if;
end process;