数字逻辑实践2->Verilog编写规范

2021年11月26日 阅读数:2
这篇文章主要向大家介绍数字逻辑实践2->Verilog编写规范,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

来源:数字逻辑与Verilog设计实验课讲解,我的作的笔记与整理。程序员

00 规范的重要性

  1. 良好的编程风格有利于减小消耗的硬件资源,提升设计的工做频率 。编程

  2. 提升系统的可移植性和可维护性。缓存

  3. 程序的格式化能体现程序员的基本素质和整个团队的风貌。异步

01 命名规则

有C语言基础的这部分能够简单略过,看看便可。无基础的能够跳过,有必定编程经验后再来总结提升。ide

01-00 命名字符集

用于命名的字符集为:字母A~Z和a~z, 数字0~9以及下划线组成。函数

例如:工具

1 data_bus
2 data_width
3 clk_48M
4 //使用用意义的名字,利于望文生义,便于维护
5 6 48M_clk//名称不能以数字开头
7 data__bus//不能连续使用下划线
8 data*bus//不能包含非字母符号

01-01 命名大小写规则

  • 参数(parameter)、常量(constant)和块标号(block label)名必须一致采用大写;测试

  • 而信号,变量和结构名(construct)以及实例标号(instance)必须一致采用小写。编码

  • 有利于在仿真时,区分不变和变化的 数据。spa

例子:

 1 module display_led(     //模块标号小写
 2     clk_48M,           //时钟
 3     ledout             //LED输出
 4 );
 5     input clk_48M;    //48M系统时钟
 6     output [7:0]ledout;//LED输出控制
 7     reg [22:0]count;   //计数器    
 8     reg [7:0]led_reg;  //LED输出缓存区
 9     wire led_clk;      //LED显示时钟控制
10     parameter COUNTER=100;
11     assign  led_clk = count[22];                   //LED显示时间控制

01-02 名字必须惟一

不区分大小写的状况下,名字必须惟一。例如,名字state和State不能同时出如今同一设计中。由于有的EDA工具不区分大小写。

01-03 不一样类型的信号的命名习惯

  • 若是一个名字由多个字组成,则使用下划线链接,用以增长名字的可读性。

  • 为了使信号的名字有意义,能够根据信号类型选取相应的后缀。

具体示例以下:

命名 信号类型 实例
xx_r 寄存器类型 Data_out_r
xx_a 异步信号 Addr_strobe_a
xx_clk 时钟信号 Sys_clk
xx_nc 不连续信号 Stata_nc
xx_n 低电平有效信号 Reset_n
xx_pn 有n个相位的信号 Enable_p2
xx_z 三态信号 Data_out_z
xx_next 状态机信号 Transmit_next
xx_test 测试模式信号 Parallel_clk_test
sys_xxx 系统信号 sys_dout,sys_din
clk_xxx 时钟信号(也可这样写) clk_768MHZ
rst_xxx reset_xxx 复位信号  
st_xxx set_xxx 置位信号  

01-04 多后缀的优先权

这个确实有点抽象...

顺序:

1 //例子
2 ram_1_clk_z_n
3 //结构
4 操做对象序号_数据类型(_clk/_next)_三态信号(_z)_低电平有效信号(_n)

01-05 模块命名习惯

  • 将模块英文名称的各个单词的首字母组合起来,造成3~5个符号的缩写。

    Arithmatic logical unit —— ALU

  • 若模块的英文名只有一个单词,可取该单词的前3个字母

    Decider —— DEC

01-06 模块间接口命名

  • 全部的变量命名分为两个部分:

    • 第一部分代表数据方向,其中数据发出方在前,数据接收方在后;

      • 第一部分所有大写,

    • 第二部分为数据名称。

      • 第二部分中全部具备明确意义的英文名所有拼写或者缩写的第一个字母大写,其他部分小写。

    • 两个部分用下划线隔离开。

  • 例:CPUMMU_WrReq (CPU发送给MMU的写请求信号)

01-07 模块内部信号

模块内部的信号由几个单词链接而成,缩写要求能基本代表本单词的含义。

02 注释

主要有三点:

  1. 普通描述注释“//”就能够

  2. 文件头注释有一点麻烦,可是显得很标准。

     

     

  3. 模块之间(always)的注释参照文件头注释

    1 //****************************************
    2 //模块名称:
    3 //功能描述:
    4 //****************************************

03 代码格式

03-00 端口

1 module buzzer (  
2                 clk_48M,      //时钟输入
3                 beep,         //蜂鸣器控制输出
4                 key,         //按键输入
5                 ledout       //LED显示控制信号
6                 );   
7 //我的感受对于复杂电路比较有用,而实验代码就没必要如此,直接相似函数参数同样声明便可。可配注释理解。

03-01 连线

1     input clk_48M;
2     input rst;
3     output lcd_en;
4     output [7:0]data_bus;
5     wire clk_lcd;
6 //紧跟module声明,一个Tab键
7 //标准要求是一行声明一个端口

03-02 正文

正文书写要求与C语言相似。

03-03 其余

  1. 用四个空格代替TAB键;由于不一样的编辑系统的Tab制表符间距可能不一样。

  2. 每行只有一个Verilog语句;对于长的语句可使用回车和缩进方法,表示成连续的语句行。

  3. 避免使用硬编码;建议使用宏或则参数来定义常数,避免使用硬编码数值。例如:

     1 //硬编码方式:
     2 input   [31:0]  data_a; //  输入比较数据A
     3 input   [31:0]  data_b; //  输入比较数据B
     4 
     5 //参数定义方式:
     6 parameter   DATA_WIDTH = 32; //总线数据宽度
     7 input   [DATA_WIDTH-1:0]    data_a; 
     8 // 输入比较数据A
     9 input   [DATA_WIDTH-1:0]    data_b; 
    10 // 输入比较数据B

    下面是更多出于美观的考虑:

  4. 各节之间加1行或者多行空格

  5. 不一样变量,变量与符号,变量与括号之间都应该保留一个空格 alwaya @ ( … )

  6. 逻辑运算符、算术运算符、比较运算符等运算符两侧各留一个空格。(单数操做运算符例外)

  7. 使用”//” 注释时,在”//”后应当有一个空格