FPGA 40 专题 verilog语法编程规范

在这里主要是给自己写一个备忘录,加强个人记忆。

详细可以参考地址1:https://www.runoob.com/w3cnote/verilog2-codestyle.html 进行学习

或者参考地址2:https://hitsz-cslab.gitee.io/diglogic/codingstyle/codingstyle/ 进行学习

1、信号变量、寄存器变量、模块名称的命名

在编写verilog代码的时候,和其它语言也是类似的,如 C/C++、python的函数、变量命名基本上是类似。

1.1 模块名称的命名

  • 文件名字保持与设计的 module 名字一致,且使用小写英文来表示

1.2输入输出信号的命名

  • 用小写字母定义wire、reg和input、inout、output信号;

(注:也有首字母大写的,我开始写代码的时候,就是首字母大写。 但是在我个人实际编写代码的时候,发现,全部用小写其实更加方便阅读,而且在编写代码的时候,频繁切换大小写也很烦,而且会提高拼写的错误风险,这个要在写代码写了一段时间后可能体会的更加深刻)

  reg     Data_To_Destination_Clock ;reg     data_to_destination_clock ; //推荐

也可以巧用数字代表英文字母,例如 2 代表 to, 4 代表 for, 可以减少变量命名过长

  reg     clk_for_test, sig_uart_to_spi ;reg     clk4test, sig_uart2spi ; //推荐
  • 用大写字母定义parameter、localparam和宏定义(`define);

parameter、localparam 的使用和区别:

注: parameter可用作在顶层模块中例化底层模块时传递参数的接口,localparam的作用域仅仅限于当前module,不能作为参数传递的接口。参考链接: https://blog.csdn.net/qq_31799983/article/details/81113198

简单做个概括:

定义在模块的 parameter 常量,在其它.v文件进行模块例化(模块集成拼接)的时候,定义的parameter可以在其它模块中进行修改。(这个一般在定义计数器、定时器、或者模块的位宽等长度的时候,可以在其它模块集成的时候根据需要进行匹配和修改,这样就增加了编写模块的灵活性)

定义在模块的 localparam 常量,在其它.v文件进行模块例话(模块集成拼接)的时候,定义的localparam 只能在本地进行修改。(一般在编写状态机的状态的时候,用localparam来定义,这个一般是固定的,不能瞎改)

// 可以(需要)通过其它.v来修改的参数可以通过  parameter 定义常量
parameter         TIME_CLK_COUNTER = 200 ; //常量
parameter         DW = 8 ; //常量
reg [DW-1 : 0]    wdata ;  //变量// 状态机用 localparam 、本地不需要变来变去的固定常量用 localparam
localparam s0 = 4'd0;
localparam s1 = 4'd1;
localparam s2 = 4'd2;
localparam s3 = 4'd3;
localparam s4 = 4'd4;
localparam s5 = 4'd5;
localparam s6 = 4'd6;
localparam s7 = 4'd7;
localparam s8 = 4'd8;
  • 寄存器变量一般加后缀 _r, 延迟打拍的变量加后缀 _r1_r2
  • 低电平有效的信号应使用后缀“_n”,如cs_n,rst_n;
  • 常用其他尾缀:_d 可以表示延迟后的信号,_t 可以表示暂时存储的信号,_n 可以表示低有效的信号,_s 可以表示 slave 信号,_m 可以表示 master 信号等。

主要有两大好处:

1、 RTL 设计时容易根据变量类型对数据进行操作

2、是综合后网表的信号名字经常会改变,加入后缀容易在综合后网表中找到与 RTL 中对应的信号变量。

wire      dout_en ;
reg       dout_en_r ;
...  //dout_en_r 的逻辑
assign    dout_en = dout_en_r ;

1.3文件名:以some_module.v 文件规范写法

遵顼以上模块的命名规范写法为:

// 模板1
module some_module(input    wire            clk ,input  wire            ret_n,input wire    [3:0]   addr,output  reg                data
);endmodule// 模板2
module some_module(clk  ,ret_n,addr,data
);input wire            clk ,input  wire            ret_n,input wire    [3:0]   addr,output  reg                data
endmodule

模板1的话,在可读性方面会特别好,因为你明确的知道输入和输出信号的所有信息(如: 信号输入和输出信息、信号名称、信号位宽、信号的类型)。

模板2的话,在定义的时候只有信号名称,而其它的都没有给出,这个地方有点类似C/C++定义的函数。虽然这种方式模块定义比较简单,但是,在我们编写test_bench自己做验证的时候和模型实例化的时候会方便一些,这种看你怎么取舍,只是两种规范,反正都差不多。

1.4 always语句里面的常用编写格式

这里主要是一个 begin 和 end 之间的处理,在Verilog中,begin 和 end 是成对出现的。

因此,begin 的放置的位置会影响整个代码的风格,如下所示:

//always block 风格1
always@(posedge Clk or negedge Rst_n)if(Rst_n== 1'b0)cnt <= 0 ;
else if(Cin == 1'b1) beginif(cnt == 4'd9)cnt <= 0 ;elsecnt <= cnt + 1'b1 ;end
elsecnt <= cnt ;//always block 风格2
always@(posedge Clk or negedge Rst_n)if(Rst_n== 1'b0)cnt <= 0 ;
else if(Cin == 1'b1) beginif(cnt == 4'd9)cnt <= 0 ;elsecnt <= cnt + 1'b1 ;end
elsecnt <= cnt ;

其实上述代码就是一个begin 位置的事情,对于刚刚开始的学习Verilog 的新手来说,我自己开始用的就是 风格1,这样我就能很好的去找我想要的代码(尤其是我在新手阶段时,刚开始接触状态机的时候,感触会比较深刻),便于我开始的学习。但是,如果你写python或者c/c++用的多的时候,你就会觉得那个begin特别变扭,莫名奇妙多了个这么个玩意,就感觉不舒服。

后续在慢慢进阶的时候,就可以考虑 风格2 的方式了,这个时候,你看代码或者自己写的多了,基本上就知道那个部分对应的是哪里,这样写的话,阅读性上会比第一种好一些,这种也是在工作中用的比较多的一种方式,可以根据自己的情况来过渡。

1.5常用代码优化方式

使用圆括号确定程序的优先级或逻辑结构。为避免操作符优先级问题导致设计错误,建议多多使用圆括号。同时,圆括号的巧妙使用有时候也会优化逻辑综合后的结构。例如:

    //往往被综合成串行的 3 个加法器assign F = A + B + C + D ;//往往被综合成并行的的 2 个加法器和 1 个级联的加法器,时序更加宽松assign F = (A + B) + (C + D) ;//不推荐assign flag = cnt == 4'd2 && mode == 2'b01;//推荐assign flag = (cnt == 4'd2) && (mode == 2'b01);

1.6模块例化

模块例化时,端口信号尽量与连接信号隔开,并各自对齐。连接信号为向量时指明其位宽,方便阅读、调试。

    ram   u_ram(.CLK_WR          (clk),.WR_EN           (wren),.ADDR_WR         (addr),.D               (wdata[9:0]),.Q               (rdata[31:0]));

这个地方和.v 文件编写规范(1.3文件名:以some_module.v 文件规范写法)的 模板2是非常类似的,这样在例化的时候非常方便。

FPGA 40 专题 verilog语法编程规范相关推荐

  1. Verilog HDL 编程规范

    文章目录 目录 前言 一.文件声明 二.命名 三.注释 四.模块 五.wire.reg 六.表达式 七.条件语句 八.可综合性 九.可重用性 十.同步设计 十一.循环语句 十二.约束 十三.PLL.D ...

  2. FPGA笔记1——Verilog语法

    目录 一.Verilog基础语法 1.1 逻辑值: 1.2 数字进制: 1.3 标识符 1.4 数据类型: 寄存器 线网 参数类型 1.5 运算符 二.Verilog程序框架 2.1 注释 2.2 关 ...

  3. FPGA笔记之verilog语言(基础语法篇)

    文章目录 FPGA笔记之verilog语言(基础语法篇) 1. verilog 的基础结构 1.1 verilog设计的基本单元--module 1.2 module的使用 1.3 I/O的说明 1. ...

  4. Verilog编程规范——reset

    Verilog编程规范--reset 有样学样,本篇内容从Verilog编程规范中的复位信号,讲到FPGA中复位的场景. 内容实质来自<通信IC设计>一书,仅作整合用于学习. Verilo ...

  5. C语言代码示范与讲解+C语言编程规范及基础语法+编程实战

    上一篇文章:C语言程序设计概述+C语言简介+算法概述 C语言代码示范与讲解+C语言编程规范及基础语法+编程实战 一:代码示范集加讲解 1.C语言第一个代码:打印"This is the fi ...

  6. (40)FPGA面试题Verilog实现可预置初值的循环计数器

    1.1 FPGA面试题Verilog实现可预置初值的循环计数器 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题Verilog实现可预置初值的循环计数器: ...

  7. Cyclone FPGA踏足笔记(二):Verilog语法学习总结

    欢迎来我的个人博客:https://codinglover.top/ 转转! 前言 花了一个月时间零零碎碎看了下Verilog的语法,终于把Verilog的基本语法学了个大概,可以自己写点小东西了,由 ...

  8. 【杂谈】FPGA之路——Verilog与编辑器的那些事儿

    目录 前言 「 Verilog与Notepad++ 」 「 Verilog与Sublime Text3」 「 Verilog与VS Code」 「 Verilog与Vim」 「 重拾旧爱Notepad ...

  9. [转]verilog语法学习心得

    verilog语法学习心得 1.数字电路基础知识: 布尔代数.门级电路的内部晶体管结构.组合逻辑电路分析与设计.触发器.时序逻辑电路分析与设计 2.数字系统的构成: 传感器  AD  数字处理器  D ...

最新文章

  1. Go 学习笔记(39)— Go 反射
  2. python:编写登陆接口(day 1)
  3. WCF基础 (续 暴露元数据交换节点)
  4. 成功解决import win32api, sys, osImportError: DLL load failed: 找不到指定的模块。
  5. windows10 ipv4设置两个(多个)网段同时连接(多网段、双网段)
  6. 如何让页面动起来?支付宝2020新春红包前端3D技术揭秘
  7. Laravel5.5之事件监听、任务调度、队列
  8. Codeforces 138C(区间更新+离散化)
  9. Http状态行和状态码介绍
  10. pdf英文转换成html网页,PDF文件转换成html网页文件小方法
  11. Linux一键编译,linux下一键编译安装MariaDB10.0.12
  12. 特征选择---文本分类:叉方统计量 卡方
  13. python版多变量灰色预测
  14. 金融分析与风险管理——投资组合的绩效评估
  15. VMware 10M网卡变1000M兆网卡
  16. 微信数据如何与服务器配置,微信公众平台里的服务器配置设置是干什么用的
  17. If this is an unexpected issue and persists you can inspect it running `pod repo update --verbose`
  18. android应用备份,Android备份App及数据
  19. 使用Python玩转高等数学(2):幂函数
  20. 2019 年社保抵扣所得税说明

热门文章

  1. 政务外网环境下面springboot项目部署解决方案
  2. linux的rwx权限解读
  3. java 夏令时区_Java中的夏令时问题
  4. 小程序iPhonex适配
  5. php中获取数据表数据,从表中获取数据到PHP
  6. java中scanner类
  7. QZXing 识别不出条形码 / 二维码
  8. 应用提交 App Store 上架被拒的原因都有哪些?
  9. mysql8主从配置
  10. 查看QQ同时在线人数,分布