SystemVerilog中關於DPI章節的翻譯

35. Direct Programming Interface

需求

隨着時代的發展,如今的芯片規模愈來愈大,哪怕模塊級的驗證環境也須要至關長的build時間,各類仿真工具也在改進編譯和運行性能,還發明瞭增量編譯。但不管如何turnaround的時間仍是比較長,並且方法越複雜越容易出錯。而DPI-C則比較簡單,可以解決某些場景下的問題。程序員

適用範圍

DPI-C比較適用於SV和外部語言間的「簡單數據「交互編程

翻譯約定

subroutine == 子例程 == task and function
task == 子任務
function == 子函數
foreign language == 外部編程語言
在某些狀況下會保留英文表述不作翻譯數組

通用

下面章節主要包括:安全

  • DPI 子任務和子函數
  • DPI層
  • 導入和導出子函數
  • 導入和導出子任務
  • 禁用 DPI 子任務和子函數

35.2 總述

本章節主要描述了DPI以及接口中SV層的細節。
DPI是SV和外部編程語言的接口。它包含兩個獨立的層次: SV層 和 外部編程語言層。兩側是被徹底隔離的,也就是說它們彼此是透明的, 外部編譯語言和SV側徹底無關。不管是SV編譯器仍是外部編程語言編譯器都不會分析對方的代碼。不一樣編程語言應該均可以被同樣的SV層支持。但目前SV只定義了對C的支持。數據結構

這個接口的動機是雙面的。方法學上的要求是整個系統能夠包含多種語言而不只僅是SV,另外一方面是已有的代碼(好比C,C++)可以被很容易地集成進來。多線程

DPI遵循black-box原則。描述和實現隔離。真正的實現方法對於系統的其餘部分是透明的。 由於外部語言對SV來說也是透明的,不過這個標準目前只定義了C連接語義。 SV和C經過子函數爲基本單元來封裝和交互。因此任何子函數均可以被當成黑盒子,它的實現或者在SV中,或者在外部編程語言中,它的實現修改了但無需修改調用側。socket

35.2.1 tasks/functions

DPI容許語言之間的相互子函數調用。展開來說就是,SV能夠調用外部編程語言裏定義和實現的子函數,對SV來說就是imported functions; 外部編程語言能夠調用SV裏定義和實現的子函數,對SV來說就是exported functions,須要在SV中做導出聲明。DPI容許經過子函數的參數和結果來在兩個域中傳遞數據。這個接口沒有固有的開銷。編程語言

外部語言代碼也可調用SV task, 原生的SV代碼也可能調用imported tasks.
imported tasks和原生的SV task在語義上是同樣的:ide

  • 無返回值
  • 能夠消耗仿真時間

全部DPI 子函數都是不消耗仿真時間的,DPI沒法提供除數據交換和控制權轉移之外的同步手段.函數

每一個imported的subroutine都必須先聲明。
import聲明能夠寫在任何SV subroutine容許的地方。同一個外部subroutine能夠被多處調用。
imported subroutine能夠有0個可多個 input, output, inout 參數。
imported tasks只能返回void value; imported function能夠返回值或void value.

35.2.2 Data types

SV 數據類型必須是可以跨越SV和外部語言的類型, 稱爲富類型:

  • void, byte, shortint, int, longint, real, shortreal, chandle, string
  • scalar value of bit and logic
  • packed arrays, structs, uniions composed of types bit and logic
  • emumeration types (interpreted as the associated real type)
  • types constructed from the following constructs:

    • struct
    • union(packed only)
    • unpacked array
    • typedef

下面是一些注意點:

  • enum 不能被直接支持,實際上會被解釋爲enum type關聯的類型
  • 在exported DPI subroutine裏, 聲明形參爲dynamic array容易出錯
  • SV data的實際內存結構對於SV是透明的。

Function的返回值必須是small values:

  • void, byte, shortint, int, longint, real, shortreal, chandle, string
  • scalar value of bit and logic

而imported function的形參能夠是open arrays

35.2.2.1 內存數據結構

DPI並無對於數據在內存裏的存在形式作任何約束, 因此這是平臺相關的,和SV無關

35.3 DPI的兩層

DPI由獨立的兩層組成: SV層和外部編譯語言層。他們不相互依賴。雖然SV能夠支持各類編譯語言,但目前SV標準只對C作了詳細定義。不一樣的外部編程語言能夠要求SV實現使用適合的函數調用協議,參數傳遞,連接機制。但這對於用戶來說是透明的。SV標準只要求仿真器的實現者支持C協議和連接。

