Full Four Phase Handshake Protocol
Passing multi bit data or critical control signals across asynchronous clock domains without a FIFO requires a robust synchronization mechanism. A full four phase handshake guarantees safe data transfer regardless of the frequency ratio between the source and destination clocks. By strictly verifying the transition of request and acknowledge signals in both directions, the system prevents data corruption and metastability even when the clock frequencies drift or change dynamically.
The module acts as a bridge between a source clock domain and a destination clock domain. The source domain receives an 8-bit data payload and a start pulse. Upon receiving the start pulse, the source FSM captures the data, drives it to the destination, and asserts a request signal (cdc_req). The destination domain synchronizes this request, captures the data, asserts an acknowledge signal (cdc_ack), and pulses a valid signal for exactly one cycle. The source domain synchronizes the acknowledge, deasserts the request, and waits. Finally, the destination domain sees the deasserted request, deasserts the acknowledge, and the source domain returns to an idle state ready for the next transfer.
- Clock edges:
posedge clk_srcandposedge clk_dst - Reset type: Asynchronous
- Reset polarity: Active low (
rst_src_nandrst_dst_n) - Output reset values:
src_readyresets to 1; all other outputs reset to 0 - Data stability:
src_datais guaranteed to be stable whensrc_startis asserted; internal captured data must remain stable while crossing domains
Cycle 1: rst_src_n=0, rst_dst_n=0 → src_ready=1, cdc_req=0, cdc_ack=0, dst_valid=0 Cycle 2: rst_src_n=1, rst_dst_n=1, src_start=1, src_data=8'hA5 → src_ready=0, cdc_req=1 Cycle 3: cdc_req=1 propagates through destination synchronizer → dst_data=8'hA5, dst_valid=1, cdc_ack=1 Cycle 4: dst_valid=0 (pulses for one cycle only); cdc_ack remains 1 Cycle 5: cdc_ack=1 propagates through source synchronizer → cdc_req=0 Cycle 6: cdc_req=0 propagates through destination synchronizer → cdc_ack=0 Cycle 7: cdc_ack=0 propagates through source synchronizer → src_ready=1
flowchart LR
S_IDLE((S_IDLE)) -->|src_start=1| S_REQ
S_REQ((S_REQ)) -->|sync_ack=1| S_WAIT
S_WAIT((S_WAIT)) -->|sync_ack=0| S_IDLE
D_IDLE((D_IDLE)) -->|sync_req=1| D_ACK
D_ACK(["D_ACK ★"]):::out -->|sync_req=0| D_IDLE
classDef out fill:#6C5CE7,stroke:#5B4FE8,color:#fff{ "signal": [
{ "name": "clk_src", "wave": "p..........." },
{ "name": "src_start", "wave": "010........." },
{ "name": "src_ready", "wave": "10.........1" },
{ "name": "cdc_req", "wave": "0.1.....0..." },
{},
{ "name": "clk_dst", "wave": "p..........." },
{ "name": "cdc_ack", "wave": "0...1.....0." },
{ "name": "dst_valid", "wave": "0...10......" },
{ "name": "dst_data", "wave": "=.==........", "data": ["0", "8'hA5"] }
], "head": { "text": "Four phase handshake sequence across clock domains." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk_src | input | 1 | Source domain clock | | rst_src_n | input | 1 | Source domain active low asynchronous reset | | clk_dst | input | 1 | Destination domain clock | | rst_dst_n | input | 1 | Destination domain active low asynchronous reset | | src_data | input | 8 | Data payload to transfer | | src_start | input | 1 | Pulse to initiate transfer; valid only when src_ready is 1 | | src_ready | output | 1 | High when source FSM is idle and ready for new data; resets to 1 | | cdc_req | output | 1 | Cross domain request signal driven by source domain | | cdc_ack | output | 1 | Cross domain acknowledge signal driven by destination domain | | dst_data | output | 8 | Data payload captured in destination domain; holds value between transfers | | dst_valid | output | 1 | Single cycle pulse in destination domain indicating dst_data is valid |
Constraints
- The
cdc_reqandcdc_acksignals must be synchronized using exactly two flip flops in their respective receiving domains - The
dst_validsignal must assert for exactly oneclk_dstcycle per transfer - The source domain FSM must not assert
cdc_reqfor a new transfer until the synchronized acknowledge signal is completely deasserted to 0 - Data must be captured by the destination domain only on the cycle the synchronized request transitions from 0 to 1
- All domain specific sequential logic must be clocked by its respective domain clock and reset by its respective domain reset
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.