在IC设计中,时序逻辑因为能够记忆且实现流水线操作所以成为芯片运行的基础,芯片设计中最重要的是保证寄存器采集到正确的数据,也就是满足setup和hold time,不满足时会导致亚稳态,即寄存器传递出去的数据是错误的,且更严重的是亚稳态由于驱动不足,会导致下下级寄存器也出现亚稳态,类似于多米诺骨牌效应导致整个芯片大面积崩溃。
因此满足setup时间和hold时间主要是为了两个目的:
- 保证芯片不崩溃
- 保证寄存器采集的数据正确
满足时序要求主要分为两种情况:同步和异步
同步
同步时序主要是三个问题:
类型 | 原因 | 思路 | 解决方法 |
setup 不满足 | 数据无法在Tclk-Tsetup时间里从上一个寄存器输出到下一个寄存器输入 (芯片生产出来,低温正常,高温不工作可能就是setup时间不满足,因为高温载流子运动慢所以组合逻辑时间变长了) | 上一个时钟边沿(上一个寄存器输出)和下一个时钟边沿(下一级寄存器采样)之间的问题,因此和时钟周期有关 | 1.缩短寄存器间组合逻辑时间(串行改并行,拆分成流水线,增强驱动) 2.第二级寄存器clk到得晚(正的skew) 3.增加时钟周期 |
hold 不满足 | 信号传递太快,第一级寄存器还没有来得及保存第一拍信号,下一拍信号就来了 (芯片生产出来,高温正常,低温不工作可能就是hold时间不满足,因为组合逻辑时间变短了) | 同一个始终边沿(第一拍数据在第二拍时钟里保存时,第二拍数据干扰了保存过程),所以和时钟周期没关系(提高和降低频率没用) | 1. 增加组合逻辑延时(比如两级反相器,这个很简单) 2.第二级寄存器clk到的早(负的skew) |
异步复位 | 复位释放也就是寄存器采样的时刻,如果在采样时钟边沿释放,相当于压缩了setup和hold时间,因此不满足 | 复位信号撤销导致寄存器在边沿采样,和时钟周期无关 | 异步复位同步释放 |
跨时钟CDC(cross clock domain)
类型 | 位宽 | 原因 | 思路 |
同步时钟快到慢 | ①钟域内信号变化快,慢时钟域内反应不过来,没采到 | 将信号延长即可 注:有可能会忽略延长期内的信号变化 | |
异步时钟慢到快 | 单比特 | ②两个时钟域的两个时钟边沿互相靠近不对齐,必然有数据在时钟边沿发生变化,下一级寄存器就不满足setup和hold时间就会出现亚稳态 注:大部分时间内两个时钟边沿不对齐但也不靠近,可以满足setup和hold时间 | 延迟打两拍:在极小概率出现亚稳态时候给目标时钟域第一级寄存器足够从亚稳态恢复出来的时间,但只保证亚稳态不传播,采集的数据不一定对 (正确数据可以后续校验重发或者直接恢复) 注:要从上一级寄存器输出(无组合逻辑)直接打拍 |
多比特 | ② | 1. 脉冲同步:打拍传递数据有效脉冲信号,但需要打拍过程中数据不变 2. 异步fifo 其内部双端口RAM可以由不同时钟读写使用格雷码打拍跨时钟域传递读写地址判断空满,即使错误也只错一位导致提前空满不会影响数据正确性 注:直接使用RAM无法确认数据是否有效写入,因此需要构成fifo判断空满,只读写过的数据。 | |
异步时钟快到慢 | 单比特 | ①② | 1.展宽+握手:第二级采样完成后第一级数据才能变化 注:多比特数据不能每个bit都打两拍延迟采样,因为: (1)慢时钟周期内快时钟多bit数据可能分别发生变化,会漏采部分bit数据的变化 (2)每个bit都有可能因为亚稳态传错,严重时可能每个bit都是错的 2. 异步fifo |
多比特 | ①② | 2. 脉冲同步+展宽 2. 异步fifo |
需要注意的是,跨时钟域问题看图很明显,但在写verilog的时候很隐蔽
module delay_clap(
input clk1, //异步慢时钟
input sig1, //异步信号
input rstn, //复位信号
input clk2, //目的快时钟域市政
output sig2); //快时钟域同步后的信号
reg [1:0] sig2_r ; //3级缓存,前两级用于同步,后两节用于边沿检测
always @(posedge clk2 or negedge rstn) begin
if (!rstn) sig2_r <= 3'b0 ;
else sig2_r <= {sig2_r[0], sig1} ; //缓存
end
assign sig2 = sig2_r[1];
代码量如果很大,很难看出跨时钟域问题,尤其是引入另一个时钟域的信号时一般信号名不会标注时钟域,所以几乎意识不到需要跨时钟域处理,所以设计spec文档中一般需要单独标明CDC处理。
更多细节请见: