一.可移植性编码
1.只使用IEEE标准类型(VHDL):(1)使用STD_LOGIC类型,而不是STD_ULOGIC类型;(2)设计中不要创建过多的的子类型;(3)不要使用BIT和BIT_VECTOR类型。
2.不使用立即数:在设计中,不要使用立即数(但作为例外,可使用0和1),推荐使用常量。使用常量有以下优点:(1)常量对于一个设计具有更多的灵活性;(2)常量值只需要在一个地方修改;(3)编译器可能只支持常量类型,不支持立即数。
3.对于VHDL程序,把常数和参数定义在由1个或多个文件组成的程序包中。
4. 对于Verilog程序,把常数和参数定义在1个或多个小文件中。例如,文件名称为DesignName_Constant.V或DesignName_Parameters.v。
5.避免在代码中嵌入综合命令。
6.使用工艺无关库:(1)对于算法元件,使用Designware Foundation Library;(2)设计中应避免使用实体化的门设计;(3)如果设计中必须使用某些特殊工艺门,那么你可以将它隔离在某个单独模块中;(4)如果必须实例化门电路,可以使用SYNOPSYS通用工艺库GTECH。
7.注意Verilog程序和VHDL程序的差异性,保证编码的可转换性:(1)Verilog程序转换到VHDL程序:在Verilog程序设计中,元件端口映射时,不要使用任何逻辑表达式;不同的状态机之间,使用惟一状态名命名;函数在调用时,只能传递函数名、函数参数和局部寄存器变量;任务在调用时,只能传递任务参数和任务内部寄存器变量。(2)VHDL程序转换到Verilog程序:在VHDL程序设计中,不要使用GENERATE声明;不要使用BLOCK块;不要用代码修改CONSTANT声明的变量。
二. 时钟和RESET信号设计指南
1.避免使用混合时钟沿:(1)在你的设计中,要避免同时使用上升沿触发和下降沿触发这两种触发方式的寄存器。若设计中必须同时使用上升沿和下降沿进行触发,则必须确保综合和时序分析后的该模块的时序周期在最坏状态下也是正确的,必须在给用户的文档中详细描述对该设计中时序信号占空比的要求;(2)如果在你的设计中必须同时使用大量的上升沿和下降沿出发的触发器,那么应该把他们放在不同的模块中。
2,避免使用时钟缓冲器:避免在RTL代码中直接引入时钟缓冲器。时钟缓冲器通常是在综合完成之后,作为物理设计中的部分工作插入到设计中的。
3.避免使用门控时钟:避免在RTL代码中直接使用门控时钟。门控时钟电缆是一种工艺相关和时序相关的电路。
4.避免在模块内部产生时钟:在你的设计中,避免使用内部产生时钟的方法。内部产生的时钟可能导致可测性限制。
5.门控时钟和低功耗设计:(1)如果必须使用门控时钟或内部时钟,或者RESET信号,就应该把内部时钟电路或RESET电路分离出来,将它们作为顶层下的独立模块进行设计。将设计细分。保证所有单一模块,只使用一个时钟和一个RESET信号。(2)如果你的设计中需要门控时钟,那么就要在RTL代码中使用同步加载寄存器。
6.避免在模块内部产生RESET信号:(1)如果可能,尽量避免在模块内部产生RESET信号,或者避免用其它条件逻辑产生RESET信号;(2)如果确实需要条件RESET信号,那么可以创建一个独立的RESET信号,再创建一个独立的条件RESET产生逻辑模块。
7.RESET逻辑功能:RESET信号的逻辑功能应该是直接清除所有的寄存器。不要把RESET信号作为状态机的输入。
8.一位同步器:使用两级触发,在两个时钟域之间传递一位数据。如图 所示。把这些触发器用不同名字区别开,这样有利于集成时对这些亚稳态的触发器特性进行分析。为了防止毛刺的传播,不要将组合逻辑从一个时钟域连接到另一个时钟域。
9.多位同步器:在传输两个时钟域之间的多位数据时,不要使用上述的一位同步器传输方法,而应该使用一种可靠的握手电路或者像格雷码那样的多位编码方式。
三.可综合性编码
1.寄存器描述:时序逻辑电路最好采用寄存器(触发器)传输的方式设计。
2.避免产生锁存器:(1)在你的设计中,避免使用任何锁存器。但可以使用工艺无关的GETCH D锁存器。(2)通过使用下列编码技术,可以避免产生锁存器:在VHDL程序中,将默认值赋值语句写在过程的开始;在VERILOG程序中,对所有可能的输入条件,都有明确的输出;在VHDL程序中,对于条件语句的最后一个分支,使用ELSE语句(而不时使用ELSIF语句)。
3.如果必须使用锁存器:可使用多选的方法,提供一般功能或I/O借口的数据。多选器的选择控制位来自于扫描控制使能的测试模式管脚。
4.避免产生组合逻辑电路反馈:组合电路反馈是指组合逻辑电路形式的反馈环路。组合反馈环路会引起一系列问题,包括会使精确静态时序分析难以实现。
5.完整的敏感信号列表:(1)规则:每个process(VHDL)和always(Verilog)模块中的敏感信号列表必须完整。(2)对于组合逻辑模块(模块中不包括寄存器或锁存器),敏感信号列表必须包括过程中用到的每个信号,也就是出现在赋值语句右侧的信号或条件表达式中用到的信号,都应该列在敏感信号列表中。(3)对于时序逻辑模块,敏感信号列表必须包括过程中用到的时钟信号。如果时序过程模块还要用到异步RESET信号,那么敏感信号列表中还应该包括RESET信号。(4)确保过程模块敏感信号列表中的信号是必需的。敏感信号列表中没必要出现的信号会降低仿真速度。
6.阻塞和非阻塞赋值(Verilog):在书写Verilog可综合代码时,在always@(posedge clk)模块中,总是使用非阻塞赋值方式,否则会产生RTL级仿真和门级仿真功能不一样的现象。
7.信号和变量赋值(VHDL):在书写VHDL可综合代码时,建议使用信号量,而不时使用变量,以确保综合前的仿真与综合后的仿真相一致。如果你觉得使用了变量后,仿真速度得到了非常显著的提高,那么也可以使用变量。
8.CASE语句和IF-THEN-ELSE语句:(1)VHDL语言和Verilog语言中的CASE语句对应一个单级的多选电路,IF-THEN-ELSE语句对应于一个优先编码的多级组合选择电路。(2)多选器是一个相对更快的电路,因此,在不需要使用优先级编码结构时,推荐使用CASE语句,而不要使用IF-THEN-ELSE语句进行描述。如果你有一个迟到的信号时,使用IF-THEN-ELSE语句可能会有用。
9.时序逻辑电路的HDL语言描述:(1)包括像状态机这样的时序逻辑,都可以用一个时序过程进行描述。为了提高程序的可读性,应该把一些对中间变量赋值的语句移到时序逻辑描述的过程之外。(2)在VHDL语言中,把各状态变量定义为类型。在Verilog语言中,用DEFINE命令定义各状态变量。(3)队员包含FSM(有限状态机)和非FSM逻辑的模块,在综合时有不同的要求,应该把它们单独放在不同的模块中。
10.对关键信号的描述:让后到达信号尽量靠近模块的输出端口。例如,在IF-THEN-ELSE模块中,让后到达信号具有较高优先级。
11.避免使用延迟语句:在RTL编码中,不要使用任何延迟语句。
12.避免使用FULL_CASE和PARALLEL_CASE结构编程:以VHDL语句中的CASE语句的使用方法书写VERILOG语言中的CASE语句结构。
四. 可综合划分
好的可综合划分会给你带来许多优势,它包括:(1)更好的综合结果;(2)更少的编程运行时间;(3)只要使用更简单的综合策略就可以满足设计的时序要求。
1.所有输出采用寄存器输出:对于采用层次化结构的核设计,子模块中所有的输出信号都应该使用寄存器输出方式。
2.将相关的组合逻辑放在同一模块:当把相关的组合逻辑放在同一模块中后,综合可以为你的设计提供更大可优化性。因为,在一般默认的综合方法中,综合工具对模块的优化只是在模块内部进行,不会跨越到多个模块之间。
3.将具有不同设计目标的部分分配到不同模块中:如将关键逻辑和非关键路径逻辑被分配到两个不同的模块中,这时综合工具可以专门对关键路径逻辑进行速度优化,而对非关键路径逻辑进行面积优化。
4.避免使用异步逻辑:(1)设计中的异步逻辑不仅难以正确实现,同时也难一验证。(2)如果设计中必须要有异步逻辑电路存在,那么将异步逻辑电路与同步逻辑电路分配到不同的模块中。
5.合并算术单元:为了让综合工具能够在资源共享方面进行优化,就需要所有相关的共享资源都必须在同一层次结构中,也就是说在同一模块中。
6.正确划分模块,提高综合速度:随着综合工具性能的改善,在划分模块时,更重要考虑的方面应该是逻辑功能、设计目标、时序的面积需求。将功能相关的模块划分在一起,而不是把它们人为分开,加剧模块之间的时序相关。
7.避免时序设计中的例外情况:(1)在设计中,避免出现多时钟周期路径和其它时序例外情况。(2)如果在设计中必须用到时序例外情况,那么应该保证:该例外路径的起点和终点在芯片级仍然是不变的。(3)在设计中,避免出现伪路经。
8.消除顶层模块中的胶连逻辑电路:在核的顶层结构中,不要再有实例化的门级逻辑电路出现。
9.芯片划分:确保设计的顶层中包含I/OPAD环和时钟发生器电路模块。