5.2 代码编写中容易出现的问题
- 在for-loop中包括不变的表达式 浪费运算时间
for(i=0;i<4;i=i+1)
begin
Sig1=Sig2;
DataOut[i]=DataIn[i];
end
for-loop中第一条语句始终不变,浪费运算时间.
- 资源共享问题 条件算子中不存在 资源共享 ,如
z=(cond)?(a+b):(c+d);
必须使用两个加法器; 而等效的条件if-then-else语句则可以资源共享 如
if(Cond)
z=a+b;
else
z=c+d;
只要加法器的输入端复用,就可以实现加法器的共享,使用一个加法器实现。
- 由于组合逻辑的位置不同而引起过多的触发器综合 如下面两个例子
moduleCOUNT(AndBits,Clk,Rst);
OutputAndbits;
InputClk,
Rst;
RegAndBits;
//internalreg
Reg[2:0]Count;
always@(posedgeClk)begin
begin
if(Rst)
Count<=#u_dly0;
else
Count<= #u_dly Count + 1;
End//endif
AndBits<= #u_dly & Count;
End //endalways
endmodule
在进程里的变量都综合成触发器了,有4个;
moduleCOUNT(AndBits,Clk,Rst);
OutputAndBits;
InputClk,
Rst;
RegAndBits;
//internalreg
Reg[2:0]Count;
always@(posedgeClk)begin//synchronous
if(Rst)
Count<= #u_dly 0;
else
Count<= #u_dly Count + 1;
End//endalways
always@(Count)begin//asynchronous
AndBits=&Count;
End//endalways
Endmodule//endCOUNT
组合逻辑单开,只有3个触发器.
- 谨慎使用异步逻辑
moduleCOUNT(Z,Enable,Clk,Rst);
Output[2:0]Z;
InputRst,
Enable,
Clk;
reg[2:0]Z;
always@(posedgeClk)begin
if(Rst)begin
Z<=#u_dly1'b0;
end
elseif(Enable==1'b1)begin
If(Z==3'd7)begin
Z<=#u_dly1'b0;
End
elsebegin
Z<= #u_dly Z + 1'b1;
end
End
Else;
End//endalways
Endmodule//endCOUNT
是同步逻辑,而下例则使用了组合逻辑作时钟,以及异步复位.实际的运用中要加以避免.
moduleCOUNT(Z,Enable,Clk,Rst);
Output[2:0]Z;
InputRst,
Enable,
Clk;
Reg[2:0]Z;
//internalwire
wireGATED_Clk=Clk&Enable;
always@(posedgeGATED_ClkorposedgeRst)begin
if(Rst)begin
Z<=#u_dly1'b0;
end
elsebegin
if(Z==3'd7)begin
Z<=#u_dly1'b0;
end
elsebegin
Z<= #u_dly Z + 1'b1;
end
End//endif
End//endalways
Endmodule//endmodule
- 对组合逻辑的描述有多种方式 其综合结果是等效的
c=a&b;
等效于
c[3:0]=a[3:0]&b[3:0];
等效于
c[3]=a[3]&b[3];
c[2]=a[2]&b[2];
c[1]=a[1]&b[1];
c[0]=a[0]&b[0];
等效于
for(i=0;i<=3;i=i+1)
c[i]=a[i]&b[i];
可以选择简洁的写法.- 考虑综合的执行时间
- 避免点到点的例外
- 避免伪路径(False path)
- 避免使用Latch
- 当你必须使用Latch时 ,为了提高可测性, 需要加入测试逻辑。
always@(Cond)
begin
if(Cond)
DataOut<=DataInend
- 避免使用门控时钟
使用门控时钟(Gated clock)不利于移植 ,可能引起毛刺, 带来时序问题 ,同时对扫描链的形成带来问题。门控钟在低功耗设计中要用到 ,但通常不要在模块级代码中使用 。可以借助于Power compiler来生成 ,或者在顶层产生。
- 避免使用内部产生的时钟
在设计中最好使用同步设计。如果要使用内部时钟 ,可以考虑使用多个时钟。因为使用内部时钟的电路要加到扫描链中比较麻烦,降低了可测性, 也不利于使用约束条件来综合。
- 避免使用内部复位信号。
模块中所有的寄存器最好同时复位。如果要使用内部复位, 最好将其相关逻辑放在单独的模块中, 这样可以提高可阅读性。
- 如果确实要使用内部时钟, 门控时钟 ,或内部的复位信号 ,将它们放在顶层。
将这些信号的产生放在顶层的一个独立模块, 这样所有的子模块分别使用单一的时钟和复位信号。一般情况下内部门控时钟可以用同步置数替代。
6 附录
6.1 Module 编写示例
/**
Filename﹕
Author﹕
Description﹕
Calledby﹕
RevisionHistory﹕mm/dd/yy
Revision1.0
Email﹕M@sz.huawei.com.cn
Company﹕HuaweiTechnology.Inc
Copyright(c)1999,HuaweiTechnologyInc,Allrightreserved
**/
Modulemodule_name(
Output_ports,//comment;portdescription
Input_ports,//comment;portdescription
Io_ports,//comment;portdescripttion
Clk_port,//comment;portdescription
Rst_port//comment;portdescription
);
//portdeclarations
Output[31:;0]Dataout;
Input[31:0]Datain;
InoutBi_dir_signal;
Inputinput1,
Input2;
//interrnalwire/regdeclarations
Wire[31:0]internal_data;
Regoutput_enable;
//moduleinstantiations,Self-buildmodule
Module_name1Uinstance_name1(...);
Module_name2Uinstance_name2(...);
//TSC4000cell
DTC12V1(.Clk(Clk),.CLRZ(Clr),.D(Data),.Q(Qout));
//continuousassignment
AssignData_out=out_enable?Internal_data:32’hz;
//alwaysblock
Always@(input2)
Begin
...
End
//functionandtaskdefinitions
Functiom[function_type]function_name;
Declarations_of_inputs;
[declarations_of_local_variables];
Begin
Behavirol_statement;
Function_name=function_express;
End
Endfunction//endfunction_name
Endmodule//endmodule_name
6.2 testbench编写示例
下面是一个格雷码的测试模块,
moduleTB_GRAY;
regClock;
regReset;
wire[7:0]Qout;
integerfout;//输出文件指针
parameterCYC=20;
GRAYDUT(.Clock(Clock),.Reset(Reset),.Qout(Qout));
initial
begin
Clock=1'b0;
Reset=1'b1;
#(5*CYC)Reset=1'b0;
#(5*CYC)Reset=1'b1;
#(5000*CYC)
$fclose(fout);
$finish;
end
initial
begin
$shm_open("GRAY.shm");
$shm_probe("AS");
fout=$fopen("gray.dat");
end
always#CYCClock=~Clock;
//输出数据到文件gray.dat
always@(posedgeClock)
begin
$fwrite(fout,"%d%b
",Qout,Qout);
end
endmodule
-
在testbench中避免使用绝对的时间,如#20,#15或#(CYC+15)等,应该在文件前面使用parameter定义一些常量,使得时间的定义象#(CYC+OFF0)的形式,便于修改。
-
观测结果可以输出到波形文件GRAY.shm ,或数据文件gray.dat 。生成波形文件可以用simwave观测结果 ,比较直观。而生成数据文件则既可以快速定位 ,也可以通过编写的小程序工具对它进行进一步的处理。
-
对大的设计的顶层仿真 ,一般不要对所有信号跟踪, 波形文件会很大, 仿真时间延长,可以有选择的观测一些信号。
审核编辑:郭婷
-
Verilog
+关注
关注
28文章
1341浏览量
109910 -
代码
+关注
关注
30文章
4710浏览量
68190
原文标题:【华为】verilog语言编写规范(三)
文章出处:【微信号:ZYNQ,微信公众号:ZYNQ】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论