zoukankan      html  css  js  c++  java
  • (未完成)华为Verilog HDL代码书写规范笔记

    1. 目的

    本规范的目的是提高书写代码的可读性、可修改性、可重用性,优化代码综合和仿真的结果,指导设计工程师使用VerilogHDL规范代码和优化电路,规范化可编程技术部的FPGA设计输入,从而做到:① 逻辑功能正确,②可快速仿真,③ 综合结果最优(如果是hardware model),④可读性较好。

    2.适用范围

    本规范涉及Verilog HDL编码风格,编码中应注意的问题,Testbench的编码等。
    本规范适用于Verilog model的任何一级(RTL,behavioral, gate_level),也适用于出于仿真、综合或二者结合的目的而设计的模块。

    3.Verilog 编码风格

    3.1命名习惯:

    有意义而有效的名字;

    用连贯的缩写

    用最右边的字符下划线表示低电平有效,高电平有效的信号不得以下划线表示,短暂的引擎信号建议采用高有效;

    大小写原则:名字一般首字符大写,其余小写(但parameter, integer 定义的数值名可全部用大写),两个词之间要用下划线连接。

    全局信号名字中应包含信号来源的一些信息。

    同一信号在不同层次应保持一致性;

    自己定义的常数、类型等用大写标识;

    避免使用保留字;

    添加有意义的后缀,使信号名更加明确;

     一个module一个文件,且文件名能与module名对应起来;

    3.2 Modules

    顶层模块应只是内部模块间的互连;

    每一个模块应在开始处注明文件名、功能描述、引用模块、设计者、设计时间及版权信息等。代码中的所有说明、注释必须均为英文,例如:

    /*********************************************************************
    Filename : fulladd.v
    Author : Verilog_gruop
    Description : Example of a one-bit full add.
    Revision : 2000/02/29
    Company : Verilog_group
    *********************************************************************/

    不要对Input进行驱动, 在module 内不要存在没有驱动的信号,更不能在模块端口中出现没有驱动的输出信号,避免在elaborate和compile时产生warning,干扰错误定位。

    每行应限制在80个字符以内,以保持代码的清晰、美观和层次感。

    电路中调用的 module名Uxx标示, Cell名Vxx标识。向量大小表示要清晰,采用基于名字(name_based)的调用而非基于顺序的(order_based)

    用一个时钟的上沿或下沿采样信号,不能一会儿用上沿,一会儿用下沿。如果既要用上沿又要用下沿,则应分成两个模块设计。建议在顶层模块中对Clock做一非门,在层次模块中如果要用时钟下沿就可以用非门产生的Posedge Clk_, 这样的好处是在整个设计中采用同一种时钟沿触发,有利于综合。

    在模块中增加明了的英文注释。对信号、参量、引脚、模块、函数及进程等加以说明,便于阅读与维护。

    Module 名要用大写标示,且应与文件名保持一致。

    严格芯片级模块的划分.只有顶层包括IO引脚(pads),中间层是时钟产生模块、JTAG、芯片的内核(CORE),这样便于对每个模块加以约束仿真,对时钟也可以仔细仿真。

    模块输出寄存器化:对所有模块的输出加以寄存(如图1),使得输出的驱动强度和输入的延迟可以预测,从而使得模块的综合过程更简单。
    - 输出驱动的强度都等于平均的触发器驱动强度
    - 输入延迟始终等于通过触发器的路径,近于相等

    关键路径逻辑和非关键路径逻辑放在不同模块:保证DC可以对关键路径模块实现速度优化,而对非关键路径模块实施面积优化。在同一模块DC无法实现不同的综合策略。
    相关的组合逻辑放在同一模块: 有助于DC对其进行优化,因为DC通常不能越过模块的边界来优化逻辑
    ultraedit中的tab键设置为4个空格键;
    输入输出的端口定义分行写,一行定义一个输入输出,顶格对齐;
    module头中的括号内的输入输出的定义按输入输出分开,与括号对齐
    module用到的变量统一在输入输出的定义之后,按wire和reg型分开定义,并对重要的信号加注释说明
    module主体以//module begin作为起始标识
    子模块的调用顶格对齐;子模块中的输入输出的端口信号的名字尽量与调用的名字一致
    if...else一一对应,若无else时,加一个空语句;

    3.3 Net and Register

     一个reg变量只能在一个always语句中赋值;

    向量有效位顺序的定义一般是从大数到小数;

    net和register类型的输出要做声明;

    无用信号不要引入module内部,避免在elaborate和compile时产生warningr类型的输出要做声明。

    3.4 Expressions

    用括号来表示执行的优先级,尽管操作符本身有优先顺序,但用括号来表示优先级对读者更清晰,更有意义

    用一个函数(function)来代替表达式的多次重复;

    3.5 IF 语句

    向量比较时,注意长度匹配

    每一个If 都应有一个else 和它相对应;硬件设计中,常要求条件为真时执行一种动作而条件为假时执行另一动作,即使认为条件为假不可能发生。没有else可能会使综合出的逻辑和RTL级的逻辑不同

    应注意If ..else if ...else if ...else 的优先级;

    3.6 case 语句

    case语句通常综合成一级多路复用器(图的右边部分),而if-then-else则综合成优先编码的串接的多个多路复用器,如图的左边部分。通常,使用case 语句要比if语句快,优先编码器的结构仅在信号的到达有先后时使用。条件赋值语句也能综合成多路复用器,而case 语句仿真要比条件赋值语句快。

    所有的Case 应该有一个default case ,允许空语句;

    3.7 Writing functions

    在function的最后给function赋值;

    函数中避免使用全局变量否则容易引起HDL行为级仿真和门级仿真的差异;

    3.8 Assignment

    Verilog 支持两种赋值:过程赋值(procedural) 和连续赋值(continuous),也被称为阻塞赋值与非阻塞赋值。过程赋值用于过程代码(initial, always, task or function)中给reg 和 integer变量赋值,而连续赋值一般给wire 变量赋值。

    Always @(敏感表),敏感表要完整,如果不完整,将会引起仿真和综合结果不一致;

    Assign/deassign 仅用于仿真加速;

    Force/release 仅用于debug;

    避免使用Disable;

    对任何reg赋值用非阻塞赋值代替阻塞赋值;

    3.9 Combinatorial Vs Sequential Logic

    如果一个事件持续几个时钟周期,设计时就用时序逻辑代替组合逻辑;

    在simulation pattern 或 report file中,尽量不用内部信号,如果要用就把它们引到端口,这样做并不增加芯片面积。(???)

    内部总线不要悬空。在default状态,要把它上拉或下拉。

    3.10 Macros

  • 相关阅读:
    12 go实现几中基本排序算法
    5 控制语句
    9 函数
    4. 常量与运算符
    AI
    AI
    AI
    AI
    ML
    ML
  • 原文地址:https://www.cnblogs.com/kraken7/p/13824750.html
Copyright © 2011-2022 走看看