解题思路

题目中说了是两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频,属于相关时钟,避免切换时毛刺出现,只需要在组合逻辑的基础上添加下降沿触发的DFF。原理图如下:

alt

那么为什么要使用下降沿触发的DFF呢?

原因是这样,所谓去除毛刺,就是要避免毛刺的产生,那么得先明白毛刺是如何产生的,其实只要两个时钟相反时切换都换产生毛刺,如果没有DFF,比如,在clk1为低电平时,sel马上切换到clk0,恰巧clk0为高电平,但高电平只剩一点了,所以便产生了一个高电平毛刺,当然同理也有低电平毛刺。

但在此时钟切换电路中,sel信号的传输存在着DFF的延迟,也就是说在时钟切换时,两个DFF的输出存在都是0的情况,此时clk_out输出为低电平,这段时间可能很短,如果在两个时钟都是高电平的时候切换,可能会产生低电平毛刺,所以考虑要在两个都为低电平的时候切换最为稳妥。

那么使用下降沿触发的DFF,尽管sel已经有切换指令了,但需要等到下降沿后才通过DFF传到后面,因为是下降沿,所以高电平已经结束了,切换过去可确保无毛刺。

代码实现

`timescale 1ns/1ns

module huawei6(
	input    wire    clk0    ,
	input    wire    clk1    ,
	input    wire    rst     ,
	input    wire    sel     ,
	output   wire    clk_out
);
    reg q0, q1;
    
    always@(negedge clk0 or negedge rst)
        if(!rst)
            q0 <= 0;
        else 
            q0 <= ~sel & ~q1;
    
    always@(negedge clk1 or negedge rst)
        if(!rst) 
            q1 <= 0;
         else 
            q1 <= sel & ~q0;

    assign clk_out = (q0 & clk0) | (q1 & clk1);
    
endmodule

截止目前2022年4月10日,此题目正确答案未能用过牛客网的测试示例,因为牛客网标准答案中2个DFF的驱动时钟搞反了。