FPGA 40 专题 verilog语法编程规范

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) 
    begin
    if(cnt == 4'd9)
        cnt <= 0 ;
    else
        cnt <= cnt + 1'b1 ;
	end
else
    cnt <= cnt ;

//always block 风格2
always@(posedge Clk or negedge Rst_n)
    if(Rst_n== 1'b0)
        cnt <= 0 ;
else if(Cin == 1'b1) begin
    if(cnt == 4'd9)
        cnt <= 0 ;
    else
        cnt <= cnt + 1'b1 ;
	end
else
    cnt <= 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是非常类似的,这样在例化的时候非常方便。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值