电子说
在现代芯片中,芯片运行时有必要在两个不同的时钟之间切换。如果我们使用普通的多路复用器进行切换时钟会发生什么?多路复用器有一个名为 SELECT 的控制信号,该信号在设置为“零”时将 CLK1 传播到输出,或者在设置为“1”时将 CLK2 传播到输出。当 SELECT 值更改时,由于输出从当前时钟源立即切换到下一个时钟源,可能会引起毛刺。
图1普通多路复用器
verilog代码:
module clk_select1(
input clk1,
input clk2,
input rst_n,
input sel,
output out_clk
);
assign out_clk = sel?clk2:clk1;
endmodule
图2时钟切换的正常多路复用器实现的波形(有毛刺)
假如时钟由 clk1 切换到 clk2,且切换时刻为 clk1 输出电平为高的时候,此时立即切换时钟就会导致输出时钟出现毛刺(glitch)。在两个时钟电平相反的时候切换时钟,肯定有毛刺;电平相同的时候,即使不产生毛刺,时钟切换后的第一个时钟的周期或占空比也不是理想的。所以,为避免毛刺的产生,需要在两个时钟都为低电平的时候进行时钟切换。
时钟切换方案的设计思路
1.先关断当前选择的时钟,再新选择的时钟;
2.在时钟为低电平的时钟进行时钟切换;
一种典型的时钟切换威廉希尔官方网站 如下所示。其中左边部分存在一个 互锁结构 ,与SR锁存器结构类似,不同之处是中间嵌入了2个下降沿触发器,这个设计非常巧妙。 互锁威廉希尔官方网站 保证了当输出稳定后,其两端的输出值是互斥的 。插入dff后,威廉希尔官方网站 有了记忆功能, 将互锁的逻辑用下降沿DFF抓一拍后反馈给另一侧,即使当目前select发现变化,只要当前选择的时钟下降沿没有到来时,不会切换时钟,只有当select发生变化,且当前选择的时钟下降沿到来后,关闭当前选择的时钟系统,等到另一个时钟系统下降沿到来时,切换至另一个时钟系统,完成时钟无毛刺切换 ,具体如下:
图3无毛刺时钟多路复用器
verilog代码:
module clk_select2(
input clk1,
input clk2,
input rst_n,
input sel,
output out_clk
);
reg ff1;
reg ff2;
always @(negedge clk1 or negedge rst_n) begin
if(!rst_n)
ff1 <= 1'b0;
else begin
ff1 <= ~ff2 & !sel;
end
end
always @(negedge clk2 or negedge rst_n) begin
if(!rst_n)
ff2 <= 1'b0;
else begin
ff2 <= ~ff1 & sel;
end
end
assign out_clk = (ff1 & clk1) | (ff2 & clk2);
endmodule
考虑到选择信号有可能是异步信号,需要在时钟选择信号的缓存触发器之前加两级触发器进行同步处理,来减少亚稳态的传播,结构图如下。该时钟切换威廉希尔官方网站 更具有普遍性。
图4无毛刺时钟多路复用器(使用双同步器)
verilog代码:
module clk_select3(
input clk1,
input clk2,
input rst_n,
input sel,
output out_clk
);
reg ff1,ff1_d;
reg ff2,ff2_d;
always @(negedge clk1 or negedge rst_n) begin
if(!rst_n)
{ff1,ff1_d} <= 2'b00;
else begin
ff1_d <= ~ff2 & !sel;
ff1 <= ff1_d;
end
end
always @(negedge clk2 or negedge rst_n) begin
if(!rst_n) {ff2,ff2_d} <= 2'b00;
else begin
ff2_d <= ~ff1 & sel;
ff2 <= ff2_d;
end
end
assign out_clk = (ff1 & clk1) | (ff2 & clk2);
endmodule
全部0条评论
快来发表一下你的评论吧 !