glitch-free clock switching circuit
glitch:毛刺,glitch-free clock switching circuit:无毛刺时钟切换电路,今天讨论的主题就是如何实现时钟的无毛刺切换,本文将从有毛刺的时钟切换电路、无毛刺的源同步时钟切换电路、无毛刺的异步时钟切换电路三方面展开。
有毛刺的时钟切换电路:
之前曾在降低功耗相关的一篇推送中讲到过时钟使能信号:时钟使能降低功耗,当时一位大哥说这样并不是很好,很容易产生毛刺,其电路结构图为:
上图中的时钟切换电路是一个纯组合逻辑,输出时钟OUT_CLK由SELECT信号控制,但是正是因为使用了纯组合逻辑,导致该电路存在时钟毛刺的重要问题,如下所示,在进行时钟切换时,产生斩波输出时钟或在输出端产生毛刺:
同源时钟切换电路:
随着越来越多的多频时钟在芯片中的应用,经常需要在芯片运行时进行同源时钟切换,为了抑制源同步时钟切换时产生的glitch,可以在时钟选择路径中插入下降沿触发的DFF,在每个时钟的下降沿寄存选择控制信号,在其他时钟被取消使能之后才启用选择功能,提供了极好的输出故障保护,电路结构如下所示:
该电路的时钟输出波形如figure-2所示:
可以看到,在CLK的下降沿对SELECT信号进行采样,DFF的输出作为另一级DFF的disable信号,在SELECT进行任意切换时,无论其如何切换,只有在该路径上的enable信号(另一级的DFF的反向输出)为1时该路径才会生效。
因为SELECT是在下降沿被采集,而在时钟的下降沿时DFF的反向输出已经稳定,可以理解为在SELECT未选中该路径时,则释放该路径的控制权,同时通过~Q将控制权交给另一级时钟路径。
另一级时钟路径在获得控制权的前提下,在时钟的下降沿采集使能信号,并产生相应的输出,代码描述为:
reg en_r0,en_r1;
always@(negedge CLK0) en_r0<=(~SELECT)&(~en_r1)
always@(negedge CLK1) en_r1<=(SELECT)&(~en_r0)
assign OUT_CLK=( en_r0 & CLK0 ) | ( en_r1 & CLK1 );
异步时钟切换电路:
该电路是针对无关时钟源切换的毛刺保护电路:
该电路的输出时钟为:
为什么这种异步时钟切换电路不会产生毛刺时钟输出呢?
第一级DFF在上升沿对使能信号进行锁存,在第二级触发器在时钟下降沿对上一级的锁存使能信号输出进行寄存,第一级锁存的目的是为了消除亚稳态,第二级的作用是确定时钟路径的仲裁器,确定将时钟输出的控制权交给哪一条路径。在箭头1处将路径控制权交给路径2,路径2的第一级DFF在“3”处锁存输出使能信号,第二级DFF在“4”处寄存并输出使能信号,同时持续disable另一条路径(保持控制权),从而路径2输出时钟有效,代码描述为:
reg clk1_en1,clk1_en2;
reg clk2_en1,clk2_en2;
//时钟路径0
always@(posedge CLK0) clk0_en1<= sel & (~clk1_en2);
always@(negedge CLK0) clk0_en2<= clk_en1;
//时钟路径1
always@(posedge CLK1) clk1_en1<= sel & (~clk0_en2);
always@(negedge CLK1) clk1_en2<= clk_en1;
//输出时钟
assign OUT_CLK=( clk_en1 & CLK1 ) | ( clk_en0 & CLK0 );
- END -
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 深入探究immutable.js的实现机制(二)
- ES6 Promise 的最佳实践
- 「 Map最佳实践」什么时候适合使用 Map 而不是 Object
- ES2017 异步函数的最佳实践(`async` /`await`)
- React Hooks中这样写HTTP请求可以避免内存泄漏
- 用了这 7 个 VS Code 插件,想写一辈子代码
- 听说你还不知道Promise的allSettled()和all()的区别?
- React 条件渲染最佳实践(7 种方法)
- 一文带你层层解锁「文件下载」的奥秘
- Android实现简单C/S聊天室应用
- Android仿IOS回弹效果 支持任何控件
- 送你一道字节前端原题(Add sumOf)|文末送红宝书
- xadmin使用formfield_for_dbfield函数过滤下拉表单实例
- Python3之外部文件调用Django程序操作model等文件实现方式
- python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)