老生常谈-Coding Style为什么这么重要?(Verilog编码风格)

写在前面的话

经常遇见两个人在Debug的时候,第一句话往往是“你的代码风格挺好的”或者“你这代码好乱啊,我都看不懂”之类的话。其实,Verilog编码风格一直是一个令人反感的话题,因为没有完美的编码风格,也不能说一个人的编码风格不好,这好像就在说他字写得丑、人长得不好看一样,伤害到他内心的自尊。

其实每个人都有属于自己的代码风格,阅读与自己风格相似的代码总是更容易理解,心情也十分开心,而一旦遇见一个和自己风格迥异的代码段,往往都没有看下去的欲望,满脑的不舒服。但是有一点需要注意的是,每个人写的代码,不仅仅是自己的,也是世界的,重要的是自己的代码属于“靠谱的”,而不是晦涩难懂、凌乱的。

代码要求

Verilog同其他语言一样,有一些基本的要求,例如代码整洁度可读性可修改性可维护性以及重复移植性等。除此之外,还需兼顾逻辑功能正确仿真速度快综合结果优等更高要求。

对于一个开发小组或公司部门,应该共同制定一套每个开发者都认同的编码风格,共同遵守、编写最简洁的代码风格。

命名规则

选择有意义的信号和变量名,对这些进行简化统一是非常重要的,命名包括信号、变量、状态等含义。
下面列举一些通用规则:
(1)使用有意义、有效的名字。
在特定代码段,例如for和generate,没必要将指针单独列举,直接使用i、j这类就好。
(2)使用缩写,统一缩写名称。
(3)最右侧下划线表示低电平有效,高电平有效信号避免使用下划线。
(4)首字符大写,其余小写。
(5)避免使用保留字。
(6)后缀非常重要。

常用后缀如下:

后缀意义
_Clk时钟信号
_Rstn低电平复位
_n低电平有效
_n低电平有效
_a异步信号
_r寄存器输出
_t临时信号
_next锁存前信号
_z连接到三态输出
_f下降沿有效

常用缩写如下:

全称缩写中文含义
acknowledgeack应答
addressadr地址
arbiterarb仲裁
clockclk时钟
controlctrl控制信号
countcnt计数器
checkchk校验
decodede译码
encodeencd编码
data indin数据输入
data outdout数据输出
decreasedec
enableen使能
errorerr错误
framefrm
generategen生成
grantgnt申请通过
increaseinc
inputin输入
lengthlen长度(帧长)
outputout输出
pointerptr指针
rd enableren读使能
readrd读(操作)
readyrdy应答信号准备好
receiverx接收
transmittx发送
validvld有效信号
requestreq请求
resetrst复位
writewr写操作

四十条编码注意点

(1)看重设计文档,设计之前要把设计思路、数据通路、项目细节等描述清楚,做到项目可控、可实现,从易到难,逐次递进。
(2)设计时尽量使用之前的IP,使用IP开发简单可靠。
(3)单个文件单个模块,文件命名和模块名相同。
(4)顶层模块只包含各个模块的例化连接。
(5)目录结构要做到合理有效。
(6)避免造成竞争冲突。
(7)避免实例化具体门级电路。
(8)模块内部避免三态电路。
(9)注意EDA工具的综合指令,不同综合工具对代码内的综合指令处理方式不同,综合指令放到单独的脚本,避免污染设计源文件。
(10)避免使用锁存器Latch
(11)注意复位信号造成的亚稳态,推荐异步复位同步释放。
(12)所有寄存器要同时复位。
(13)谨慎使用门控时钟,门控时钟用不好会引起毛刺,造成时序问题。
(14)避免使用模块内部的时钟信号,所有时钟在测试时要来源于外部的可控时钟。
(15)避免使用模块内部的复位信号,测试的时候复位来源于外部可控信号。
(16)当个模块尽量使用一个时钟,跨时钟域要单独处理。
(17)避免同时使用上升沿和下降沿。
(18)注意多周期路径和假路径,便于做STA分析。
(19)设计时要预留测试的模式,便于后期DFT。
(20)组合逻辑敏感列表直接写always@(*)。
(21)区分阻塞赋值和非阻塞赋值,不要混用。
(22)状态机电路要合理,推荐学习三段式状态机。
(23)注意case和if else 综合出的电路区别。
(24)begin不另起行。
(25)模块实例化要按照端口名字连接。
(26)无用的信号及时删除,在完成debug后,删除所有debug模块。
(27)避免使用全局变量,localparam。
(28)注意可综合语句,tb语法不要放到设计源文件。
(29)常数声明单独放到一个文件中。
(30)parameter位置靠前。
(31)标识符区分大小写。
(32)信号按功能集中划分区域排序。
(33)组合逻辑用 “=”。
(34)时序逻辑用"<=“。

