Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
    • Low-Power RTL Hub
    • DFT and Scan Hub
    • Physical Awareness Hub
    • Waveform Debug Hub
    • STA and ECO Hub
    • RTL-to-Implementation Closure
    • DFT-Ready RTL
    • Capstone: Resilient Streaming Peripheral
    • Principal Design Review
    • Senior RTL Interview Questions & Model Answers
      • Interview: Combinational and Arithmetic
      • Interview: Sequential and Pipelines
      • Interview: FSM and Control
      • Interview: Timing and STA
      • Interview: CDC and Reset
      • Interview: Memories and Buses
        • The valid/ready contract
        • AXI backpressure and deadlock risk
        • Register file vs SRAM
        • Unmapped addresses, decode errors and SLVERR
      • Interview: Low-Power Design
      • Interview: Debug and ECO
      • Interview: Coding and Whiteboard
  • Glossary and Notation
Loading lesson

‹Interview: Memories and Buses
  1. Topics
  2. RTL Design
  3. Senior & Interview
  4. Senior RTL Interview Questions & Model Answers
  5. Interview: Memories and Buses
  6. The valid/ready contract

Part 9 · Senior · Senior

The valid/ready contract

The valid/ready handshake rules, a source/sink pair, and directed checker mutations through acceptance.

On this page

    Why this matters

    A source that refreshes its data while a stalled word waits makes the sink capture the wrong value, and the bug stays silent until the first stall. The interviewer asks when data may change to see if you know the one rule everything rests on.

    After this lesson you can: state when a transfer happens, when the source may change data, and how a skid buffer lets a sink decide late without losing a word.

    The question

    The interviewer asks: walk me through the valid/ready handshake, and tell me exactly when the source may change its data.

    This tests flow control without loss or duplication. The answer is two rules plus the reason neither side may use combinational shortcuts across the link.

    Model answer

    A transfer happens if and only if valid and ready are high in the same cycle. Before that cycle the source owns the payload; after it the sink does.

    Signal

    Driven by

    Rule

    valid

    Source

    Once high, stays high with a stable payload until ready joins it.

    ready

    Sink

    May rise and fall with capacity. A receiver may wait for valid before asserting ready; a source must not wait for ready before offering valid.

    payload

    Source

    Stable while valid waits. It may change only after the handshake.

    Assert valid from pending work, not as a prerequisite-dependent response to ready. A sink may assert ready proactively or register a decision after seeing valid. AXI forbids combinational paths between interface inputs and outputs; a generic internal ready/valid link can use combinational ready propagation only when its composition is proven loop-free and meets timing.

    The bottom row, data, holds still through the stall and then moves once while stalled. That move is the violation.

    • Slot 0: idle. valid 0, ready 1, data 0x00.

    • Slot 1: the source offers 0xA1 (valid 1). The sink stalls (ready 0).

    • Slot 2: still stalled. data holds 0xA1, as the contract requires.

    • Slot 3: data moves to 0xB2 while valid stays high and ready stays low. This is a stability violation.

    • Slot 4: ready rises. The handshake completes and carries the wrong word 0xB2.

    • Slot 5: back-to-back transfer of 0xC3 with valid and ready both high.

    • Slot 6: valid drops. The bus is idle.

    Common pitfall

    Changing the payload while valid is high and ready is low, even to a fresher value. The sink may already have sampled the old word, so the transfer duplicates or corrupts.

    Follow-ups

    The sink asserted ready, then deasserted it with valid still high. Legal. Only the source side is constrained; ready may move at any time.

    The sink needs a cycle to decide but must not lose the word. A one-deep skid buffer accepts the word while the downstream stalls, then replays it. The valid/ready technical lesson covers the pattern.

    The checker remembers the preceding rising-edge stall. At the next rising edge it requires valid and the same payload, even if ready is now high. Separate mutations drop valid and change data on the accepting edge; each must be detected once.

    Check yourself Valid is high, ready is low, and the source increments its counter. Which transfer completes?

    None. No transfer completes without ready. Every word offered so far is still pending, and the counter advance is already a stability violation.

    Check yourself The sink ties ready high permanently. What breaks?

    Nothing in the protocol, as long as the sink truly accepts every word the cycle it arrives. The risk is a later change that adds latency without adding backpressure.

    Interview

    Valid stays up and data stays still until ready answers. Everything else is commentary.

    Common wrong answers

    Ready acknowledges like a pulse, so the source may change data right after ready blips. Ready is a level, not a pulse. The transfer is the coincidence of the two levels, and the payload must be stable through it.

    The source may refresh stalled data to keep it current. Freshness is the sink's decision after the handshake. Refreshing under stall breaks the one guarantee the sink relies on.

    Tie ready high and skip the checker, since this link never stalls. Links that never stall still need the checker. The day one stalls, the bug is silent without it.

    Testbench

    The sampled stability rule as an SVA snippet. The procedural implementation below uses the same preceding-edge obligation. Reset cancels the pending obligation.

    design.sv
    1
    2
    3
    4
    // snippet
    // The stability rule as a property (the testbench below checks the same rule procedurally):
    // assert property (@(posedge clk) disable iff (!rst_n)
    //                  (valid && !ready) |=> valid && $stable(payload));

    The full source, sink, and checker below drive stimulus on falling edges and sample offers before rising-edge NBA updates. The clean scoreboard samples delivered data after NBA settlement. Each fault trial resets the source/sink; the data mutation is applied after a sampled stall and before its accepting edge.

    vr_src.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    `timescale 1ns/1ps
    module vr_src (
      input  logic       clk, rst_n, ready,
      output logic       valid,
      output logic [7:0] payload
    );
      logic [7:0] next_val;
      always_ff @(posedge clk) begin
        if (!rst_n) begin
          valid    <= 1'b0;
          payload  <= 8'h00;
          next_val <= 8'h00;
        end else if (!valid || (valid && ready)) begin
          payload  <= next_val;
          valid    <= 1'b1;
          next_val <= next_val + 8'h01;
        end
      end
    endmodule
    
    module vr_sink (
      input  logic       clk, rst_n, valid,
      input  logic [7:0] payload,
      output logic       ready,
      output logic [7:0] got,
      output logic       took
    );
      logic [3:0] phase;
      always_ff @(posedge clk) begin
        if (!rst_n) begin
          phase <= 4'd0;
          got   <= 8'h00;
          took  <= 1'b0;
        end else begin
          phase <= phase + 4'd1;
          took  <= valid && ready;
          if (valid && ready) got <= payload;
        end
      end
      assign ready = (phase[1:0] != 2'b10);   // stall one cycle in four
    endmodule
    

    Remember

    • A transfer happens when valid and ready are both high in the same cycle.

    • Once valid is high, valid and payload hold until the handshake. Only ready may move freely.

    • A link that never stalls still needs the stability checker, or the bug appears the day one stalls.

    Rule of thumb: valid stays up and data stays still until ready answers.

    How this was checked

    Source, sink and checker bench Run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It is checker evidence for the finite regression, not a proof over all sequences. Each fault trial resets the source and sink.

    Keep going

    • Practice: Two-stage valid/ready pipeline: backpressure and skid buffers

    • Code lab: AXI stream handshake

    • Interview: run a mock interview on this topic

    Related topics

    • Valid/ready buses

    • AXI-Stream

    Previous

    333 / 350

    Next: AXI backpressure and deadlock risk

    Up next

    Up nextAXI backpressure and deadlock risk

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Register file vs SRAM
    • Unmapped addresses, decode errors and SLVERR
    clkvalidreadydata0a1b2c3
    A valid/ready stall with stable data, then a mid-stall change