一道简单的笔试题_时钟切换电路(Glitch-free clock switching circuit)
由一道某科笔试开始,如下:
解析:
电路功能:两个异步时钟源切换电路;
DFF1和DFF3作用:在选择路径插入一个上升沿触发器,用于缓存数据,将数据传递给下一级;若去掉,会电路产生由异步信号引起的亚稳态;
DFF2和DFF4采用负沿采用原因:SELECT与反馈输出相与,下降沿采样反馈可以保证一个时钟被完全取消选择后,输出才输出另一个时钟,从而避免产生毛刺。
前言
纯组合逻辑时钟切换电路:电平相反时,切换时钟不可避免产生毛刺;
相关时钟切换:下降沿切换(反馈实现),下个上升沿切换生效,消除毛刺;
无关时钟切换:下降沿触发之前添加一个上升沿触发器,消除亚稳态;
一、有毛刺的时钟切换
纯组合逻辑的时钟切换,由于为电平触发,不可避免会产生毛刺;
如图所示,这个时钟切换电路是一个纯组合逻辑,输出时钟(OUT CLOCK)由选择信号(SELECT)控制,当SELECT为1时输出CLK1,反之,输出CLK0.
看似很简单,实现了时钟的切换,实则存在着很大的隐患,如下图所示:
由图中可知,SELECT信号变化的位置没有和切换的时钟对齐;当SELECT信号发生改变时,当前时钟源(CLK0)正好处于高电平,因此,会在输出端产生毛刺。
对上图的Verilog描述:
assign outclk = (clk1 & select) | (~select & clk0);
二、相关时钟源的时钟切换
以下为两个时钟源成倍数的关系的时钟切换电路:
在每个时钟源的选择路径中插入一个负边沿触发的D触发器。确保在切换时钟源时,即使时钟正处在高电平,也不会影响输出变化;
当时钟源切换时,这个反馈可以保证一个时钟被完全取消选择后,输出才输出另一个时钟,从而避免产生毛刺;
电路描述:
当SELECT为0时,CLK1的那部分通路到输出无效,仅看下半部分电路即可,在CLK0的下降沿采样SELECT(取反后)信号,与CLK0相与之后输出;
当SELECT为1时,同理上半部分电路有效;
如图首先SELECT为0,也就是在CLK0的下降沿采样寄存SELECT(取反后)信号与CLK0相与,输出时钟为CLK0;
当在图中时刻SELECT由低电平变为高电平,此时未到CLK0的下降沿,寄存器的输出还将一直是高电平(SELECT之前为0,取反为1),当到达CLK0的下降沿时刻,采样到SELECT为高电平,此时SELECT为1,也就是下半部分电路从此无效,上半部分电路有效,此时需要等到CLK1的下降沿采样SELECT值,在此之前,输出仍为 CLK0,到达CLK1的下降沿后,输出变成了CLK1和SELECT的与,也就是CLK1。由图可见,输出时钟完成切换,并没有出现毛刺。
module glitch_2 (
input clk0,
input clk1,
input select,
input rst_n,
output clkout);
reg out1;
reg out0;
always @(negedge clk1 or negedge rst_n)begin
if(rst_n == 1'b0)begin
out1 <= 0;
end
else begin
out1 <= ~out0 & select;
end
end
always @(negedge clk0 or negedge rst_n)begin
if(rst_n == 1'b0)begin
out0 <= 0;
end
else begin
out0 <= ~select & ~out1;
end
end
assign clkout = (out1 & clk1) | (out0 & clk0);
endmodule
三、异步时钟源的时钟切换
异步时钟源的切换是在相关时钟源切换的基础上插入一个上升沿D触发器,对选择信号进行同步处理,避免产生亚稳态。
第一个触发器采样数据寄存,然后到第二个触发器输出第一个触发器寄存的数据。
还是按这张图进行仿真:
SELECT为0时候,clk0时钟上升沿采样得到DFF3Q,之后得到DFF4Q,下降沿采样得到DFF4_Q反馈,DFF4Q信号与clk0相与得到F;
DFF4_Q反馈到时钟域clk1,与SELECT相与,用clk1上升沿采样得到DFF1Q,之后得到DFF2Q,再用clk1下降沿采样得到DFF2_Q,DFF2Q信号与clk1相与得到输出E;
最终的输出为E与F的或,即输出clkout为无毛刺的时钟切换波形。
module glitch_DFF (
input clk0,
input clk1,
input select,
input rst_n,
output clkout
);
wire B;
reg DFF3Q, DFF4Q, DFF4_Q; //DFF4Q=Q,DFF4_Q=~Q
wire A;
reg DFF1Q, DFF2Q, DFF2_Q; //DFF2Q=Q,DFF2_Q=~Q
assign A = select & DFF4_Q;
assign B = ~select & DFF2_Q;
//第一级触发器用上升沿采样,选择信号与反馈信号的与运算
always@(posedge clk1 or negedge rst_n) begin
if(~rst_n)
DFF1Q <= 0;
else
DFF1Q <= A;
end
//第二级触发器用下降沿采样
always@(negedge clk1 or negedge rst_n) begin
if(~rst_n) begin
DFF2Q <= 0;
DFF2_Q <= 1;
end
else begin
DFF2Q <= DFF1Q;
DFF2_Q <= ~DFF1Q;
end
end //====================================================================
//第一级触发器用上升沿采样,选择信号与反馈信号的与运算
always@(posedge clk0 or negedge rst_n) begin
if(~rst_n)
DFF3Q <= 0;
else
DFF3Q <= B;
end
//第二级触发器用下降沿采样
always@(negedge clk0 or negedge rst_n) begin
if(~rst_n) begin
DFF4Q <= 0;
DFF4_Q <= 1;
end
else begin
DFF4Q <= DFF3Q;
DFF4_Q <= ~DFF3Q;
end
end
wire E, F;
assign E = clk1 & DFF2Q;
assign F = clk0 & DFF4Q;
assign clkout = E | F;
endmodule
参考资料:
https://www.eetimes.com/techniques-to-make-clock-switching-glitch-free/
- 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 数组属性和方法
- leetcode栈之二叉树的前序遍历
- 解决Linux下Mysql5.7忘记密码问题
- CentOS8.0 安装配置ftp服务器的实现方法
- Linux实现自动登录的实例讲解
- Linux中date命令转换日期提示date: illegal time format问题解决
- leetcode队列之最近的请求次数
- 安防视频云服务EasyCVR集成海康SDK时语音对出现杂音问题,如何解决?
- arm linux利用alsa驱动并使用usb音频设备
- linux 磁盘转移空间的方法
- 详解git中配置的.gitignore不生效的解决办法
- Apache Thrift环境配置
- CentOS 7更新时出现:Multilib version problems问题的解决方法
- Linux模拟网络丢包与延迟的方法
- centos6.5通过yum安装nginx
- Linux系统利用cp命令实现强制覆盖功能的方法