题目
用verilog实现无毛刺时钟切换电路。输入sel,clka,clkb,sel为1时输出clka,sel为0时输出clkb
分析
如果单纯地在sel高是选择clka输出,sel为低时选择clkb输出,那么很有可能在时钟切换的时刻出现毛刺,这甚至会导致电路故障。所以要进行专门的时钟切换电路的设计,保证电路切换中不会有毛刺的出现,这一根本原理在时钟切换过程中,要在原时钟和待切换时钟的低电平进行切换。
这里分为两种情况:
- 时钟源为倍数关系
- 时钟源是异步时钟
第一种情况,用反馈结构的电路便能实现
第二种情况,在情况一的结构下加同步器来实现
代码
情况一:
module Change_Clk_Source(
input clk1,
input clk0,
input sel,
input rstn,
output outclk
)
reg out0,out1;
always @(negedge clk1 or negedge rstn)begin
if(!rstn)
out1 <= 0;
else
out1 <= ~out0 & sel;
end
always @(negedge clk0 or negedge rstn)begin
if(!rstn)
out0 <= 0;
else
out0 <= ~out1 & ~sel;
end
assign outclk = (out1 & clk1) | (out0 & clk0);
情况二
module Change_Clk_Source(
input clk1,
input clk0,
input sel,
input rstn,
output outclk
)
reg out0,out1;
reg out0_dly0,out0_dly1;
reg out1_dly0,out1_dly1;
always @(negedge clk1 or negedge rstn)begin
if(!rstn)begin
out1 <= 0;
out1_dly0 <= 0;
out1_dly1 <= 0;
end
else
out1 <= ~out0 & sel;
out1_dly0 <= out1;
out1_dly1 <= out1_dly0;
end
always @(negedge clk0 or negedge rstn)begin
if(!rstn)begin
out0 <= 0;
out0_dly0 <= 0;
out0_dly1 <= 0;
end
else begin
out0 <= ~out1 & ~sel;
out0_dly0 <= out0;
out0_dly1 <= out0_dly0;
end
end
assign outclk = (out1_dly1 & clk1) | (out0_dly1 & clk0);