35.3.1 SV layer

不依賴於外面究竟是什麼語言。外部語言的實際函數調用規則和參數傳遞機制對於SV來說是透明和無關的。SV同等看待因此外部語言接口。SV側的接口語義和外部編譯語言側的接口無關。

35.3.2 foreign language layer

定義實參是如何被傳遞的, SV data(如logic, packed)是如何表示的。如何與類C的類型轉換
對於不一樣的外部語言,SV端的代碼應該是同樣的

35.4 imported and exported functions的全局命名空間

每一個imported subroutine最終最會有一個全局符號標誌;而每一個exported subroutine會定義一個全局符號標誌。
它們必須惟一。它們遵循C的命名規則,必須以字母或_開頭。
import和export聲明時能夠定義顯式地一個全局名字。它必須是以開頭以空格結尾

export "DPI-C" f_plus = function \f+ ; // "f+" exported as "f_plus"
export "DPI-C" function f; // "f" exported under its own name
import "DPI-C" init_1 = function void \init[1] (); // "init_1" is a linkage name
import "DPI-C" \begin = function void \init[2] (); // "begin" is a linkage name

相同C標識符的多個export 聲明是容許,前提是它們在不一樣的scope裏

35.5 imported tasks and functions

35.5.1 屬性 (properties)

pure
若是一個function的返回值只依賴於它的輸入參數,且沒有反作用, 那麼它能夠聲明爲pure
imported task毫不能聲明爲pure
context
一個imported subroutine要調用exported subroutines, 或要獲取SV data objects(e.g., via VIP calls)而不是它的實際值, 那麼須要聲明它爲context。
若是沒有描述,那麼subroutine應該不訪問SV data objects; 不過它能夠進行一些有反作用的行爲,好比寫文件,操做一個全局變量
compiler不會對這些properties進行檢查, 因此使用它們要當心

35.5.1.1 instant completion of imported functions

它們當即被執行,而且無耗時

35.5.1.2 input, output, inout

input: 不會被修改
ouput: output的初始值是不肯定的,因此imported function不該該依賴於它
inout: imported function能夠獲得inout變量的初始值。imported function對於inout參數的修改能夠被function外面看到

35.5.1.4 內存管理

外部語言和SV各自負責本身內存的申請和釋放
一個比較複雜且容許的狀況是一個imported function申請了一塊內存並把handle傳到SV裏, 而後SV調用另外一個imported function來釋放它

35.5.1.5 重入 (Reentrancy of imported tasks)

對於imported task的調用可能會致使自身進程暫停。這種狀況發生在imported task又調用帶有delay或event wait的exported task時。
因此有可能一個imported C code把多個線程同時激活。關於標準的重入規則是由C端決定。可使用一些標準的多線程安全庫,或者靜態變量來作控制

35.5.1.6 C++異常 (C++ exceptions)

可使用C++,但前提是在language邊界遵照C連接約定。
C++異常不該該傳播到subroutine之外, 若是異常傳遞到SV裏,那麼這是一個未定義的行爲

35.5.2 Pure functions

pure function特色之一是若是它的返回不須要那麼能夠把pure function調用去掉。或者它的輸入沒變,那麼能夠不用從新計算。
只有沒有output和inout形參的nonvoid function能夠被聲明爲pure
聲明爲pure的function沒有任何反作用
返回只依賴於輸入值
對於這種funciton的調用能夠被SV compiler優化。或者當input沒變時,能夠直接使用以前的值
pure function應該不直接或間接(好比調用其餘function)執行下面動做:

  • 文件操做
  • 對任何事物的讀寫,包括I/O, 環境變量,來自操做系統,程序,進程的對象, shared memory, socket等
  • 訪問任何永久變量,好比全局的或靜態的變量

35.5.3 context tasks and functions

當imported subroutine要求調用上下文須要被知道時,調用者要採起特別的指令來提供這樣的上下文。特殊的指令好比建立一個指向目前實例的內部變量。
當有當context被顯式指定時,纔會作這樣的instrumentation。

exported subroutine必須知道它被調用時的上下文, 包括當它們被imported subroutine調用時。
imported subroutine能夠在調用exported subroutine前,先調用svSetScope來顯式地設定上文。不然,exported sobroutine的上下文就是調用import subroutine時的實例所在上下文。因爲一個imported subroutine會存在於多個實例化後的做用域(scope)裏, 因此展開(elaboration)後會有多個exported subroutine的實例(instances).若是不調用svSetScope, 那麼這些exported instances的上下文就是調用imported subroutine的做用域(instantiated scope)

