Location>code7788 >text

Gated Clock - Hairless Clock Switching

Popularity:994 ℃/2024-11-18 13:33:14

I. Issues

Assume that such a clock control model exists:

CLK1, CLK2 and the system clock frequency and phase are not consistent, we want to clk_sel = 1, the output CLK1, and vice versa output CLK2, CLK_SEL can be driven by the system clock, can also be driven by the combinatorial logic. In this case, the following "burr" problem occurs:

It can be seen that at the junction of CLK_SEL, it is very easy to have a burr in the CLK_OUT clock, thus affecting the normal operation of the system.

II. Solutions

(The following method is from B station UP: Pitt Pie)

The specific ideas are: 1. Two clocks are mutually exclusive outputs, i.e., the two non-gates B4 and B5 are used as inputs to the final A2 and A4;

2. The S3 and S6 registers are synchronized to sel using a falling edge drive, so that the output of both clocks can be done without burrs with a delay of one beat.

The analysis is as follows: when sel is 0, the initial value of ali_2 is 0, ali_1 is 1, and A1 is selected, and then two beats of synchronization are made to the ai signal driven by CLKA, and then S3 samples the beat-synchronized signals at the falling edge of CLKA, so that CLK-OUT is always pulled low due to the fact that CLKA is 0 before the falling edge to the latter rising edge, and then CLKA is high, at which time CLKA is 1 and ai2_2 is 1 because ai2_2 has been synchronized on the previous falling edge, at which time CLK_OUT outputs CLKA.
Essentially trading delay for accuracy.

III. Codes

Based on the above RTL, the code is as follows:

  1. RTL

// // =============================================================================
// File Name    : clk_gating_module.v
// Module       : clk_gating_module
// Function     : Burr free clock switching
// Type         : RTL
// Aythor       : Dongyang
// -----------------------------------------------------------------------------
// Update History :
// -----------------------------------------------------------------------------
`timescale 1 ns/1 ns
module  clk_gating_module(
        input            sys_clk    ,
        input            sys_rst_n  ,
  
        input            i_clka     ,
        input            i_clkb     ,
        input            i_clk_sel  ,
        output           o_clk_out  

);

//******************** siganl define ********************
wire         a1i_1        ;
wire         a1i_2        ;
wire         a3i_1        ;
wire         a1o          ;
wire         a3o          ;
wire         a3i_2        ;
wire         a2o          ;
wire         a4o          ;
reg          a4i_2    =  'b0;
reg          a2i_2    =  'b0;
reg  [1:0]   a1o_dly  =  'b0;
reg  [1:0]   a3o_dly  =  'b0;  

//******************** assign  *****************************
assign   a1i_1 =   ~i_clk_sel         ;
assign   a3i_1 =    i_clk_sel         ;
assign   a1i_2 =    ~a4i_2         ;
assign   a3i_2 =    ~a2i_2         ;
assign   a1o   =   a1i_1 & a1i_2 ;
assign   a3o   =   a3i_2 & a3i_1;
assign   a2o   =   i_clka & a2i_2;
assign   a4o   =   a4i_2 & i_clkb;
assign   o_clk_out = a2o | a4o   ;

//**********************always*********************************
// CLKA domain
always @(posedge i_clka) begin
    if(~sys_rst_n) begin
        a1o_dly <= 'b0;
    end
    else begin
        a1o_dly<= {a1o_dly[0],a1o};
    end
end

always @(negedge i_clka) begin
    if(~sys_rst_n) begin
        a2i_2 <= 'b0;
    end
    else  begin
        a2i_2 <= a1o_dly[1];
    end
end

//CLK B domain
always @(posedge i_clkb) begin
    if(~sys_rst_n) begin
        a3o_dly <= 'b0;
    end
    else begin
        a3o_dly<= {a3o_dly[0],a3o};
    end
end

always @(negedge i_clkb) begin
    if(~sys_rst_n) begin
        a4i_2 <= 'b0;
    end
    else  begin
        a4i_2 <= a3o_dly[1];
    end
end

endmodule
  1. TestBench

`timescale 1 ns/1 ns
module  tb_clk_gatting();

reg    clka   = 'b0;
reg    clkb   = 'b0;
reg    sys_clk = 'b0;
reg    sys_rst_n = 'b0;
reg    clk_sel  = 'b0 ;

initial begin
clka   = 'b0;
clkb   = 'b0;
sys_clk = 'b0;
sys_rst_n = 'b0;
clk_sel  = 'b0 ;
#6
clkb   = 'b1;
#100
sys_rst_n = 'b1;
#1000
clk_sel  = 1'b1;
#756
clk_sel  = 1'b1;
#1500
clk_sel  = 1'b0;
end

always  # 10   sys_clk = ~sys_clk;    //sys_clk     50M
always  # 50   clka    = ~clka   ;    // CLKA       10M
always  # 30   clkb    = ~clkb   ;     // CLKB     16.6M
clk_gating_module  U_clk_gating_module(
        .sys_clk    (sys_clk),
        .sys_rst_n  (sys_rst_n),
        .i_clka     (clka),
        .i_clkb     (clkb), 
        .i_clk_sel  (clk_sel), 
        .o_clk_out  ()

);

endmodule

IV. Simulation Waveforms