An MCP formulation separates the transfer into two parts:
-
Unsynchronized multi-bit data bus
- The data signals are sent directly from the source domain to the destination domain — without synchronization.
- The data is held stable for multiple destination clock cycles.
-
Synchronized control signal
- A single control signal (often a
load,enable, orvalid) is synchronized across the clock boundary using a two-flip-flop synchronizer. - This control signal tells the destination domain when to safely capture the data.
- A single control signal (often a
🧠 Key Principle
The receiving clock domain never samples the data until after the control signal has been fully synchronized.
Because the data remains stable for several destination cycles, the receiving register will always sample a stable, valid data word — never a transitioning one.
🔄 Timing Summary
Here’s how it works step-by-step:
- The source clock domain places a new data word (
DATA[n:0]) on the CDC bus. - The source then asserts an enable or load signal at the same time.
- The data remains unchanged for at least two cycles of the destination clock (to allow the enable to synchronize safely).
- After two synchronization stages in the destination domain, the enable signal becomes active (
enable_sync). - On the next rising edge of the destination clock, the receiving register captures the stable data.
📉 Simplified Timing Diagram
Source domain signals:
DATA: [==== D0 ====] [==== D1 ====]
ENABLE: ____|‾‾‾‾‾‾‾‾‾‾‾‾‾‾|__________
Destination domain (after 2FF synchronizer):
ENABLE_SYNC: ________|‾‾‾‾‾‾‾‾|______
CAPTURE: ↑ (captures D0 safely)
Here, DATA is stable long before ENABLE_SYNC arrives — ensuring the data is captured correctly.
✅ Advantages
-
No need to calculate pulse widths
The source doesn’t need to stretch or time its pulses precisely relative to the destination clock (unlike open-loop approaches). -
Simplified control logic
The enable signal doesn’t need to return low — it can remain high until the next data transaction. -
Safe multi-bit transfers
The destination samples all bits simultaneously on one clock edge — avoiding skew or partial updates. -
No metastability in data
Since data is stable when sampled, metastability risk is isolated to the control synchronizer only.
⚙️ Typical Implementation Example (Verilog)
Source Clock Domain
// Source domain logic
always @(posedge src_clk) begin
if (send_new_data) begin
data_bus <= next_data; // Drive new data
enable <= 1'b1; // Pulse or level change
end
end
Destination Clock Domain
// Synchronize control signal
reg [1:0] enable_sync;
always @(posedge dest_clk) begin
enable_sync <= {enable_sync[0], enable};
end
// Capture data after synchronization
always @(posedge dest_clk) begin
if (enable_sync[1])
dest_data <= data_bus; // Data is stable and safe to sample
end
⚠️ Important Design Rules
- The data bus must remain stable for at least two destination clock cycles after
enableis asserted. - Only the control signal should cross through a synchronizer.
- The destination must never sample data based directly on the unsynchronized control signal.
- Always constrain the timing properly in static timing analysis (STA) — the unsynchronized data paths are treated as multi-cycle paths.
🧩 Why It’s Called “Multi-Cycle Path”
Because the destination clock sees the data as valid and unchanged for multiple cycles before capture, the data path is allowed more than one cycle to settle.
In timing analysis terms, this path is declared as multi-cycle, meaning its setup requirement spans multiple destination cycles — consistent with how the logic actually operates.
🚀 Summary
| Feature | Description |
|---|---|
| Data Path | Unsynchronized multi-bit data, held stable for multiple destination cycles |
| Control Path | Single synchronized enable or load signal |
| Synchronization Depth | Two-flip-flop synchronizer for control |
| Safety Guarantee | Data always stable when sampled |
| Primary Use Case | Multi-bit bus transfers (e.g., configuration words, FIFO interfaces) |