4.3 Verilog Cross-Clock Domain Transfer: Fast to Slow
Category Verilog Tutorial Advanced Chapter
When signals are transferred from a fast clock domain to a slow clock domain, synchronization processing is required based on the characteristics of the signal. For single-bit signals, they are generally distinguished as level signals and pulse signals.
Level Signal Synchronization
In synchronous logic design, a level signal refers to a signal that remains unchanged for a long time. The time limit for remaining unchanged is relative to the slow clock. As long as the signal from the fast clock maintains a high or low level for a sufficiently long time to be captured by the slow clock under the condition of meeting timing constraints, it can be considered a level signal.
Since the level signal can be safely captured, the level signal from the fast clock domain to the slow clock domain also uses the method of delayed strobing for synchronization.
Pulse Signal Synchronization
In synchronous logic design, a pulse signal refers to a signal with an effective width less than the slow clock cycle output from the fast clock domain. If the slow clock domain directly captures this narrow pulse signal, it may be missed.
If the pulse width of such a pulse signal is consistent, and knowing the ratio of the two clock frequencies, the synchronization can be achieved by using the method of "fast clock domain pulse width expansion + slow clock domain delayed strobing."
If sometimes the narrow pulse signal also shows the characteristics of a level signal, that is, sometimes the effective width of the signal is greater than the slow clock cycle and can be captured by the slow clock, then it is obviously not economical to further expand the pulse for such signals. At this time, synchronization can be achieved through the "handshake transmission" method.
Assuming that the high level period of the pulse signal is the effective signal period, the basic principle is as follows.
(1) The fast clock domain detects the pulse signal, and when a high level is detected, a high-level signal pulse_fast_r is output. Or when the fast clock domain outputs a high-level signal, do not rush to pull the signal low, and first maintain the output signal in a high state.
(2) The slow clock domain samples the signal pulse_fast_r from the fast clock domain with delayed strobing. Because the pulse signal is kept high by the fast clock domain at this time, delayed strobing will definitely capture the signal.
(3) After the slow clock domain confirms that it has sampled a high-level signal pulse_fast2s_r, it feeds back to the fast clock domain.
(4) The fast clock domain samples the feedback signal pulse_fast2s_r with delayed strobing. If a high-level feedback signal is detected, it proves that the slow clock domain has received an effective high-level signal. If the fast clock domain's own logic no longer requires the pulse signal to be in a high state at this time, the pulse signal of the fast clock domain can be pulled low.
This method essentially expands the pulse width of the narrow pulse signal by mutual handshaking.
The Verilog model description for synchronization using handshake signals is as follows.
Example
``` //Synchronization module with a working clock of about 25MHz //Asynchronous data pairs come from a module with a working clock of 100MHz module pulse_syn_fast2s #( parameter PULSE_INIT = 1'b0 ) ( input rstn, input clk_fast, input pulse_fast, input clk_slow, output pulse_slow);
wire clear_n ; reg pulse_fast_r ; /**************** fast clk ***************/ //(1) When the fast clock domain detects a pulse signal, do not rush to pull the pulse signal low always@(posedge clk_fast or negedge rstn) begin if (!rstn) pulse_fast_r <= PULSE_INIT ; else if (!clear_n) pulse_fast_r <= 1'b0 ; else if (pulse_fast) pulse_fast_r <= 1'b1 ; end
reg [1:0] pulse_fast2s_r ; /* slow clk / //(2) The slow clock domain samples the signal with delayed strobing always@(posedge clk_slow or negedge rstn) begin if (!rstn) pulse_fast2s_r <= 3'b0 ; else pulse_fast2s_r <= {pulse_fast2s_r[0], pulse_fast_r} ;