Clock domain crossing awareness helps you safely move signals between parts of a circuit running on different clocks. This avoids errors caused by timing mismatches.
Clock domain crossing awareness in Verilog
module sync_ff( input wire clk_dest, input wire async_signal, output reg sync_signal ); reg sync_ff1; always @(posedge clk_dest) begin sync_ff1 <= async_signal; sync_signal <= sync_ff1; end endmodule
This example shows a 2-stage synchronizer to safely transfer a signal from one clock domain to another.
Using two flip-flops reduces the chance of metastability, which can cause unpredictable behavior.
reg sync_ff1, sync_ff2; always @(posedge clk_dest) begin sync_ff1 <= async_signal; sync_ff2 <= sync_ff1; end assign sync_signal = sync_ff2;
reg [3:0] data_sync; always @(posedge clk_dest) begin data_sync <= async_data; end
wire handshake_signal; // Use handshake signals to safely transfer data between clock domains.
This example shows a simple 2-stage synchronizer module and a testbench with two different clocks. It prints the original and synchronized signals over time.
module clock_domain_crossing( input wire clk_src, input wire clk_dest, input wire async_signal, output reg synced_signal ); reg sync_ff1; // Synchronizer in destination clock domain always @(posedge clk_dest) begin sync_ff1 <= async_signal; synced_signal <= sync_ff1; end endmodule // Testbench to show usage module testbench(); reg clk_src = 0; reg clk_dest = 0; reg async_signal = 0; wire synced_signal; clock_domain_crossing uut( .clk_src(clk_src), .clk_dest(clk_dest), .async_signal(async_signal), .synced_signal(synced_signal) ); // Source clock: 10 time units period always #5 clk_src = ~clk_src; // Destination clock: 7 time units period always #3.5 clk_dest = ~clk_dest; initial begin $monitor($time, " ns: async_signal=%b synced_signal=%b", async_signal, synced_signal); async_signal = 0; #12 async_signal = 1; #20 async_signal = 0; #30 $finish; end endmodule
Always use at least two flip-flops to synchronize signals crossing clock domains.
Multi-bit signals need special handling like FIFOs or handshake protocols to avoid data corruption.
Metastability is a hardware condition where signals take unpredictable time to settle; synchronizers reduce its risk.
Clock domain crossing awareness helps avoid errors when signals move between different clocks.
Use 2-stage flip-flop synchronizers for single-bit signals crossing clock domains.
For complex data, use handshake or FIFO methods to safely transfer information.
Practice
Solution
Step 1: Understand clock domain crossing
Signals crossing from one clock domain to another can cause timing errors if not handled properly.Step 2: Role of synchronizers
Synchronizers, typically two flip-flops in series, help avoid metastability by safely transferring signals between different clock domains.Final Answer:
To safely transfer signals between different clock domains -> Option AQuick Check:
Synchronizer = Safe signal transfer [OK]
- Thinking synchronizers increase clock speed
- Confusing synchronizers with power-saving methods
- Assuming synchronizers generate clocks
async_signal crossing into clk domain?Solution
Step 1: Identify correct clock edge and signal assignment
The synchronizer must sample the asynchronous signal on the positive edge of the destination clock (clk), soposedge clkis correct.Step 2: Check flip-flop chaining order
The first flip-flop capturesasync_signal, the second captures the output of the first. This is correctly done assync_0 <= async_signal;thensync_1 <= sync_0;.Final Answer:
reg sync_0, sync_1; always @(posedge clk) begin sync_0 <= async_signal; sync_1 <= sync_0; end -> Option BQuick Check:
Correct clock edge and flip-flop order = reg sync_0, sync_1; always @(posedge clk) begin sync_0 <= async_signal; sync_1 <= sync_0; end [OK]
- Using negedge instead of posedge
- Swapping flip-flop assignments
- Triggering on async_signal edge
data_in from clk_a domain to clk_b domain using a 2-flip-flop synchronizer, what is the expected output of data_sync after several clock cycles?reg sync_0, sync_1; always @(posedge clk_b) begin sync_0 <= data_in; sync_1 <= sync_0; end assign data_sync = sync_1;
Solution
Step 1: Understand synchronizer behavior
The 2-flip-flop synchronizer delays the asynchronous input by two clock cycles ofclk_band reduces metastability risk.Step 2: Analyze output
data_syncdata_syncreflectsdata_inbut delayed and synchronized toclk_bdomain, not immediate.Final Answer:
data_syncwill be a delayed and synchronized version ofdata_in-> Option DQuick Check:
Synchronizer output = delayed synchronized signal [OK]
- Expecting immediate signal match
- Assuming no delay in synchronization
- Thinking code causes synthesis error
data_bus[7:0] from clk_a to clk_b domain:reg [7:0] sync_0, sync_1; always @(posedge clk_b) begin sync_0 <= data_bus; sync_1 <= sync_0; end
Solution
Step 1: Recognize multi-bit signal crossing issues
Multi-bit signals crossing clock domains can cause data corruption if bits change at different times.Step 2: Understand proper methods for multi-bit crossing
Simple flip-flop synchronizers are not safe for multi-bit buses; handshake protocols or FIFOs are needed.Final Answer:
Multi-bit signals require handshake or FIFO, not simple flip-flop synchronizers -> Option CQuick Check:
Multi-bit crossing needs handshake/FIFO [OK]
- Assuming flip-flops alone are safe for buses
- Changing clock edge without reason
- Ignoring metastability risks
clk_fast domain to clk_slow domain safely. Which method best ensures data integrity and avoids metastability?Solution
Step 1: Consider multi-bit data crossing challenges
Transferring 16-bit data across clock domains risks partial updates and metastability if not handled properly.Step 2: Evaluate synchronization methods
Using handshake protocols with valid and acknowledge signals ensures complete and safe data transfer between different clock domains.Final Answer:
Use a handshake protocol with data valid and acknowledge signals -> Option AQuick Check:
Handshake ensures safe multi-bit crossing [OK]
- Trying to synchronize each bit separately
- Ignoring synchronization and assigning directly
- Relying on asynchronous reset for crossing
Ready to prove it?
Pass the test and this pattern moves unknown
