RTL Bench PRO

Active-low reset: why rst_n is everywhere

Almost every digital design has a reset. Almost every reset is named rst_n, rst_l, or reset_b โ€” with a lowercase letter that quietly encodes the polarity. Miss it and your simulation never leaves reset.

The short version

An active-low reset asserts when the signal is 0 and deasserts when it is 1. It is the opposite of an active-high reset, which asserts on 1.

The suffix on the port name tells you which one you have. These suffixes all mean "active-low":

NameMeansWhat it does
rst_n reset, negated Pull low to reset
rst_l reset, low Pull low to reset
reset_b reset, bar Pull low to reset
n_rst negated reset Pull low to reset
rst reset Pull high to reset (active-high)

There's no universal standard. Every company picks a convention. What matters is that the same convention is used consistently โ€” and that the simulator agrees with you.

Why active-low is so common

Three practical reasons, in order of how often they come up:

  1. Transistors historically reset more reliably to ground. An N-channel pull-down to 0 was the natural way to force a node low in older process nodes. That physical habit became a naming convention that outlived the reason.
  2. Board-level resets are usually open-drain. A supervisor IC pulls the reset line low when power is bad and lets it float high when power is good. The signal is naturally active-low at the pin.
  3. It's a single-character suffix. rst_n is shorter than reset_negated or reset_active_low, and it fits in a port list without wrapping.
๐Ÿ’ก Mixed conventions are a common source of bugs. If one submodule uses rst (active-high) and another uses rst_n (active-low), a designer wiring them together has to invert the signal somewhere. Those inversions are where reset bugs live.

How RTL Bench detects polarity

RTL Bench looks at the port name. If it ends with _n, _l, _b, or starts with n_, it treats the port as active-low. Otherwise, a port whose name contains rst or reset is treated as active-high.

The detection matters when you click โ–ถ Run Testbench. The auto-generated stimulus holds the reset in its asserted state for the first few cycles, then releases it. Active-low gets held at 0; active-high gets held at 1.

module counter (
    input  logic       clk,
    input  logic       rst_n,   // โ†’ driven low for the first 12ns
    output logic [7:0] q
);
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) q <= 8'h00;
        else        q <= q + 8'd1;
    end
endmodule
Run this in RTL Bench

If you swap rst_n for rst in the same design, the auto-testbench holds the signal at 1 for the first few cycles, then releases it to 0. The waveform changes accordingly โ€” no code changes required.

โš ๏ธ Detection is name-based. If you call your active-low reset kill_sw or por_ok, the simulator will treat it as a generic input and drive it with random values. The design will never leave reset. Rename the port, or write your own testbench.

What to do instead of renaming

If you cannot rename the port โ€” because it is part of a legacy interface, or the name is defined in a spec you have to match โ€” write your own testbench. RTL Bench will use it verbatim, and you control exactly how the reset signal is driven.

module tb;
    logic        clk = 0;
    logic        por_ok = 0;   // active-low reset, custom name
    logic [7:0]  q;

    counter dut (.clk(clk), .por_ok(por_ok), .q(q));

    always #5 clk = ~clk;

    initial begin
        $dumpfile("waves.vcd");
        $dumpvars(0, tb);
        #20  por_ok = 1;    // release reset
        #500 $finish;
    end
endmodule

See Simulation & waveforms for the full testbench guide, including the $dumpfile and $dumpvars requirements.

Which convention should you use?

Use rst_n unless you have a reason not to.

  • It is the most common in open-source RTL and modern ASIC design.
  • RTL Bench and most linters recognise it automatically.
  • It sorts naturally in editor autocomplete.
  • It is unambiguous โ€” nobody has to look at a comment to know the polarity.

If your team already uses reset_b or rst_l, stay consistent with the team. Consistency beats correctness when they conflict.

Frequently asked questions

Why is active-low reset preferred over active-high in ASIC and FPGA design?

Active-low reset (rst_n) was historically preferred because bipolar TTL circuits could sink more current in the low state than source high. In CMOS ASIC standard cells, active-low reset inputs require fewer transistors and offer better noise immunity against supply rail transients.

How does RTL Bench automatically detect active-low reset signals?

RTL Bench inspects your top-level port names and sensitivity lists using pattern matching for common suffixes (_n, _l, _b) and negedge clauses, asserting reset at logic low during initial simulation cycles.

What is the difference between asynchronous assertion and synchronous deassertion?

Asynchronous assertion forces flip-flops to reset immediately regardless of clock. Synchronous deassertion releases reset synchronously to the clock domain, preventing recovery/removal timing violations that cause metastability.

Next

  • Simulation & waveforms How the auto-testbench drives clocks, resets, and inputs โ€” and how to override it.
  • VHDL in the browser Entity, architecture, and GHDL โ€” with a 4-bit counter that uses an active-low reset.
  • Timing analysis (STA) How reset paths interact with static timing analysis in a real design.
Try it in the workbench โ†’