2019年5月13日

glitch-free的两个时钟切换电路。


可以看到这是一个星期之前的题目了,现在才抽空做,把这篇颠倒个顺序吧,也是最后一天了,以后的题目都是讨论性质的,不会以第多少天的形式来写了。


这个题目是设计一个时钟切换电路,且使得切换过程中没有毛刺产生。

为了理解无毛刺的时钟切换电路,先讨论下时钟切换时产生毛刺的原因:

有毛刺的时钟切换电路

如下原理图1a:

图1a: Clock switching multiplexer

如图1a所示,这个时钟切换电路是一个纯组合逻辑,输出时钟(OUT CLOCK)由选择信号(SELECT)控制,当SELECT为1时输出CLK1,反之,输出CLK0.

看似很简单,实现了时钟的切换,实则存在着很大的隐患,如下图1b所示:

图1b

图1b中的时序图显示了当SELECT控制信号发生变化时,输出OUT CLOCK如何产生毛刺。 这种开关(SELECT)的问题在于开关控制信号可以相对于源时钟随时改变,因此产生斩波输出时钟或在输出端产生毛刺的可能性。

对上图的Verilog描述:

assign outclk = (clk1 & select) | (~select & clk0);


相关时钟源的毛刺保护

成相互倍数的时钟切换电路无毛刺方案:

图 2a 显示了防止源时钟相互倍数的时钟开关输出出现毛刺的解决方案。在每个时钟源的选择路径中插入一个负边沿触发的D触发器。 在时钟的下降沿采样选择控制(SELECT),以及仅在首先使其他时钟无效后使能选择(SELECT),可以提供出色的输出保护。

貌似英文原文的更容易理解:

A solution to prevent glitch at the output of a clock switch where source clocks are multiples of each other is presented in Figure 2. A negative edge triggered D flip-flop is inserted in the selection path for each of the clock sources. Registering the selection control at negative edge of the clock, along with enabling the selection only after other clock is de-selected first, provides excellent protection against glitches at the output.

图2a

下面简单的解释下这个电路:

当SELECT为0时,明显CLK1的那部分通路到输出无效,仅仅看下半部分电路即可,在CLK0的下降沿采样SELECT(取反后)信号,与CLK0相与之后输出;

当SELECT为1时,同理上半部分电路有效;

以后都不是问题,需要重点分析的是当SELECT在任意时刻切换的时候,输出会不会出现毛刺?

如下图2b:

首先SELECT为0,也就是在CLK0的下降沿采样寄存SELECT(取反后)信号与CLK0相与,输出时钟为CLK0;

当在图中时刻SELECT由低电平变为高电平,此时未到CLK0的下降沿,寄存器的输出还将一直是高电平(SELECT之前为0,取反为1),当到达CLK0的下降沿时刻,采样到SELECT为高电平,那么!SELECT为0,也就是上半部分电路从此无效,上半部分电路有效,此时需要等到CLK1的下降沿采样SELECT值,在此之前,输出仍未CLK0,到达CLK1的下降沿后,输出变成了CLK1和SELECT的与,也就是CLK1。由图可见,输出时钟完美切换,并没有出现斩波信号以及毛刺。

从原文中截出一段话供参考:

Registering the select signal at negative edge of the clock guarantees that no changes occur at the output while either of the clocks is at high level, thus protecting against chopping the output clock. Feedback from one clock's selection to the other enables the switch to wait for de-selection of the Current Clock before starting the propagation of the Next Clock, avoiding any glitches.

在时钟的下降沿寄存选择信号(SELECT)可确保在任一时钟处于高电平时输出端不会发生变化,从而防止斩波输出时钟(意思是下降沿寄存,可以保证下降沿到来之前输出端保持不变,这样就不会斩断当前时钟了)。 从一个时钟的选择到另一个时钟的反馈使开关能够在开始传播下一个时钟之前等待取消选择当前时钟,从而避免任何毛刺(意思是即使当前SELECT突然变化了,也必须等待到当前时钟的下降沿到来才能去使当前时钟无效,这一段时间就避免了毛刺(glitch))。

该电路中有三个时序路径需要特别考虑 -  SELECT控制信号到两个负边沿触发触发器中的任何一个,DFF0输出到DFF1的输入,DFF1的输出到DFF0的输入。 如果这三条路径中的任何一条路径上的信号与目标触发器时钟的捕获边缘同时发生变化,则该寄存器的输出很可能变为亚稳态,这意味着它可能会进入理想的0和1两者之间的状态。

(例如SELECT在CLK0或者CLK1的下降沿变化,就会导致亚稳态;)

时钟多路复用器和另一个触发器的使能反馈可以不同地解释亚稳态。 因此,需要将触发器的捕获边缘和SELECT信号的发射边缘彼此分开以避免任何异步接口。 这可以通过使用适当的多周期保持约束或最小延迟约束来容易地实现,因为在两个时钟之间已知定时关系。

这里提到了,多周期保持约束?这是以后需要补充的功课!

对上图的Verilog描述为:

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 outclk = (out1 & clk1) | (out0 & clk0);


针对无关时钟源的毛刺保护

先前避免时钟开关输出处的毛刺的方法需要两个时钟源彼此的倍数,使得用户可以避免信号与任一时钟域异步。在该实现中没有处理异步信号的机制。

这导致实现具有同步器电路的时钟开关的第二种方法,以避免由异步信号引起的潜在的亚稳态。当两个时钟源彼此完全无关时,异步行为的源可以是SELECT信号或从一个时钟域到另一个时钟域的反馈。

如图3所示,通过为每个时钟源添加一个额外级的正边沿触发触发器来提供针对亚稳态性的保护。每个选择路径中的正边沿触发触发器以及现有的负边沿触发触发器防止潜在的亚稳态性,这可能是由异步SELECT信号或从一个时钟域到另一个时钟域的异步反馈引起的。

同步器只是两级触发器,其中第一级通过锁定数据来帮助稳定数据,然后将数据传递到下一级,由电路的其余部分解释。

第三种相对而言,比较难,但是我既然写这篇博文了,还是想谈谈自己的愚见,上图头上的最后一句话是:

同步器只是两级触发器,其中第一级通过锁定数据来帮助稳定数据,然后将数据传递到下一级,由电路的其余部分解释。

可以知道,第一个触发器采样数据寄存,然后到第二个触发器输出第一个触发器寄存的数据。

再看上图时序图,在CLK0的第二个时钟上升沿,采样数据为SELECT为1,但是要等到时钟的下降沿才被输出,这时CLK0的传播到此结束。到了CLK1的时代,也不难理解下面的行为了。

对上图的Verilog描述为:

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);

总结:

通过使用本文中介绍的设计技术,可以通过非常小的开销避免在时钟源之间切换时在时钟线上产生毛刺的危险。 这些技术完全可扩展,可以扩展到时钟切换两个以上的时钟。 对于多个时钟源,每个时钟源的选择信号将通过所有其他源的反馈启用。

参考文献:Techniques to make clock switching glitch free

Glitch Free时钟切换技术

