Verilog99题-47-49题(时钟相关)

前言

不忘出芯veriloig99题的47-49题是关于时钟。

47. 画出clock gating cell的原理图。

单纯从功能上来说,门控时钟只需要一个与门或者或门就可以实现。例如,

assign clk_out = en & clk;assign clk_out = ~en | clk;

但是这里en信号就可以随时变化,一旦其变化的时机不合适就会产生毛刺。例如下图(基于与门)中未画出的clk_out,每次en使能有效时,输出时钟的首尾都会产生毛刺。

glitch

为了避免这种情况发生,需要处理控制信号的不合时机的变化。见以下两种Integrated Clock Gating Cell(ICG):

基于latch和与门

由以上分析,若采用与门搭建门控时钟,比较关键的是:在时钟高电平期间,en控制信号要稳定,否则就会有毛刺。所以基于与门设计的话,则要采用控制端为低电平有效的latch。en控制信号经过latch之后在时钟的高电平期间总是稳定的,便避免了毛刺的产生。

ICG_AND
AND_ICG_tim

基于latch和或门

若基于或门搭建的话,首先使能信号得取反(时钟信号与低电平相或才能出来时钟)。若直接相或,使能在时钟低电平期间变化就会产生毛刺。所以要采用控制端为高电平有效的latch来处理使能信号,这样en控制信号经过latch之后在时钟的低电平期间总是稳定的,便避免了毛刺的产生。

ICG_OR
OR_ICG_timOR_ICG_tim

48. 用verilog实现静态时钟切换电路。外部管脚输入sel,clk,testclk。sel为1输出clk,sel为0输出testclk。

module clk_switch(
    input                   clk0        ,
    input                   clk1        ,
    input                   rst_n       ,
    input                   select      ,
    output                  outclk      
    );

    assign outclk = select ? clk1 : clk0;

49. 用verilog实现glitch free时钟切换电路。输入sel,clka,clkb,sel为1输出clka,sel为0输出clkb。

module clk_switch(
    input                   clk0        ,
    input                   clk1        ,
    input                   rst_n       ,
    input                   select      ,
    output                  outclk      
    );

reg     out_r1;
reg     out1;
reg     out_r0;
reg     out0;
 
 always @(posedge clk1 or negedge rst_n)begin
     if(rst_n == 1'b0)begin
         out_r1 <= 0;
     end
     else begin
         out_r1 <= ~out0 & select;
     end
 end
 
 always @(negedge clk1 or negedge rst_n)begin
     if(rst_n == 1'b0)begin
         out1 <= 0;
     end
     else begin
         out1 <= out_r1;
     end
 end
 
 always @(posedge clk0 or negedge rst_n)begin
     if(rst_n == 1'b0)begin
         out_r0 <= 0;
     end
     else begin
         out_r0 <= ~select & ~out1;
     end
 end
 
 always @(negedge clk0 or negedge rst_n)begin
     if(rst_n == 1'b0)begin
         out0 <= 0;
     end
     else begin
         out0 <= out_r0;
     end
 end
 
 assign outclk = (out1 & clk1) | (out0 & clk0);
endmodule

具体请点击中文版英文版

另附1篇

即将入行的数字IC设计工程师