题目描述:
存在两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频,现在要设计一个切换电路,sel选择时候进行切换,要求没有毛刺。
解:
直接采用选择逻辑对时钟进行切换的电路图如下所示。
假如时钟选择信号 sel_clk1 与两个时钟都是异步的,那么时钟切换时刻就是任意的。假如时钟由 clk1 切换到 clk2,且切换时刻为 clk1 输出电平为高的时候,此时立即切换时钟就会导致输出时钟出现毛刺(glitch)。波形示意图如下:
下图显示了防止源时钟相互倍数的时钟开关输出出现毛刺的解决方案。在每个时钟源的选择路径中插入一个负边沿触发的D触发器。 在时钟的下降沿采样选择控制(SELECT),以及仅在首先使其他时钟无效后使能选择(SELECT),可以提供出色的输出保护 :
下面简单的解释下这个电路:
当SELECT为0时,明显CLK1的那部分通路到输出无效,仅仅看下半部分电路即可,在CLK0的下降沿采样SELECT(取反后)信号,与CLK0相与之后输出;当SELECT为1时,同理上半部分电路有效;
需要重点分析的是当SELECT在任意时刻切换的时候,输出会不会出现毛刺?
首先SELECT为0,也就是在CLK0的下降沿采样寄存SELECT(取反后)信号与CLK0相与,输出时钟为CLK0;
当在图中时刻SELECT由低电平变为高电平,此时未到CLK0的下降沿,寄存器的输出还将一直是高电平(SELECT之前为0,取反为1),当到达CLK0的下降沿时刻,采样到SELECT为高电平,那么!SELECT为0,也就是下半部分电路从此无效,上半部分电路有效,此时需要等到CLK1的下降沿采样SELECT值,在此之前,输出仍未CLK0,到达CLK1的下降沿后,输出变成了CLK1和SELECT的与,也就是CLK1。由图可见,输出时钟完美切换,并没有出现斩波信号以及毛刺。
在时钟的下降沿寄存选择信号(SELECT)可确保在任一时钟处于高电平时输出端不会发生变化,从而防止斩波输出时钟(意思是下降沿寄存,可以保证下降沿到来之前输出端保持不变,这样就不会斩断当前时钟了)。 从一个时钟的选择到另一个时钟的反馈使开关能够在开始传播下一个时钟之前等待取消选择当前时钟,从而避免任何毛刺(意思是即使当前SELECT突然变化了,也必须等待到当前时钟的下降沿到来才能去使当前时钟无效,这一段时间就避免了毛刺(glitch));
该电路中有三个时序路径需要特别考虑
1、 SELECT控制信号到两个负边沿触发触发器中的任何一个;
2、DFF0输出到DFF1的输入;
3、DFF1的输出到DFF0的输入。
如果这三条路径中的任何一条路径上的信号与目标触发器时钟的捕获边缘同时发生变化,则该寄存器的输出很可能变为亚稳态,这意味着它可能会进入理想的0和1两者之间的状态。
以上理解借鉴了两位大佬,我只是整理了一下,以我的理解来整合了一下:
1.(数字 IC 设计)5.4 时钟切换 - 知乎 (zhihu.com)
2. 时钟切换中的毛刺(glitch)_dxz44444的博客-CSDN博客_时钟毛刺
完整代码如下:
在这段代码中,需要注意使用的是哪一个时钟;
`timescale 1ns/1ns
module huawei6(
input wire clk0 ,
input wire clk1 ,
input wire rst ,
input wire sel ,
output reg clk_out
);
//*************code***********//
reg q0;
reg q1;
always@(negedge clk0 or negedge rst)
if(rst == 1'b0)
q0 <= 1'b0;
else
q0 <= ~sel & ~q1;
always@(negedge clk1 or negedge rst)
if(rst == 1'b0)
q1 <= 1'b0;
else
q1 <= sel & ~q0;
always@(*)
if(rst == 1'b0)
clk_out <= 1'b0;
else
clk_out <= (q0 & clk0)|(q1 & clk1);
//*************code***********//
endmodule