要求:
用 Verilog 实现 glitch free 时钟切换电路。输入 sel,clka,clkb,sel 为 1 输出 clka,sel 为 0 输出 clkb。
module Change_Clk_Source ( input rst_n, input clk_a, input clk_b, input sel, output clk_o );
一、有毛刺写法
assign clk_o = sel ? clk_a : clk_b;
二、两个时钟是倍数关系
reg clk_a_vld; reg clk_b_vld; always @(negedge clk_a or negedge rst_n)begin if(!rst_n)begin clk_a_vld <= 0; end else begin clk_a_vld <= sel & ~clk_b_vld; end end always @(negedge clk_b or negedge rst_n)begin if(!rst_n)begin clk_b_vld <= 0; end else begin clk_b_vld <= ~sel & ~clk_a_vld; end end assign clk_o = (clk_a_vld & clk_a) | (clk_b_vld & clk_b);
三、两个时钟是异步关系
reg clk_a_vld; reg clk_b_vld; reg clk_a_vld_r; reg clk_b_vld_r; always @(posedge clk_a or negedge rst_n)begin if(!rst_n)begin clk_a_vld <= 0; clk_a_vld_r <= 0; end else begin clk_a_vld <= sel & ~clk_b_vld_r; clk_a_vld_r <= clk_a_vld; end end always @(posedge clk_b or negedge rst_n)begin if(rst_n == 1'b0)begin clk_b_vld <= 0; clk_b_vld_r <= 0; end else begin clk_b_vld <= ~sel & ~clk_a_vld_r; clk_b_vld_r <= clk_b_vld; end end assign clk_o = (clk_a_vld_r & clk_a) | (clk_b_vld_r & clk_b); endmodule