In FPGA design, handling cross-time domain (Cross-Time Domain, commonly referred to as Cross Clock Domain CDC) is a key technology to ensure reliable signal transmission between different clock domains, with the core issue being the resolution of the metastability problem.
1. Single Bit Signal Crossing Domain: Two-Stage Synchronizer
This is the most basic method, suitable for control signals, flags, and other single-bit signals (from slow clock domain to fast clock domain, or fast to slow).
-
Principle: Synchronize the single-bit signal crossing the domain through two-stage registers in the target clock domain. The first stage register may enter a metastable state, but after one clock cycle, the second stage register can stably sample, preventing metastability from propagating to subsequent circuits.
-
Note:
Example code (Verilog):
module
sync_single_bit (
input src_clk,// Source clock domain
input src_data,// Single bit signal from source clock domain
input dst_clk,// Target clock domain
output dst_data // Synchronized data
);
reg ff1, ff2;
always @(posedge dst_clk)begin
ff1 <= src_data;// First stage synchronization
ff2 <= ff1;// Second stage synchronization, output stable signal
end
assign dst_data = ff2;
endmodule
- The source signal must remain stable for at least one target clock cycle in the source clock domain (to avoid missing signal transitions).
- Only applicable to single bits; multi-bit signals may encounter “data inconsistency” issues.
2. Multi-Bit Signal Crossing Domain: Handshake Protocol
Suitable for multi-bit data transmission (such as commands, configuration information), ensuring reliable data reception through a “request-response” mechanism.
- Principle
- The source clock domain sends data and raises the “request signal (req)” to synchronize to the target domain.
- After the target domain receives req, it raises the “acknowledgment signal (ack)” and synchronizes back to the source domain.
- After the source domain receives ack, it confirms that the data has been received, retracting req and the data.
3. Large Data Crossing Domain: Asynchronous FIFO
Suitable for high-frequency, continuous data transmission (such as data acquisition, interface conversion), which is the most commonly used cross-domain data buffering solution in FPGA.
- Principle
- Based on dual-port RAM, with read and write ends operating in their respective clock domains.
- Synchronizes read and write pointers using “Gray Code” (where adjacent values differ by only 1 bit, avoiding multi-bit transitions across domains), and generates “empty” and “full” signals to prevent read/write overflow.
- Advantages Efficient buffering, supports clock domains with different frequencies and phases, without complex handshakes.
4. Counter / State Machine Crossing Domain: Gray Code Conversion
Suitable for multi-bit counters or state machines crossing domains (such as addresses, state values).
- Principle Converts binary encoded counter/state values to Gray Code (where adjacent values differ by only 1 bit), then synchronizes each bit through a single-bit synchronizer, and finally converts back to binary in the target domain.
- Advantages Avoids sampling errors due to simultaneous transitions of multiple bits, suitable for slowly changing multi-bit signals.
5. Other Special Scenarios
- Wide bus from fast clock to slow clock can first latch the data in the fast clock domain, then transmit it through handshake or asynchronous FIFO.
- High-frequency signal crossing domain should avoid direct crossing; it is better to divide the frequency in the source domain before synchronizing.
Core Principles
- Avoid Metastability Propagation by ensuring stable signals in the target domain through multi-stage synchronization or protocols.
- Prevent Data Loss / Errors by selecting synchronizers, handshakes, or FIFOs based on data volume and frequency.
- Timing Constraints Cross-domain signals should be marked as “false path” in synthesis tools to avoid timing analysis errors.
In actual design, the most suitable solution should be chosen based on signal type (single bit/multi-bit), data volume, and clock frequency relationships. Asynchronous FIFO and two-stage synchronizers are the most commonly used basic methods.