Skip to content
VLSI Mentor

Wishbone · Module 4

RST_I

Wishbone's reset is synchronous and active high, and initialisation happens at the clock edge after assertion rather than at assertion: what RULES 3.00 and 3.20 require, and what an asynchronous reset breaks.

Chapter 4.1 established the observation model. RST_I is the other signal that arrives from SYSCON rather than from any transfer, and it is the one an engineer arriving from ordinary RTL is most likely to get wrong — on both polarity and synchronicity, in the same line of code.

What state must a Wishbone interface establish when reset is asserted, how long must it be held, and what is deliberately outside its reach?

1. Active High — RULE 2.30

The polarity is not a property of reset specifically. It follows from a rule about every signal on the interface:

RULE 2.30"All WISHBONE interface signals MUST use active high logic."

So RST_I asserted means RST_I high, for the same reason STB_O asserted means STB_O high. There is no RST_I_n and no negative-logic variant, and a core presenting one has not implemented a Wishbone interface.

Engineering consequence. A uniform polarity convention removes an entire class of integration error. When every signal on an interface is active high, a wiring mistake is a wrong connection rather than a silently inverted meaning — and a wrong connection is usually loud.

What it does not dictate. RULE 2.30 governs the interface. A core whose internals use an active-low reset internally is free to invert at its boundary; what it may not do is present an active-low reset as a Wishbone signal.

2. Synchronous — RULE 3.00 and RULE 3.05

Two rules together fix the timing.

RULE 3.00"All WISHBONE interfaces MUST initialize themselves at the rising [CLK_I] edge following the assertion of [RST_I]."

Read the word following. The interface does not initialise when RST_I rises. It initialises at the next rising clock edge after that. That is the definition of a synchronous reset: the reset is a sampled input, exactly like every other input under RULE 5.00's third sentence, and it takes effect at an observation instant.

RULE 3.05"[RST_I] MUST be asserted for at least one complete clock cycle on all WISHBONE interfaces."

And this rule exists because of the previous one. If reset takes effect at a sampled edge, a pulse narrower than a clock period can fall entirely between two edges and be observed by nobody. RULE 3.05 is the obligation on whoever generates reset — SYSCON — to make sure every interface sees it.

Engineering consequence, and it is a real integration hazard. A reset derived from a push-button, a power-on detector or another clock domain has no natural relationship to CLK_I. Handing such a signal straight to RST_I violates RULE 3.05 whenever it happens to be narrow, and — worse — a reset released asynchronously relative to CLK_I creates a recovery/removal timing violation at every flop it feeds. The standard answer is a reset synchroniser in SYSCON, and it is SYSCON's job rather than each interface's.

3. What Reset Must Establish — RULE 3.20

The rules above say when. One rule says what, and it is specific about which signals matter:

RULE 3.20"The following MASTER signals MUST be negated at the rising [CLK_I] edge following the assertion of [RST_I], and MUST stay in the negated state until the rising [CLK_I] edge that follows the negation of [RST_I]: [STB_O], [CYC_O]."

Only two signals are named, and that is deliberate. STB_O and CYC_O are the qualifiers — Chapter 3.2's two levels. With both negated, nothing else the master drives means anything: RULE 3.60 makes the address, write data, byte selects and direction meaningful only under STB_O, so an unqualified bus carries values that no slave may act on.

The rule therefore establishes exactly what it needs to and nothing more. A master is not required to zero its address bus during reset. It is required to assert nothing.

Read the second half of the rule too. The negated state must hold until the rising edge that follows the negation of RST_I — so a master may not begin a cycle in the same cycle reset releases. There is a defined quiet edge between reset ending and bus activity starting.

