Verilog代码标准
来源:互联网 发布:nba乔丹职业生涯数据 编辑:程序博客网 时间:2024/05/24 01:20
一、工程建立规范:
1、工程的组成:
(1) 一个顶层文件夹
(2) 顶层文件夹下,至少包括以下四个子文件夹
a) project文件夹:存放ISE工程文件,包括ise、bit、mac等文件
b) source文件夹:存放verilog源文件
c) explain文件件:存放注释说明文档
d) test文件夹:存放测试程序代码,可进一步分为软件调试程序、硬件调试程序
2、 工程的命令:
(3) 定层文件夹命令为top_xxx,xxx为工程的识别名称
(4) 顶层文件夹的子文件夹分别命名为:project、source、explain、test
二、 RTLCODE 规范
1.标准的文件头
在每一个版块的开头一定要使用统一的文件头,其中包括作者名,模块名,创建日期,概要,更改记录,版权等必要信息。
统一使用以下的文件头:
//**************************************************************
// COPYRIGHT(c)2005, Hislicon Technologies Co, Ltd
// All rights reserved.
//
// IP LIB INDEX : IP lib index just sa UTOPIA_B
// IP Name : the top module_name of this ip,usually, is same
// as the small ip classified name just as UTOPIA
// File name : file_name of the file just as “tx_fifo.v”
// Module name : module_name of this file justas “TX_FIFO”
// Full name : complete Emglish nme of thisabbreviated
//
// Author : Athor/ID
// Email : Author’s email
// Data :
// Version : V 1.0
//
//Abstract :
// Called by : Father Module
//
// Modification history
//------------------------------------------------------------------------------------------------------
// //
// $Log$
//
//*********************************************************************
2. 标准的module格式 (module 整体结构)
对于模块的书写采用统一的格式便于项目内部成员的理解和维护,我们用批处理建立了一个MODULE模块,其内容解释如下:
l 端口定义按照输入,输出,双向的顺序:
l 模块名、模块例化名统一,例化名前加大写U_以区分 (多次例化另加标识 ),三者关系:
文件名 :xxx .v (小写)
模块名 :Xxx (首字母大写)
例化名 :U1_xxx (首字母大写)
IP 内部所有的模块名都要加IP名或者IP名简称作前缀,如USB_CTRL、USB_TX_FIFO。
// *****************************
// DEFINE MODULE PORT //
//******************************
//
// module MODULE_NAME (
// INPUT
input_port_1,
…
input_port_m,
// OUTPUT
output_port_1,
…
output_port_m,
);
//*****************************
// DEFINE PARAMETER //
// ******************************
parameter…
//******************************
// DEFINE INPUT
//******************************
input rst_n ; // reset, active low .
input clk_* ; // clock signal , 50M .
input [n:0] a_din ; // *****
input [k:0] b_din ; // *****
//******************************
// DEFINEOUTPUT //
//******************************
output [m:0] a_dout ; // *****
output [i:0] b_dout ; // *****
//******************************
// OUTPUTATRRIBUTE //
//******************************
// REGS
reg [m:0] a_dout ; // *****
//WIRES
wire [i:0] b_dout ; // *****
//******************************
// INSTSNCEMODULE //
//******************************
MODULE_NAME_A U_MODULE_NAME_A(
.A (A ),
.B (B ),
.C (C ),
); …
//******************************
//MAIN CODE //
//******************************
… …
… …
… …
//****************************** //
Endmodule
3.一致的排版
A. 一致的缩排
l 统一的缩排取4个空格宽度
l 输入输出信号的宽度定义与关键字之间,信号名与宽度之间要用空格分开;所有宽度定义对所有信号名对齐,代码风格统一如下:
input [3:0] input_a ; // *****
input input_b ; // *****
…
output [128:0] output_a ;
output [15:0] output_b ;
output output_c ;
B. 一致的 begin end 书写方式
always 中,一定要用begin end 区分,格式和代码风格统一如下:
always @ (postedge clk or negedge rst_n)
begin
if(rst_n==1’b0)
syn_rst<= ‘DLY 1’b0;
else
begin
if (a==b)
syn_rst<= ‘DLY 1’b1;
else
syn_rst<= ‘DLY 1’b0;
end
end
if else 中仅有一个语句行时,不要使用begin end; 如果有多个语句行时,begin end和if ()或else ()空四个格。
格式如下:
if (…)
…
else if (…)
else
********************************************************************
if (…)
…
else if (…)
begin
…
…(
end
else
4. 一致的信号命名风格
简洁,清晰,有效是基本的信号命名规则,详见命名规范。
全称
缩写
中文含义
acknowledge
ack
应答
adress
addr(ad)
地址
arbiter
arb
仲裁
check
chk
校验,如CRC校验
clock
clk
时钟
config
cfg
Configuration,装置
control
ctrl
控制
count
cnt
计数
data in
din(di)
数据输入
data out
dout(do)
数据输出
decode
de
译码
decrease
dec
减一
delay
dly
disable
dis
不使能
error
err
错误(指示)
enable
en
使能
frame
frm
帧
generate
gen
生成,如CRC生成
grant
gnt
申请通过
increase
inc
加一
input
in(i)
length
len
(帧、包)长
nmport
nm
网管相关
output
out(o)
packet不推荐packet
pkt
与帧相同
priority
pri
优先级
pointer
ptr
指针
rd enable
ren
读使能
read
rd
读(操作)
ready
rdy
应答信号或准备好
receive
rx
(帧数据)接收
request
req
(服务、仲裁)请求
reset
rst
segment
seg
souce
scr
源(端口)
ststistics
stat
统计
timer
tmr
定时器
switcher
sf
Switch fabric
temporary
tmp
临时
transmit
tx
发送(帧数据)相关
Valid
vld(v)
有效、校验正确
wr enable
wen
写使能
write
wr
写操作
a. 端口、信号、变量名的所有字母小写:函数名、宏定义、参数定义用大写
b. 使用简称、缩略词(加上列表)
c. 基于含义命名(避免以数字命名的简单做法),含义可分段(最多分三段),每一小段之间加下划线”_”,如tx_data_val;命名长度一般限制在20个字符以内。
d. 低电平有效信号,加后缀”_n”,如 rst_n
e. 无条件寄存的寄存信号在原信号上加ff1、ff2… 如原信号 data_in, 寄存一拍data_in_ff1,寄存两拍data_in_ff2
f. 不能用 ”reg”,作为最后的后缀名,因为综合工具会给寄存器自动加上_reg, 如果命名里就用_reg作为后缀名则扰乱了网表的可读性。
5.统一的表达式书写
A. 括号的使用
如果一个表达式的分组情况不是很明显时,加上括号有助于理解。
例如下面的代码加上括号就清晰很多。
if (&a==1’b1&&!flag==1’b1 || b==1’b1) //
改为:
if ((&a==1’b1)&&(!flag==1’b1)||( b==1’b1)) //
B.适当的使用空格
一般表达式在运算符的两侧要各留出一个空格,但定义比较长的表达式,去掉预先级高的运算符前的空格,使其与运算对象紧连在一起,可以更清晰的显示表达式结构。
还是上面的例子:
if ((&a==1’b1)&&(!flag==1’b1)||( b==1’b1)) //
改为:
if ((&a == 1’b1)&&(!flag == 1’b1)||( b == 1’b1)) //
”<=”, ”==”前后都要加空格。
C. 赋值要指明比特宽度
赋值或者条件判断时要注明比特宽度,注意表达式的位宽匹配。如:
reg [4:0] signal_a;
错误: 1 signal_a <= 5;
2 if(signal_a == 5)
3 signal_a <= signal_b[3:0]+4;
正确: 1 signal_a <= 5d5
2 if(signal_a == 5d5)
3 signal_a <= {1’b0,signal_b[3:0]+5d4
因为工具默认是32位宽,如果不注明位宽,工具检查会报warning,而且这样增加了设计的严谨性。
6.统一的语句书写――条件判断结构书写方式
A. 条件的完整性
Ifelse搭配使用,对于缺省的条件要写”else;”;
Ifelsed 条件判别式要全面,比如if(a == 1’b0);
Case中的缺省条件要写”default”;
B.”if else”结构:适用于复杂条件判断的语句
但对于复杂的条件判断,使用?:如果不仔细分析条件的每一条路径,就让读代码搞不清它是到底要做什么。例如:
C =(!Ic&&!rc)?0(Ic?rc:Ic) // (?:)
改为:
always @(Ic or rc) // if else
begin
if((Ic==0)&&(rc==0))
c = 0;
else if(Ic==1)
c = rc;
else
c = Ic;
end
即使是简单的条件判断,我们也必须使用IF-ELSE,当涉及复杂的条件判断,使用IF-ELSE结构以获得清晰的结构便于理解和维护。因此必须使用IF-ELSE。
C.”IFELSE”结构VS”CASE”结构
IF ELSE结构综合的结构可能是与或非门构成的,也可能是一组多路选择器,而case结构综合结果一般会是多路选择器,但对于可以优化的case综合工具会综合出更简单的结构。
所有对于可以写出平行结构的条件,优先写成case结构,例如地址译码等,条件之间有重复和嵌套的情况则是写成if else结构。
D. Finite StateMachine
不允许有模糊不清的状态机模式,所有的状态机必须清晰明了。
我们要求将状态机的时序部分和组合逻辑部分分开。
例如:
module state4 (
clock
reset
out
);
input reset
input clock;
output [1:0] out;
parameter [1:0] stateA=2’b00;
parameter [1:0] stateB=2’b01;
parameter [1:0] stateC=2’b10;
parameter [1:0] stateD=2’b11;
reg [1:0] state;
reg [1:0] nextstate;
reg [1:0] out;
always @ (posedge clock)
begin
if (reset ==1,0’b0)
state <= stateA;
else
state <= nextstate;
end
always @ (state)
begin
case (state)
stateA: begin
nextstate = stateB;
end
stateB: begin
nextstate = stateC;
end
stateC: begin
nextstate = stateD;
end
stateD: begin
nextstate = stateA;
end
endcase
end
always@(postdge clock or negedge reset)
begin
if (reset==1’b0)
out <= 2’b0;
else begin
if (state==…)
out <= …;
else
out <= …;
end
end
endmodule
7. 统一格式的always程序块的书写
A.always 中的变量的赋值方式――阻塞与非阻塞赋值
当进行时序逻辑建模时,always块中使用非阻塞赋值――NON_BLOCKING;
参加如下代码:
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1’b0;
myreg <=1’b0;
else
myreg <=‘DLY1’b1;
end
always块中使用的NON_BLOCKING赋值时在”<=”前要加上#‘DLY,如上例;
当使用always语句进行组合逻辑建模时,always块中使用阻塞赋值――BLOCKING;
参见如下代码:
always @(addr)
begin
case (addr)
2’b00 : cs0_n=1’b0;
2’b01 : cs0_n=1’b1;
2’b10 : cs0_n=1’b0;
2’b11 : cs0_n=1’b1;
default: cs0_n=1’b1;
endcase
end
· 如果要使用always语句同时进行时序与组合逻辑建模时,一定使用非阻塞赋值;例如:
//组合逻辑与时序逻辑在同一个always块中
always@(posedge clk or negedge reset_n)
begin
if(reset_n==1’b0)
out<=1’b0;
else
begin
case(count)
2’b00 : out<= `DLY in_a;
2’b01 : out<= `DLY in_b;
2’b10 : out<= `DLY in_c;
2’b11 : out<= `DLY in_c;
default: out<= `DLY in_a;
end
end
B.always中变量赋值的唯一性
· 组合always块一定要注意敏感量列表中的触发项完整且不冗余;如果不是这样,综合的电路会与实际设计不符合,会报warning;
· 不要再多个always模块中对同一个reg型变量进行赋值;
· 更不能再同一个always中随一个变量双重赋值;
例如:
always@(posedge clk or posedge reset_n)
begin
if(reset_n==1’b0)
out<=1’b0;
else
out<= `DLY1’b1; //out 1 0
out<= `DLY1’b0;
end
· 推荐不要在一个always块里给多个变量赋值。如果将一组条件相同的变量写在一个always块中更有利于可读性的提高和功能的实现时候,可有例外情况,但请尽量多加注释,以增加可读性,并注意在组合always块中不要出现LATCH(不如对状态机的组合always块及它对条件相似的多个变量赋值);
C.always中复位的书写
复位的条件表达式及命名要和always敏感列表中的描述相统一,并且一定要使用异步复位。所有的复位必须低有效。
例如:
//
always@(posedge clk ot negedge rst_n) //
begin
if(rst_n==1’b0)
…
else
…
end
D.always的注释
要在每一个always块之前加一段注释,增加可读性和便于调试。
//cmcarry count which …
always@(posedge clk_xc or negedge rst_n)
begin
if(rst_n==1’b0)
cm_carry_cnt<=1’b0;
else
cm_carry_cnt<=#`DLY1’b1;
end
8.合理的注释
· 代码中应采用英文作详细的注释,注释量应达到代码总量的50%以上。
· 指示应该与代码一致,修改程序的时候一定要修改相应的注释;
· 注释不应重复代码已经表明的内容,而是简介的点明程序的突出特征;
· 注释应该整个一个程序的线索和关键词,它连接整个程序中分散的信息并它帮助理解程序中不能表明的部分。
9.重用化设计
层次结构与模块划分
· 层次设计的原理以简单为主――尽量避免不必要的层次;层次结构设计得好,在综合中就不需要太多的优化过程;
· 模块的划分根据层次设计来决定――模块化对于布线有很大帮助,模块化的设计中要尽量减少全局信号的使用;
· 通用的部分尽量提取出来作为一个共用模块,同时为了适应需求的更改也应提供用户定制模块入库的方式。
参数传递
· 需要传递参数的模块,在多次例化的时候统一都传递参数,不要例化同一个模块,有的传参数,有的不传。
模块划分的技巧:
将不同的时钟域分离开来;
按照不同的设计目标划分成块,分块式应在数据流方向上切分;
在同一模块中实现逻辑资源和算术资源的共享。
二.关于REVIEW
1.Review目的
发现缺陷
降低成本
提高质量
2.流程
1. 完成第一个字模块时,请提交该模块代码,进行规范检查评审。
2. Coding 期间 每两星期 提交依次代码和review报告。
Review报告主要包括内容:
· Review工作时,review的代码模块
· 参与人
· 发现的缺陷和解决情况。
Review建议:
(1) 制定review计划;(2) 每次review代码不超过500行。
ANNEX
CODESTYLE TEMPLATE
This a template of verilog code file, including file header and themain body of code in which some coding rules are demonstrated.
//********************************************************
//
// Copyright(c)2005, Hisilicon Technologies Co., Ltd
// All rights reserved
//
// IPLIB INDEX : IP lib index just as UTOPIA_B
// IPName : the top module_name of this ip, usually, issame as
the small ipclassified name just as UTOPIA
// File name : file_name of this file just as tx_fifo.v
// Module name : module_name of this file just as TX_FIFO
// Full name : complete English name of the abbreviatedmodule_name
// Author : Author
// Email : Author’s email
// Data : 2005/07/20
// Version : current version, just this: v1.0, must sameas the CVS version
//
// Abstract :
//
// Called by : Father module just as TX_PROC
//
// Modification history
// ----------------------------------------------------------------------------
// Version Data(yyyy/mm/dd) name
// Description
//
// $Log$
//
//*************************************************************
//*******************
//DEFINE(s)
//*******************
//`define UDLY 1 //Unit delay, for non-blocking assignmentsin sequential logic
//*******************
//DEFINE MODULE PORT
//*******************
module MODULE_NAME(
//INPUT
rest_n ,
clk_* ,
a_din ,
b_din ,
//OUTPUT
a_dout ,
b_dout
);
//*******************
//DEFINE PARAMETER
//*******************
//Parameter(s)
//*******************
//DEFINE INPUT
//*******************
input rst_n ; //reset, active low .
input clk_* ; //clock signal, 50M .
input [n:0] a_din ; //*****
input [k:0] b_din ; //*****
//*******************
//DEFINE OUTPUT
//*******************
output [m:0] a_dout ; //*****
output [i:0] b_dout ; //*****
//********************
//OUTPUT ATTRIBUTE
//********************
//REGS
reg [m:0] a_dout ; //*****
//WIRES
wire [i:0] b_dout ; //*****
//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
reg [3:0] counter ; //*****
//WIRES
wire [7:0] temp1 ; //*****
//*********************
//INSTANTCE MODULE
//*********************
//**************************************************************
//instance of module MODULE_NAME_Afilename:module_name_a.v
//**************************************************************
MODULE_NAME_A U_MUDULE_NAME_A(
.A (A ),
.B (B ),
.C (C )
);
//*********************
//MAIN CORE
//*********************
//Sequential logic style
always@(posedge clk_* or negedge rest_n)
begin : SEQ_BLOCK_NAME
if(rst_n==1’b0)
counter<=4’b0;
else
begin
if (expression)
counter <= #`DLY siginal_b;
else;
end
end // SEQ_BLOCK_NAME
//Combinational logic style
always@(signal_a or signal_b)
begin:COM_BLOCK-NAME
case (expression)
item1 :begin
signal_c=*****;
end
item2 : //statement;
default ://statement;
endcase
end // COM_BLOCK_NAME
//*********************
endmodule
MACRO DEFINE TEMPLATE
//********************************************************
//
// Copyright(c)2005, Hisilicon Technologies Co., Ltd
// All rights reserved
//
// IPLIB INDEX : IP lib index just as UTOPIA_B
// IPName : the top module_name of this ip, usually, issame as
the small ipclassified name just as UTOPIA
// File name : macro.v
// Module name :
// Full name : complete English name of the abbreviatedmodule_name
// Author : Author
// Email : Author’s email
// Data : 2005/07/20
// Version : current version, just this: v1.0, must sameas the CVS version
//
// Abstract :
//
// Called by : Father module .
//
// Modification history
// ----------------------------------------------------------------------------
// Version Data(yyyy/mm/dd) name
// Description
//
// $Log$
//
//*************************************************************
//*******************
//DEFINE(s)
//*******************
`define UDLY 1 //Unit delay, for non_blocking assignmentsin sequential logic
`define DATA_WIDTH 32 //AHB data width
`define ADDR_WIDTH 32 //AHB address width
- Verilog代码标准
- verilog分频器代码
- Verilog代码编写规范
- verilog分频器代码
- verilog 24分频代码
- Verilog 代码 书写规范
- Verilog代码编写规范
- FIFO的verilog代码
- Verilog代码编辑工具
- verilog代码风格
- Verilog代码规范
- verilog代码风格
- verilog转c代码
- RGB数字信号VESA标准时序verilog设计
- verilog二分频代码&verilog三分频代码
- verilog二分频代码&verilog三分频代码
- Verilog代码编写规范-转贴
- Verilog代码编写规范小结
- modelsim使用命令
- Spring core
- poj.1753dfs
- 闪回数据库(Flashback Database)
- makefile双冒号规则
- Verilog代码标准
- Web开发中的用户角色权限设计总结
- Ruby函数lambda知识讲解
- 输入输出流的理解
- 如何在TOMCAT下指定JDK的路径
- Java heap terminology: young, old and permanent generations
- 第7周项目求a和b两个数之和
- 学习python动态扩展包stevedore
- pc 机上串口代码