RTL建模中的函數(shù)和任務(wù)(Function 和 task)
SystemVerilog的函數(shù)和任務(wù)可以將復(fù)雜的功能劃分為更小的、可重用的代碼塊。函數(shù)對于RTL建模非常有用,本文將對此進(jìn)行研究。
任務(wù)雖然有自己的優(yōu)勢,但在RTL模型中幾乎沒有價值。使用void函數(shù)(將在本節(jié)后面討論)是比使用任務(wù)更好的RTL編碼方式。因此,本文僅簡要討論任務(wù)。
函數(shù)和任務(wù)可以在使用它們的模塊或接口中定義。定義可以出現(xiàn)在調(diào)用函數(shù)或任務(wù)的語句之前或之后完成,函數(shù)和任務(wù)也可以在包中定義,然后導(dǎo)入到模塊或接口中,包導(dǎo)入語句必須出現(xiàn)在調(diào)用函數(shù)或任務(wù)之前。
函數(shù)
調(diào)用時,函數(shù)執(zhí)行其編程語句并返回值。對函數(shù)的調(diào)用可以在任何可以使用表達(dá)式(如網(wǎng)絡(luò)或變量)的地方使用。這里展示了一個函數(shù)定義示例和對該函數(shù)的調(diào)用。本節(jié)后面將展示更實用的可綜合示例。

SystemVerilog語法要求函數(shù)在零仿真時間內(nèi)執(zhí)行。可綜合函數(shù)不能包含時鐘周期或傳播延遲。
靜態(tài)和自動(Static and automatic)函數(shù)。函數(shù)(和任務(wù))可以聲明為靜態(tài)或自動。如果兩者都未指定,則模塊、接口或包中定義的函數(shù)的默認(rèn)值為靜態(tài)。
靜態(tài)函數(shù)保留從一個調(diào)用到下一個調(diào)用的任何內(nèi)部變量或存儲的狀態(tài)。函數(shù)名和函數(shù)輸入是隱式內(nèi)部變量,在函數(shù)退出時將保留它們的值。
這種靜態(tài)存儲的效果是-對函數(shù)的新調(diào)用可以記住以前調(diào)用的值。這種“記憶性”在驗證代碼中很有用,但這種行為并不能準(zhǔn)確地仿真綜合編譯器從函數(shù)實現(xiàn)的門級行為,這可能導(dǎo)致RTL模型仿真與ASIC或FPGA的實際功能不匹配。
自動函數(shù)在每次調(diào)用該函數(shù)時都會分配新的存儲。遞歸函數(shù)調(diào)用(如上文所示的 階乘f(factorial_f) 函數(shù)示例)需要自動存儲(兩個不同過程同時調(diào)用同一任務(wù)的可重入任務(wù)調(diào)用也需要自動存儲)
| 最佳實踐指南6-8 |
|---|
| 將RTL模型中使用的函數(shù)聲明為自動函數(shù)。 |
靜態(tài)存儲的默認(rèn)設(shè)置不適用于硬件行為的RTL建模。此外,綜合編譯器要求包或接口中聲明的函數(shù)必須聲明為自動函數(shù)。
函數(shù)默認(rèn)為靜態(tài)存儲是有歷史原因的。在Verilog仿真的最初幾年,當(dāng)時計算機(jī)內(nèi)存有限且處理器速度慢得多,靜態(tài)存儲有助于提高仿真運(yùn)行時性能,與使用現(xiàn)代仿真器和計算服務(wù)器的自動存儲相比,靜態(tài)存儲沒有性能優(yōu)勢。SystemVerilog標(biāo)準(zhǔn)保留了靜態(tài)函數(shù)的原始語言默認(rèn)值,以便與遺留的驗證代碼保持向后兼容,這些代碼可能是為了利用函數(shù)的靜態(tài)存儲而編寫的。
函數(shù)返回。
函數(shù)的返回數(shù)據(jù)類型定義在函數(shù)名之前。在上面的 階乘f(factorial_f) 示例中,該函數(shù)返回一個N位寬的向量,其類型為logic(4-state)。如果未指定返回類型,則默認(rèn)情況下,函數(shù)返回為1位logic(4-state)類型。
SystemVerilog提供了兩種指定函數(shù)返回值的方法。一種方法是使用return關(guān)鍵字,如上面的factorial_f示例所示。return關(guān)鍵字后面是函數(shù)要返回的值?;蛘?,可以將此返回值括在括號中。
第二種指定返回值的方法是為函數(shù)名賦值。函數(shù)名是與返回值數(shù)據(jù)類型相同的隱式變量類型,當(dāng)函數(shù)計算返回值時,此隱式變量可用于臨時存儲。分配給函數(shù)名的最后一個值將成為函數(shù)返回值。本節(jié)開頭顯示的 階乘f(factorial_f) 函數(shù)可以重新編碼,以使用函數(shù)名作為隱式內(nèi)部變量來計算返回值。

