Verilog代码风格

 今天在看正点原子的ZYNQ PL端控制EEPROM读写时,找到之前写的i2c读写控制模块想对比着来学习,结果那个代码风格惨不忍睹,一度怀疑真的是自己写的吗?痛定思痛决定规范自己的代码风格,不管是后续的团队合作和代码复用都有很多好处。

 这是规格化之前的,只是一部分,在这里插入代码片因为最开始惨不忍睹的代码已经被我修改过了,这里只是还原。

module i2c_ctrl
#(
    parameter FPGA_clk = 26'd50_000_000,
    parameter I2C_clk = 18'd250_000
)(
    input sys_clk,//系统时钟,会分频
    input rst_n,   
    input [7:0]slave_addr,//器件地址,不设为常量是考虑多从机情况
    input [7:0]write_data,//写数据
    input [15:0]word_addr,//字地址 高8位可以无效
    input w_en,//写使能
    input r_en,//读使能

    output reg [7:0]read_data,//读入数据
    output done,//一次i2c操作完成
    output scl,
    inout  sda
    );

 规格化后的。Markdown里看着差别不大,但是我在Vscode里感觉完全不一样。

module i2c_ctrl
#(
    parameter FPGA_clk = 26'd50_000_000 ,
    parameter I2C_clk = 18'd250_000
)(
    input               sys_clk     ,   //系统时钟,会分频
    input               rst_n       ,   
    input       [7:0]   slave_addr  ,   //器件地址,不设为常量是考虑多从机情况
    input       [7:0]   write_data  ,   //写数据
    input       [15:0]  word_addr   ,   //字地址 高8位可以无效
    input               w_en        ,   //写使能
    input               r_en        ,   //读使能

    output reg  [7:0]   read_data   ,   //读入数据
    output              done        ,   //一次i2c操作完成
    output              scl         ,
    inout               sda
    );

下面是总结的几条规范化建议:

1 端口信号定义时位宽,变量名,逗号,注释上下对齐

 看verilog代码第一眼就是端口信号,一个整齐的信号美观度Max,而且,例化时非常方便,直接alt+shift/ctrl赋值若干列,效率高。
 端口信号名,若有时钟,说明频率,如clk_50M,统一使用pll生成频率时会很方便。若有输出时钟,命名为对应外设时钟,如i2c_clk,spi_clk。

2 定义常量(parameter)用大写字母,定义变量用小写字母

parameter   [12:0]  IDLE       = 13'd1     ;
reg [9:0] clk_cnt;

3 变量名做到见名知义,用连贯的写法,分割用下划线,某些介词用数字代替

 连贯的写法指clock->clk, address->addr。节省阅读成本。下划线连接两个不同的名词构成一个专有名词,比如bit_cnt。一些介词有同音的数字,比如to->2,for->4,我不太习惯,但看到过很多人用。

4 变量定义时不要赋初值

 定义时赋初值的作用是仿真会用到和仿真开始没有红色的X信号,美观一点,其余都是坏处。reg sda_in = 1'b0若一个信号被定义了但没有在后续赋值,而这个信号也要赋值给其他信号,那么若有初始值时在仿真阶段不能明显的被检查到,增加纠错成本。
 verilog描述的是硬件电路,硬件电路最开始很多地方也是没有初始值的,上电复位后等一段时间才有稳定的输出,那么就不该赋初值。这也是我非常讨厌把模块例化比作C语言函数调用行为的地方。
 也不是没有例外,不过看成特殊的常量就行。
reg [8:0] clk_div = FPGA_clk / I2C_clk;

5 clk用posedge,rst_n用negetdge,统一时钟

 竞争和冒险,在状态机出现异常状态跳变查不出具体问题在哪时很崩溃。PLL的输出范围在6.25M-800M,不在范围内的要手动分频,多时钟电路注意。

6 一个always语句对一个信号赋值(三段式状态机)

 复用,后续修改和阅读很方便,也是很多公司会用到的标准。有时候关联性强的信号,比如scl和sda,clk_cnt和scl_clk可以一起。(不确定)

7 begin和关键字同行,end另起一行,一条语句也要begin-end

 Verilog和C很像,begin-end从{…}来的,不过C的代码写法也一直在变,有左右括号单独列一行,有左括号跟关键字右括号单独列一行,因为是先学的C,所以总会不习惯,就定一个最多人用的风格。
 补充:状态机begin-end单独列一行,因为状态后面可能会写注释。always语句begin和always并列,因为可以在always前单独开一行写注释。

8不要小瞧注释,可以在注释里画时序图甚至FSM

 最好是英文写注释,不会因为编码格式不同而乱码。看到过用- / | \ _几个符号画信号时序图的注释,惊呆我一整年。
verilog编码风格

9 例化名用u_模块名_<0~9>命名

 以前用的格式u0,u1,u2…。导出原理图时都不认识哪个模块是什么了。

10 顶层模块只提供连线和例化模块,不写任何逻辑

想到接着补充

verilog代码规范1
verilog代码规范2

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值