目录
写在前面
2 同步和复位
2.1 同步设计
2.1.1 避免使用行波计数器
2.1.2 门控时钟
2.1.3 双边沿或混合边沿时钟
2.1.4 用触发器驱动另一个触发器的异步复位端
2.2 推荐的设计技术
2.2.1 避免在设计中出现组合环路
2.2.2 避免数字设计中的延迟链
2.2.3 避免使用异步脉冲产生器
2.2.4 避免使用锁存器
2.2.5 避免使用双沿时钟
2.3 时钟方案
2.3.1 内部产生的时钟
2.3.2 多路时钟
2.4 门控时钟方法学
2.4.1 不含锁存器的门控时钟电路
2.4.1 基于锁存器的门控时钟电路
2.5 复位信号设计
2.5.1 同步复位
2.5.2 异步复位
2.5.3 过滤复位毛刺
这个博客系列是对最近阅读的书籍《硬件架构的艺术》的读书笔记,大部分的内容是摘抄书上的内容,小部分是自己的笔记,对书上部分知识点的理解以及拓展(有标注)。
在同步设计中,由单个主时钟和单个主置位/复位信号驱动设计中所有的时序器件。
经验表明对 ASIC 的时域控制最安全的方法就是同步设计。
同步设计能够最大程度的确保建立时间和保持时间的要求,并且在使用单时钟和单复位时,最好使用系统时钟和系统复位,因为系统时钟/复位的驱动能力最强,到达每一处的延时也几乎相等,这样设计系统会更加稳定。
用触发器来驱动其他触发器的时钟输入端,一般会存在问题。由于第一个触发器时钟到q的延迟而使第二个触发器的时钟输入产生偏移,而且不能在每个时钟边沿都激活。用这种方式连接两个以上的触发器就会形成,如下图所示的行波计数器。注意,由于使用了更多的触发器,会使延迟累积增加,所以不推荐使用这种方式。
行波进位加法器如果位宽较大就会导致延时过大,比较推荐超前进位加法器或者以流水线的形式。
时钟线上的门控单元会导致时钟偏移,并会引入尖峰脉冲作用于触发器。在时钟线上存在多路复用器时,这个问题尤为严重,如下图所示。
含门控时钟的设计在仿真时可能工作很正常,但是进行综合时就会出现问题。
意思就是说在使用使能信号去控制时钟会导致时钟偏移,从而影响系统的稳定性。
如下图所示,两个触发器由两个相位相反的时钟信号控制。这会为使用同步复位和使用插入扫描链这样的测试方法带来麻烦,同时也会增加确定关键信号的路径的难度。
在下图中,第二级触发器的输出不仅仅只受时钟边沿的影响,这违反了同步设计原理。此外,该电路还包含第二级触发器时钟和复位之间的潜在竞争条件。
在使用 HDL 代码进行设计时,理解综合工具是如何对不同的 HDL 编码风格和结果进行解释是很重要的。从硬件角度思考作为一种特别的设计风格(或相当于编码风格)很重要,这会影响到设计门数和时序性能。
组合环路是数字设计中导致不稳定和不可靠的最常见因素。在同步设计中,所有反馈回路都应包含寄存器。组合环路建立了不含寄存器的直接反馈回路,这违背了同步设计原理。
在 HDL 语言中,当信号经过若干组合 always 。块产生自身时,或者算术表达式左边的内容也出现在右边时,就会形成组合环路。组合环路对设计是一种冒险,在遇见组合环路时综合工具总是会报错,它是不可综合的。
组合环路的产生可以从下图的气泡图中理解。每个气泡表示一个组合always块,进入其中的箭头表示该 always 块要用到的信号,从气泡中出去的箭头表示该块的输出信号。很明显信号“a”通过信号“d”依赖于自身产生,因此形成了组合环路。
就好比一个方程 x = 3x + 1,对于我们来说很好解,但是对于电路综合工具就会报错,因为组合逻辑是不需要时钟进行去驱动的,如果“因”发生变化,那么“果”会立刻发生变化,这对于电路实现是不现实的,一个值的产生和它本身有关,这样就会导致矛盾。
为了移除组合环路,必须改变其中一个信号的生成方式,以消除信号对彼此的依赖性。解决这个问题的简单方法是在组合环路中引入一个触发器或寄存器,以将直接通路打断。
下图展示了另一个例子,这里寄存器的输出通过组合逻辑直接控制同一个寄存器的异步输入端。
组合环路是固有的高风险设计结构。组合环路的行为与该环路中所有逻辑的传播延迟相关。因为传播延迟会根据不同条件而改变,所以组合环路的行为也可能变化。在许多设计工具中,组合环路都会导致无休止的循环运算。在设计流程中使用到的各种工具可能会以不同的方式将组合环路打断,以与原始设计意图不- -致的方式对其进行处理。
在用两个或多个带有单扇入和单扇出的连续节点产生延迟时,就会形成延迟链。通常将反向器链在一起以增加延迟。延迟链通常出现在异步设计中,有时用来解决由其他组合逻辑导致的竞争条件。在 FPGA 和 ASIC 中,都会因为布局布线产生延迟。延迟链能导致各种各样的设计问题,包括增加设计对操作环境的敏感性,降低设计的可靠度,以及增加将设计移植到不同器件结构上的难度。避免使用延时链,需要在设计中用同步技术取代异步技术。
设计通常要求基于某些事件产生脉冲。设计人员有时会使用延迟链产生单个脉冲(脉冲产生器)或- -系列脉冲(多振子)。有两种常用方法产.生脉冲。这些技术是纯异步的,应尽可能避免使用。
推荐使用的同步脉冲产生器如下图所示。
在上面的同步脉冲产生器中,脉冲宽度总是与时钟周期宽度相等。
该脉冲产生器是可预测的,可以用时序分析进行验证,并易于移植到其他体系结构中,同时独立于具体的工艺。
这种操作在上升沿检测经常使用,对待检测信号打一拍并进行异或操作,两个信号不同时机会有脉冲出现,其余的都为低电平。
在数字设计中,锁存器用来在新的值到来前保持原来信号的值。避免在所有可能的位置使用锁存器,而应用触发器代替。如下图所示,如果 X 和 Y 信号都变为高,因为锁存器由电平触发,所以将它们同时开启会使电路产生振荡。锁存器会为设计增加各种各样的问题。虽然锁存器是与寄存器相似的存储器件,但是它们有根本的区别。锁存器是连通模式的,即在数据输入和输出之间存在直接通路。输入端的毛刺能传递到输出端。
静态时序分析器通常会作出与锁存器有关的错误假设,并要么发现通过数据输入端口的伪路径要么将真正的关键路径丢失。锁存器本身的时序也是模糊的。锁存器常常使电路不可测。
锁存器给FPGA设计带来了不同的挑战,因为FPGA是寄存器密集型的;所以使用锁存器的设计会占用更多逻辑,并且比使用寄存器的设计性能更低。
出现锁存器的一般原因:
如下图的情况,没有给出 a 在 else 的情况下的值就会对 a 的输出产生锁存器。
总的来说,在 RTL 组合逻辑设计时,注意语句的完整性,以免产生锁存器造成不必要的影响。
使用双沿时钟是指在时钟的上升沿和下降沿都传输数据。使得数据传输能达到双倍的吞吐率。但它可能存在一些问题。
下图给出了一个由双沿时钟触发的电路。
使用双沿时钟时遇到的一-些问题如下:.
但也不是说双沿时钟完全不能用,它也有好处:提高工作时钟频率,比如 SDR 和 DDR,DDR 就是采用双边沿采样从而提高速率,同时也可以降低功耗。
组合逻辑搭建的时钟产生器会引入毛刺,使功能出现问题,此外由组合逻辑所导致的延迟也会导致时序方面的问题。在同步设计中,数据输入端的毛刺不会引起任何问题,因为数据是在时钟边沿处捕获的,所以可以将毛刺自动滤掉。
毛刺会违背寄存器的最小脉冲宽度要求。在毛刺到达时钟输入端时,如果寄存器的数据输入变化,会违背建立和保持时间。即使设计没有违背时序要求,寄存器也可能输出随机值,使整个设计功能出现风险。
下图展示了使用组合逻辑在同步计数器上产生时钟的效果。在时序图中可以看到,由于时钟沿处的毛刺,计数器在所示的时钟周期上递增了两次。由于时钟毛刺的作用,计数器增加了额外的计数值,这样就可能导致功能出现问题。
解决上述问题的一个简单方法是在组合逻辑的输出端增加一个寄存器,用寄存器的输出作为后面的时钟信号。这个寄存器可以保证在寄存器的数据输入端阻止组合逻辑所产生的毛刺。
在产生内部时钟时,注意在输出端加上寄存器,使时钟输出更加稳定,在实际工程中也可以直接调用官方的 PLL IP 来产生所需要的时钟要求(固定的频率和相位等)。
时钟多路器用于使同一个逻辑功能具有不同的时钟。某些类型的多路逻辑选择图中所示的时钟源。
例如,需要处理多个频率标准的通信应用常常使用多个时钟。
虽然在时钟信号上引入多路逻辑会导致前面所提及的问题,但是在不同的应用中对多路时钟的要求差别很大。
如果能满足下面的标准,时钟多路操作就是可接受的:
在传统的同步设计风格中,系统时钟连接到每个寄存器的时钟端。功耗主要由三个部分组成。
对时钟路径进行门控能大幅降低触发器的功耗。门控时钟可以存在于时钟树的根部、末端,或两者之间的任何位置。
由于时钟树几乎消耗了整个芯片功耗的50%,因此最好始终在根部产生或关闭时钟。
下图是一个带门控时钟的三位计数器。
除了把门控时钟器件插入时钟网络中,该电路与传统的实现方式是相同的,这样只有在INC输入为高电平时才由时钟驱动触发器。当INC输人为低电平时,触发器无时钟输入,因此保持原来的值。这样就节省了触发器前面的3个多路器。
这样做的目的有两个:
不含锁存器的门控时钟使用一个“与”门或“或”门实现(取决于触发器使用哪个边沿),如下图一所示。
为了避免过早截断时钟脉冲或误产生多个时钟脉冲(或时钟上的毛刺),正确的操作强制要求使能信号从时钟活跃沿(上升沿)起到时钟不活跃沿(下降沿)止一直保持常量。
下图二说明了未满足上述要求而使产生的时钟过早被截断的情况。
这种限制使得在基于单时钟触发器的设计中不适合使用不含锁存器的门控时钟。
基于锁存器的门控时钟风格向设计中加入了一个电平敏感的锁存器,以在时钟活跃沿和不活跃沿之间保持使能信号不变,这样就无须依靠门控电路本身来满足这一要求了,如下图所示。
由于锁存器能捕捉到使能信号并使它保持到产生完整的时钟脉冲,因此使能信号只需要在时钟上升沿附近保持稳定即可。
使用这种技术,每次只需要改变门的一个输入端来打开或关闭时钟,就能保证电路的输出不含任何毛刺或尖峰脉冲。
在选择复位策略之前必须考虑许多设计方面的问题,如使用同步复位还是使用异步复位,是否每一个触发器都要接收到复位信号等。
复位目的是使 SoC 进入能稳定操作的确定状态。这可以避免 SoC 在上电后进入随机状态而死机。设计可以选择使用异步复位或同步复位,或者同时使用两者。两种复位方式各都有各自明显的优点和缺点,在实际的设计中任何一种方法可以有效使用。
在某些情况下,当流水线的寄存器(移位寄存器触发器)在高速应用中使用时,可以去掉某些寄存器的复位信号以使设计达到更高性能。
同步复位的复位信号只有在时钟的有效沿到来时才能影响或者复位触发器的状态。在某些仿真器中,根据电路的逻辑,可能会阻止复位信号到达触发器中。这只是仿真中出现的现象,并不存在于真实的硬件中。
由于复位树的高扇出,复位相对于时钟周期可能是一个“延迟的信号”。即使复位信号经过了复位缓冲树的缓冲,也要尽可能减少其到达本地逻辑前穿过的逻辑数量。
下面展示了带有同步复位的可加载触发器的 RTL 代码和对应的硬件实现。
module load_syn (
input clk,
input in,
input load,
input rst_n,
output out
);
always @(posedge clk) begin
if (!rst_n)
out <= 'd0;
else
out <= in;
end
endmodule
同步复位的优点
同步复位的缺点
异步复位触发器在设计时加入了一个复位引脚。通过低电平有效的复位,当该信号使触发器的复位端变为逻辑低电平时,触发器进入复位状态。
下面展示了带有异步复位的可加载触发器的 RTL 代码和对应的硬件实现图。
module load_syn (
input clk,
input in,
input load,
input rst_n,
output out
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
out <= 'd0;
else
out <= in;
end
endmodule
异步复位的优点
异步复位的缺点
在 RTL 的设计中,一般推荐异步复位同步释放的设计思想。
异步复位对毛刺很敏感,任何满足触发器最小复位脉冲宽度的输入都能引起触发器复位。因此过滤毛刺很有必要。其中一个方法就是利用数字延时来过滤毛刺。复位输入引脚也必须是施密特触发器引脚才有助于毛刺过滤。图为复位毛刺滤除器的电路和时序图。
这个过滤毛刺的设计方法实现起来还是比较简单的,就是对复位信号加一个短暂的延时,然后将延时复位信号和原复位信号做 “与” 操作,这样可以得到一个新的复位信号,并且将毛刺过滤掉。但是这也存在一定的问题就是延时大小的控制,如果延时太小就无法过滤毛刺,如果延时太大不仅会影响整个链路的复位延时,甚至可能将复位信号给过滤掉,因此把握延时的大小是这个方法设计的关键。