常用设计思想

来源:互联网 发布:三大范式知乎 编辑:程序博客网 时间:2024/06/06 20:52

1. 一般性指导原则

RTL级设计的评判标准很多,如时序性能、所占面积、可测试性、可重用性、功耗、时钟域的分配、复位信号的设计等。根据这些标准的组合,可以派生出很多设计原则,这里只讨论一般意义上的指导原则。

1. 面积与速度互换原则

“面积”是指一个设计所消耗的目标器件的硬件资源数量,对FPGA来说,用消耗的触发器(FF)和查找表(LUT)数量来衡量;“速度”是指一个设计在芯片上稳定运行时所能达到的最高频率。面积(Area)与速度(Speed)这两个指标贯穿于RTL设计的始终,是衡量设计的终极标准。面积与速度是对立统一的。作为矛盾的两方面,面积和速度的地位是不一样的,相比之下,满足时序、工作频率的要求更重要一些,所以当两者发生冲突时,应采用速度优先的原则。

从理论上讲,如果一个设计的时序余量较大,所能跑的频率远远高于设计要求,那么就能通过功能模块复用减少整个设计所消耗的芯片面积,用速度优势换取面积的节约;反之,如果一个设计的时序要求很高,普通方法达不到设计频率,那么可以通过将数据流串并转换,并行复制多个操作模块,对整个设计采取“乒乓操作”和“串并转换”的思想进行处理,在芯片输出模块处再对数据进行“并串转换”,相当于用面积复制换取速度的提高。面积和速度互换的操作技巧很多,比如“流水线”、“模块复用/复制”、”乒乓操作”、“并串转换”等。

2. 硬件原则

Verilog HDL语言同软件语言(如C、C++)有本质区别,Verilog HDL的最终实现结果是芯片内部的实际电路。所以评判一个Verilog HDL设计优劣的最终标准是:电路功能以及所达到的性能(包括速度和面积两个方面)。评价一个设计的代码水平高低,仅仅是说这个设计由硬件向HDL代码这种表现形式转换的更流畅、更合理。而一个设计的最终性能,在更大程度上取决于设计工程师所构想的硬件事项方案的效率以及合理性。

因此,Verilog HDL代码编写不需要追求代码的简洁、简短。合理的编码方法是:首先理解要实现的硬件电路,对该部分的硬件的结构和连接十分清楚,然后再用可综合的HDL语言描述出来,而不能凭空写代码,只有存在的电路才是可实现的。因此,并不是由了HDL就可以放弃硬件电路的基本知识了,相反,只有深入的理解了电路本身,才能通过HDL语言完成高质量的设计。

3. 系统原则

系统原则包含两层含义,一是实现的目标器件本身就可以看做一个系统,需要充分有效的发挥该系统每个单元的功效。因为当代FPGA都内嵌了很多固有的硬件资源,如何合理的使用这些硬件资源,对设计的全局有个宏观的合理安排,显得至关重要。从更高层看,任何一个硬件系统如何进行模块划分和任务分配,什么样的算法和功能适合放在可编程逻辑中实现,什么样的算法和功能适合放在DSP、CPU等微处理器中实现,如何划分软、硬件功能、安排模块接口设计等问题都非常重要。在系统上模块复用节省的面积远比代码上的小打小闹实惠的多。

2. 同步设计原则和多时钟处理

1. 同步设计原则

简单比较一下异步电路与同步电路的异同:

异步电路:

  • 电路的核心用组合逻辑实现,比如异步的FIFO/RAM读写信号、地址译码等电路
  • 电路的主要信号、输出信号不依赖与任何一个时钟性信号,不是由时钟信号驱动触发器(FF)产生的
  • 异步电路最大的缺点是容易产生毛刺
  • 不利于器件移植,包括FPGA器件族之间的移植和FPGA向结构化ASIC的移植
  • 不利于静态时序分析(STA)和验证设计时序的性能

