5.2 代碼編寫中容易出現(xiàn)的問題
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;
只要加法器的輸入端復用,就可以實現(xiàn)加法器的共享,使用一個加法器實現(xiàn)。
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
在進程里的變量都綜合成觸發(fā)器了,有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個觸發(fā)器.
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)不利于移植 ,可能引起毛刺, 帶來時序問題 ,同時對掃描鏈的形成帶來問題。門控鐘在低功耗設計中要用到 ,但通常不要在模塊級代碼中使用 ??梢越柚赑ower compiler來生成 ,或者在頂層產(chǎn)生。
在設計中最好使用同步設計。如果要使用內部時鐘 ,可以考慮使用多個時鐘。因為使用內部時鐘的電路要加到掃描鏈中比較麻煩,降低了可測性, 也不利于使用約束條件來綜合。
模塊中所有的寄存器最好同時復位。如果要使用內部復位, 最好將其相關邏輯放在單獨的模塊中, 這樣可以提高可閱讀性。
將這些信號的產(chǎn)生放在頂層的一個獨立模塊, 這樣所有的子模塊分別使用單一的時鐘和復位信號。一般情況下內部門控時鐘可以用同步置數(shù)替代。
/* *\ 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; //輸出數(shù)據(jù)到文件gray.dat always @(posedge Clock) begin $fwrite(fout,"%d %b\n",Qout,Qout); end endmodule
在testbench中避免使用絕對的時間,如#20,#15或#(CYC+15)等,應該在文件前面使用parameter定義一些常量,使得時間的定義象#(CYC+OFF0)的形式,便于修改。
觀測結果可以輸出到波形文件GRAY.shm ,或數(shù)據(jù)文件gray.dat 。生成波形文件可以用simwave觀測結果 ,比較直觀。而生成數(shù)據(jù)文件則既可以快速定位 ,也可以通過編寫的小程序工具對它進行進一步的處理。
對大的設計的頂層仿真 ,一般不要對所有信號跟蹤, 波形文件會很大, 仿真時間延長,可以有選擇的觀測一些信號。