1、第 八 章任務與函數 (Tasks and Functions),8.1 任務與函數不同之處(Differences between Tasks and Functions),表8-1 任務與函數,8.2任務(Tasks) 任務是以關鍵字task與endtask宣告,適用的情況如下:需要用到延遲、時間或是事件控制指令的時候。需要有零個或一個輸出的時候。沒有輸入的時候。,8.2.1任務的宣告與引用 輸入輸出的關鍵字input跟output,對一個任務而言是將訊號傳出彙傳入一個任務的工作而已,並不是一個埠。,8.2.2任務範例 在任務中如何使用input跟output。任務bitwise_oper
2、是將兩個十六位元的數,a與b分別作位元邏輯運算的結果顯示出來,總共有兩個輸入a與b,三個輸出ab_or與ab_and與ab_xor。,範例8-2 任務中的input與output,/定義一個名為operation的模組,並包含一個名為bitwise_/oper的任務。 module operation;parameter delay=10; reg15:0 A,B; reg15:0 AB_AND, AB_OR, AB_XOR;,always (A or B) /每當A or B改變其值 begin/呼叫任務bitwise_oper並提供兩個數入引數A、B/提出三個輸出引數ab_or,ab_an
3、d,ab_xor。/引數的順序必須要跟定義任務時的順序相同 bitwise_oper(ab_or,ab_and,ab_xor) end /定義任務bitwise_oper task bitwise_oper; output15:0 ab_or,ab_and,ab_xor; /任務的輸出 input15:0a,b; /inputs to the task begin,範例8-2 任務中的input與output(續),#delay ab_and=a end endtask endmodule,範例8-2 任務中的input與output(續),8.3 函數 (Functions) 函數的宣告適用
4、關鍵字function與endfunction,適用的時機 如下: 程序中沒有延遲、時間或是事件控制的指令時。 程序傳回單一個值時。 至少有一個傳入參數的時候。 沒有輸出或輸出入埠。 沒有阻礙程序。,8.3.1 函數的宣告與引用 當函數宣告的時候,verilog同時也內宣告了一個以函數的名稱為名的暫存器,當函數執行完畢,函數的輸出則經由這個暫存器傳回到我們呼叫函數的地方。,8.3.2 範例,列舉兩個範例,一個是奇偶計時器,傳回1個位元表示輸入數的奇偶性質,第二個是32位元的左/右移位器,傳回一個32位元的移位結果。,/定義一個包含函數calc_parity的模組 module parity;
5、reg31:0 addr; reg parity; /當address值改變的時候,即重新計算奇偶性 always (addr) begin,範例8-7 奇偶計時器,parity=calc_parity(addr); /第一次呼叫 calc_parity 函數$display(“Parity calculated=%b”,calc_parity(addr); /第二次呼叫 calc_parity 函數 end /定義計算奇偶性質的函數 function calc_parity;,input 31:0 address; begin /運用內定的暫存器 calc_parity 來輸出值 calc_
6、parity =address; /利用簡化的互斥或運算計算出 address 的奇偶性 end endfunction endmodule,/定義一個包含有函數shift的模組 module shifter; /左/右移位器 define LEFT_SHIFT 1b0 define RIGHT_SHIFT 1b1 reg31:0 addr,left_addr,right_addr; reg control; /當addr值變動時,即重新計算新addr的左/右移位後的值 always (addr),範例8-9 左/右移位器,begin /呼叫shift函數計算左移或右移left_addr=sh
7、ift(addr,LEFT_SHIFT);right_addr=shift(addr,RIGHT_SHIFT); end /定義一個輸出為32位元的shift函數 function31:0shift; input 31:0address; input control; begin,/視control訊號作左移或是右移運算 shift=(control=LEFT_SHIFT)?(address1):(address1); end endfunction endmodule,8.3.3 自動(遞迴)函數 通常函數並不會有遞迴使用的狀況,如果同時間兩段程式呼叫使用同一個函數,因為函數內佔用同一份記憶
8、體空間,會造成無法確認的結果,所以我們利用關鍵字automatic來定義一個自動(允許遞迴)函數,將會動態分配到獨立的空間給函數,彼此不會干擾。範例8-10是利用automatic的功能來實作階乘。 範例8-10 利用遞迴(Automatic)函數,/利用遞迴函數呼叫來作階乘 module top; /定義函數 function automatic integer factorial; input 31:0 oper;,integer i; begin if(operand=2)factorial= factorial(oper-1)*oper; /遞迴呼叫 elsefactorial=1; end endfunction /呼叫函數 integer result;,initial beginresult=factorial(4);/計算4的階乘$display(“Factorial of 4 is %0d”,result);/答案是24 end endmodule,