快捷搜索:  汽车  科技

ic验证需要学习ic设计的什么知识(free时钟选择器的设计过程)

ic验证需要学习ic设计的什么知识(free时钟选择器的设计过程)q1和q2之间,q3和q4之间的控制逻辑应该是相似的。该组合逻辑有两个输入,以clka时钟为例,应该满足以下条件:在q1和q2之间还存在简单的组合逻辑,该组合逻辑的输入分别是sel和feedback_b,feedback_b与q4输出相关,也就是与clkb输出状态相关;同理,在q3和q4之间也存在这样的组合逻辑。这两部分组合逻辑的作用是为了实现sel信号对时钟使能/禁止的控制。为了满足上述条件,在最简的实现下,clka时钟域至少存在一个寄存器,该寄存器输出clka的时钟控制信号,用于实现clka的同步输出/禁止控制,该寄存器记为q2;同理clkb时钟域也存在这样一个寄存器,记为q4。除了clka同步禁止外,禁止和启动顺序也很重要。clka需要先被禁止,然后clkb同步使能。所以,clkb的控制逻辑需要知道何时clka被禁止。为了实现该过程,那么q2的输出一定会被反馈给clkb的控制逻辑,然

芯片设计,包括FPGA程序设计中,都可能出现时钟选择器。在时钟选择器设计中,非常重要的一点就是避免在时钟切换时产生毛刺。

关于glitch free时钟选择器设计的文章很多,但大多数都是直接给出了几种设计方法,而没有思考过程。本文则记录了自己的这一过程。

1. glitch free时钟选择器的基本结构会是什么样的?

假设存在两个时钟,clka和clkb,sel为0时clka输出,为1时clkb输出;当前sel为0,clka正在输出。在上述假设下,如果sel切换为1,那么clkb需要输出。

首先从考虑实现glitch free需要满足什么样的条件。第一,clka的输出需要先被同步关闭;第二,clkb需要在clka同步关闭后,再被同步开启。

为了满足上述条件,在最简的实现下,clka时钟域至少存在一个寄存器,该寄存器输出clka的时钟控制信号,用于实现clka的同步输出/禁止控制,该寄存器记为q2;同理clkb时钟域也存在这样一个寄存器,记为q4。

除了clka同步禁止外,禁止和启动顺序也很重要。clka需要先被禁止,然后clkb同步使能。所以,clkb的控制逻辑需要知道何时clka被禁止。为了实现该过程,那么q2的输出一定会被反馈给clkb的控制逻辑,然后送给q4。q2的输出为clka时钟域的信号,当他被送给q4前,需要经由clkb重新进行同步处理。同理,q4到q2之间也存在同样的反馈回路和同步过程。

基于上述分析,glitch free时钟选择器的最简实现中,至少包含4个寄存器。q2和q4分别产生clka和clkb的同步时钟控制信号。在q2之前还存在q1,在q4之前还存在q3,分别实现对上文提到的反馈信号的同步处理。

在q1和q2之间还存在简单的组合逻辑,该组合逻辑的输入分别是sel和feedback_b,feedback_b与q4输出相关,也就是与clkb输出状态相关;同理,在q3和q4之间也存在这样的组合逻辑。这两部分组合逻辑的作用是为了实现sel信号对时钟使能/禁止的控制。

2. q1和q2,q3和q4之间的组合逻辑是什么样的?

q1和q2之间,q3和q4之间的控制逻辑应该是相似的。该组合逻辑有两个输入,以clka时钟为例,应该满足以下条件:

当sel为1时,clka输出被禁止,feedback_b的值不重要;

当sel由1切换为0时,组合逻辑输出不会立即发生变化。而是等待feedback_b,当feedback_b也发生变化时,组合逻辑输出才会变化,最终使能clka。

基于上述思考,可以考虑在q1和q2之间使用“与”逻辑。该“与”逻辑的行为是:当sel为1时,组合逻辑输出立即变化,导致clka最先被同步关闭;当sel由1变为0时,只是满足了“与”逻辑输出值变化的一个条件,需要继续等待feedback_b变化后,输出才会翻转,最终使能clka。

3. 时钟使能/禁止逻辑

这部分选择的自由度应该比较大。我们就选择使用或逻辑来实现时钟输出的使能和禁止,当时钟被禁止时,输出为常1。clka和clkb的“或”逻辑输出,进行“与”操作后作为最终的时钟输出。如下图。

ic验证需要学习ic设计的什么知识(free时钟选择器的设计过程)(1)

4. 分析并确定具体的实现逻辑

当我们确定基本结构和组合逻辑的基本形式后,需要找到一个切入点来确定最终的实现形式。个人认为最好的切入点是sel变化时,被禁止的时钟。因为禁止行为最先发生,使能行为后发生。

假设sel由0变为1,此时q2的输出需要在下一个clka上升沿后立即变为1,从而实现clka的禁止操作。

ic验证需要学习ic设计的什么知识(free时钟选择器的设计过程)(2)

代码如下。

`timescale 1ps / 1ps module clk_switch ( input clka input clkb input sel // 0: clka 1: clkb output clk_o ); reg ff1 ff2 ff3 ff4; wire clka_inner_src clkb_inner_src; always_ff @ (posedge clka) begin ff2 <= ~sel & ~ff1; ff1 <= ff4; end always_ff @ (posedge clkb) begin ff3 <= ff2; ff4 <= sel & ~ff3; end assign clka_inner_src = ~ff2 | clka; assign clkb_inner_src = ~ff4 | clkb; assign clk_o = clka_inner_src & clkb_inner_src; endmodule

猜您喜欢: