20220321在看【2019-2-22-你要的FPGA&数字前端笔面试题都在这儿了.pdf】这个文档,前面都挺简单的,就看到【用Verilog实现glitch free时钟切换电路】这个题目,卡了半个下午吧,最后发现是看错了。不过解法本身还是值得记录一下,
考虑到切换的时候需要没有毛刺,即时钟高电平信号不可被截断,即旧时钟关闭的时候应该处于低电平,新时钟开启的时候也应该处于低电平,所以我们可以在SELECT和SELECT ’ 信号进入与门前面插一个对应时钟触发的下降沿寄存器,如下图所示
但是这样也存在一个问题,那就是由于clk1和clk0的下降沿不是同时到达,这就导致S1和S0不是严格反相,在一个时钟下降沿到达一个还没到达的时间内,它们是同相的。这就导致两个时钟都被选通了或者都被关闭了,这是不对的。因为后面是或门,同时关闭是可以的,但是同时导通就会造成毛刺。
所以需要对寄存器的输入做一些处理,让s1和s0两个选通信号不能同时导通。即将两个寄存器的反向输出端拉到对方的输入端与输入做一下与操作再输入,就构成了一个输出端插了两个寄存器的SR触发器。
与SR触发器不同的是,加了寄存器之后,它的输出跳变会有所延迟。跳变分为两个阶段,在阶段一清零,在阶段2输出反相信号。
例如S(select)信号由1跳变到0,clk0的寄存器叫D0,clk1的寄存器叫D1;
假如clk0的下降沿先到
time | S | D0 | D1 | Q0 | Q1 |
0 | 1 | 0 | 1 | 0 | 1 |
s < = 0 | 0 | 0 | 0 | 0 | 1 |
clk0 negedge | 0 | 0 | 0 | 0 | 1 |
clk1 negedge | 0 | 1 | 0 | 0 | 0 |
clk0 negedge | 0 | 1 | 0 | 1 | 0 |
假如clk1的下降沿先到
time | S | D0 | D1 | Q0 | Q1 |
0 | 1 | 0 | 1 | 0 | 1 |
s < = 0 | 0 | 0 | 0 | 0 | 1 |
clk1 negedge | 0 | 1 | 0 | 0 | 0 |
clk0 negedge | 0 | 1 | 0 | 1 | 0 |
上面考虑的是clk0和clk1是同源时钟。如果clk0和clk1是异步时钟,那么将对方时钟域的信号拉过来采样还要打一到两拍消除亚稳态。