外部語言能夠經過一些其餘接口(如 VPI callback)來調用svSetScope或其餘DPI相關的scope APIs, 而後也能夠在一個指定的做用域(instantiated scope)裏調用exported subroutine。
DPI的scope相關APIs的行爲和DPI exported subroutine的調用由各simulator決定,DPI spec不作規定

在SV裏最開始調用imported subroutine的地方稱爲調用鏈初始點(root of the call chain)

上下文屬性會從SV裏應用到每個imported subroutine. 這意味着根部的或調用鏈中間的imported call不必定可以把它的上下文環境傳遞到它的下一個import call.
因此一個無上下文環境的imported subroutine不可以調用一個SV exported subroutine. 這樣的行爲會致使出錯

下面是關於imported call chain的一些特性:

  • 下面動做決定導入調用鏈(import call chain)的上下文值:

    • 當SV subroutine調用一個導入DPI subroutine, 一個導入聲明所在的實例化做用域的上下文就爲這個導入調用鏈(imprt call chain)建立好了
    • 當處於導入調用鏈(import call chain)中的一個routine調用svSetScope並傳入一個合法參數時,調用鏈的上下文就被設置成svSetScope參數所示上下文
    • 當一個導入調用鏈中調用一個導出的SV subroutine完成並返回時,調用鏈的上下文回到調用前的值
  • 仿真器須要管理DPI的上下文,須要檢測控制權如何在SV和外部語言間傳遞。若是用戶代碼裏經過如C裏的setjmp/longjmp等結構來從一個導出的調用鏈(SV)回到它的導入調用鏈的調用者(C), 那麼它的結果是未定義的。(例如:CA -> SVA -> CB, CB裏經過setjmp/longjmp回到CA)
  • 一個特定的import subroutine是否上下文相關是由它自身聲明時的context屬性決定的。這個屬性不會傳遞到它的後續的import function (譯者注:這個地方是function而不是subroutine?)
  • import call的上下文特性沒法動態改變
  • 上下文特性和調用鏈綁定,而不是和imported subroutine; 所以,一個subroutine能夠在一個調用鏈中是context,而在另外一個調用鏈中non-context。

一個沒有定義爲context的imported subroutine只訪問它的實現參數。因此不是仿真器優化的障礙。而context的imported subroutine可以經過VPI和export subroutine來訪問任何SV data objects, 因此會形成SV compiler的優化障礙。

只有context imported subroutine是被特殊裝置地,並只作保守的優化。只有這種subroutine能夠在安全地其餘subroutines, 包括VPI或exported SV subroutines; 不然調用VPI和exported SV subroutine的行爲是不可預測的,若是被調用者須要的上下文沒有普查正確設置,那麼會形成崩潰。定義一個context import subroutine並不會使simulator的其餘接口自動可用。好比VPI訪問仍是依賴於正確的實現機制。DPI 調用不會自動建立或提供任何句柄或特定環境給其餘接口用。這個是用戶的責任。

context imported subroutines老是隱性地有一個完整實例名的做用域(scope)。這個做用域定義了哪些SV subroutines能夠被importored subroutine直接調用;也只有這此在相同做用域的exported subroutine能夠被直接調用。若是要調用其餘的exported SV subroutine, imported subroutine須要先修改它的目前做用域。

相關的DPI functions能夠容許imported subroutines來獲取或接口用它的做用域, 如svGetScope(), svSetScope, svGetNameFromScope, svGetScopeFromName。

35.5.4 Import declarations

全部imported subroutine都須要被聲明。
imprted subroutine和SV的subroutine類似,能夠有0個或多個input, output或inout形參。imported functions能夠返回一個或0個(void)值。imported tasks老是返回一個int值,在外部語言裏至關於一個int function。
(譯者: 原文中說是做爲DPI disable protocol的一部分,沒搞明白)

dpi_import_export ::=                                                         // from A.2.6
        import dpi_spec_string [ dpi_function_import_property ] [ c_identifier = ] dpi_function_proto ;
        | import dpi_spec_string [ dpi_task_import_property ] [ c_identifier = ] dpi_task_proto ;
        | export dpi_spec_string [ c_identifier = ] function function_identifier ;
        | export dpi_spec_string [ c_identifier = ] task task_identifier ;
