0.引言

随着越来越多的多频时钟被应用在今天的芯片中,尤其是在通信领域中,经常需要在芯片运行时切换时钟线的源时钟。这通常是通过在硬件中复用两个不同的频率时钟源,并通过内部逻辑控制多路选择器选择线来实现的。

这两个时钟频率可能彼此完全无关联,或者它们可以是彼此之间存在倍数的关系。在这两种情况下,都有可能在切换时在时钟线上产生毛刺(glitch)。时钟线上的毛刺对整个系统来说是十分危险的,因为它可以被一些寄存器解释为捕获时钟边缘(满足建立时间等),而其他寄存器忽略此毛刺,则整个系统数据出现混乱。

本文将会介绍两种时钟切换方法,分别对应两种情况,第一种时两个时钟源的频率呈倍数关系,第二种是两个时钟源完全没有关系。

1.时钟切换的毛刺问题

切换电路:

图1:实时时钟切换

  电路语言描述:

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

  当SELECT变化时,可能会由于从当前时钟源的输出立即切换到下一个时钟源而引起毛刺。当前时钟(Current Clock)是当前SELECT选择的时钟源,而下一个时钟(Next Clock)是对应于新SELECT值的时钟源。

图2:实时时钟切换时序

  仿真结果:

图3:实时时钟切换仿真

  图2中的时序图和图3的仿真结果显示了当SELECT控制信号发生变化时,输出时钟如何产生毛刺(glitch)。这种切换导致的问题是切换控制信号(SELECT)可以相对于源时钟的任何时间发生改变(本质是SELECT信号完全异步),从而产生了切断输出时钟或在输出处产生毛刺的潜在可能。SELECT控制信号最有可能是由两个源时钟中的任一个驱动的寄存器生成的,这意味着它要么与两个时钟具有已知的时序关系,要么这两个时钟是彼此的倍数,或者如果源时钟不存在任何的关系,则它可能与至少一个时钟异步。

  在不知道这些时钟的频率或相位关系的情况下,需要避免在任一时钟的高状态期间进行切换。固定延迟可用于引起两个源时钟的开始和停止时间之间的间隔,但仅当两个时钟源之间存在固定关系时可以使用。它不能在输入频率未知或时钟不相关的情况下使用。

2.相关时钟切换的毛刺避免Glitch protection for related clock sources

  在图4中给出了防止时钟切换导致输出毛刺的解决方案,其中两个时钟源频率成倍数关系。在每个时钟源的选择路径中插入下降沿触发的D触发器。在时钟的下降沿上用寄存器寄存一下SELECT控制信号,以及仅在其他时钟被取消选择之后才启用选择(既先屏蔽旧时钟,然后在开启新时钟),从而在输出端防止毛刺的产生。

  在时钟的下降沿处寄存SELECT信号,保证在任意一个时钟处于高电平时,时钟输出(CLOCK_OUT)中不发生变化,从而防止对输出时钟进行切割(Chopping)。从一个时钟选择到另一个时钟的反馈使得在开始下一个时钟的传播之前必须等待当前时钟的取消,从而避免任何毛刺的产生。

图5:相关时钟无毛刺切换电路

图6:相关时钟无毛刺切换时序

  电路语言描述:

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

  图6显示了SELECT信号从0到1的转换时,首先在CLK0的下降沿时停止了CLK0的输出,然后在CLK1的下降沿处的开始输出CLK1时钟到OUT CLOCK。

  仿真结果:

  亚稳态问题:

  在该电路中,有三个时序路径需要特别考虑:SELECT控制信号到两个下降沿触发触发器中的任一个、DFF0输出到DFF1的输入以及DFF1的输出到DFF0的输入。如果在这三个路径中的任何一个信号与目标触发器时钟的捕获边缘(这里是下降沿)同时变化,那么该寄存器的输出可能变为亚稳态,这意味着它可能进入理想的“1”和理想的“0”之间的状态。时钟多路复用器和另一触发器的使能反馈可以对亚稳态进行不同的解释。因此在异步接口中,需要把两个触发器的捕获边沿和SELECT信号的变换沿(SELECT信号的上升沿)分开,避免亚稳态的产生。这可以容易地通过使用适当的多周期保持约束或最小延迟约束(时序约束)来实现,因为两个时钟之间的时序关系是已知的。

