Valid/Ready Pipeline Register

Medium · Interfaces & Handshakes · Pipelining

Implement a pipeline register slice for a valid/ready stream: one register stage that can be dropped between a producer and a consumer to break a long data path, without losing, duplicating or reordering any data and without reducing throughput.

The valid/ready handshake

A stream moves one beat (one data word) at a time between a sender and a receiver:

transfer happens. The receiver may change ready at any time.

Your module is a receiver on its s_* (upstream) side and a sender on its m_* (downstream) side, so it must obey those sender rules on m_*.

Specification

module valid_ready_reg #(
    parameter int WIDTH = 8
) (
    input  logic             clk,
    input  logic             rst,      // synchronous, active-high
    input  logic             s_valid,  // upstream side
    output logic             s_ready,
    input  logic [WIDTH-1:0] s_data,
    output logic             m_valid,  // downstream side
    input  logic             m_ready,
    output logic [WIDTH-1:0] m_data
);

The module holds at most one beat. "Full" means m_valid = 1.

  1. Registered outputs. m_valid and m_data are driven directly by flip-flops.
  2. Ready. s_ready is combinational and must be exactly

s_ready = !m_valid || m_ready: the slice accepts a beat when it is empty, or when the beat it holds is leaving in the same cycle. (This makes s_ready depend combinationally on m_ready. That is fine for this simple version; the skid buffer problem removes that path.)

  1. Rising edge behavior (when rst is 0):
  2. if s_valid && s_ready: the slice stores s_data, and in the next cycle

m_valid = 1 and m_data is that beat (latency: exactly 1 cycle);

and m_data must not change.

  1. Throughput. With s_valid and m_ready both held at 1, one beat must transfer on

each side in every cycle.

  1. Reset. On a rising edge with rst = 1, the slice becomes empty: in the next cycle

m_valid = 0 (and therefore s_ready = 1). A beat held at that moment is discarded. m_data does not need a reset.

s_data is ignored when s_valid = 0 (the tests drive garbage there), and m_data is not checked when m_valid = 0. The tests' sender follows the handshake rules above.

Example

Beats A, B and C. In cycle 2 the downstream stalls (m_ready = 0) while the slice is full, so s_ready drops and B waits. From cycle 3 on, data flows at one beat per cycle.

cycles_valids_datas_readym_validm_datam_readytransfers at end of cycle
11A10–0A in
21B01A0(stall)
31B11A1A out, B in
41C11B1B out, C in
50–11C1C out
60–10–0

Sign up free to solve Valid/Ready Pipeline Register in your browser.

More Interfaces & Handshakes problems