(35)#delay 在综合会忽略。
(36)不要在多个语句块中,对同一个变量赋值。
(37)一个always块,只描述一个电路。
(38)区别function和task。
(39)尽量避免直接使用乘法、除法取余数等。
(40)输入信号是wire,输出可以wire或reg。
(41)尽量使用同步设计。
(42)不对时钟信号做判断。
(43)避免过长代码,分行写最好。
(44)多利用tab和空格对齐。
(45)模块例化、连线时注意位宽。
(46)例化时检查所有端口。

个人编码示例

这里将本人的编码风格展现出来,欢迎相互交流。

代码头

代码头关键信息包含,谁写的?是什么?什么时候写的?完成到哪了?是做什么的?

// Copyright (c) 2014-2022 All rights reserved
// -----------------------------------------------------------------------------
// Author :  1320343336@qq.com
// File   : cnn_mnist.v
// Create : 2022-09-15 17:06:16
// Revise : 2022-09-15 17:06:16
// Editor : HFUT Integrated Circuit Design & Research Center
// Verdion:  V1.2
// Description: CNN 顶层文件
// -----------------------------------------------------------------------------
// 所有注释部分的代码仅供debug 

输入输出端口声明

能看懂就行

module cnn_mnist(
    input                   sys_clk_p               ,
    input                   sys_clk_n               ,
    input                   rst_n                   ,
    input                   rx_pin                  ,
    //uart module 
    output    wire          tx_pin                  ,
    output    wire          tx_pin_stm32            , 
    //hdmi display module 
    output                  hdmi_clk                ,
    output[23:0]            hdmi_d                  ,
    output                  hdmi_de                 ,
    output                  hdmi_hs                 ,
    output                  hdmi_vs                 ,
    output                  hdmi_nreset             ,
    inout                   hdmi_scl                ,
    inout                   hdmi_sda   
    );

always块

always @(posedge clk_50m or negedge rst_n) begin 
    if(~rst_n) begin
         wr_ram <= 1'b1     ;
    end 
    else if (addra == 'd784)begin
         wr_ram <= 1'b0     ;
    end
    else begin
        wr_ram  <=  wr_ram  ;
    end
end

模块例化

            hdmi_top inst_hdmi_top
        (
            .clk_148mhz  (clk_148mhz        ),
            .clk_100mhz  (clk_100mhz        ),
            .pll_locked  (pll_locked        ),
            .decision    (decision          ),      //4bit
            .rst_n       (rst_n             ),
            .valid_out_6 (valid_out_6       ),

            .clk_ram     (clk_50m           ),
            .wr_ram      (wr_ram            ),
            .wr_addr_ram (addra             ),      //10bit
            .din_ram     (ram_data          ),      //ram_data rom_data//8bit

            .hdmi_clk    (hdmi_clk          ),
            .hdmi_d      (hdmi_d            ),      //24bit
            .hdmi_de     (hdmi_de           ),
            .hdmi_hs     (hdmi_hs           ),
            .hdmi_vs     (hdmi_vs           ),
            .hdmi_nreset (hdmi_nreset       ),
            .hdmi_scl    (hdmi_scl          ),
            .hdmi_sda    (hdmi_sda          )
        );

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值