3.时钟容错

  在芯片启动时间,两个触发器DFF0和DFF1都应该重置为“0”状态,使得时钟中的任何一个都不被作为初始传播。通过在“零”状态下启动触发器,将容错建立在时钟切换中。

  假设其中一个时钟由于启动时的故障而没有切换。如果与故障时钟相关联的触发器已在“1”状态启动,则它将阻止选择其他时钟作为下一个时钟,并且由于缺少运行时钟,其自身状态不可改变。通过以“零”状态启动两个触发器,即使其中一个源时钟未运行,仍然能够将另一个好的时钟传播到开关的输出,保证输出时钟的稳定。

4.非相关时钟切换的毛刺避免Glitch protection for unrelated clock sources

  上述避免时钟切换输出处的毛刺的方法需要两个时钟源彼此的倍数关系,使得用户可以避免信号与任一时钟域异步。 但在该实现中没有处理异步信号的机制(上面的办法只是通过时序约束解决异步的问题,并没有真正解决异步的问题)。这引出了实现具有同步器电路的时钟切换的第二种方法,以避免由异步信号引起的潜在的亚稳态。 当两个时钟源彼此完全无关时,异步发送的源头可以是SELECT信号或从一个时钟域到另一个时钟域的反馈。

  第二种方法是针对两个异步时钟源的切换,这个方法是在第一种方法的基础上,在选择路径上再插入一个上升沿触发D触发器,这是为了针对对两个异步时钟源产生的反馈信号以及异步信号SELECT,对选择信号进行同步处理,这样即使是两个异步的时钟源进行切换,也可以避免亚稳态的产生。同步器只是两级触发器,其中第一级通过锁定数据来帮助稳定数据,然后将数据传递到下一级,由电路的其余部分解释。

图7:非相关时钟切换毛刺避免电路

图8:非相关时钟切换毛刺避免时序

  电路语言描述:

