Bird
Raised Fist0
Verilogprogramming~7 mins

Clock domain crossing awareness in Verilog

Choose your learning style10 modes available
Introduction

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.

When you have two parts of a chip running at different speeds or phases.
When you want to send a signal from one clock to another without glitches.
When designing hardware modules that communicate asynchronously.
When you want to avoid data corruption caused by timing issues.
When you need to synchronize control signals crossing clock boundaries.
Syntax
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.

Examples
This is a common 2-flip-flop synchronizer pattern to safely cross clock domains.
Verilog
reg sync_ff1, sync_ff2;
always @(posedge clk_dest) begin
  sync_ff1 <= async_signal;
  sync_ff2 <= sync_ff1;
end
assign sync_signal = sync_ff2;
For multi-bit signals, simple synchronization like this can cause errors; special techniques are needed.
Verilog
reg [3:0] data_sync;
always @(posedge clk_dest) begin
  data_sync <= async_data;
end
Handshake protocols help transfer complex data safely across clock domains.
Verilog
wire handshake_signal;
// Use handshake signals to safely transfer data between clock domains.
Sample Program

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.

Verilog
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
OutputSuccess
Important Notes

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.

Summary

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

(1/5)
1. What is the main purpose of using a synchronizer in clock domain crossing?
easy
A. To safely transfer signals between different clock domains
B. To increase the clock frequency
C. To reduce power consumption
D. To generate a new clock signal

Solution

  1. Step 1: Understand clock domain crossing

    Signals crossing from one clock domain to another can cause timing errors if not handled properly.
  2. Step 2: Role of synchronizers

    Synchronizers, typically two flip-flops in series, help avoid metastability by safely transferring signals between different clock domains.
  3. Final Answer:

    To safely transfer signals between different clock domains -> Option A
  4. Quick Check:

    Synchronizer = Safe signal transfer [OK]
Hint: Synchronizers prevent timing errors between clocks [OK]
Common Mistakes:
  • Thinking synchronizers increase clock speed
  • Confusing synchronizers with power-saving methods
  • Assuming synchronizers generate clocks
2. Which Verilog code snippet correctly implements a 2-flip-flop synchronizer for a single-bit signal async_signal crossing into clk domain?
easy
A. reg sync_0, sync_1; always @(posedge clk) begin sync_1 <= async_signal; sync_0 <= sync_1; end
B. reg sync_0, sync_1; always @(posedge clk) begin sync_0 <= async_signal; sync_1 <= sync_0; end
C. reg sync_0, sync_1; always @(posedge async_signal) begin sync_0 <= clk; sync_1 <= sync_0; end
D. reg sync_0, sync_1; always @(negedge clk) begin sync_0 <= async_signal; sync_1 <= sync_0; end

Solution

  1. 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), so posedge clk is correct.
  2. Step 2: Check flip-flop chaining order

    The first flip-flop captures async_signal, the second captures the output of the first. This is correctly done as sync_0 <= async_signal; then sync_1 <= sync_0;.
  3. Final Answer:

    reg sync_0, sync_1; always @(posedge clk) begin sync_0 <= async_signal; sync_1 <= sync_0; end -> Option B
  4. Quick 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]
Hint: Use posedge clk and chain flip-flops in order [OK]
Common Mistakes:
  • Using negedge instead of posedge
  • Swapping flip-flop assignments
  • Triggering on async_signal edge
3. Given the following Verilog code snippet crossing a signal 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;
medium
A. The code will cause a synthesis error
B. data_sync will always match data_in immediately
C. data_sync will never change from initial value
D. data_sync will be a delayed and synchronized version of data_in

Solution

  1. Step 1: Understand synchronizer behavior

    The 2-flip-flop synchronizer delays the asynchronous input by two clock cycles of clk_b and reduces metastability risk.
  2. Step 2: Analyze output data_sync

    data_sync reflects data_in but delayed and synchronized to clk_b domain, not immediate.
  3. Final Answer:

    data_sync will be a delayed and synchronized version of data_in -> Option D
  4. Quick Check:

    Synchronizer output = delayed synchronized signal [OK]
Hint: Synchronizer delays and syncs signals, no immediate match [OK]
Common Mistakes:
  • Expecting immediate signal match
  • Assuming no delay in synchronization
  • Thinking code causes synthesis error
4. Identify the problem in this Verilog code crossing a multi-bit signal 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
medium
A. The clock edge should be negedge instead of posedge
B. The code is correct and safe for multi-bit crossing
C. Multi-bit signals require handshake or FIFO, not simple flip-flop synchronizers
D. Missing reset signals causes metastability

Solution

  1. Step 1: Recognize multi-bit signal crossing issues

    Multi-bit signals crossing clock domains can cause data corruption if bits change at different times.
  2. 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.
  3. Final Answer:

    Multi-bit signals require handshake or FIFO, not simple flip-flop synchronizers -> Option C
  4. Quick Check:

    Multi-bit crossing needs handshake/FIFO [OK]
Hint: Use handshake or FIFO for multi-bit signals [OK]
Common Mistakes:
  • Assuming flip-flops alone are safe for buses
  • Changing clock edge without reason
  • Ignoring metastability risks
5. You need to transfer a 16-bit data word from clk_fast domain to clk_slow domain safely. Which method best ensures data integrity and avoids metastability?
hard
A. Use a handshake protocol with data valid and acknowledge signals
B. Directly assign the data bus without synchronization
C. Use a 2-flip-flop synchronizer on each bit individually
D. Use asynchronous reset on the data bus

Solution

  1. Step 1: Consider multi-bit data crossing challenges

    Transferring 16-bit data across clock domains risks partial updates and metastability if not handled properly.
  2. Step 2: Evaluate synchronization methods

    Using handshake protocols with valid and acknowledge signals ensures complete and safe data transfer between different clock domains.
  3. Final Answer:

    Use a handshake protocol with data valid and acknowledge signals -> Option A
  4. Quick Check:

    Handshake ensures safe multi-bit crossing [OK]
Hint: Handshake protocols ensure safe multi-bit crossing [OK]
Common Mistakes:
  • Trying to synchronize each bit separately
  • Ignoring synchronization and assigning directly
  • Relying on asynchronous reset for crossing
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard