5.4 Verilog Clock Switching
Category Advanced Verilog Tutorial
Due to various application constraints, chips often need to switch between different clock sources during operation, such as low-frequency clocks for low-power mode and high-frequency clocks for high-performance mode. The two clock sources may be homologous and synchronized, or they may be unrelated. Directly using selection logic for clock switching is likely to cause glitches in the divided clock signal, so special handling is also required for clock switching logic.
Clock Switching Issues
The circuit diagram for directly switching clocks using selection logic is shown below.
Clock Switching Solutions
Switching clocks when the levels are opposite will definitely cause glitches; when the levels are the same, even if no glitches are generated, the first clock cycle or duty cycle after switching is not ideal. Therefore, to avoid glitches, clock switching needs to be performed when both clocks are at a low level.
A typical clock switching circuit is shown below.
This circuit uses the falling edge of the clock to buffer the clock selection signal sel_clk1. At the same time, a clock selection signal provides feedback control to another clock, ensuring that only one clock path is active at any given time. Finally, the two clock paths are combined using an "OR operation" to complete the clock switching process.
The waveform diagram for completing clock switching (clk1->clk2) using the above circuit is shown below.
As seen in the diagram, when switching from clk1 to clk2, clk1 is first turned off, then clk2 is turned on. Since the clock selection signal is synchronized to the clock falling edge, no glitches occur during the switching process.
The waveform diagram for switching from clk2 to clk1 is shown below.
Considering that the selection signal may be an asynchronous signal, two flip-flops need to be added before the clock selection signal buffer flip-flop for synchronization processing to reduce the propagation of metastability, as shown in the structure diagram below. This clock switching circuit is more universal.
Clock Switching Design
A general and safe clock switching logic description is as follows.
Example
module clk_switch(
input rstn ,
input clk1,
input clk2,
input sel_clk1 , // 1 clk1, 0 clk2
output clk_out
);
reg [2:0] sel_clk1_r ;
reg [1:0] sel_clk1_neg_r ;
reg [2:0] sel_clk2_r ;
reg [1:0] sel_clk2_neg_r ;
// Using 3-stage buffer, synchronize the "AND" logic operation of the other clock control signal with the current clock control signal
always @(posedge clk1 or negedge rstn) begin
if (!rstn) begin
sel_clk1_r <= 3'b111 ; // Note the default value
end
else begin
// sel clk1, and not sel clk2
sel_clk1_r <= {sel_clk1_r[1:0], sel_clk1 & (!sel_clk2_neg_r[1])} ;
end
end
// On the falling edge, use a 2-stage buffer for the clock selection signal
always @(negedge clk1 or negedge rstn) begin
if (!rstn) begin
sel_clk1_neg_r <= 2'b11 ; // Note the default value
end
else begin
sel_clk1_neg_r <= {sel_clk1_neg_r[0], sel_clk1_r[2]} ;
end
end
// Using 3-stage buffer, synchronize the "AND" logic operation of the other clock control signal with the current clock control signal
always @(posedge clk2 or negedge rstn) begin
if (!rstn) begin
sel_clk2_r <= 3'b0 ; // Note the default value
end
else begin
// sel clk2, and not sel clk1
sel_clk2_r <= {sel_clk2_r[1:0], !sel_clk1 & (!sel_clk1_neg_r[1])} ;
end
end
// On the falling edge, use a 2-stage buffer for the clock selection signal
always @(negedge clk2 or negedge rstn) begin
if (!rstn) begin
sel_clk2_neg_r <= 2'b0 ; // Note the default value
end
else begin
sel_clk2_neg_r <= {sel_clk2_neg_r[0], sel_clk2_r[2]} ;
end
end
// Clock logic operations generally use specific process cell libraries.
// Here, Verilog's built-in logic gate units are used instead
wire clk1_gate, clk2_gate ;
and (clk1_gate, clk1, sel_clk1_neg_r[1]) ;
and (clk2_gate, clk2, sel_clk2_neg_r[1]) ;
or (clk_out, clk1_gate, clk2_gate) ;
endmodule
The testbench description is as follows, mainly generating asynchronous clock selection signals.
Example
`timescale 1ns/1ps
module test ;
reg clk_100mhz, clk_200mhz ;
reg rstn ;
reg sel ;
wire clk_out ;
always #(2.5) clk_200mhz = ~clk_200mhz ;
always @(posedge clk_200mhz)
clk_100mhz = #1 ~clk_100mhz ;
initial begin
clk_100mhz = 0 ;
clk_200mhz = 0 ;
rstn = 0 ;
sel = 1 ;
#11 rstn = 1 ;
#36.2 sel = ~sel ;
#119.7 sel = ~sel ;
end
clk_switch u_clk_switch(
.rstn (rstn),
.clk1 (clk_100mhz),
.clk2 (clk_200mhz),
.sel_clk1 (sel),
.clk_out (clk_out));
initial begin
forever begin
#100;
if ($time >= 10000) $finish ;
end
end
endmodule
The simulation results are as follows, showing that no glitches are generated when switching between clocks, but there is a delay.
Source Code Download for This Chapter
-1.2 Verilog Switch-Level Modeling
-2.2 Verilog Combinational Logic UDP
-2.3 Verilog Sequential Logic UDP
-3.2 Verilog specify Block Statements
-3.3 Verilog Setup and Hold Time
-3.5 Verilog Delay Backannotation
-4.1 Verilog Synchronous and Asynchronous
-4.2 Verilog Clock Domain Crossing: Slow to Fast
-4.3 Verilog Clock Domain Crossing: Fast to Slow
-5.1 Verilog Reset Introduction
-5.2 Verilog Clock Introduction
- 5.4 Verilog Clock Switching
-6.1 Verilog Low Power Introduction
-6.2 Verilog System-Level Low Power Design
-6.3 Verilog RTL-Level Low Power Design (Part 1)
-6.4 Verilog RTL-Level Low Power Design (Part 2)
-7.3 Verilog Random Numbers and Probability Distribution
-7.4 Verilog Real to Integer Conversion
-7.5 Verilog Other System Tasks
-8.3 Verilog TF Subroutine List
-8.5 Verilog ACC Subroutine List
-9.2 Verilog Synthesizable Design WeChat Follow