reg clk0_f , clk0_ff;
reg clk1_f , clk1_ff; always@(posedge clk0 or negedge rst_n)begin
if (rst_n == 1'b0)
clk0_f <= 1'b0;
else
clk0_f <= (~select) & (~clk1_ff);
end
always@(negedge clk0 or negedge rst_n)begin
if (rst_n == 1'b0)
clk0_ff <= 1'b0;
else
clk0_ff <= clk0_f;
end always@(posedge clk1 or negedge rst_n)begin
if (rst_n == 1'b0)
clk1_f <= 1'b0;
else
clk1_f <= (select) & (~clk0_ff);
end
always@(negedge clk1 or negedge rst_n)begin
if (rst_n == 1'b0)
clk1_ff <= 1'b0;
else
clk1_ff <= clk1_f;
end assign clk_out = (clk0_ff & clk0) | (clk1_ff & clk1);

  仿真电路:

  仿真结果:

图9:非相关时钟切换毛刺避免仿真结果

  仿真结果十分明显。

5.结论

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

参考:https://www.eetimes.com/techniques-to-make-clock-switching-glitch-free/Techniques to make clock switching glitch-free

时钟切换电路(无毛刺)——clock switching glitch free的更多相关文章

  1. 单片机成长之路(51基础篇) - 023 N76e003 系统时钟切换到外部时钟

    N76e003切换到外部时钟的资料很少(因为N76e003的片子是不支持无源晶振的,有源晶振的成本又很高,所以网上很少有对N76e003的介绍).有图有真相: 代码如下: main.c #includ ...

  2. RS485自动收发切换电路 [原创www.cnblogs.com/helesheng]

    RS485是最常见的一种远距离可靠传输和组网的UART串口信号接口协议.与同样传输UART串口信号的RS422协议相比,RS485使用半双工通信,即只有一个信道,在同一时刻要么从A到B,要么从B到A传 ...

  3. 电池和Adapter切换电路改进实验(转)

    源:电池和Adapter切换电路改进实验 目的:很多单电池的机器在大负载的情况下,如把背光开到最亮,运行3D游戏,此时拔DC电源很容易出现机器死机,或花屏现象: 原因:Q5的导通时间不够,希望通过G极 ...

  4. 单片机成长之路(stm8基础篇)- 025 stm8 时钟切换

    stm8 时钟切换; /************************************ 时钟设置 ************************************/ // 时钟 0: ...

  5. 电池和Adapter切换电路改进实验

    目的:很多单电池的机器在大负载的情况下,如把背光开到最亮,运行3D游戏,此时拔DC电源很容易出现机器死机,或花屏现象: 原因:Q5的导通时间不够,希望通过G极的快速放电,加快到导通时间: 修改前的电路 ...

  6. tab标签切换(无炫效果,简单的显示隐藏)

    从最简单的效果开始写起,一个简单的JQ写出tab切换效果,很静态,没有任何的轮转特效,单纯的点击标签显示区域块. 附上代码: HTML: <div class="wrapper&quo ...

  7. JS的checkbox状态切换dom无变化

    今天调试checkbox,手动加上checked="checked"和去掉,都对实际页面没有产生影响 搜索一番 1.对radio .checkbox 来说说,checked属性可以 ...

  8. 你要的fpga&数字前端笔面试题都在这儿了

    转自http://ninghechuan.com 你要的FPGA&数字前端笔面试题来了 FPGA&ASIC基本开发流程 题目:简述ASIC设计流程,并列举出各部分用到的工具. 勘误:C ...

  9. 时钟分组的用法---Clock Groups

    时钟分组的用法---Clock Groups 哪些时钟互相之间需要分组 同步时钟: 异步时钟: 不确定的时钟: 即使是从同一个MMCMs出来的时钟,有可能为不确定关系的时钟,如果它们之间的相位没有一个 ...

  10. MSP430 G2553 基本时钟模块+ (Basic Clock Module+)

    一.时钟源 MSP430的Basic Clock Module+支持的时钟源有: DCOCLK:内部数字控制振荡器,Internal digitally contrlled oscillator.所有 ...

随机推荐

  1. js 获取当前时间转换时间戳 (毫秒)

    js 当前时间转换毫秒数 五种方式   var date = new Date().getTime(); var date = new Date().valueOf(); var date = +ne ...

  2. JavaScript:如何知道一个变量的数据类型?:typeof

    使用typeof去查看一个变量的数据类型,如下图所示,展示了JS的七大基础数据类型和对象: 这里有必要提一下: 函数也是一个对象,但是函数的特殊性,使得在使用typeof去判断其类型的时候,会输出fu ...

  3. [seaborn] seaborn学习笔记11-绘图实例(3) Drawing example(3)

    11 绘图实例(3) Drawing example(3)(代码下载) 本文主要讲述seaborn官网相关函数绘图实例.具体内容有: Plotting a diagonal correlation m ...

  4. [OpenCV实战]44 使用OpenCV进行图像超分放大

    图像超分辨率(Image Super Resolution)是指从低分辨率图像或图像序列得到高分辨率图像.图像超分辨率是计算机视觉领域中一个非常重要的研究问题,广泛应用于医学图像分析.生物识别.视频监 ...

  5. Fast RCNN论文阅读笔记

    1.Introduction 1.1 RCNN 和SPPnet RCNN有几个显著的问题:1.训练的时候是多阶段的训练,分别分三个阶段训练卷积层.SVM.边框回归矩阵.2.训练很耗时.3.目标定位非常 ...

  6. DVWA靶场实战(二)——Command Injection

    DVWA靶场实战(二) 二.Command Injection: 1.漏洞介绍: Command Injection,中文叫做命令注入,是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令 ...

  7. ionic+vue+capacitor系列笔记--capacitor3.X和2.X+android自定义capacitor的JSbridge插件注册与使用(不同版本注册方式不同,返回值格式也不同,使用方法也不同)

    经过我的多番折腾,终于搞明白了这个东西的用法,不同版本的注册方法,使用方法都不一样,现在把这个折腾的结果记录下来,造福大家~ 首先编写一个类,然后注册,注意,这个和2.x不一样,2.x的时候我们会使用 ...

  8. angular组件共用服务打印日志父子组件传值2创建服务注入

  9. 解决node.js报错Invalid character in header content ["Content-Disposition"]

    遇到这种报错一般在于下载文件时候,如果Content-Disposition设置文件名有中文会出现此种问题,解决方案如下: 把第二段代码改为第一段,即可~~ 'Content-Disposition' ...

  10. Windows喝水记录工具v2.0

    Windows喝水记录工具v2.0 作者以前基本不喝水,后面体检出来身体出现了一些问题(肾结晶什么的),多喝水可以减轻甚至痊愈,由于没有喝水的习惯怕喝多或者喝少,所以做了这个桌面小工具,喝一杯记录一下 ...