dpi_spec_string ::= "DPI-C" | "DPI"
dpi_function_import_property ::= context | pure
dpi_task_import_property ::= context
dpi_function_proto  ::= function_prototype
dpi_task_proto ::= task_prototype
function_prototype ::= function data_type_or_void function_identifier [ ( [ tf_port_list ] ) ]
task_prototype ::= task task_identifier [ ( [ tf_port_list ] ) ]             // from A.2.7

21) dpi_function_proto return types are restricted to small values, per 35.5.5
22) Formals of dpi_function_proto and dpi_task_proto cannot use pass by reference mode and class types cannot be
passed at all; see 35.5.6 for a description of allowed types for DPI formal arguments.

import 聲明描述了subroutine名, function返回值類型,和它的形參的類型和方向。它也可以提供形參的默認值。形參名是可選的,除非須要按名稱綁定參數。
imported function能夠有contextpure屬性; imported tasks能夠有context屬性

導入聲明至關於定義一個subroutine名, 因此多個相同的subroutine名是不容許導入同一做用域的。

  • dpi_spec_string*能夠取"DPI-C"或「DPI」。「DPI"是用於指示使用不建議用的sv packed array傳輸語義。這種語義下,參數是使用它在仿真器裏的表示法來傳遞,而不是規一化的形式。
  • c_identifier*是這個subroutine在外部語言裏的連接名(linkage name). 若是沒有提供的話就和它的SV subroutine名相同。

對於一個c_identifier, 全部聲明都必須使用相同的類型簽名(type signature), 包括返回值類型, 每一個參數的數目, 順序, 方向, 類型。類型包括維數,數組的邊界和維數。類型簽名也包括pure/context限定符, 和dpi_spec_string的值。

在多個不一樣做用域中能夠有一樣imported或exported subroutine的多個不一樣聲明;所以, 參數名和默認值可能不一樣。

正式的參數名要區別packed和unpacked數組維數。

限定符ref不能用在import聲明中。實際的實現方法只決取於外部語言層。實現方法對於SV邊是透明的。

下面是一些聲明的例子:

import "DPI -C " function void myInit();

// from standard math library
import "DPI -C " pure function real sin(real);

// from standard C library: memory management
import "DPI -C " function chandle malloc(int size); // standard C function
import "DPI -C " function void free(chandle ptr); // standard C function

// abstract data structure: queue
import "DPI -C " function chandle newQueue(input string name_of_queue);

// Note the following import uses the same foreign function for
// implementation as the prior import, but has different SystemVerilog name
// and provides a default value for the argument.
import "DPI -C " newQueue=function chandle newAnonQueue(input string s=null);
import "DPI -C " function chandle newElem(bit [15:0]);
import "DPI -C " function void enqueue(chandle queue, chandle elem);
import "DPI -C " function chandle dequeue(chandle queue);

// miscellanea
import "DPI -C " function bit [15:0] getStimulus();
import "DPI -C 」 context function void processTransaction(chandle elem, output logic [64:1] arr [0:63]);
import "DPI -C " task checkResults(input string s, bit [511:0] packet)

35.5.5 Function result

imported function的返回值類型被限定爲"small values":

  • void , byte , shortint , int , longint , real , shortreal , chandle , and string
  • Scalar values of type bit and logic

一樣的限定也適用於exported function的返回值類型上

35.5.6 Types of formal argument (形參類型)

SV中豐富的數據類型能夠被做爲形參用於imported和export的例程。一般,C兼容的類型,packed類型,用戶定義的類型和他們的組合均可以用做DPI例程的形參。
下面是SV中容許的全部能夠做爲DPI例程形參的類型:

  • void, byte, shortint, int, longint, real, shortreal, chandle, time, integer, string
  • bit, logic
  • 由bit, logic組成的packed數組,結構體或聯合體。在外部語言側,全部packed類型數據都被譯成1維的數組。
  • 枚舉類型被解釋成同枚舉自己相同的類型
  • 新類型能夠同下面幾種方法構建

    • struct
    • union (packed only)
    • Unpacked array
    • typedef

下面是一些注意事項:

  • 枚舉類型不能被直接支持。代替地,枚舉數據的實際類型被使用
  • SV沒有規定 packed或unpacked結構體,數組的實際內存存放結構。unpacked數據和它們的打包方式有管,而打包方式和C編譯器有關。
  • 在導出的DPI例程中, 不容許使用動態數組作爲形參
  • SV數據類型在內存中的實際存放結構對於SV語義來說是透明的。它和外部語言有關。但咱們能夠大約知道SV數據類型是如何實現的。除了unpacked array,對導入例程的形參類型並無什麼限制。SV實現方式限制了哪些unpacked arrays會被當成固定大小的數組。(雖然它也能夠被傳輸成非固定大小的open array). 實際的變量和實現相關,而open array提供了一種實現無關的方法。

35.5.6.1 Open arrays

不管是packed維,或是unpacked維,或者二者均可以保留爲空。這樣的數據就叫open array. Open array提供了一種針對不一樣數據大小的通用解決方案。
導入函數的形參能夠被描述成open array. 而導出函數不可以使用它做爲形參。open array是惟一的一種放鬆參數匹配規則的方法。實際參數就能夠處理不一樣大小的數據,從而達到代碼通用化的目標。
雖然數組的packed部分能夠是任意大小的,形參的變長維只能有一個是packed維。 這不是很是嚴厲的, packed類型都等價於一個一維packed數組,因此只有一個是可變的就至關於整個均可變。而unpacked維則沒有限制。
若是形參有一個變長的packed維, 那麼它將匹配任何packed維的實參。若是形參的unpacked維是變長的,那麼它要求實參擁有同樣的維數,只不過對應的具體維上長度是可變的。
下面是一些合法形參的例子:

logic
bit [8:1]
bit []
bit [7:0] array8x10 [1:10]
logic [31:0] array32xN []
logic [] arrayNx3 [3:1]
bit [] arrayNxN []

下面是導入函數聲明例子

import "DPI-C" function void f1(input logic [127:0]);
import "DPI-C" function void f2(logic [127:0] i []); //open array of 128-bit

下面是利用open array來匹配不一樣長度實參的例子

typedef struct {int i; ...} MyType;
import "DPI-C" function void f3(input MyType i [][]);

MyType a_10x5 [11:20][6:2];
MyType a_64x8 [64:1][-1:-8];

f3(a_10x5);
f3(a_64x8);

35.6 調用導入函數

調用導入函數和使用SV原生函數是同樣的。因此導入函數聲明和SV原生函數是同樣的規範。特別地,帶有默認值的參數在調用時能夠省略;若是形參命名則能夠用名字來作綁定。

35.6.1 變量傳遞

變量傳遞的規則是「所見即所得"。形參的計算順序遵循SV通用規則。
變量的兼容性和強制轉換都與SV原生函數同樣。若是須要進行強制轉換,那麼會建立臨時變量,並把它傳遞給實際變量。對於input和inout變量, 臨時變量會被初始化成強制轉換後的值。對於output和inout變量,實際值會被強制轉換後而後賦給臨時變量。臨時變量和實際值之間的賦值遵循SV的賦值和強制轉換通用規則。
在SV側, 導入函數的輸入值和調用者無關。形參輸出值在開始是末定義的,而後被實際值賦值(可能發生強制轉換)。導入函數不會改變輸入變量的原始值。
在SV側,變量傳遞的語義是: input變量是"copy-in", output變量是」copy-out", inout變量是"copy-in"和「copy-out"。 這裏的"copy-in"和」copy-out"不是暗示它們的實際實現方式,而是指假想的賦值。
變量傳遞的真正實現對SV側是透明的。SV並不清楚它其實是值傳遞仍是引用傳遞。它的實際實現方式是由外部語言定義的。

35.6.1.1 WYSIWYG原則

WYSIWYS(所見即所得)原則保證了導入函數的形參類型:實際變量被要求要和形參徹底相同,除了open array. 形參只和導入函數的聲明現場有關。
沒有編譯器(C或者SV)能夠在形參和實參類型間作強制轉換。調用者的形參是被定義在另一種語言裏,因此它們相互間沒法可見。用戶須要理解並保證它們是匹配的類型。
open array中的可變長維度會有實參的實際長度。形參中的變長,packed的維度會擁有實際參數的範圍。變長, packed維度會被歸一化 ([15:8] -> [8:0]). 變長範圍在調用現場才能肯定。其餘信息都在函數聲明中定義了。

所以, 若是一個形參被定義成bit [15:8] b [], 那麼它描述了一個unpacked array, 它的每一個元素也是一個packed bit array, 數據綁定範圍是15到8. 實際參數的長度會被綁定到它的unpacked部分。
有時候容許傳遞一個動態數組會爲導入function和task的實參。原則同SV裏傳遞動態數組給原生function和task。

