时钟切换基本模型,本文围绕“ 基本组合电路切换、解决前毛刺切换、解决后毛刺切换”三方面完成时钟无缝切换。
一、组合逻辑 时钟切换
组合逻辑切换,本质就是二选一多路器
如下图,CLK_SEL 0与1分别控制时钟CLK_A CLK_B输出。
组合逻辑输出只跟当前输入状态有关,CLK_SEL异步不可控导致输出毛刺或不可控亚稳态。
二、时序逻辑 时钟切换
时序逻辑能够去除亚稳态以及毛刺,那么,我们把CLK_SEL同步到对应时钟时域,看能否解决问题。
1.代码部分
module glitch_free(
CLK_A,
CLK_B,
RST_n,
CLK_SEL,
CLK_OUT
);
input CLK_A;
input CLK_B;
input RST_n;
input CLK_SEL;
output CLK_OUT;
//sync clk_sel to clka and clkb
reg sync_sel_a;
reg sync_sel_b;
always @(posedge CLK_A or negedge RST_n)
if(!RST_n)
sync_sel_a<=1'b1;
else
sync_sel_a<=CLK_SEL;
//sync clk_sel to clka and clkb
always @(posedge CLK_B or negedge RST_n)
if(!RST_n)
sync_sel_b<=1'b0;
else
sync_sel_b<=~CLK_SEL;
assign CLK_OUT=(CLK_A&&sync_sel_a)||(CLK_B&&sync_sel_b);
endmodule
2.分析 综合 打开RTL视图
vivado TCL命令框分步输入如下命令,并回车,得到如下图。
1.reset_run synth_1
2.launch_runs synth_1 -jobs 4
3.synth_design -rtl -name rtl_1
3.仿真(tb代码见第五部分)
如下图所示,显然,此方法不能满足设计要求。这是为什么呢?
(仔细看,这里很多网络教程都讲的不是清楚)
原因:
尽快clk_sel信号发生跳变,但是有如下两点需要注意。
1.clk_sel信号同步到clka,会有一拍延迟。即sync_sel_a 信号延迟一拍
2.clk_sel信号同步到clkb,会有一拍延迟。即sync_sel_b 信号延迟一拍
因此 当进行切换时候可能存在上一个时钟状态sync_sel_x仍然有效或sync_sel_a和sync_sel_b同时有效(只有下一个时钟周期才能稳定输出符合设计的波形)。
assign CLK_OUT=(CLK_A&&sync_sel_a)||(CLK_B&&sync_sel_b);
解惑:
clk_sel同步到两个时钟域,都需要打一拍延迟。此拍虽然解决了组合逻辑引起的毛刺和亚稳态,但是打拍延迟却导致了新的毛刺。
三、反馈电路 时钟切换
解决双时钟选择信号同时有效,确保同一时刻只有一个时钟能够被选择输出。
1.代码部分
module glitch_free(
CLK_A,
CLK_B,
RST_n,
CLK_SEL,
CLK_OUT
);
input CLK_A;
input CLK_B;
input RST_n;
input CLK_SEL;
output CLK_OUT;
reg negedge_sel_a;
reg sync_sel_a;
reg negedge_sel_b;
reg sync_sel_b;
//sync clk_sel to clka and clkb
always @(posedge CLK_A or negedge RST_n)
if(!RST_n)
sync_sel_a<=1'b1;
else
sync_sel_a<=CLK_SEL&&(~negedge_sel_b);
//sync clk_sel to clka and clkb
always @(posedge CLK_B or negedge RST_n)
if(!RST_n)
sync_sel_b<=1'b0;
else
sync_sel_b<=(~CLK_SEL&&(~negedge_sel_a));
//gen negedge control
always @(negedge CLK_A or negedge RST_n)
if(!RST_n)
negedge_sel_a<=1'b1;
else
negedge_sel_a<=sync_sel_a;
//gen negedge control
always @(negedge CLK_B or negedge RST_n)
if(!RST_n)
negedge_sel_b<=1'b0;
else
negedge_sel_b<=sync_sel_b;
assign CLK_OUT=(CLK_A&&negedge_sel_a)||(CLK_B&&negedge_sel_b);
endmodule
2.分析 综合 打开RTL视图
vivado TCL命令框分步输入如下命令,并回车,得到如下图。
1.reset_run synth_1
2.launch_runs synth_1 -jobs 4
3.synth_design -rtl -name rtl_1
3.仿真(tb代码见第五部分)
如下图所示,显然,此方法能满足设计要求。这又是为什么呢?
(仔细看重点解释)
当前时钟在下降沿时候关闭,并且反馈到待切换时钟域,待切换时钟域在下降沿开启输出。就是我关了,告诉你之后,你才可以开。我不管,且不通知你开,你永远没机会开。文章来源:https://www.toymoban.com/news/detail-409811.html
四、时钟切换 总结
同时钟域,可采用vivado 源语 BUFGMUX等切换。
本节针对时钟速率不高 异步 同步 时域切换。
同时,教会大家如何使用反馈信号。文章来源地址https://www.toymoban.com/news/detail-409811.html
五、仿真代码(例程通用)
module glitch_free_tb();
reg clka;
reg clkb;
reg rst_n;
reg sel;
wire clk_out;
glitch_free glitch_reg(
.CLK_A(clka),
.CLK_B(clkb),
.RST_n(rst_n),
.CLK_SEL(sel),
.CLK_OUT(clk_out)
);
initial begin
clka=1;
clkb=1;
end
wire clk;
always #3000 clka=~clka;
always #2800 clkb=~clkb;
initial begin
rst_n=0;
#1001_00;
rst_n=1;
sel=1;
#1001_00;
sel=0;
#1001_00;
sel=1;
#1001_00;
sel=0;
#1000_00;
$stop;
end
endmodule
到了这里,关于FPGA(Verilog)时钟无缝切换设计与验证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!