同步电路:

  • 电路的核心使用各种触发器实现
  • 电路的主要信号、输出信号由某个时钟信号沿驱动触发器产生
  • 同步时序电路可以很好的避免毛刺
  • 有利于器件移植
  • 利于静态时序分析(STA)和验证设计时序的性能

比较分析(略),推荐使用同步时序设计方式。同步时序设计需要注意“异步时钟域的数据转换”、“组合逻辑电路的设计方法”、“同步时序电路的时钟设计”、“同步时序电路的延时:最常用的方法是分频、倍频的时钟或同步计数器完成。”

2. 亚稳态

异步时钟域数据转换的核心就是要保证下级时钟对上级数据采样的Setup时间和Hold时间,如果触发器的setup时间或者hold时间不能得到满足,则有可能会产生亚稳态,此时,经过决断时间(resolution time),Q端输出结果会稳定在0或者1,但是究竟是0还是1,结果是随机的,与输入没有关系。亚稳态的危害主要体现在破坏系统的稳定性上。由于输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值,因此亚稳态将导致逻辑误判,严重情况下输出0~1之间的电压值还会使下一级产生亚稳态,即导致亚稳态的传播。

只要系统中有异步原件存在,亚稳态就无法避免,因此在设计电路时,首先要减少由亚稳态而导致的错误;其次要使系统对产生的错误不敏感。前者主要靠同步设计实现,后者则根据不同的设计应用采用不同的处理方法来解决。使用两级以上的寄存器可以有效的降低亚稳态继续传播的概率。两级寄存器采样仅能降低亚稳态的概率,并不能保证第二级输出的稳态电平就是正确电平,这种方法不能排除采样错误的产生,这时要求系统对采样错误有一定的容忍度。

3. 异步时钟域数据同步

数据时钟域不同步的情况主要有两种:

  • 两个时钟域的频率相同,但是相位差不固定,或者相位差固定,但是不可测,简称同频异相问题
  • 两个时钟域的频率不同,简称异频问题

两种不推荐的异步时钟域操作方法:

  • 通过Buffer等组合逻辑延时线调整采样时间

    在数字逻辑设计中,特别是FPGA/CPLD设计中,这种方法应该坚决避免,因为buffer和非门等单元是组合逻辑,容易产生毛刺,而且这种设计方法的时序余量差,一旦外界条件改变,采样时序就可能完全紊乱,造成电路瘫痪。另外,一旦芯片更新换代,就必须对延时重新进行调整,电路的可维护性和继承性都很差。

  • 盲目使用时钟正负沿调整数据采样

    初学者随意使用时钟的正负沿来调整采样,甚至还会产生一系列不同相位或不同占空比的时钟来使用其正负沿调整数据,这种方法是不推荐的。原因如下:1.使用一个时钟的双沿进行操作,相当于使用了一个同相的倍频时钟,此时,由于时钟频率提升了,所以约束会变更紧,不利于实现;2.芯片中的PLL、DLL一般只能保证某个时钟边沿Jitter、Skew、占空比等各种参数指标,而对另外一时钟沿的指标控制并不严格。所以,如果不是很清楚使用双边沿的注意事项,还不如直接使用同相倍频时钟更加简单、可靠。

异步时钟域数据同步问题的解决方法:

  • 同频异相

    简单解决方法是使用后级时钟对前级数据采样两次,即通常说的用寄存器打两次,这种方法可以有效减少亚稳态的传播,单不能保证两次采样的数据时正确的电平值,所以,只适用于对少量错误不敏感的功能单元。

    可靠的方法是用DPRAM、FIFO或者一段寄存器Buffer完成异步时钟域的数据传输,因为时钟频率相同,所以DPRAM、FIFO两端的数据吞吐率一致,因此实现起来比较简单。

  • 异频

    解决异频问题的可靠方法是使用DPRAM、FIFO。需要注意的是,因为时钟频率不同,两端的数据吞吐率不同,需要设置好缓冲区的大小,通过监视信号(full、empty等)确保数据不会溢出。

3. 组合逻辑的注意事项

相对复杂一些的设计都由两部分组成:顺序逻辑(Sequential Logic)和组合逻辑(Combination Logic)。同步时序设计系统并不是不包含组合逻辑,而是更加合理的设计、划分组合逻辑。