35.6.2 output和inout變量的值變化

仿真器負責處理output和inout變量的值變化。這樣的值改變會被仿真器探測到,並被返回到SV代碼。
對於output和inout變量, 值傳播會當即發現一旦控制權從導入函數返回。若是有多個變量返回,那麼值傳播的順序遵循SV的通用規則。

35.7 導出函數

DPI容許其餘語言調用SV函數。函數和變量兼容性要求和導入函數同樣。聲明SV函數被導出並不改變它的語義和行爲;沒有什麼反作用除了當它被用於DPI 調用鏈中(好比調用者又被SV導入並調用)。

能夠被其餘語言調用的SV函數須要被聲明爲export。 聲明必須在函數被定義的做用域裏。每一個函數只能被export聲明一次。
一個重要的限制是: 類的成員函數不能被導出, 其餘均可以。
同導入聲明同樣, 賣出聲明能夠定義一個可選的C標識符(用於其餘語言)

dpi_import_export ::=         //from A.2.6
     ...
     | export dpi_sepc_string [c_identifier=] function function_identifier;
     ...
dpi_spec_string ::= "DPI-C" | "DPI"

35.8 導出任務

SV容許外部語言能夠調用tasks. 同函數同樣, 這樣的task被定義爲導出taks。
上面對於導出函數的全部描述均可應用於導出task。包括合法的定義做用域和可選的C標識符。

從一個導入的函數裏調用一個導出的task是非法的。這個語義和原生SV語義是一致的,函數不能調用task。

只有導入的task擁有context屬性時才能夠被導入的task調用。

導出task和導出函數的一個不一樣處是SV task沒有返回值。導出task的返回值是一個int類型值,用來指示是否有disable用於當前線程。
類似的,導入task也會返回一個int類型值來的說明導入task是否收到一個disable.

35.9 禁用DPI task和function

使用disable語句能夠禁用正在執行的DPI調用鏈。當導入的例程被禁用時,C代碼會遵循一個簡單的關閉協議。協議會容許C代碼去執行必要的資源釋放清理工程,好比關閉文件句柄,關閉VPI句柄,釋放堆內存。

當一個disable語句做用於某個目標或它的父範圍域,那麼咱們就稱這個導入task或function在disable狀態。一個導入task或function若是調用了一個導出的task或function, 那麼在進入disable狀態前我必須從調用中返回。這個協議的關鍵之處在於被關閉的導入task或function將確認他們被關閉了。task或function能夠經過svIsDisabledState()來肯定它是否在disable狀態。

這個協議由以下部分組成:
a) 當一個導出的task被disable時,返回1, 不然返回0;
b) 當一個導入的task被disable時,返回1, 不然返回0
c) 當導入的function被disable時, 它將會先調用svAckDisabledState()
d) 一旦導入的task或function進入disable狀態,它將不容許再調用任何導出的task或function

b), c), d)是強制行爲。DPI的輸寫者須要確保正常的行爲。
a)是由SV仿真器來保證的。此外仿真器也會檢查b), c), d)是否被遵照。若是任何協議沒被遵照,仿真器應該提示致命錯誤。

DPI的另一側包含一個禁用協議,該協議由用戶代碼與仿真器一塊兒實現。禁用協議容許外部模型參與SystemVerilog禁用處理。參與方法是經過DPI task的特殊返回值和特殊API調用來完成。特殊的返回值不須要更改SV代碼中導入或導出DPI task的調用語法。雖然仿真器保證了導出task的返回值,但對於導入task,DPI另外一側必須確保返回正確的值。對導入task的調用與對SV原生task的調用是沒法區分的。一樣,對代碼中的導出task的調用與對非SV task的調用是沒法區分的。若是導出的task自己是禁用的目標,則當導出task返回時,其父項導入的task不被視爲處於disable狀態。在這種狀況下,導出的任務應返回值0,而且對svIsDisabledState()的調用也應返回0。當DPI導入的子例程因爲被禁用而返回時,其輸出和inout參數的值未定義。一樣,當導入的函數因爲禁用而返回時,函數返回值是不肯定的。 C程序員能夠從禁用的函數中返回值,而C程序員能夠將任意值寫入導入例程的output和inout參數位置。可是,若是禁用有效,SV仿真器沒有義務將任何此值傳播到調用SystemVerilog代碼中。

相關文章
相關標籤/搜索