接着上一次的读书笔记,在翻译的过程中遇到很多在编写VHDL代码时候出现的问题,今天这才豁然。再一次说明了,知行合一的重要性。
另,个人建议,在看这些建议或者这本书之前,最好具备一些VHDL或者Verilog的编程经验,否则会觉得有些不知所云了。
设计和模块化的建议5. 一般HDL建模建议
*在尝试对模块进行编码之前,确定完善的架构和相应的区域划分(partition)
*HDL 代码可以折射出设计的结构化划分。有效的区域划分才能使得综合工具可以着眼于高效的逻辑优化。综合工具一般可以综合上至相当于5000个等效逻辑门的电 路。超过了5000个等效逻辑门,综合工具使用的算法不一定总能得到最佳的结果,而且还很消耗CPU。更多细节性的结构化划分需要通过并发声明来完成,如process(VHDL)/always(Verilog);这并不意味着要描述到门级水平
*Only include timing in a model when critial at interfacing boundaries.Timing should come from the technology cells mapped to by the synthesis tool.(个人理解存在问题,所以没做翻译)
*VHDL是一种强类型语言,而Verilog不是。在Verilog中,不同长度的信号可以自 由付给其他任何信号。Verilog编译器无法在宽度不匹配的情况下探测哪些是无效位,所以在使用verilog要格外小心。如果赋值信号宽度不匹配,或 舍弃,或补全为逻辑'0'
*写HDL代码的时候要牢记:
硬件意图(硬件到底是如何实现的)
综合模块的类型和它相关的约束
*为了让设计的代码更短,同时也更加易读,尽可能使用子程序。子程序主要的好处就是代码的重用。
*为了模块重用,尽可能利用models generic,这就意味着信号宽度的参数化
*在相同的条件赋值的不同分支下,不要重复同一段代码,而应该挪到条件表达式外面。类似,循环不变的信号不应该包含在循环中。尽管很明显,但是这样的错误往往会消耗了更多仿真时间
*VHDL是不区分大小写的,而Verilog相反
*为了模块更加容易地阅读和维护,使用抽象的数据类型。这意味着VHDL下枚举数据类型(enumerated data type),Verilog 下`define
让编译器重新定向数据类型。虽然Verilog不允许数据类型枚举,但是使用'define编译器重定向在很多场合很凑效,不仅仅是抽象数据类型
*使用有意义的信号名称。例如_n,意味着低电平有效信号
*使用注释
6. 确保仿真的正确性
*VHDL&Verilog.确保VHDL下的process敏感信号列表的完整性,以及Verilog下的always事件列表的完整性。
7.改善仿真的速度
*VHDL&Verilog。优先使用process(VHDL)或always(verilog)对并行信号赋值(concurrent signal assignments)。这样减少了仿真器跟踪变化的信号的数量,从而改善了仿真的时间。
*VHDL&Verilog。在设计模块的时候最小化敏感信号列表中信号的数量。跟踪更少的信号也可以改善仿真的速度。
*VHDL&Verilog。不要设计很多短的process(VHDL)/always(Verilog)语句,这样会花更多的时间去激活和暂停它们。如果很多寄存器都是在同一个时钟下,放在一个进程(process)下比分开赋值要好。
*VHDL。综合的时候对RTL建模不要使用block语句,而应该使用process语句。使用block没有什么好处,而且在仿真过程中一直激活着
*VHDL。当方便的时候,转换向量数据类型,如signed,unsigned 转化成integer数据类型
*VHDL。尽可能在process中使用变量(variables)替代信号(signals)
*VHDL。在使用bit对象类型的时候,使用'event
应该比'stable更优先;‘stable属性一直在寻找电平,所以一直处于激活状态。但是最好还是使用rising_edge和falling_edge函数
8. 综合模块建议
*VHDL&Verilog。对纯粹的组合逻辑进行建模的时候,确保条件赋值信号每个条件分支下都有赋值。
*VHDL&Verilog。对于组合逻辑,在case语句下,确保在case语句之前默认输出信号会被赋值或者输出信号不管进入case语句的那个分支都会被赋值。这样做是为了避免锁存器无意中加入。others(VHDL)默认case语句分支是可选的,用于保证所有条件分支都覆盖到了。而default(verilog)case语句分支是必须的,也是用于保证所有条件分支都覆盖到了,以避免锁存器。
*VHDL&Verilog。当数据对象在for循环中进行赋值时,数据对象在for语句前应该被立即赋值一个默认值。
*VHDL。if,else-if
和case语句,优先使用case,因为这样会更有效的综合。if语句会进行有优先级的编码。但是不像VHDL,Verilog下的case语句也常常被综合工具进行有优先级的编码,跟if语句一样。
*VHDL。不要使用无边界的整数型数据类型,这样会给综合工具更多的工作去处理和优化调额外和冗余的逻辑
*VHDL。只对bit和boolean两种数据类型的信号使用'event进行边缘检测。为了对多种类型的数据使用'event的时候,例如std_logic的属性'last_value必须添加上,以表示用来检测0到1真正的上升沿变化,而非未知状态X到1的变化。何况'last_value没办法进行综合
*VHDL。在表达中使用括号以提供更好的结构控制
*VHDL。在for-loop语句中尽可能使用单一的变量
*VHDL。没有必要使用wait语句来声明触发器。if语句不仅可以胜任所有wait语句所能做的,而且允许纯粹的组合逻辑和分散的时序逻辑存在于同一个process中
*Verilog。不要尝试在task中对同步逻辑进行建模。
9. 仿真和综合模块化结合建议
*VHDL&Verilog。将非变量的赋值放到for循环语句之外,否则,整个模块会花很长时间去仿真,而且综合出多余重复的逻辑,而这些逻辑还要通过优化器去优化。 |