SystemVerilog Assertions for Clock Domain Crossing
Handshake protocols across clock domains are notoriously difficult to verify using manual waveform inspection. A missed acknowledge or unstable data bus can cause silent data corruption or system deadlocks. Formal verification engineers write concurrent SystemVerilog assertions (SVA) to mathematically prove protocol correctness. For simulation-based grading, these assertions can be modeled as a synthesizable protocol monitor that flags violations in real-time.
The cdc_protocol_monitor module observes a transmitter's clock domain crossing interface. It monitors the req and data signals, along with the synchronized ack_sync returning from the receiver. The module must detect two specific protocol violations. First, if a request is initiated but dropped before the acknowledge is received, it must flag a dropped request. Second, if the data payload changes at any point while the request is active, it must flag a data stability violation.
- Clock edge:
posedge clk - Reset type: Synchronous, active-low (
rst_n) - Output values on reset: Both error flags reset to
0 - Dropped Request Violation:
err_req_dropasserts to1for exactly one clock cycle ifreqis1andack_syncis0on cycle N, andreqtransitions to0on cycle N+1. The flag appears on cycle N+1. - Data Stability Violation:
err_data_changeasserts to1for exactly one clock cycle ifreqis1on both cycle N and cycle N+1, anddataon cycle N+1 differs from cycle N. The flag appears on cycle N+1. - Both outputs are registered.
Cycle 1: rst_n=0, req=1, ack_sync=0, data=8'hAA → err_req_drop=0, err_data_change=0 Cycle 2: rst_n=1, req=1, ack_sync=0, data=8'hAA → err_req_drop=0, err_data_change=0 (Transaction starts) Cycle 3: rst_n=1, req=1, ack_sync=0, data=8'hAA → err_req_drop=0, err_data_change=0 (Waiting for ack) Cycle 4: rst_n=1, req=1, ack_sync=0, data=8'hBB → err_req_drop=0, err_data_change=1 (Violation: data changed) Cycle 5: rst_n=1, req=0, ack_sync=0, data=8'hBB → err_req_drop=1, err_data_change=0 (Violation: req dropped early) Cycle 6: rst_n=1, req=1, ack_sync=0, data=8'hCC → err_req_drop=0, err_data_change=0 (New transaction starts) Cycle 7: rst_n=1, req=1, ack_sync=1, data=8'hCC → err_req_drop=0, err_data_change=0 (Ack received) Cycle 8: rst_n=1, req=0, ack_sync=0, data=8'h00 → err_req_drop=0, err_data_change=0 (Clean completion)
| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Synchronous active-low reset; all outputs go to 0 when asserted | | req | input | 1 | Handshake request signal from the transmitter | | ack_sync | input | 1 | Synchronized acknowledge signal returning from the receiver | | data | input | 8 | Data payload being transferred | | err_req_drop | output | 1 | Registered error flag; asserts high for one cycle when req drops before ack_sync is received | | err_data_change | output | 1 | Registered error flag; asserts high for one cycle when data changes while req is high |
Constraints
- All outputs must be updated synchronously on the positive edge of
clk. - Reset is synchronous and active-low.
- Error flags must assert for exactly one clock cycle per violation event.
- The
err_data_changeflag must not assert on the very first cyclereqgoes high, only if data changes on subsequent cycles whilereqremains high. - If
reqwas high andack_syncwas high on cycle N, droppingreqon cycle N+1 is legal and must not triggererr_req_drop.
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.