SystemVerilog——任務和函數(Tasks and Functions)

SystemVerilog從Verilog繼承了任務和函數功能。任務和函數是兩種用來定義子程序的方式。如果子程序需要消耗仿真時間,使用任務,否者子程序消耗仿真時間爲0,則使用函數。另外,函數可以有返回值,而任務沒有。

SystemVerilog給任務和函數增加了新的語義特性. 這些新的特性對高級抽象建模非常重要:

  • 靜態和自動作用域
  • 參數傳遞
  • 線程
  • 參數化函數

靜態和自動作用域

 


Verilog中變量的作用域

Verilog中,任務和函數中局部定義的變量是靜態作用域。因此,如果多次調用函數/任務,則此局部變量將在多個函數執行線程中共享。在遞歸函數以及任務中通過fork-join執行多線程的情況下發生。因此,Verilog的函數/任務僅僅只可能本地(native)遞歸。由於Verilog主要用來做RTL級的設計,遞歸函數不是必須的。

【【譯者查資料,猜想本地遞歸是指函數調用中沒有變量,僅僅只有函數自己和參數的運算,舉例如下:

fibonacci (n) 
        if (n <2) return n
        else return fibonacci(n-1)+fibonacci(n-2)

】】

靜態和自動作用域

Statically靜態作用域變量被綁定到應用程序的數據存儲區域(在這裏是指仿真器). 此存儲區域將被所有的線程所共享. 而另一方面對於自動變量,將映射到棧區存儲區, 對同一個函數進行多次調用,自動變量將映射到棧中互補相同的區域。

For 對於行爲級建模,遞歸和多線程基本上都需要。爲此,SystemVerilog允許變量以自動作用域綁定。爲了在函數/任務中使用自動綁定功能,函數/任務需要聲明爲automatic. 另外,所有在program塊中聲明的函數/任務缺省都是自動作用域的。如果在自動作用域子程序中仍然需要使用靜態變量,那麼必須使用static關鍵字顯式聲明此變量。注意在C/C++以及其他語言中,缺省就是這樣的(類似program塊中的樣子: 缺省自動,顯式聲明靜態)。

 

 

 

 

 


//Factorial using automatic binding

function automatic int unsigned factorial(int unsigned n);

  if (n = 1) return 1;

  else return n * factorial(n-1);

endfunction: factorial


參數傳遞


下面講述使用函數的通用情況,大部分也是用於SystemVerilog的任務.

值傳遞

SystemVerilog中函數參數缺省是通過值傳遞,適用於所有的數據類型,包括容器類型。唯一一個例外是類對象,對象本身並沒有綁定到變量描述符,描述符所綁定的是對象的句柄(類似C/C++中的指針). 當一個類實例(實際上是它的句柄)被傳遞的時候,句柄本身是值傳遞,但是,因爲句柄僅僅是指向真實數據,所以,被參數指向的真實的對象就和函數(任務)內部看到的對象是一樣的——等效於類對象看起來是通過引用來傳遞的.

SystemVerilog提供了一個ref關鍵字作爲函數參數的前綴。當使用ref時,表明參數是使用引用傳遞,'ref'語法類似C++中的引用.

有兩種情況下使用'ref'做參數比較有意義。第一種情況,由於函數只能有一個返回值(不考慮傳統Verilog上的input/output參數端口聲明),任務沒有返回值。當函數需要返回多個值或者任務需要返回一個以上值的時候,通過引用傳遞就用得上。

第二種情況是運行效率的考慮。當大量的數據需要作爲參數傳遞的時候,值傳遞效率很低。所有的數據需要在每次函數調用的時候被複制。如果參數使用'ref'前綴,可以不需要進行數據複製。但是這樣會使得參數的數據容易被函數/任務中的代碼修改。此危險可以通過聲明ref參數爲常量來解決.

 

 

 

 

 


// virtual base class
class xactn;
  // user functions
  virtual function void pack(ref bytes[]);
  virtual function void unpack(const ref bytes[]);
  // other function declarations omitted
endclass

 

 

 

 

函數參數中的缺省值

SystemVerilog允許給函數設置缺省值。如果沒有給參數指定值,並且參數有缺省值,那麼函數將使用參數的缺省值。此指定缺省值的語法和C++類似.


task void foo (int unsigned x, int unsigned y = 10);
  // the tasks implementation is not provided
endtask: foo

SystemVerilog提供了額外的特徵,不像C++, SystemVerilog允許用戶將使用指定值的參數放在使用缺省值的參數的後面。使用缺省的參數很簡單的在函數調用的參數列表中不出現,後面指定值的參數放在一個逗號後面,此逗號在一個空格之後,表示沒有相應的參數。


function void foo(int unsigned first = 1,

                                int unsigned second = 2,

                         int unsigned third = 3,

                         int unsigned fourth = 4);

  // function's code omitted

endfunction: foo

// foo函數的調用例子:

// 第3個和第4個參數使用缺省值

foo (10, 20);

// 第1個和第3個參數使用缺省值

foo ( ,20, ,40);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章