【Verilog HDL 训练】第 14 天(glitch-free的两个时钟切换电路)相关推荐

  1. 无毛刺的时钟切换电路(Glitch-free clock switching circuit)设计(Verilog)

    从秋招的经验来看,Verilog设计类的题目,如:奇偶分频,状态机,序列检测,波形产生,跨时钟域处理,门控时钟,同步FIFO,格雷码与二进制码转换,异步复位同步释放,时钟切换,异步FIFO等,其中最为 ...

  2. 【Verilog HDL 训练】第 11 天(分频电路)

    设计一个占空比50%的三分频电路. 针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的.针对其中的错误,我令立博文记录之:[ Verilog ]alw ...

  3. 【Verilog HDL 训练】第 06 天(边沿检测)

    1. 复习verilog语法 [选做题] - reg和wire的区别 寄存器数据类型 Verilog中规定,凡是在程序块中被赋值的变量,都必须是寄存器类型的.(程序块:例如always块) 这里未免还 ...

  4. 【Verilog HDL 训练】第 09 天(按键消抖)

    5月7日 按键防抖 1. 用verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz. 在编写Verilog代码之前,先分析下一些前提问题,首先是几个按键(1个,多个),我们以1个和三 ...

  5. 【Verilog HDL 训练】第 05 天(序列检测)

    1. dff和latch有什么区别. 锁存器是一种对脉冲电平(也就是0或者1)敏感的存储单元电路,而触发器是一种对脉冲边沿(即上升沿或者下降沿)敏感的存储电路. "触发器" 泛指一 ...

  6. c语言实现按键的抖动与消除,【Verilog HDL 训练】第 09 天(按键消抖)

    5月7日 按键防抖 1. 用verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz. 在编写Verilog代码之前,先分析下一些前提问题,首先是几个按键(1个,多个),我们以1个和三 ...

  7. 【Verilog HDL 训练】第 04 天(竞争、冒险、译码等)

    1. 什么是竞争和冒险? 记得我刚学FPGA那会,恶补基础知识,其中之一就是竞争与冒险,我参考了<FPGA之道>,记录了几篇博客: [ FPGA ]组合逻辑中的竞争与险象问题(一) 第一篇 ...

  8. 【Verilog HDL 训练】第 13 天(存储器、SRAM)

    存储器. 1. rom,ram,flash,ddr,sram,dram,mram..列举并解释一下这些名词. 2. 用verilog实现一个深度为16,位宽8bit的单端口SRAM.搭建一个仿真环境, ...

  9. 【Verilog HDL 训练】第 10 天(PWM 呼吸灯)

    5月8日 PWM 用verilog实现PWM控制呼吸灯.呼吸周期2秒:1秒逐渐变亮,1秒逐渐变暗.系统时钟24MHz,pwm周期1ms,精度1us. 今天的题目我是第一次见,答案借鉴大神的:Veril ...

最新文章

  1. NLP-基础知识-004(生成模型)
  2. 开发函数计算的正确姿势——轻松解决大依赖部署
  3. Eclipse使用添加tomcat后,默认部署目录不是tomcat/webapps,修改方法如下
  4. linux mint 用户管理,Linux Mint 新工具:将网站转变为独立的应用
  5. 计算机网络——CSMA/CD最小帧长相关题目
  6. ResultSet转换为List的方法
  7. php之简单的文件管理(基本功能
  8. 如何在官网上下载MySQL驱动--最新方法
  9. ArcGIS教程 - 5 地图可视化
  10. 数字信号处理-基础一
  11. vscode 初始化HTML结构
  12. HBuilder手机Iphone运行提示“未受信用的企业级开发者”
  13. 慕测平台的使用—— 在eclipse上安装mooctest插件
  14. vue实现tagsview多页签导航功能
  15. Openstack中给windows虚拟机加载virtion驱动
  16. pygame 躲避僵尸
  17. CUDA:使用CUFFT来合成和 实时渲染海洋表面实例
  18. Codeforces Round #807 (Div. 2)A~E个人题解
  19. SSM_jsp实现汽车销售管理系统
  20. Hadoop简介和家族成员介绍

热门文章

  1. 训练和验证准确性_通过沉浸式虚拟现实观察动作增强运动想象训练
  2. oracle的shell命令,Shell实现的Oracle启动脚本分享
  3. 图片旋转对于识别模式带来的变化
  4. 利用WiFi模块实现MicroPython远程开发
  5. 连续举办了十七年的韩国大学生智能车竞赛谢幕了
  6. 角度编码器 ST-3806-15-RS
  7. 基于STC8H1K28的双轴机械臂驱动模块:步进电机42HS348E,BH32角度传感器
  8. 影响声音定位的几个因素
  9. java华农组合模式,华农《数据库应用》往年考试例卷
  10. anaconda自带python_基于anaconda来解决Python安装问题