5.2 代码编写中容易出现的问题
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;
只要加法器的输入端复用,就可以实现加法器的共享,使用一个加法器实现。
module COUNT (AndBits, Clk, Rst);
Output Andbits;
Input Clk,
Rst;
Reg AndBits;
//internal reg
Reg [2:0] Count;
always @(posedge Clk) begin
begin
if (Rst)
Count <= #u_dly 0;
else
Count <= #u_dly Count + 1;
End //end if
AndBits <= #u_dly & Count;
End //end always
endmodule
在进程里的变量都综合成触发器了,有4个;
module COUNT (AndBits, Clk, Rst);
Output AndBits;
Input Clk,
Rst;
Reg AndBits;
//internal reg
Reg [2:0] Count;
always @(posedge Clk) begin //synchronous
if (Rst)
Count <= #u_dly 0;
else
Count <= #u_dly Count + 1;
End //end always
always @(Count) begin //asynchronous
AndBits = & Count;
End //end always
Endmodule //end COUNT
组合逻辑单开,只有3个触发器.
module COUNT (Z, Enable, Clk, Rst);
Output [2:0] Z;
Input Rst,
Enable,
Clk;
reg [2:0] Z;
always @(posedge Clk) begin
if (Rst) begin
Z <= #u_dly 1'b0;
end
else if (Enable == 1'b1) begin
If (Z == 3'd7) begin
Z <= #u_dly 1'b0;
End
else begin
Z <= #u_dly Z + 1'b1;
end
End
Else ;
End //end always
Endmodule //end COUNT
是同步逻辑,而下例则使用了组合逻辑作时钟,以及异步复位.实际的运用中要加以避免.
module COUNT (Z, Enable, Clk, Rst);
Output [2:0] Z;
Input Rst,
Enable,
Clk;
Reg [2:0] Z;
//internal wire
wire GATED_Clk = Clk & Enable;
always @(posedge GATED_Clk or posedge Rst) begin
if (Rst) begin
Z <= #u_dly 1'b0;
end
else begin
if (Z == 3'd7) begin
Z <= #u_dly 1'b0;
end
else begin
Z <= #u_dly Z + 1'b1;
end
End //end if
End //end always
Endmodule //end module
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];
可以选择简洁的写法.
always @(Cond)
begin
if (Cond)
DataOut <= DataIn end
使用门控时钟(Gated clock)不利于移植 ,可能引起毛刺, 带来时序问题 ,同时对扫描链的形成带来问题。门控钟在低功耗设计中要用到 ,但通常不要在模块级代码中使用 。可以借助于Power compiler来生成 ,或者在顶层产生。
在设计中最好使用同步设计。如果要使用内部时钟 ,可以考虑使用多个时钟。因为使用内部时钟的电路要加到扫描链中比较麻烦,降低了可测性, 也不利于使用约束条件来综合。
模块中所有的寄存器最好同时复位。如果要使用内部复位, 最好将其相关逻辑放在单独的模块中, 这样可以提高可阅读性。
将这些信号的产生放在顶层的一个独立模块, 这样所有的子模块分别使用单一的时钟和复位信号。一般情况下内部门控时钟可以用同步置数替代。
/* *
Filename ﹕
Author ﹕
Description ﹕
Called by ﹕
Revision History ﹕mm/dd/yy
Revision 1.0
Email ﹕ M@sz.huawei.com.cn
Company ﹕ Huawei Technology .Inc
Copyright(c) 1999, Huawei Technology Inc, All right reserved
* */
Module module_name(
Output_ports, //comment ; port description
Input_ports, //comment ; port description
Io_ports, //comment ; port descripttion
Clk_port, //comment ; port description
Rst_port //comment ; port description
);
//port declarations
Output [31:;0] Dataout;
Input [31:0] Datain;
Inout Bi_dir_signal;
Input input1,
Input2;
//interrnal wire/reg declarations
Wire [31:0] internal_data;
Reg output_enable;
//module instantiations , Self-build module
Module_name1 Uinstance_name1(...);
Module_name2 Uinstance_name2(...);
// TSC4000 cell
DTC12 V1 (.Clk(Clk), .CLRZ(Clr), .D(Data), .Q(Qout));
//continuous assignment
Assign Data_out = out_enable ? Internal_data : 32’hz;
//always block
Always @(input2)
Begin
...
End
//function and task definitions
Functiom [function_type] function_name;
Declarations_of_inputs;
[declarations_of_local_variables];
Begin
Behavirol_statement;
Function_name = function_express;
End
Endfunction //end function_name
Endmodule //end module_name
下面是一个格雷码的测试模块,
module TB_GRAY;
reg Clock;
reg Reset;
wire [7:0] Qout;
integer fout; //输出文件指针
parameter CYC = 20;
GRAY DUT(.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 #CYC Clock = ~ Clock;
//输出数据到文件gray.dat
always @(posedge Clock)
begin
$fwrite(fout,"%d %b
",Qout,Qout);
end
endmodule
在testbench中避免使用绝对的时间,如#20,#15或#(CYC+15)等,应该在文件前面使用parameter定义一些常量,使得时间的定义象#(CYC+OFF0)的形式,便于修改。
观测结果可以输出到波形文件GRAY.shm ,或数据文件gray.dat 。生成波形文件可以用simwave观测结果 ,比较直观。而生成数据文件则既可以快速定位 ,也可以通过编写的小程序工具对它进行进一步的处理。
对大的设计的顶层仿真 ,一般不要对所有信号跟踪, 波形文件会很大, 仿真时间延长,可以有选择的观测一些信号。
全部0条评论
快来发表一下你的评论吧 !