参考这篇文章:数字电路时钟无毛刺切换
因为直接用组合逻辑判断去切换时钟,会产生毛刺,如下图所示。

产生该毛刺的原因: sel没有在时钟跳边沿改变。因为我们一般是用clk上升沿采样数据,所以我们sel选择信号最好是在clk下降沿改变,可以让切换的时候,不会错过上升沿。

我理解的整体思路: 将en信号先经过打3拍(异步时钟要打三拍),然后经过一个ICG(integrate clock Gating)
ICG框图

作用:让sel同步于时钟并且在下降沿改变。

设计代码

module clock_switch(input                   s_rst_n                 ,       input                   s_clk_1                 ,       input                   s_clk_2                 ,       input                   s_clk_3                 ,       input [1:0]             i_clk_sel               ,//00: clk1, 01: clk2, 10/11: clk3       output                  o_clk
);//========================================================================\
// =========== Define Parameter and Internal signals ===========
//========================================================================/
wire                            clk1_sel                        ;
reg                             clk1_sel_syn1                   ;
reg                             clk1_sel_syn2                   ;
reg                             clk1_sel_syn3                   ;    wire                            clk2_sel                        ;
reg                             clk2_sel_syn1                   ;
reg                             clk2_sel_syn2                   ;
reg                             clk2_sel_syn3                   ;       wire                            clk3_sel                        ;
reg                             clk3_sel_syn1                   ;
reg                             clk3_sel_syn2                   ;
reg                             clk3_sel_syn3                   ;       reg                             clk1_sel_real                   ;
reg                             clk2_sel_real                   ;
reg                             clk3_sel_real                   ;       assign clk1_sel = (i_clk_sel == 2'b00)? 1'b1: 1'b0;
assign clk2_sel = (i_clk_sel == 2'b01)? 1'b1: 1'b0;
assign clk3_sel = (i_clk_sel == 2'b10 || i_clk_sel == 2'b11)? 1'b1: 1'b0;always  @(posedge s_clk_1 or negedge s_rst_n) beginif(s_rst_n == 1'b0) beginclk1_sel_syn1       <= 'd0            ;       clk1_sel_syn2       <= 'd0            ;       clk1_sel_syn3       <= 'd0            ;    endelse beginclk1_sel_syn1       <= clk1_sel  & (~clk2_sel_syn3) & (~clk3_sel_syn3)       ;       clk1_sel_syn2       <= clk1_sel_syn1    ;       clk1_sel_syn3       <= clk1_sel_syn2    ;   endendalways  @(posedge s_clk_2 or negedge s_rst_n) beginif(s_rst_n == 1'b0) beginclk2_sel_syn1       <= 'd0            ;       clk2_sel_syn2       <= 'd0            ;       clk2_sel_syn3       <= 'd0            ;    endelse beginclk2_sel_syn1       <= clk2_sel & (~clk1_sel_syn3) & (~clk3_sel_syn3)        ;       clk2_sel_syn2       <= clk2_sel_syn1    ;       clk2_sel_syn3       <= clk2_sel_syn2    ;   endendalways  @(posedge s_clk_3 or negedge s_rst_n) beginif(s_rst_n == 1'b0) beginclk3_sel_syn1       <= 'd0            ;       clk3_sel_syn2       <= 'd0            ;       clk3_sel_syn3       <= 'd0            ;    endelse beginclk3_sel_syn1       <= clk3_sel  & (~clk1_sel_syn3) & (~clk2_sel_syn3)       ;       clk3_sel_syn2       <= clk3_sel_syn1    ;       clk3_sel_syn3       <= clk3_sel_syn2    ;   end
endalways  @(negedge s_clk_1 or negedge s_rst_n) beginif(s_rst_n == 1'b0)clk1_sel_real <= 'd0;elseclk1_sel_real <= clk1_sel_syn3;
//         clk1_sel_real <= clk1_sel_syn2;
endalways  @(negedge s_clk_2 or negedge s_rst_n) beginif(s_rst_n == 1'b0)clk2_sel_real <= 'd0;elseclk2_sel_real <= clk2_sel_syn3;//clk2_sel_real <= clk2_sel_syn2;
endalways  @(negedge s_clk_3 or negedge s_rst_n) beginif(s_rst_n == 1'b0)clk3_sel_real <= 'd0;elseclk3_sel_real <= clk3_sel_syn3;//clk3_sel_real <= clk3_sel_syn2;
end
//验证了,只打两拍确实有问题
assign o_clk = (clk1_sel_real & s_clk_1) | (clk2_sel_real & s_clk_2) | (clk3_sel_real & s_clk_3);endmodule

testbench 代码

`timescale      1ns/1nsmodule clock_switch_tb();reg                             s_rst_n                         ;
reg                             s_clk_1                         ;
reg                             s_clk_2                         ;
reg                             s_clk_3                         ;
reg  [1:0]                      i_clk_sel                       ;
wire                            o_clk                           ;       clock_switch  clock_switch_inst(.s_rst_n                (s_rst_n                ),.s_clk_1                (s_clk_1                ),.s_clk_2                (s_clk_2                ),.s_clk_3                (s_clk_3                ),.i_clk_sel              (i_clk_sel              ),.o_clk                  (o_clk                  )
);always #5 s_clk_1 = ~s_clk_1;
always #10 s_clk_2 = ~s_clk_2;
always #20 s_clk_3 = ~s_clk_3;initial begins_rst_n     = 0                    ;       s_clk_1     = 0                    ;       s_clk_2     = 0                    ;       s_clk_3     = 0                    ;       i_clk_sel   = 0                    ;   #20;s_rst_n = 1;#200;i_clk_sel = 1;#200;i_clk_sel = 2;#200;        i_clk_sel = 3;#200;$finish;
end
//generate fsdb file
initial begin$fsdbDumpfile("clock_switch_tb.fsdb");$fsdbDumpvars(0,clock_switch_tb);
end
endmodule

仿真波形

一般无毛刺切换,切换始终的时候,都会需要几个clock的缓冲。

IC基础知识:时钟无毛刺切换相关推荐

  1. IC基础知识(4)电源管理简介:稳压器IC

    文章目录 写在前面 正文 线性与开关 线性稳压器 开关稳压器 其他类型的功率IC 结论 写在前面 原文链接:Introduction to Power Management: Voltage Regu ...

  2. 数字电路基础知识|时钟和时序

    时钟的概念 时钟对数字电路而言非常重要,没有时钟数字电路就没法工作,其全称是时钟频率,一般由晶振来提供时钟频率. 在数字电路中,所有数据.逻辑单元等状态的更新都是以时钟为基础的,时钟频率在数字电路中起 ...

  3. IC基础知识(3)通用模拟,数字和混合信号集成电路

    文章目录 写在前面 正文 数字IC 逻辑 内存 处理器 模拟IC 混合信号IC 结论 交个朋友 写在前面 原文链接:Common Analog, Digital, and Mixed-Signal I ...

  4. FPGA/IC基础知识

    1.简述建立时间和保持时间 建立时间Tsu(setup):触发器在时钟上升沿到来之前,其数据输入端的数据必须保持不变的最小时间. 保持时间Th(hold):触发器在时钟上升沿到来之后,其数据输入端的数 ...

  5. IC基础知识(二)锁存器与触发器

    目录 1.双稳态器件 2.常见的锁存器结构 3.D锁存器的应用 4.D触发器 5.D触发器的建立时间和保持时间 微信公众号 1.双稳态器件 双稳态器件是指稳定状态有两种,一种是0,一种是1的器件:双稳 ...

  6. IC基础知识(一)CMOS器件

    目录 1.MOS晶体管结构与工作原理简述 2.CMOS单元电路与版图 3.CMOS门电路 4.CMOS的功耗表示 微信公众号 ​ 作为一个微电子专业的ICer,应该都学过一些基本的器件知识,今天就来聊 ...

  7. IC基础知识(2)模拟和数字电子学导论

    文章目录 写在前面 正文 模拟世界 数字系统 模拟和数字IC 概括 交个朋友 写在前面 该教程探讨了重要的主题,这些主题使我们可以将集成电路分为两大类. 承接上一篇:集成电路简介 原文地址:Intro ...

  8. IC基础知识(1)集成电路(IC)简介

    文章目录 写在前面 正文 什么是集成电路? IC中有什么? IC封装类型 结论 写在前面 在最前面还是分享下一个英文网站吧,挺不错的教程网站,觉得一些知识讲解的还算吸引人,为了阅读起来没那么障碍,这里 ...

  9. IC基础知识(六)SV中default input #1 output #1的解释

    目录 1. clocking-endclocking块 2. clocking shew的含义 3. 实例代码 4. clocking event 5. clock cycle延时 '##' 6. d ...

最新文章

  1. 图像滤镜艺术---PS图层混合模式之明度模式
  2. 分布式MySQL数据库TDSQL架构分析
  3. python横向合并merge_【Python代替Excel】7:merge、concat、append
  4. python机制_python异常机制个人理解(参考网上资料)
  5. leetcode542. 01 矩阵(bfs/dp)
  6. python大型项目教程_在大型项目开发上,python真是个“烂语言”吗?
  7. C语言-01基础语法
  8. CamShift算法,OpenCV实现1--Back Projection
  9. 51单片机按键控制数码管0~9_0.39寸2位数码管厂家
  10. DHCP八种报文详解
  11. MySQL学习第三弹——约束与多表查询详解
  12. IndexError: Target 25 is out of bounds.
  13. Error inflating class出现报错
  14. 重磅:腾讯低代码平台正式开源!可拖拽生成手机、PC等项目!接私活福利啊!...
  15. 网页前端设计之多选按钮
  16. 经典同步时序逻辑电路分析汇总(第八道)(同步三进制计数器)
  17. php expecting,php – 解析错误:语法错误,意外的’.’,expecting’,’或’;’
  18. 唯品会技术架构一览表
  19. 星转二手交易平台/二手交易系统/二手网站
  20. 微信小程序:图片404错误,更换默认图片

热门文章

  1. 缓慢变化维常见解决方案
  2. 黑马程序员---从头开始,回忆JAVA基础之反射
  3. 如何快速锁定 Mac,Macbook快速锁定的几种方法
  4. cccc 天梯赛后总结
  5. python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法
  6. C语言打印所有“水仙花数”
  7. 三个经典电话,帮你促进销售技巧
  8. rⅰd的意思_自动挡上的P、R、N、D、S、L是啥意思?一个口诀教会你!
  9. 商用WIFI 四种模式均分天下
  10. javascript的纯函数