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的源语有何异同。

以上。

posted @ 2022-01-13 17:56  小翁同学  阅读(450)  评论(0编辑  收藏  举报