4. RTL — Correct Reset, and the Pattern That Is Not

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_reset_ref — the reset convention every Module 4 module uses, shown on
// both sides of the interface.
//
// SPECIFICATION REQUIREMENTS implemented here:
//   RULE 2.30  all interface signals active high  → rst_i asserted = HIGH
//   RULE 3.00  initialise at the rising CLK_I edge FOLLOWING assertion
//              → synchronous reset: rst_i is INSIDE the clocked block and
//                is NOT in the sensitivity list
//   RULE 3.20  STB_O and CYC_O negated at that edge, and held negated until
//              the rising edge following the negation of RST_I
//
// EDUCATIONAL CHOICE (not a rule): the slave below also clears its
// application registers. RST_I is only required to reset the interface.
// ─────────────────────────────────────────────────────────────────────────
module wb_reset_ref #(
  parameter int unsigned AW = 32,
  parameter int unsigned DW = 32
) (
  input  logic            clk_i,
  input  logic            rst_i,        // SYNCHRONOUS, ACTIVE HIGH

  // Master-side local request
  input  logic            go_i,
  input  logic [AW-1:0]   adr_i,

  // Wishbone MASTER outputs
  output logic            m_cyc_o,
  output logic            m_stb_o,
  output logic [AW-1:0]   m_adr_o,

  // Wishbone SLAVE inputs / outputs
  input  logic            s_cyc_i,
  input  logic            s_stb_i,
  input  logic            s_we_i,
  input  logic [DW-1:0]   s_dat_i,
  output logic            s_ack_o,
  output logic [DW-1:0]   s_ctrl_o      // an application register
);
  // ── MASTER side ──────────────────────────────────────────────────────
  // `active_q` IS the cycle. Clearing it in the reset branch negates both
  // CYC_O and STB_O in one assignment, which is exactly RULE 3.20.
  logic active_q;

  always_ff @(posedge clk_i) begin
    if (rst_i) begin
      active_q <= 1'b0;                 // RULE 3.20
      m_adr_o  <= '0;                   // not required; tidy and harmless
    end else if (!active_q) begin
      if (go_i) begin
        active_q <= 1'b1;
        m_adr_o  <= adr_i;
      end
    end
  end

  assign m_cyc_o = active_q;
  assign m_stb_o = active_q;

  // ── Note on the second half of RULE 3.20 ─────────────────────────────
  // The rule requires CYC_O and STB_O to stay negated until the rising edge
  // FOLLOWING the negation of RST_I. This structure satisfies it without a
  // special case: on the last edge at which rst_i is still high, the reset
  // branch runs and active_q is cleared. The first edge at which rst_i is
  // low is therefore the earliest at which go_i can be sampled, so the
  // earliest possible assertion of CYC_O is one edge after that — which is
  // later than the rule's floor, never earlier.

  // ── SLAVE side ───────────────────────────────────────────────────────
  logic xfer;
  assign xfer = s_cyc_i & s_stb_i;      // RULES 3.30 & 3.35, developed in 4.8

  always_ff @(posedge clk_i) begin
    if (rst_i) begin
      s_ctrl_o <= '0;                   // EDUCATIONAL CHOICE, not RULE 3.00
    end else if (xfer && s_we_i) begin
      s_ctrl_o <= s_dat_i;
    end
  end

  assign s_ack_o = xfer;                // see Chapter 4.10
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_reset_wrong — the pattern most RTL uses, which is a DIFFERENT contract.
//
// This module is syntactically fine and would be perfectly good RTL in a
// design whose reset convention is asynchronous and active low. It is not a
// conforming Wishbone interface, and Section 6 is what that costs.
// ─────────────────────────────────────────────────────────────────────────
module wb_reset_wrong (
  input  logic clk_i,
  input  logic rst_n,                   // WRONG on two counts at once
  input  logic go_i,
  output logic cyc_o,
  output logic stb_o
);
  logic active_q;

  // DEFECT 1 — ASYNCHRONOUS. `rst_n` is in the sensitivity list, so the
  //   outputs change the instant reset asserts rather than at the rising
  //   edge FOLLOWING assertion. RULE 3.00 specifies the latter.
  //
  // DEFECT 2 — ACTIVE LOW. RULE 2.30 requires active-high interface
  //   signals. Connected to a Wishbone RST_I this block is held in reset
  //   whenever the bus is running and released whenever the bus resets:
  //   exactly inverted.
  always_ff @(posedge clk_i or negedge rst_n) begin
    if (!rst_n) active_q <= 1'b0;
    else if (go_i) active_q <= 1'b1;
  end

  assign cyc_o = active_q;
  assign stb_o = active_q;
endmodule

Reading the pair