1. always组合逻辑信号敏感表

正确的信号敏感表设计方法是将always模块中用到的输入信号和条件判断信号都列在信号敏感表中。希望通过信号敏感表的增减来实现某项逻辑功能是大错特错的,不完整的信号敏感表有时会综合前造成仿真与综合后仿真、布局布线后仿真的结果不一致。一般综合工具对不完整信号敏感表的默认做法是,将处理进程中用到的所有输入信号和条件判断信号都添加到敏感表中,并给出warning,提示用户敏感表不完整。

2. 组合逻辑反馈环路

组合逻辑反馈环路是数字同步设计的大忌,它最容易因震荡、毛刺、时序违规等问题引起整个系统的不稳定和不可靠。组合逻辑反馈环路是一种高风险设计,原因是组合反馈环的逻辑功能完全依赖于其反馈环路上组合逻辑的门延时和布线延时等,如果这些延时发生变换,则组合逻辑反馈单元的功能将彻底改变,改变后的逻辑功能很难确定。

同步时序系统应该避免组合逻辑反馈环路,牢记任何反馈环路必须包含寄存器;检查综合、实现报告的Warning,发现Combinational Loops后立即进行相应的修改。

3. 脉冲产生器

异步脉冲序列产生电路又称为毛刺发生器,它利用组合反馈环路振荡而不断产生毛刺,组合反馈是同步设计必须避免的,所以必须避免使用

3. 慎用锁存器(Latch)

同步时序设计要尽量慎用latch,特别要注意,如果综合处与设计意图不一致的latch,则将导致仿真和设计错误。对于一定要使用latch的设计,一定要明确该latch是否为有意设计的。综合处与设计不符的latch主要是使用不完全的条件判断语句,或者设计中有组合逻辑的反馈环路等异步逻辑。

防止产生非目的性latch的方法:

  • 使用完备的if...else语句
  • 检查是否含有组合逻辑反馈环路
  • 为每个输入设计输出操作,为case语句设置default操作。
  • 在使用case语句时,附加综合属性为full case

4. 时钟设计的注意事项

1. 内部逻辑产生的时钟

如果要使用内部逻辑产生时钟,则必须要在组合逻辑产生的时钟后面插入寄存器,如果直接使用组合逻辑产生的信号作为时钟信号或者异步置位/复位信号,则将使设计不稳定。因为组合逻辑会产生毛刺,这些毛刺信号对时钟信号、置位/复位信号的影响是致命的。所以,使用组合逻辑来产生内部时钟仅仅适用于时钟频率较低、时钟精度要求不高的情况。

2. Ripple Counter

Ripple Counter就是行波计数器,这种计数器常常用于异步分频电路,是一种典型的异步时序逻辑,根据“同步设计原则”,应该严格避免Ripple Counter

3. 时钟选择

在通信系统中,为了适应不同的数据速率要求,经常要进行始终切换,有时为了节省功耗,可能会把高速时钟切换为低速时钟,或者进行时钟休眠操作。切换时钟的最佳途径是使用芯片内部专用的Clock MUX,这些MUX反应速度快,锁定时间短。

4. 门控时钟

门控时钟即Gated Clock,是IC设计中一种常用的减少功耗的手段。但是Gated Clock不是同步时序电路,其门控逻辑Gated Logic会污染Clock的质量,产生毛刺,使适中的Jitter、Skew等指标恶化。在同步设计中,应该尽量避免使用Gated Clock。如果功耗成为首要问题,应该采用其他方法减少功耗,如低功耗芯片、芯片休眠、Clock MUX等。

5. 时钟同步使能端

大多数像寄存器这样的同步单元都支持时钟的同步使能(Synchronous Clock Enable),需要注意的是,虽然使能无效时这些单元没有输出,但是并不能像Gated Clock一样减少功耗。不过Synchronous Clock Enable能够非常方便的完成一些逻辑,可以有效节约芯片面积并提高设计频率。