240 likes | 344 Views
第 九 章 有用的程式技巧 (Useful Modeling Techniques). 9.1 程序持續指定 (Procedural Continuous Assignments) 9.1.1 assign 和 deassign 關鍵字 assign 和 deassign 是用來表示,第一種型態的程式持續指定。程式持續指定的左邊,可以是暫存器或者連續的暫存器,而不能是一個接點的部份位元或暫存器的陣列。程式持續指定複寫正規程序指定,其一般運用在週期控制。
E N D
第 九 章 有用的程式技巧 (Useful Modeling Techniques)
9.1 程序持續指定(Procedural Continuous Assignments) 9.1.1 assign和deassign 關鍵字assign和deassign是用來表示,第一種型態的程式持續指定。程式持續指定的左邊,可以是暫存器或者連續的暫存器,而不能是一個接點的部份位元或暫存器的陣列。程式持續指定複寫正規程序指定,其一般運用在週期控制。 範例6-8的非同步設定負緣觸發D型正反器,在範例9-1中將使用assign和deassign完成。
範例9-1 程序持續指定D型正反器 //非同步設定負緣觸發D型正反器 module edge‑dff (q, qbar, d, clk, reset); //輸出輸入 output q, qbar; input d, c.k, reset; reg q, qbar; //宣告q和qbar是暫存器變數 always @(negedge clk) // 在clock負緣指定q和qbar的值 begin q = d; qbar =~d; end always @(reset) //當reset為高電位使用程序持續指定複寫q //和qbar
if (reset) begin //如果reset為高電位,使用程序持續指定複寫q和qbar assign q=1’b0; assign qbar=1’b1; end else begin //如果reset為低電位,移除複寫在移除複寫後,q=d //and qbar=~d 將要等到下一個clock負緣才能更改暫存 //器變數的值 deassign q; deassign qbar; end endmodule
9.2 複寫參數(Overriding Parameters) 9.2.1 defparam敘述 關鍵字defparam可用來模組別名(module instance)中之參數,模組別名之階層名可用來複寫參數值。 範例9-2說明使用defparam敘述,來更改參數的方法。 範例9-2 defparam敘述 //定義模組hello_world module hello_world; parameter id_num = 0; // 定義一模組識別數 = 0 initial // 顯示識別數 $display(“Displaying hello_world id number=%d”,id_num); endmodule
//定義最高層次模組 module top; //改變在這取別名模組的參數值 //使用 defparam敘述 defparam w1.id_num = 1, w2.id_num = 2; //取別名二個hello_world模組 hello_world w1 (); hello_world w2 (); endmodule
9.3 有條件的編譯與執行(Conditional Compilation and Execution) vVerilog程式的部分可能是用某些環境,而不是用某些環境,再某些旗標被設定時才被編譯,這就是有條件的編譯。 9.3.2 有條件的編譯 有條件的編譯是由編譯指令:‘ifdef、’ifndf、’else、’elsif和‘endif來完成。
範例9-5 有條件的編譯 //有條件的編譯 //範例1 ‘ifdef TEST //如果文字巨集TEST北定義,編譯模組test。 module test; … … endmodule ‘else //否則預設編譯模組stimulus module stimulus; … … endmodule ‘endif //完成 ‘ifdef 條件敘述
範例9-5 有條件的編譯(續) //範例2 module top; bus_master b1();//無條件取別名模組 ‘ifdef ADD_B2 bus_master b2();//如果文字巨集ADD_B2被定義,取別名模組b2. ‘elsif ADD_B3 bus_master b3(); //如果文字巨集ADD_B3被定義,取別名模組b3。 ‘else bus_master b4(); //預設取別名模組b4 ‘endif
範例9-5 有條件的編譯(續) ‘ ifdif IGNORE_B5 bus_master b5(); //如果文字巨集ADD_B3未被定義,取別名模組b5。 ‘endif endmodule
9.4 時間刻度(Time Scales) 模擬當中經常需要在某一模組中定義延遲數值的時間單位,如lus,而在另一模組又中定義不同的時間單位,如100ns。 範例9-8 時間刻度 //定義模組dummy1的時間刻度 //時間單位為100奈秒,精確度為1奈秒。 ‘timescale 100 ns /1 ns module dummy1; reg toggle; //設定toggle初始值 initial toggle = 1‘b0; //每5個時間單位,反轉toggle暫存器變數值 //在模組中,每5個時間單位=500 ns =.5us always #5
begin toggle =~toggle; $display(“%d, In %m toggle =%b”, $time ,toggle); end endmodule // 定義模組dummy2的時間刻度 // 時間單位為1微秒,精確度為10奈秒。 ‘timescale 1us/10ns module dummy2; reg toggle;
// 設定toggle初始值 initial toggle = 1‘b0; // 每5個時間單位,反轉toggle暫存器變數值。 // 在模組中,每5個時間單位 = 5us =5000ns。 always #5 begin toggle =~toggle; $display(“%d, In %m toggle = %b”, $time, toggle); end endmodule
9-5 有用的系統任務(Useful System Tasks) 系統任務:檔案輸出、顯示階層、閃控、亂數產生器。 9.5.1 檔案輸出(File Output) 系統任務$fopen可開啟一個檔案 語法:$fopen(“<name_of_file>”); 語法:<file_handle>=$fopen(“<name_of_file>”); 任務$fopen將傳回32位元的值叫作多通道描述符號,僅有一個位元會被設定,標準輸出的多通道描述符號的最末一個位元會被設定(bit=0),標準輸出叫作通道0(channel 0 )。
Writing to files The system tasks $fdisplay, $fmonitor, $fwrite, and $fstrobe are used to write to files Usage: $fdisplay(<file_descriptor>, p1, p2 ..., pn); $fmonitor(<file_descriptor>, p1, p2,..., pn);
9.5.3 閃控(Strobing) 關鍵字為$strobe類似$display,但是,當有多個敘述和 $display在同一時間執行,則其執行順序是不可知的。如果,$strobe運用在相同的地方,則可確定在同一時間執行的敘述,將先執行後才執行$strobe。(always executed after all other assignment statements ) 範例9-11 閃控 // 閃控 always @ (posedge clock) begin a = b; c = d; end always @ (posedge clock) $strobe(“Displaying a=%b, c=%b”, a, c); // 在正緣觸發顯示值
9.5.4 亂數產生器(Random Number Generation) 語法: $random; 語法: $random(<seed>); <seed>參數可以是reg、integer或是time變數,系統任務$random會送出32位元的有號整數,如範例9-12。 範例9-12 亂數產生 // 產生亂數並送至一個簡單的ROM module test; integer r_seed; reg [31:0] addr; // 輸入到ROM wire [31:0] data; // 從ROM輸出 … … ROM rom1 (data,addr);
initial r_seed = 2; // 任意定義seed為2 always @ (posedge clock) addr = $random (r_seed); // 產生亂數 … // <比對ROM的輸出與預期的結果> … … endmodule
9.5.5 Initializing Memory from File • Two tasks are provided to read numbers in binary or hexadecimal format. • Keywords $readmemb and $readmemh • Usage: • $readmemb("<file_name>", <memory_name>); • $readmemb("<file_name>", <memory_name>, <start_addr>); • $readmemb("<file_name>", <memory_name>, start_addr>,<finish_addr>); • Identical syntax for $readmemh.
Example 9-14 Initializing Memory • module test; • reg [7:0] memory[0:7]; //declare an 8-byte memory • integer i; • initial • begin • //read memory file init.dat. address locations given in memory • $readmemb("init.dat", memory); • module test; • //display contents of initialized memory • for(i=0; i < 8; i = i + 1) • $display("Memory [%0d] = %b", i, memory[i]); • end • endmodule
Example 9-14 Initializing Memory • A sample file, init.dat, is shown below. • @002 • 11111111 01010101 • 00000000 10101010 • @006 • 1111zzzz 00001111 • When the test module is simulated, we will get the following output: • Memory [0] = xxxxxxxx • Memory [1] = xxxxxxxx • Memory [2] = 11111111 • Memory [3] = 01010101 • Memory [4] = 00000000 • Memory [5] = 10101010 • Memory [6] = 1111zzzz • Memory [7] = 00001111
9.5.6 數值變化轉儲檔案(Value Change Dump File) 所有的信號或一組被選擇的信號,在模擬時皆可被寫入數值變化轉儲檔案。後置處理器可以將數值變化轉儲檔案輸入、並顯示階層資訊、信號值和信號波形。使用數值變化轉儲檔案除錯分析的流程如圖9.1。 儲 至 數 值 改 變 計 畫 VCD File 除錯/分析原因 後 置 處 理 器 圖9.1 數值變化轉儲檔案除錯分析的流程
VCD System tasks • System tasks are provided for selecting module instances or module instance signals to dump ($dumpvars), name of VCD file ($dumpfile), starting and stopping the dump process ($dumpon, $dumpoff), and generating checkpoints ($dumpall).
Example 9-15 VCD File System Tasks • //specify name of VCD file. Otherwise,default name is • //assigned by the simulator. • initial • $dumpfile("myfile.dmp"); //Simulation info dumped to myfile.dmp • //Dump signals in a module • initial • $dumpvars; //no arguments, dump all signals in the design • initial • $dumpvars(1, top); //dump variables in module instance top. • //Number 1 indicates levels of hierarchy. Dump one • //hierarchy level below top, i.e., dump variables in top, • //but not signals in modules instantiated by top. • initial • $dumpvars(2, top.m1);//dump up to 2 levels of hierarchy below top.m1 • initial • $dumpvars(0, top.m1);//Number 0 means dump the entire hierarchy • // below top.m1 • //Start and stop dump process • initial • begin • $dumpon; //start the dump process. • #100000 $dumpoff; //stop the dump process after 100,000 time units • end • //Create a checkpoint. Dump current value of all VCD variables • initial • $dumpall;