Purpose. wb_reset_ref establishes the convention used by every later chapter. wb_reset_wrong is the pattern a reader is most likely to bring with them.

Ports that matter. rst_i versus rst_n is the polarity defect; the sensitivity list is the synchronicity defect. Both are visible in the module header, which is where a reviewer should catch them.

Ownership. SYSCON drives reset; every interface consumes it. No interface drives it.

Combinational logic. In the correct module, m_cyc_o and m_stb_o are assignments from active_q — so a single registered bit satisfies RULE 3.20 for both.

Sequential logic. One master state bit, one slave application register. Both are updated only at the rising edge, and rst_i is tested inside the clocked block.

Timing. At the first rising edge where rst_i is high, active_q clears — RULE 3.00's "at the rising edge following the assertion". It cannot be set again until an edge at which rst_i is low, so RULE 3.20's second half holds structurally.

Reset state established. CYC_O and STB_O negated, which is the requirement; the address zeroed and the control register cleared, which are choices.

Simplifications. No termination handling, no error path, no multi-transfer cycle. Later chapters add them on this skeleton.

Failure modes. Asynchronous reset changes when outputs move. Active-low inverts whether the block is in reset. Omitting the reset branch for active_q leaves the master's qualifiers undefined at power-up — which on an FPGA is a defined bitstream value that may happen to be zero, and in an ASIC is genuinely unknown.

5. Waveform — Assertion, the Edge That Matters, and Release

RST_I: assertion, effect, and the quiet edge after release

10 cycles
A Wishbone interface over ten clock cycles. A bus cycle is in progress with both cycle and strobe asserted when reset is asserted part way through cycle two. Nothing happens immediately: the interface initialises at the rising edge that begins cycle three, at which point both cycle and strobe are negated. Reset is held through cycles three and four, satisfying the requirement that it be asserted for at least one complete clock cycle. Reset is negated during cycle five. The qualifiers remain negated across the rising edge that begins cycle six, which is the edge following the negation of reset, and the earliest the master asserts a new cycle is the following edge in cycle seven.RST_I asserted — nothing changes yetRST_I asserted — nothingchanges yetRULE 3.00: initialise at THIS edgeRULE 3.00: initialise atTHIS edgeRULE 3.05 satisfied: held ≥ 1 full cycleRULE 3.05 satisfied: held ≥1 full cycleearliest new cycle, after the quiet edgeearliest new cycle, afterthe quiet edgeCLK_IRST_Igo_iCYC_OSTB_OADR_O0x400010040x400010040x000000000x000000000x000000000x000000000x400020080x400020080x400020080x40002008t0t1t2t3t4t5t6t7t8t9
Figure 1 — reset takes effect at the rising edge FOLLOWING assertion, and the qualifiers stay negated past the edge that follows its negation.

Cycle 1 is the one people expect to be different. RST_I is already high and CYC_O is still asserted. That is correct: RULE 3.00 says the interface initialises at the rising edge following the assertion, and that edge is the one beginning cycle 2. An implementation that dropped the qualifiers the instant RST_I rose would be asynchronous, which is wb_reset_wrong.

Cycles 2 to 4 satisfy RULE 3.05. Reset spans more than one complete clock cycle, so every interface in the system observes it at at least one rising edge regardless of where it started.

Cycle 5 into 6 is RULE 3.20's second half. RST_I is negated during cycle 5; the qualifiers stay negated across the edge that begins cycle 6. The master's earliest possible new cycle is the following edge.

6. Failure Modes and Discriminating Evidence

Reset defects have a signature that is worth memorising, because it points at reset before anything else does.

Symptom: the design works after configuration and fails after a warm restart.

Candidate causes. Wrong polarity, so the block is never reset. On an FPGA it powers up to its bitstream initial value — which is often exactly the value a correct reset would produce — so the first run is clean and the second inherits the previous run's state.

Discriminating evidence. Capture rst_i together with one internal register at assertion. A block holding non-zero state while rst_i is high was never reset, and that is conclusive in one waveform.

Likely RTL location. The module header — rst_n versus rst_i — and the reset branch's condition.

Property. P1 in Section 7.

