FPGA中多时钟切换(无毛刺):通过代码的方式
前言
在实际的项目开发中,一个逻辑块在不同的时刻可能需由不同的时钟进行驱动。
比如存在clk1,clk2,有always@(posedge i_clk)需要执行,在0时刻使用clk1进行驱动,在1时刻使用clk2进行驱动,则需要进行时钟切换。
参考文档
Glitch free clock switching circuit design (Verilog)
流程
源语的方式:
Altera和XIlinx均提供了时钟切换的源语,不过相关的源语都有相应的限制。
代码的方式:
两个时钟切换最简单的使用sel就可以进行切换:
assign o_clk_sel = w_sel ? i_clk1 : i_clk0;
但上述方式显然会存在问题,产生时钟毛刺。因为w_sel跳变时刻是随机的。
参考上述链接中的结构进行编码并仿真:
代码可如下所示:
module clk_sel (
input i_clk_0 ,
input i_clk_1 ,
input i_sel ,
output o_clk_sel
);
reg r_clk_0_pos = 1'b0;
reg r_clk_0_neg = 1'b0;
reg r_clk_1_pos = 1'b0;
reg r_clk_1_neg = 1'b0;
always @(posedge i_clk_0)
begin
r_clk_0_pos <= ~r_clk_1_neg & i_sel;
end
always @(negedge i_clk_0)
begin
r_clk_0_neg <= r_clk_0_pos;
end
always @(posedge i_clk_1)
begin
r_clk_1_pos <= ~r_clk_0_neg & (~i_sel);
end
always @(negedge i_clk_1)
begin
r_clk_1_neg <= r_clk_1_pos;
end
wire w_clk_0;
wire w_clk_1;
assign w_clk_0 = r_clk_0_neg & i_clk_0;
assign w_clk_1 = r_clk_1_neg & i_clk_1;
assign o_clk_sel = w_clk_0 | w_clk_1;
endmodule
仿真:可以看到没有异常的毛刺产生。
当然,具体实际上板子还需验证。
Q:
不知道这种方法跟使用FPGA的源语有何异同。
以上。