0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog有哪几个版本?怎样去写出它?

FPGA之家 ? 来源:电子电路开发学习 ? 作者:wcc149 ? 2021-06-15 16:12 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

众所周知,用于FPGA开发的硬件描述语言(HDL)主要有两种:Verilog和VHDL,VHDL的出现时间要比Verilog早,Verilog由于其简单的语法,和C语言的相似性,目前被各大公司广泛使用。

其实我大学时学习的是VHDL语言,后来由于公司都是使用的Verilog,又重新学习了Verilog,好在有C语言基础,Verilog很快就上手了。

Verilog标准文档主要有3个版本,分别是:

Verilog-1995

Verilog-2001

Verilog-2005

都是由IEEE颁布。目前最新的Verilog标准是2005版,相比于前两个版本,2005更简洁,更灵活。

虽然一些官方的代码,如Xilinx一些IP核代码,为了兼容以前的综合工具,还是基于Verilog-2001标准,但我还是强烈建议你使用最新的Verilog-2005标准。

IEEE-2005

所以,本文都是基于IEEE-2005语法标准,即《IEEE P1364-2005/D3:Draft Standard for Verilog HardwareDescription Language》官方标准文档。

良好的代码规范可以提高代码的可读性、可复用性、简洁清晰,这也是一种职业素质的体现。

我们的目标是:

WriteNowhere, ReadEverywhere

封面

都有哪些内容?

命名

文件命名

端口命名

变量命名

参数命名

结构

整体结构

端口声明

空格和缩进让代码更清晰

小括号增加可读性

例化

注释

其他

IEEE-2005标准下载

命名

命名主要包括文件和模块命名,端口命名,变量命名,参数命名等,概括来说就是:有意义,简短易读,重要的是不要使用拼音!

文件命名

文件名和模块名保持一致,一个文件只写一个模块。

文件命名 文件命名要有含义,且简短易读,文件名统一使用小写字母,并使用下划线分割文件名。

底层驱动类模块命名,使用drv_xxx类型,如:drv_led.v,drv_i2c.v,drv_ad7606.v

串口发送一字节:uart_tx_byte.v

异步和同步FIFO,并指示深度和宽度:fifo_async_512_16.v和fifo_sync_256_64.v

TestBench文件名问源文件名后加_tb,如源文件drv_led.v,则对应的testbench文件命名为drv_led_tb.v

顶层模块统一命名为top.v,或top_project_name.v,如EEPROM读写示例工程顶层命名为top_eeprom_demo.v

端口命名

端口命名和文件命名一样,统一使用小写字母,并使用下划线进行分割。

如果是顶层模块,而且是连接到实际的FPGA管脚,后加_pad_i,_pad_o,_pad_io来命名,表示连接到实际的FPGA硬件管脚上。

顶层端口命名

变量命名

时钟信号统一使用clk命名,如果是特定时钟频率,可以在后面添加时钟频率,如clk_50m

复位信号统一使用rst命名,如果是低电平有效,后加_n表示,如rst_n

标志位命名:flag_rise/flag_fall/flag_clr

寄存器打拍信号命名添加_reg:reg rxd_reg

移位寄存器命名添加后缀_sreg:reg [3:0] busy_sreg

部分通用的缩写:

缩写 全拼 含义
rst reset 复位
clk cloc 时钟
rd read 读取
wr write 写入
addr address 地址
ack acknowledge 响应

参数命名

Verilog中的参数类似于C语言中的define,主要有以下两类localparam和parameter,两者的区别是前者不可以在例化时进行参数传递,而后者可以在例化时进行参数传递。

其他的变量,文件名都是统一小写,只有参数定义有全部大写的待遇,当需要定义一些常量时,可以通过参数声明指定一个有意义的名称。如:

parameterLED_ON=1'b0; parameterLED_OFF=!LED_ON; parameterBAUD_RATE=115200; parameterTIME_100MS=25_000_000;

状态机的状态通常使用localparam来定义,并指定有意义的名称,统一使用Sn_NAME的格式,并指定位宽。如:

localparamS0_IDLE=4'd0; localparamS1_START=4'd1; localparamS2_DOING=4'd2; localparamS3_END=4'd3; localparamS_FINISH=4'd4; localparamS_ERROR='d5;//autoadaptive

结构

整体结构

建议Verilog模块文件按照如下结构进行书写。

/*1.文件头:说明版权信息,文件功能,作者,版本历史等*/ /*2.端口声明:input/output/inout*/ /*3.宏定义:`define*/ /*4.参数定义:localparam/parameter*/ /*5.寄存器定义:reg*/ /*6.线网类型定义:wire*/ /*7.互联定义:assign*/ /*8.时序逻辑描述:always*/

示例:

/*1.filehead*/ /*********************************************************** Copyright2021'wechat:mcu149'.Allrightsreserved. FileName:drv_led.v Function:leddriver Author:mcu149 SVN: SVNRevision:1490 SVNDate:2021-06-051949 Revision: 2020-09-09:Rev1.0 2020-10-01:Rev1.1 ************************************************************/ /*2.input/output/inout*/ moduledrv_led( //Inputs inputrst_n, inputclk_50m, inputen, //Outputs outputled1, outputregled2=0//defineinitialvalueis0 ); /*3.define*/ /*4.parameter/localparam*/ parameterTIME_500MS=32'd25_000_000; /*5.reg*/ reg[31:0]cnt=0; /*6.wire*/ wireflag_toggle=(cnt==TIME_500MS); /*7.assign*/ assignled1=(en==0)?0:cnt[20]; /*8.alwaysblock*/ always@(posedgeclk_50m)begin if(!rst_n) cnt<=?0; ????else?if(flag_toggle) ????????cnt?<=?0; ????else? ????????cnt?<=?cnt?+?1; end always?@?(posedge?clk_50m)?begin ????if(!rst_n) ????????led2?<=?0; ????else?if(!en)? ????????led2?<=?0; ????else?if(en)?begin ????????if(flag_toggle) ????????????led2?<=?!led2; ????end end endmodule

端口声明

输入端口放在一起,输出端口放在一起,双向端口放在一起。如果某个输出信号需要确定初始值,可以在端口定义时直接进行指定,这也是Verilog-2005新添加的功能。

端口命名

这一点有些朋友可能是按照功能进行划分,如连接同一芯片的放在一起。

输入输出分开放的好处是,在例化时可以很方便的区分哪些是输入哪些是输出。

空格和缩进让代码更清晰

运算符两端增加一个空格,可以让程序结构更清晰,可读性更高

缩进风格采用KR风格,即begin写在行尾,不占用单独一行,end单独占用一行

缩进统一使用4个空格来代替TAB键

if/else等语句只有一行时,可以省略begin-end

合理添加空行进行块区分,不同的always块进行换行隔开

以下是两种代码的书写规范,合理缩进,合理增加空格大大增加了可读性。

合理缩进

小括号增加可读性

在学校里有些考试题,为了考察学生对各种运算符优先级的掌握程度,出一些反人类的题目。

而做实际项目不像考试,追求的是可读性和易用性,所以当使用多个运算符时,为了增强可读性,避免歧义,不要吝啬使用小括号来表示运算的优先级。

运算符优先级

例化

例化可以认为是FPGA开发的灵魂所在了,例化的过程其实就是硬件模块的调用过程,比如我们用Verilog描述了一个3-8译码器的模块,可以在不同的地方去使用(例化)它,并分别命名为ut0/ut1/ut2等等,而且还可以在例化时指定参数,如串口发送和接收模块,通过指定不同的参数来实现不同波特率的兼容。

例化和端口声明顺序保持一致,输入端口放在一起,输出端口放在一起

多比特信号,在例化时需要指定位宽,以增加可读性

顶层模块只进行模块例化,不写任何控制语句

示例:

wire[7:0]rx_data; wirerx_done; wirerx_err; /*串口接收1字节*/ uart_rx_byte#( .BAUD_RATE(32'd115200), .EN_PARITY(2'd0),//0:无校验位,1:奇校验,2:偶校验 .EN_STOP_2(1'b0)//1:使能2位停止位 )uart_rx_byte_0( //Inputs .clk(clk_32m), .rst_n(rst_n), .rxd(uart_rxd), //Outputs .data_rx(rx_data[7:0]),//指定位宽 .done(rx_done), .err(rx_err) );

注释

不要相信什么代码就是最好的注释!我不否认有些人的代码写的就是很规范,命名合理,格式清晰。

但是我觉得你还没有达到那种程度,不能保证每一个人都能读懂没有注释的代码。注释不仅是为了给别人看,更多的也是为了给自己看,好记性不如烂笔头。

注释统一使用/**/注释的方式,或者使用与//混合使用,看个人习惯!

每个变量定义后需要注释变量的功能

每个always块功能需要注释

状态机状态含义需要注释

条件语句的后面需要添加注释

代码修改,注释也要随之修改

其他

合理使用generate for可以批量化定义和例化模块,减少代码量,提高可读性

testbench中使用task和function可以提高效率

移位操作替换为拼接补0操作,更易读

时序逻辑统一使用非阻塞赋值,即<=符号

一行字符不要超过80个,过长通过换行来处理

先有顶层设计,然后划分子模块功能,或者自底向上方法

模块化设计,提高模块可复用程度

能用case的尽量不要用if/else

reg类型变量,根据需要看是否锁存。

责任编辑:lq6

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Verilog
    +关注

    关注

    29

    文章

    1367

    浏览量

    112444
  • vhdl
    +关注

    关注

    30

    文章

    820

    浏览量

    130102

原文标题:如何写出易于维护的Verilog代码?

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    TC397哪几个Nodes支持TT-CAN呢?

    TC397 具有3个modules,每个modules具有4个Nodes,共支持12路CAN。哪几个Nodes支持TT-CAN呢?支持TT-CAN的Nodes能否用做普通的CAN呢?
    发表于 07-29 10:38

    NTC温度传感器哪几个温度特性

    NTC温度传感器是由NTC(负温度系数)热敏电阻作为温感元件组装而成的温度传感器。其温度特性主要体现在以下几个方面:
    的头像 发表于 04-02 09:46 ?622次阅读
    NTC温度传感器<b class='flag-5'>有</b><b class='flag-5'>哪几个</b>温度特性

    水利大坝安全监测哪几个方面

    监测的内容:变形监测,渗流监测,内部监测,水力学监测以及环境量观测等。在所需监测的项目中,变形和渗流监测是最为重要的监测项目。变形监测变形监测是通过人工或仪器手段
    的头像 发表于 03-28 10:13 ?436次阅读
    水利大坝安全监测<b class='flag-5'>有</b><b class='flag-5'>哪几个</b>方面

    Verilog 与 ASIC 设计的关系 Verilog 代码优化技巧

    Verilog在ASIC设计中的作用主要体现在以下几个方面: 逻辑设计 :使用Verilog可以描述数字电路的行为和逻辑结构,包括输入输出端口
    的头像 发表于 12-17 09:52 ?1107次阅读

    Verilog与VHDL的比较 Verilog HDL编程技巧

    Verilog 与 VHDL 比较 1. 语法和风格 VerilogVerilog 的语法更接近于 C 语言,对于 C 语言背景的工程师来说,学习曲线较平缓。
    的头像 发表于 12-17 09:44 ?1848次阅读

    请问ADS1299EEGFE-PDK支不支持QSPI?

    支不支持QSPI,如果支持,芯片上的线接哪几个引脚。
    发表于 11-21 07:36

    ADS9234R这个AD的寄存器如何配置,需要用到哪几个引脚?

    请问一下,ADS9234R这个AD的寄存器如何配置,需要用到哪几个引脚?时序是怎样的?与复位信号什么关系?感觉官方文档对寄存器配置这一块描述比较少,我用FPGA与ADS9234R做接口,写入寄出器参数,读出总是不对。
    发表于 11-15 07:48

    正弦波产生电路包括哪几个部分

    等。 1. 振荡器 振荡器是正弦波产生电路的核心部分,的主要功能是产生稳定的正弦波信号。振荡器可以分为以下几种类型: 1.1 LC振荡器 LC振荡器是一种利用电感(L)和电容(C)元件的谐振特性来产生正弦波的电路。包括以下
    的头像 发表于 10-09 16:22 ?1277次阅读

    用TPA3136典型应用电路波形异常,从哪几个方面寻找问题?

    是这样的,波形异常,展开后发现是和功放开关频率一样的噪声叠加在上面的,请问我可以从哪几个方面寻找问题,谢谢!
    发表于 10-09 09:01

    PCM1795如何在通电的情况下切换PCM模式和DSD模式?

    Ti工程师您好,项目上有用到PCM1795这枚芯片,因为具有DSD解码与PCM解码功能,之前没有使用过类似产品 两个问题请教下: 1、用MCU初始化PCM1795让它能正常工作,至少需要配置哪几个相关寄存器 2、如何在通
    发表于 09-29 06:00

    GUTOR备品备件主要包括哪几个组成部分?

    GUTOR备品备件主要包括哪几个组成部分?
    发表于 09-12 17:19

    labview的应用程序包括哪几个部分

    LabVIEW(Laboratory Virtual Instrument Engineering Workbench)的应用程序主要由以下几个部分组成: 前面板(Front Panel) : 功能
    的头像 发表于 09-04 16:06 ?1274次阅读

    光纤收发器正常亮哪几个

    光纤收发器是一种用于将电信号转换为光信号或将光信号转换为电信号的设备,广泛应用于通信、网络、监控等领域。 电源指示灯(Power LED) 电源指示灯是光纤收发器最基本的指示灯之一,用于显示设备的电源状态。当光纤收发器接通电源后,电源指示灯会亮起,表示设备已经通电。正常情况下,电源指示灯应为绿色或蓝色,表示设备正常工作。如果电源指示灯不亮或闪烁,可能是电源故障或设备故障。 光纤链路指示灯(FX/Fiber LED) 光纤链路指示灯用
    的头像 发表于 08-23 10:29 ?2842次阅读

    工业自动化控制系统是由哪几个环节组成的?

    。 ? ? ?工业自动化控制系统由控制器和被控对象组成。但要实现复杂的控制任务,一个典型的自动控制系统通常还应当包括:定值元件、执行元件、测量变送元件和比较元件。那么,工业自动化控制系统几个环节组成? ? ? ?工业自动化控制系统按控
    的头像 发表于 08-15 08:55 ?1152次阅读

    TAS2505-Q1的MCLK, WCLK, DIN, BCLK这几个PIN,对应的mcu这边的哪几个pin?

    1.请问参考设计的中的耳机接口HPOUT 及 IOVSS,在PIN描述中没有这两个PIN呢? 2.请问2505的MCLK, WCLK, DIN, BCLK这几个PIN,对应的mcu这边的哪几个pin?下面的这个图片是MCU端的I2S接口描述,多谢!
    发表于 08-08 08:28