Void函數(shù)。
函數(shù)返回類型可以聲明為void。Void函數(shù)不返回值,不能像其他函數(shù)一樣用作表達(dá)式。void函數(shù)被稱為語句,而不是表達(dá)式。

| 最佳實踐指南6-9 |
|---|
| 使用void函數(shù)代替任務(wù)進(jìn)行RTL建模。僅在驗證代碼中使用任務(wù)。 |
void函數(shù)和任務(wù)之間的唯一區(qū)別是函數(shù)必須在零時間內(nèi)執(zhí)行。大多數(shù)綜合編譯器不支持任務(wù)中任何形式的時鐘延遲。使用void函數(shù)代替任務(wù)使得這種綜合限制成為語法要求,并且可以防止編寫可以仿真但不可以綜合的RTL模型。
函數(shù)參數(shù)。函數(shù)定義中的參數(shù)稱為形式參數(shù)(formal arguments)。函數(shù)調(diào)用中的參數(shù)稱為實際參數(shù)(actual arguments)。形式參數(shù)可以是input、output或inout,并使用與模塊端口相同的語法聲明,默認(rèn)方向(如果未定義)為input,上面fill_packet示例中的形式參數(shù)是32-bit 4-state輸入,用戶定義的packet_t類型的輸出形式參數(shù)。
形式參數(shù)也可以聲明為ref(reference的縮寫)代替端口方向(direction),ref參數(shù)是指向函數(shù)調(diào)用的實際參數(shù)的指針形式,函數(shù)必須聲明為自動函數(shù)(automaticfunction)才能使用ref參數(shù)。
| 最佳實踐指南6-10 |
|---|
| 在RTL模型中使用的函數(shù)中只使用輸入和輸出(input 和 output)形式參數(shù),不要使用inout或ref形式參數(shù)。 |
所有RTL綜合編譯器都支持輸入和輸出(input 和 output)函數(shù)參數(shù)。某些RTL綜合編譯器不支持inout和ref參數(shù)。
調(diào)用函數(shù)。
調(diào)用函數(shù)時,將實際參數(shù)傳遞給形式參數(shù)有兩種編碼樣式:按順序傳遞和按名稱傳遞。按順序傳遞時,第一個實際參數(shù)傳遞給第一個形式參數(shù),第二個實際參數(shù)傳遞給第二個形式參數(shù),依此類推。按名稱傳遞使用與按名稱連接模塊相同的語法。形式參數(shù)的名稱前面有逗號(.),后跟括號中的實際參數(shù)。
給定函數(shù)定義:

傳遞實際參數(shù)的兩種方式是:

函數(shù)輸入默認(rèn)值。
可以為形式參數(shù)指定默認(rèn)值,如下所示:

具有默認(rèn)值的參數(shù)不需要傳遞實際參數(shù),如果沒有傳遞實際參數(shù),則使用默認(rèn)值。例如:

如果傳入實際值,則使用實際值,如下所示:

| 筆記 |
|---|
| 在編寫本文時,一些綜合編譯器不支持默認(rèn)輸入值,工程師應(yīng)該確保項目中使用的設(shè)計流程中的所有工具在RTL模型中使用之前都支持默認(rèn)參數(shù)值。 |
使用return提前退出函數(shù)。
return語句也可以用于在函數(shù)中的所有語句都執(zhí)行之前退出函數(shù),下面的示例可以在3個不同的點退出函數(shù)。如果 max 輸入為0,則函數(shù)在執(zhí)行for循環(huán)之前退出;如果for循環(huán)迭代器達(dá)到max值,則函數(shù)在到達(dá)循環(huán)末尾之前退出;如果for循環(huán)完成,則函數(shù)在到達(dá)endfunction時退出。

