Valid and Ready Handshake Transmitter
Data transfer across digital systems requires flow control to prevent data loss when a receiving module is busy processing previous data. The valid and ready handshake protocol is the industry standard mechanism for this, forming the foundation of modern bus architectures like AXI Stream.
The transmitter module acts as a bridge. It receives a request to send data via a send signal. Upon receiving this request, it latches the incoming data_in, asserts the valid output, and holds the data steady on data_out. It simultaneously asserts a busy signal to indicate to the upstream source that it cannot accept new data. The valid signal remains high until the downstream receiver asserts ready. Once ready is sampled high while valid is high, the transaction completes, and the module returns to an idle state.
Timing and Reset Rules
- Clock edge:
posedge clk - Reset: Asynchronous active-low (
rst_n) - Reset values:
valid= 0,busy= 0,data_out= 8'b00000000 - Priority rules: If
busyis high, any assertion ofsendis ignored.data_outmust remain strictly constant whilevalidis 1 andreadyis 0. Once a transaction completes,data_outholds its last value until a newsendrequest is processed.
Worked Trace
Cycle 1: rst_n=0 → valid=0, busy=0, data_out=0 Cycle 2: rst_n=1, send=1, data_in=170, ready=0 → (Registers update on next edge) Cycle 3: send=0 → valid=1, busy=1, data_out=170 Cycle 4: ready=0 → valid=1, busy=1, data_out=170 (Hold state) Cycle 5: ready=1 → (Handshake completes on this edge) Cycle 6: send=0, ready=0 → valid=0, busy=0, data_out=170 (Idle, holding last data)
State Diagram
flowchart LR
RESET(( )) -->|reset| IDLE
IDLE((IDLE)) -->|send=1| ACTIVE
IDLE -->|send=0| IDLE
ACTIVE(["ACTIVE ★"]):::out -->|ready=1| IDLE
ACTIVE -->|ready=0| ACTIVE
classDef out fill:#6C5CE7,stroke:#5B4FE8,color:#fffTiming Diagram
{ "signal": [
{ "name": "clk", "wave": "p....." },
{ "name": "rst_n", "wave": "01...." },
{ "name": "send", "wave": "010..." },
{ "name": "data_in", "wave": "x=xxxx", "data": ["0xAA"] },
{ "name": "ready", "wave": "0...10" },
{},
{ "name": "valid", "wave": "0.1..0" },
{ "name": "busy", "wave": "0.1..0" },
{ "name": "data_out", "wave": "=.=..=", "data": ["0x00", "0xAA", "0xAA"] }
], "head": { "text": "Basic valid/ready handshake transaction." } }Port Table
| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; sets valid=0, busy=0, data_out=0 | | send | input | 1 | Request to transmit data | | data_in | input | 8 | Data to be transmitted | | ready | input | 1 | Downstream receiver is ready to accept data | | valid | output | 1 | High when data_out contains valid data | | data_out | output | 8 | Data being transmitted; holds last value after completion | | busy | output | 1 | High when module is processing a transaction and cannot accept send |
Constraints
- Clock edge is
posedge clkand reset is asynchronous active-low. - On reset,
valid,busy, anddata_outmust all be0. - If
busyis high, any assertion ofsendmust be ignored completely. data_outmust not change whilevalidis high andreadyis low.validandbusymust be registered outputs; they cannot depend combinationally onready.
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.