目录
Verilog 编程规范
1、编程规范重要性
2、工程组织形式
4、输入输出定义
5、parameter 定义
6、wire/reg 定义
7、信号命名
8、always 块描述方式
9、assign 块描述方式
10、空格和 TAB
11、注释
12、模块例化
13、其他注意事项
本节主要给大家介绍下编程规范,良好的编程规范是一个 FPGA 工程师必备的素质。
当前数字电路设计越来越复杂,一个项目需要的人越来越多,当几十号设计同事完成同一个项目时候,大家需要互相检视对方代码,如果没有一个统一的编程规范,那么是不可想象的。大家的风格都不一样,如果不统一的话,后续维护、重用等会有很大的困难,即使是自己写的代码,几个月后再看也会变的很陌生,也会看不懂(您可能不相信,不过笔者和同事交流发现大家都是这样的,时间长不看就忘记了),所以编程规范的重要性显而易见。
另外养成良好的编程规范,对于个人的工作习惯、思路等都有非常大的好处。可以让新人尽快融入项目中,让大家更容易看懂您的代码。
工程的组织形式一般包括如下几个部分,分别是 doc、par、rtl 和 sim 四个部分。
XX 工程名
|--doc
|--par
|--rtl
|--sim
3、文件头声明
每一个 Verilog 文件的开头,都必须有一段声明的文字。包括文件的版权,作者,创建日期以及内容介绍等,如下表所示。
//
// Company:
// Engineer:
//
// Create Date: 2023/06/19 11:56:45
// Design Name:
// Module Name: shfit_reg4
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
//实验任务:
//本节的实验任务是设计一个 4 级串联寄存器电路。
建议一个.V 只包括一个 module,这样模块会比较清晰易懂。
端口的输入输出有 Verilog 95 和 2001 两种格式,推荐大家采用 Verilog 2001 语法格式。下面是 Verilog 2001 语法的一个例子,包括 module 名字、输入输出、信号名字、输出类型、注释。
module flow_led(
// input sys_clk, //50MHz系统时钟(一个周期是20ns:1/50MHz=0.02us=20ns)
//differential system clocks //200MHz系统时钟(一个周期是5ns:1/200MHz=0.005us=5ns)
input sys_clk_p, //system clock positive
input sys_clk_n, //system clock negative
input sys_rst_n, //系统复位,低电平有效
output reg [3:0] led //4个LED输出信号
);
建议如下几点:
建议如下几点:
//parameter define
parameter T = 5; //黑金FPGA-xc7a5tfgg484-2-时钟周期为5ns
parameter WIDTH = 25;
parameter COUNT_MAX = 25_000_000; //板载50M时钟=20ns,0.5s/20ns=25000000,需要25bit位宽.
一个 module 中的 wire/reg 变量声明需要集中放在一起,不建议随处乱放。
因此,我们建议如下:
//input define
//reg sys_clk; //时钟信号
reg sys_clk_p; //时钟信号
wire sys_clk_n;
reg sys_rst_n; //复位信号
//output define
wire [3:0] led;
大家对信号命名可能都有不同的喜好,我们建议如下:
always 块的编程规范,我们建议如下:
//计数器对系统时钟计数,计时0.2秒,仿真时间设为10
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter <= 24'd0;
else if (counter<24'd1000_0000)
//else if (counter<24'd9) //仅用于仿真
counter <= counter + 1'b1;
else
counter <= 24'd0;
end
assign 块的编程规范,我们建议如下:
//计数到最大值时产生高电平使能信号
assign counter_en = (counter == (COUNT_MAX - 1'b1)) ? 1'b1 : 1'b0;
由于不同的解释器对于 TAB 翻译不一致,所以建议不使用 TAB,全部使用空格。
添加注释可以增加代码的可读性,易于维护。我们建议规范如下:
//用于产生 0.5 秒使能信号的计数器
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)
counter <= 1'b0;
else if (counter_en) // counter_en 为 1 时,counter 清 0
counter <= 1'b0;
else
counter <= counter + 1'b1;
end
模块例化我们建议规范如下:
① moudle 模块例化使用 u_xx 表示。
//例化计时模块
time_count #(
.MAX_NUM (TIME_SHOW)
) u_time_count(
.clk (sys_clk ),
.rst_n (sys_rst_n),
.flag (add_flag )
);
//例化数码管静态显示模块
seg_led_static u_seg_led_static (
.clk (sys_clk ),
.rst_n (sys_rst_n ),
.add_flag (add_flag ),
.sel (sel ),
.seg_led (seg_led )
);
其他注意事项如下:
良好的编程规范是大家走向专业 FPGA 工程师的必备素质,希望大家都能养成良好的编程规范。