參數(shù)化函數(shù)(Parameterized function)。
參數(shù)化函數(shù)是SystemVerilog中功能強(qiáng)大且廣泛使用的功能。可以為模塊的每個實例重新定義參數(shù),使模塊易于配置和重用。模塊級參數(shù)可以在函數(shù)定義中使用,如前面的sum_to_endpoint_f函數(shù)示例所示。使用模塊級參數(shù)意味著對函數(shù)的所有調(diào)用將具有相同的向量大小。如果調(diào)用函數(shù)的每個位置使用不同的向量大小,則無法對函數(shù)進(jìn)行配置。
函數(shù)不能像模塊那樣進(jìn)行參數(shù)化,SystemVerilog不允許函數(shù)定義具有內(nèi)部參數(shù),這些參數(shù)可以在調(diào)用函數(shù)的每個地方重新定義——這限制了編寫可重用、可配置函數(shù)的能力。但是,對于這個限制,有一個解決方法,即在參數(shù)化虛擬類中聲明靜態(tài)函數(shù),可以使用范圍解析操作符(無需創(chuàng)建對象)直接調(diào)用類定義中的靜態(tài)函數(shù)。
在調(diào)用函數(shù)的每個地方,都可以重新定義類(class)參數(shù),如下例所示:

參數(shù)化函數(shù)可以只創(chuàng)建和維護(hù)函數(shù)的一個版本,而不必定義具有不同數(shù)據(jù)類型、向量寬度或其他特征的多個版本。
請注意,在類定義中,static關(guān)鍵字位于function關(guān)鍵字之前,而在模塊中,static或automatic關(guān)鍵字位于function關(guān)鍵字之后。有一個重要的語義差異,在類中,靜態(tài)函數(shù)聲明類中函數(shù)的生存期,并限制函數(shù)在類中可以訪問的內(nèi)容,在模塊中,靜態(tài)函數(shù)或自動函數(shù)指函數(shù)中參數(shù)和變量的生存期。
| 筆記 |
|---|
| 在寫這本文的時候,并不是所有的綜合編譯器都支持參數(shù)化虛擬類中的靜態(tài)函數(shù)。在RTL模型中使用靜態(tài)函數(shù)之前,工程師應(yīng)該確保項目中使用的所有工具都支持參數(shù)化虛擬類中的靜態(tài)函數(shù)。 |
任務(wù)-Task
任務(wù)是封裝一條或多條編程語句的子例程,因此可以從不同的位置調(diào)用封裝的語句,或在其他項目中重用。與函數(shù)不同,任務(wù)沒有返回值。一個例子是:

任務(wù)被稱為編程語句,并使用輸出形式參數(shù)從任務(wù)中傳遞值。

語法上;任務(wù)與函數(shù)非常相似,只是任務(wù)沒有返回類型。任務(wù)和函數(shù)之間的一個重要區(qū)別是,任務(wù)可能包含時鐘周期和傳播延遲。然而,大多數(shù)綜合編譯器要求任務(wù)中的編程語句在零仿真時間內(nèi)運(yùn)行。這種綜合限制使任務(wù)幾乎與void函數(shù)相同,因為void函數(shù)在語法上強(qiáng)制零時間執(zhí)行,所以最佳編碼實踐是在RTL模型中需要子例程時使用void函數(shù)而不是任務(wù)。上面的ReverseBits任務(wù)可以重寫為void函數(shù),如下所示:

審核編輯:劉清
-
FPGA
+關(guān)注
關(guān)注
1660文章
22410瀏覽量
636273 -
asic
+關(guān)注
關(guān)注
34文章
1274瀏覽量
124576 -
RTL
+關(guān)注
關(guān)注
1文章
394瀏覽量
62650
原文標(biāo)題:SystemVerilog-Function 和 task
文章出處:【微信號:Open_FPGA,微信公眾號:OpenFPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于任務(wù)鏈的實時多任務(wù)軟件可靠性建模
S函數(shù)建模和仿真過程的研究
如何在Zstack中實現(xiàn)自己的任務(wù)詳細(xì)分析和函數(shù)資料概述
FreeRTOS任務(wù)控制API函數(shù)介紹
FreeRTOS任務(wù)應(yīng)用函數(shù)介紹
FreeRTOS系列第12篇---FreeRTOS任務(wù)應(yīng)用函數(shù)
Verilog設(shè)計中函數(shù)和任務(wù)的作用分析
如何使用Arduino millis函數(shù)執(zhí)行多任務(wù)處理
X態(tài)如何通過RTL級和門級仿真模型中的邏輯進(jìn)行傳播呢?
Verilog任務(wù)與函數(shù)的區(qū)別
FreeRTOS中內(nèi)核控制函數(shù)
FreeRTOS中其他任務(wù)API函數(shù)
FreeRTOS任務(wù)通知通用發(fā)送函數(shù)
RTL建模中的函數(shù)和任務(wù)討論
評論