14 / 24 · Concept
Design a one-slot elastic register
Accept into an empty slot or replace a simultaneously consumed item.
Lessons are free to read. Enroll to save your learning progress.
Derive ready from available storage
A one-slot buffer contains a full bit and a payload register. When empty, it can accept an input even if the sink is stalled. When full, it can accept a replacement if the sink consumes the existing output at that edge. Thus input-ready is !full OR output-ready, and output-valid is full. This registered buffer has no combinational data fall-through.
If input-ready is high, next full equals input-valid. Capture the payload when an input exists; otherwise empty the slot. If input-ready is low, preserve full and payload. Clearing full simply because an output transferred loses a simultaneous replacement. Capturing on input-valid alone overwrites a full, stalled slot.
module elastic_byte (
input logic clk, rst,
input logic in_valid,
output logic in_ready,
input logic [7:0] in_data, in_tag,
output logic out_valid,
input logic out_ready,
output logic [7:0] out_data, out_tag
);
logic full;
assign in_ready = !full || out_ready;
assign out_valid = full;
always_ff @(posedge clk) begin
if (rst) full <= 1'b0;
else if (in_ready) begin
full <= in_valid;
if (in_valid) begin
out_data <= in_data;
out_tag <= in_tag;
end
end
end
endmodule| Old full | out-ready | in-valid | Action |
|---|---|---|---|
| 0 | 0 | 1 | Store input |
| 1 | 0 | 1 | Reject input and hold output |
| 1 | 1 | 1 | Deliver old item and store replacement |
| 1 | 1 | 0 | Deliver old item and empty slot |
Store tag0,y9 at edge 0. Stall at edge 1. At edge 2, consume tag0 and store tag1,y12; the slot remains full. At edge 3, consume tag1 and empty it if no input exists. Replacement permits one transaction per cycle.
Connecting many stages creates a backward combinational ready path. Registering ready requires extra storage for arrivals before the stall notification takes effect. Check any bus-specific combinational-path restrictions separately. Regardless of payload width, store data and every companion field under the same condition, and verify all four update cases.
Try it yourself
At an edge with full=1, out-ready=1, and in-valid=1, consume tag7 and offer tag8. What are next full and out-tag? What goes wrong if full is always cleared on consumption?
Read the explanation
Input-ready is high, so store tag8 and keep full=1. Out-tag becomes 8. Always clearing full loses tag8 after accepting it.