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

产生该毛刺的原因: 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. 那些有用但不为大家所熟知的 Java 特性
  2. 安装IE8不能调试VS2005的解决办法
  3. 不用悬浮窗权限弹出全局dialog的解决方法
  4. 时间序列数据的存储和计算 - 开源时序数据库解析
  5. kafka如何彻底删除topic及数据
  6. 院士倪光南:Win10不安全 中国必须用自主操作系统
  7. Ubuntu18.04 Flutter开发环境搭建
  8. Pytorch离线安装 matlibplot
  9. 我从GitHub 企业版找到严重的 RCE 漏洞,意外得$2万奖金 (GitHub $6.1万系列之一)...
  10. 相亲交友小程序,案例:情深深之恋
  11. SDU-nachos安装及初步编译
  12. VB.NET读取数据库时多线程显示进度条
  13. Could not set the project description for 'hotelseqbid.ws' because the project d
  14. java整数最大_Java 整数最大值
  15. 人工智能学习历程---计算机视觉篇
  16. go import导入包详解
  17. 新猿木子李:0基础学python培训教程 Python操作Redis
  18. 自学Java第二天 解决java不能输出中文问题
  19. 白领的一天 场景7:薪水与福利
  20. 用Python画小篮子

热门文章

  1. 【误码率仿真】基于matlab的小波包的OFDM误码率仿真
  2. 【EMC电磁兼容】02.02——详说EMC设计的三大出发点
  3. vue中设置花样字体
  4. 遥感影像道路提取算法——SGCN
  5. 我为什么在美国也不给孩子喝牛奶?
  6. 简单常用滤波算法c语言实现,简单常用滤波算法C语言实现
  7. 传智播客定制2019新年播仔“天天向上”礼盒,为老学员送祝福
  8. 华三交换机查看上层交换机vlan
  9. SPSS 操作(一)数据选取 :个案选取和字符变量的筛选
  10. 牛客竞赛数据结构专题班树状数组、线段树练习题