Symptom: the master asserts CYC_O or STB_O while reset is asserted.

Candidate causes. The qualifier register has no reset branch, or the block was never reset at all.

Discriminating evidence. Probe RST_I, CYC_O and STB_O together. Any qualifier high at a rising edge where rst_i is high is a direct RULE 3.20 violation, and a slave may legitimately act on it.

Likely RTL location. The state register driving the qualifiers.

Property. P2.

Symptom: some blocks come out of reset one cycle after others, and the first transfer after reset misbehaves.

Candidate causes. Reset resynchronised at different depths on different paths, or a mixture of synchronous and asynchronous reset conventions across blocks.

Discriminating evidence. Capture every block's reset input at release and compare the edges. A block releasing on a different edge from its neighbours has an extra synchroniser stage — or a different convention.

Likely RTL location. The reset distribution in SYSCON, not the endpoints.

Symptom: reset appears to have no effect at all, intermittently.

Candidate causes. A reset pulse narrower than a clock period, violating RULE 3.05 — typically a reset from a button, a power-on detector, or another clock domain, handed straight to RST_I.

Discriminating evidence. Measure the pulse against the clock period. If it can be shorter than one period, it can land entirely between two rising edges and be observed by nobody.

Likely RTL location. SYSCON's reset generation, which needs a stretcher and a synchroniser.

