//OUTPUTs clocks , resets , enables ,
other control signals data
,
? 在输入和输出两类端口之间留一个空行来提高可读性。如上例所示。 ? 端口列表之后,使用parameter定义内部信号宽度以及其他参数化设置。 ? IO信号申明和内部信号申明要单独成行,参考sample.v文件
? 使用简单的语句,一般使用if … else…和case就能满足大部分需求,不要使用复
杂的语句 ? 常量
(1)一位的控制信号采用二进制表达方式,如1'b0; (2)常数位宽不可缺省; 如:
Bad: if ((rst_n == 0) && (cnt_addr == 15)) Good:if ((rst_n == 1'b0) && (cnt_addr == 5'd15)) ? 变量
(1)Net and Register
(a)一位位宽的wire信号的声明不可缺省 (b)一个reg变量只可以在一个always语句中赋值
(c)(建议)任一register的赋值加上单位延迟,对异步复位同样加上单位延迟; (d)向量有效位顺序的定义采用倒序格式,如:Data[4:0] (2)Memory
代码中不建议使用Memory(存储器阵列),Memory只用于Testbench中,访问存储器阵列中某一向量的某一位或几位,需要通过中间变量进行。 例:
reg[15:0] mem[0:255];
temp = mem[33]; //temp gets data at addr 33 3_bit_reg = temp[8:6]; //get three bits of addr 33 ? 运算符及表达式 (1)表达式
(a)用括号来表示执行的优先级,尽管操作符本身有优先顺序,但用括号表示优
第 9 页 共 28 页
先级对读者更清晰,更有意义 如:
Bad: A + B ? C : D; Good: (A + B) ? C : D; (b)适当使用括号
适当使用括号可以控制生成的电路结构,如Z = A + B + C + D,综合结果可能为三级加法器,而变换为Z = (A + B) + (C + D),综合结果则可能为两级加法器; (c)注意资源共享
需要资源共享的部分一定要放在同一个模块的同一个always语句中,不同模块不同always语句之间的代码不能实现资源共享。 如:always @(...)
if (...) d0 = A + B; else
d0 = C + D;
中,DC可能只会生成一个加法器。 条件算子中不存在资源共享
如:z = (cond==1’b1)? (a+b) : (c+d); 必须使用两个加法器;
而等效的条件if-else语句可以资源共享,如: if (cond==1’b1) z = (a+b); else z = (c+d);
只要加法器的输入端复用,就可以实现加法器的共享,使用一个加法器实现。 (d)尽量采用公共子表达式
如 : x=a+b+c y=d+a+b 改为:z=a+b
x=z+c y=d+z
(2)算符
(a)条件运算符
第 10 页 共 28 页
r1 = gate? r2 : r3; 避免使用条件嵌套:
r1 = (aa = 0)? ((bb == 0)? r2 : r3) : r4; or r1 = {aa,bb} == 0? r2: {aa,bb} == 0? r3: {aa,bb} == 0? R4:r4; (b)逻辑操作符
在if(),while(),()?A:B 之类的表达式中,括号中的表达式应该是一个逻辑表达式,相应的操作符应该用逻辑操作符。 如:wire x,A,B;
(x) ? A:B 与 (x == 1'b1) ? A:B If(A&B) 与 if((A&&B)==1’b1)
While(A=B) 与 while(A==B) 操作结果相同,但显然前者不规范。 (c)乘法运算符“*”
对于一个变量data与常数constant相乘data * constant,如果常数不是2的整数次幂,建议先将其分解,如constant= 53 = 32 + 16 + 4 + 1 = 2^5 + 2^4 + 2^2 + 2^0,这样乘积就可以表示为变量data移位结果的相加。对于乘法运算符“*”,综合后通常得到的是乘法器,时延较大。
? 赋值语句
(1)不要在信号列表中进行运算操作
如:Bad: addr(a,b,d&e); Good: addr(a,b,c); c=d&e; (2)BLOCK赋值和NON-BLOCK赋值的使用
(a)组合逻辑采用BLOCK赋值(=)
如:
always @(dat) i_dat = dat;
(b)非组合逻辑(主要是寄存器)采用NON-BLOCK赋值并加delay以保证前仿真和后仿真的一致
如:
always @(posedeg clk) q <= #`DEL d;
(3)在同一块语句中不允许同时出现阻塞赋值和非阻塞赋值
第 11 页 共 28 页
? 条件语句 (1)IF语句
(a)向量比较时,比较的向量长度要相等,同样向量和常量比较时长度也要求匹
配,长度不同时要求进行显式位扩展(verilog对位数小的向量做0扩展以使它们的长度相匹配,该扩展是隐式的)
如:
reg [7:0] abc; reg [3:0] def; .......
if (abc == {4'b0,def}) begin .......
if (abc == 8'h0) begin (b)不要采用if表达式的简写形式
例如:
if (variable) 等同于 if (variable != 0) if (!variable) 等同于 if (variable == 0) 但后者才合乎规范
(c)每个if都应该有一个else与之相对应,如果条件为假时不进行任何操作,
则用一条空语句else;避免产生latch (d)if...else if...else if...else的代码书写格式如下,要注意优先级
if (...) begin ...... end else begin
if (...) ...... else (...) if (...) else (...) end
(d)如果变量在if-else语句中非完全赋值,则应给变量一个缺省值
第 12 页 共 28 页
相关推荐: