**这是本文档旧的修订版!**

====1.RTL CODE 规范====

===1.1标准的文件头===

在每一个版块的开头一定要使用统一的文件头,其中包括作者名,模块名,创建日期,概要,更改记录,版权等必要信息。 统一使用以下的文件头:其中为必需的项目 <code verilog> Copyright©2016, ECBC All rights reserved File name : MODULENAME.v Module name : MODULE_NAME Author : tony-ning Description :
Email : Author’s email Data : 2016/08/01 Version : current version, just this: v1.0 Abstract :
Modification history —————————————————————————- Version : Data(yyyy/mm/dd):
Name : Description : * </code> ===1.2标准的module格式=== —— 对于模块的书写采用统一的格式便于项目内部成员的理解和维护,我们用批处理建立了一个MODULE模块,其内容解释如下:
端口定义按照输入,输出,双向的顺序:
模块名、模块例化名统一,例化名前加大写U以区分 ( 多次例化另加标识 ),三者关系:
文件名 :xxx .v (小写)
模块名 :XXX (大写)
例化名 :U
XXX (大写)
IP 内部所有的模块名都要加IP名或者IP名简称作前缀,如USBCTRL、USBTXFIFO。 <code verilog> * DEFINE MODULE PORT module MODULENAME 模块名一行 ( 括号顶格,端口部分换行 INPUT 尽量先输入,后输出定义 inputport1, 可同时按接口对象等分类,一行一个 … inputportm, OUTPUT outputport1, … outputport_m, ); * DEFINE PARAMETER parameter… 参数名采用大写 DEFINE INPUT input rstn ; reset, (active low) . input到寄存器名之间四个tab键,注意对齐 input clk* ; clock signal , 50M . 注意注释的格式,简洁有力,尽量使用英文 input [n:0] adin ; * 此处是在模块名部分没有声明端口类型时用 input [k:0] bdin ; * 注释尽量不要挨到前面,然后全左对齐 DEFINE OUTPUT
output [m:0] adout ; * 位宽定义和output之间加一个tab或空格,统一即可 output [i:0] bdout ; * OUTPUT ATRRIBUTE
REGS reg [m:0] adout ; * WIRES wire [i:0] bdout ;
* INSTSNCE MODULE
MODULENAMEA UMODULENAME_A(
例化名从和模块名相距四个tab,括号后换行 .A (A ), 端口和例化名对齐,后3个tab再括号连线 .B (B ), 括号内3个tab的宽度,全对齐 .C (C ), ); … MAIN CODE
… … … … … … endmodule 结尾顶格,中间部分均从一个tab开始 </code> ===1.3一致的排版=== ——
A. 一致的缩排 <code verilog> 统一的缩排取4个空格宽度 输入输出信号的宽度定义与关键字之间,信号名与宽度之间要用tab分开;所有宽度定义对所有信号名对齐,代码风格统一如下:
input [3:0] inputa ; input inputb ; … output [128:0] outputa ; output [15:0] outputb ; output outputc ; </code>
B.一致的 begin end 书写方式 <code verilog> always 中,一定要用begin end 区分,格式和代码风格统一如下: always @ (postedge clk or negedge rstn) begin if (rstn==1’b0) synrst⇐ ‘DLY 1’b0; else begin if (a==b) synrst⇐ ‘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 </code> ===1.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.基于含义命名(避免以数字命名的简单做法),含义可分段(最多分三段),每一小段之间加下划线””,如txdataval;命名长度一般限制在20个字符以内。
d.低电平有效信号,加后缀”
n”,如 rstn
e.无条件寄存的寄存信号在原信号上加ff1、ff2… 如原信号 data
in, 寄存一拍datainff1,寄存两拍datainff2
f.不能用 ”reg”,作为最后的后缀名,因为综合工具会给寄存器自动加上reg, 如果命名里就用reg作为后缀名则扰乱了网表的可读性。 ====2.模板示例==== —— <code verilog>
Copyright©2016, ECBC All rights reserved File name : MODULENAME.v Module name : MODULENAME Full name : complete English name of the abbreviated module_name Author : tony-ning Description :
Email : Author’s email Data : 2016/08/01 Version : current version, just this: v1.0 Abstract :
Called by : Father module . Modification history —————————————————————————- Version Data(2016/08/01) V1.0 Description $Log$ DEFINE(s) * DEFINE(s) * define UDLY 1 //Unit delay, for non-blocking assignments in sequential logic //******************* //DEFINE MODULE PORT //******************* module MODULE_NAME ( //INPUT rest_n , clk_* , a_din , b_din , //OUTPUT a_dout , b_dout ); //******************* //DEFINE PARAMETER //******************* parameter T1S = 24_999_999; //******************* //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_A filename: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 siginalb; else; end end SEQBLOCKNAME Combinational logic style always@(signala or signalb) begin:COMBLOCK-NAME case (expression) item1 :begin signalc=*; end item2 : statement; default :statement; endcase end COMBLOCKNAME assign out = expression ? (1’b0):(1’b1); * endmodule </code>