7. Verification

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_reset_checker — the reset contract, as properties.
//
// P1 and P2 are SPECIFICATION requirements (RULE 3.20). P3 is a local
// design policy of this module's RTL and is labelled as such — a conforming
// Wishbone interface is NOT required to reset its application registers.
// ─────────────────────────────────────────────────────────────────────────
module wb_reset_checker #(
  parameter int unsigned DW = 32
) (
  input logic          clk_i,
  input logic          rst_i,
  input logic          cyc_o,
  input logic          stb_o,
  input logic [DW-1:0] ctrl_q       // white-box: an application register
);
  // NOTE: no `default disable iff` here. These properties are specifically
  // ABOUT the reset interval, so disabling them during reset would remove
  // the only cycles they are meant to check — a mistake worth avoiding
  // deliberately rather than by accident.

  // P1 — SPECIFICATION (RULE 3.20). One cycle after RST_I is observed high
  //      at a rising edge, both qualifiers must be negated. Expressed with
  //      |=> because the rule says "at the rising edge FOLLOWING the
  //      assertion", which is the next clock tick.
  property p_qualifiers_negated_after_reset;
    @(posedge clk_i) rst_i |=> (!cyc_o && !stb_o);
  endproperty
  a_qualifiers_negated : assert property (p_qualifiers_negated_after_reset)
    else $error("RULE 3.20: CYC_O/STB_O not negated after RST_I assertion");

  // P2 — SPECIFICATION (RULE 3.20, second half). The negated state holds
  //      while reset remains asserted. Catches a master that restarts a
  //      cycle mid-reset.
  property p_qualifiers_stay_negated;
    @(posedge clk_i) (rst_i && $past(rst_i)) |-> (!cyc_o && !stb_o);
  endproperty
  a_qualifiers_stay_negated : assert property (p_qualifiers_stay_negated)
    else $error("RULE 3.20: a qualifier asserted during sustained reset");

  // P3 — LOCAL POLICY, NOT A SPECIFICATION RULE. This module's slaves clear
  //      their application registers on reset. RST_I only resets the
  //      WISHBONE interface; a conforming slave may legitimately retain
  //      application state, and binding this to third-party IP would
  //      produce false failures.
  property p_local_app_state_cleared;
    @(posedge clk_i) (rst_i && $past(rst_i)) |=> (ctrl_q == '0);
  endproperty
  a_local_app_state_cleared : assert property (p_local_app_state_cleared)
    else $error("local policy: application register not cleared by reset");
endmodule

The P1/P3 distinction is the point of this section. P1 and P2 are enforceable against any Wishbone master and a failure is a conformance defect. P3 is a house rule. Binding it to a purchased core would report failures on a block that is behaving exactly as its datasheet says, and an engineer who then "fixed" that core would be destroying state it was designed to retain.

Why there is no default disable iff (rst_i) here. Every other checker in this track disables during reset, because most properties describe normal operation. These properties describe reset itself, so the usual guard would switch off precisely the cycles under test. It is an easy mistake and it silently produces a checker that passes everything.

Tooling limitation, stated plainly. Icarus Verilog has no SVA support — a minimal property/assert property probe fails to parse — so this checker and every other in Module 4 was reviewed by inspection only. No tool available here has executed them. The synthesisable RTL is elaborated.

8. Common Mistakes

"Wishbone reset is active low because most RTL uses rst_n."

Wrong mental model: reset polarity is a house style.

Concrete bug: a core with rst_n wired to a Wishbone RST_I. It is held in reset for the entire time the bus is running and released exactly when the bus resets — perfectly inverted.

Observable evidence: a block that does nothing at all, or one whose state changes only during system reset.

Correct model: RULE 2.30 requires every interface signal to be active high. A core may use active-low internally; it may not present one at the interface.

"Asynchronous reset is safer, so I will use it here."

Wrong mental model: async reset is universally better practice.

Concrete bug: outputs that change the instant reset asserts rather than at the following rising edge — a different contract from RULE 3.00 — and a recovery/removal timing hazard at release if reset is not synchronously deasserted.

Observable evidence: an interface whose first post-reset cycle is occasionally wrong, on some builds and not others.

Correct model: this is not a claim that asynchronous reset is bad. It is a claim about conformance: the Wishbone interface's contract is synchronous, and an interface that implements a different one is not interoperable regardless of the merits.

"RST_I resets the peripheral."

Wrong mental model: one reset covers everything in the block.

Concrete bug: an integrator assuming a timer's count, a FIFO's contents or a calibration result is cleared, and building start-up sequencing on that assumption.

Observable evidence: a peripheral that behaves differently on a warm restart from a cold one, with no bus-level fault.

Correct model: the specification says RST_I only resets the Wishbone interface and is not required to reset other parts. What a given core does with its application state is a datasheet question, and some state is deliberately retained.

"A short reset pulse is fine because it is a level."

Wrong mental model: the interface will notice reset whenever it happens.

Concrete bug: a reset narrower than one clock period lands between two rising edges and is observed by nobody. The system does not reset, intermittently.

Observable evidence: reset that works most of the time and occasionally does nothing.

Correct model: RULE 3.05 requires assertion for at least one complete clock cycle, and it exists precisely because RULE 3.00 makes reset a sampled input.

9. Interview Reasoning

Synchronous and active high — the opposite of the common rst_n plus negedge in the sensitivity list, on both counts.

RULE 2.30 requires all interface signals to be active high. RULE 3.00 requires interfaces to initialise at the rising CLK_I edge following assertion, which makes reset a sampled input like any other. RULE 3.05 requires it to be asserted for at least one complete clock cycle, which is the obligation that follows from being sampled.

Why it matters to an integrator specifically: both defects are quiet. Wrong polarity means the block is never reset — and on an FPGA it powers up from the bitstream to a value that is frequently the same as a correct reset would produce, so the first run works and the second inherits stale state. Wrong synchronicity means outputs move at a different instant, which only shows up in the first cycles after release.

The diagnostic worth naming: correct after configuration, wrong after a warm restart points at reset before anything else, and one waveform settles it — capture rst_i with one internal register and look for non-zero state while reset is high.

10. Understanding Check

11. What's Next

Clock and reset are settled: one reference, one sampling edge, and an active-high synchronous reset that negates the qualifiers and leaves application state alone.

Both signals come from SYSCON and neither is part of a transfer. Everything from here is.

What does the Wishbone address actually represent, when may anyone trust it, and why does a 32-bit port's address bus not have bits 1 and 0?

Chapter 4.3 — ADR_O answers it. The full path is on the Wishbone curriculum index.

Continue learning

Standards & specifications

Governing standard
Wishbone SoC Interconnection Architecture (OpenCores)(opens OpenCores in a new tab)

Defines the Wishbone signal set, the bus cycles built from it and the interface rules a portable IP core must follow. It deliberately leaves interconnect topology, address map and arbitration policy to the integrator, so those are system decisions rather than requirements of the specification.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the Wishbone curriculum.