推荐答案
测试一下
题目
4.7 时钟切换方法
参考答案与知识点
参考答案
普通切换直接使用组合逻辑选择器实现:assign clk_o = sel_clkb ? clk_b : clk_a; 这种实现会因选择信号与时钟边沿对齐而产生毛刺,适用于切换时下游模块处于复位或非工作状态,毛刺不会触发误动作。去毛刺无缝切换需要避免切换时的毛刺,经典实现如下:
1. 对选择信号sel进行跨时钟域同步,分别用clk_a和clk_b的下降沿(或上升沿)打两拍,使切换信号稳定并与对应时钟对齐。
2. 使用反馈回路确保切换时源时钟先关闭再开启目标时钟。
Verilog代码示例:
reg sel_a_d1, sel_a_d2, sel_b_d1, sel_b_d2;
wire sel_a_q, sel_b_q;
always @(posedge clk_a or negedge rst_n) begin
if (!rst_n) begin sel_a_d1 <= 1'b0; sel_a_d2 <= 1'b0; end
else begin
sel_a_d1 <= ~sel & ~sel_b_d2; // 当sel=0且sel_b同步输出为0时,准备开启clk_a
sel_a_d2 <= sel_a_d1;
end
end
assign sel_a_q = sel_a_d2;
always @(posedge clk_b or negedge rst_n) begin
if (!rst_n) begin sel_b_d1 <= 1'b0; sel_b_d2 <= 1'b0; end
else begin
sel_b_d1 <= sel & ~sel_a_d2; // 当sel=1且sel_a同步输出为0时,准备开启clk_b
sel_b_d2 <= sel_b_d1;
end
end
assign sel_b_q = sel_b_d2;
assign clk_o = (clk_a & sel_a_q) | (clk_b & sel_b_q);
该电路确保切换时先关闭当前时钟(使能信号变为0),再开启目标时钟,避免了同时选通两个时钟导致的毛刺。注意同步器使用下降沿触发可进一步减少毛刺,但上升沿也可通过打两拍配合反馈实现。去毛刺切换适用于时钟切换时下游模块处于工作状态,不允许毛刺诱发FF误触发。
涉及知识点
- 时钟切换毛刺产生原因
- 组合逻辑MUX vs 同步切换
- 跨时钟域同步(双级FF)
- 反馈回路防止同时选通
- 下降沿采样减少竞争风险