Blocks leave reset at different times. A producer that starts while the consumer is still in reset loses words.
Either one reset sequencer controls the release order (sequencing), or the receiver announces readiness and the sender waits.
Each slot is one clock cycle, numbered from 0. A word on v0 or v1 is taken by the consumer at the edge that ends its slot, and only counts if rst_c_n is already high there.
Slot 1: the producer leaves reset. The consumer stays in reset for three more cycles and leaves it in slot 4.
Slots 2 to 6: v0 sends its 5 words at once. The words of slots 2 and 3 reach a consumer still in reset and are lost: 3 of 5 arrive.
Slots 5 and 6: alive rises one cycle after the consumer's reset ends, and v1 starts on the next cycle. All 5 of its words arrive.
No transfer is in flight across the crossing.
All handshake wires are at their idle value (req and ack low, valid low).
FIFOs are empty, pointers equal.
Both sides know the other's state: either a flag says so, or the reset sequence guarantees it.
The consumer reports its actual readiness instead of assuming a release delay. But a synchronized copy may remain high for several producer cycles after a remote reset. Planned reset must close acceptance and drain first; unexpected reset needs the recovery acceptance interlock, containment and an epoch/cancellation policy.
Two producers under a staggered reset release, with and without waiting.
// Two blocks on one clock. The producer sends 100 words, one per cycle. The consumer counts the words it sees.
// 'alive' becomes 1 one cycle after the consumer leaves reset: "I am ready to receive".
module consumer (input logic clk, rst_n, valid, output logic alive, output int received);
initial received = 0;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) alive <= 1'b0;
else alive <= 1'b1;
always @(posedge clk) if (rst_n && valid) received++; // words arriving while in reset are lost
endmodule
module producer #(parameter bit WAIT_ALIVE = 1) (input logic clk, rst_n, alive, output logic valid, output int sent);
int n = 0;
initial sent = 0;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin valid <= 1'b0; n <= 0; end
else if (n < 100 && (!WAIT_ALIVE || alive)) begin valid <= 1'b1; n <= n + 1; end
else valid <= 1'b0;
always @(posedge clk) if (valid) sent++;
endmodule
Producer behaviour | Sent | Received | Lost |
|---|---|---|---|
Starts as soon as it leaves reset | 100 | 81 | 19 |
Waits for the consumer's | 100 | 100 | 0 |
This one-clock test demonstrates planned staggered startup only. With unrelated clocks, synchronize alive and account for its detection latency. A stale high alive cannot guarantee protection against an unannounced reset, a stopped clock or power loss; use the recovery barrier and appropriate isolation/fault controls.