Can you summarize the following document?
        
  SystemVerilog的歷史可以追溯到2002年,當時一個被稱為“Superlog”的語言被捐贈給Accellera公司(Verilog的主要支持者)。而Synopsys公司捐贈的OpenVera後來發展成為SystemVerilog中硬體驗證語言子集。2005年,SystemVerilog獲批成為電氣電子工程師學會1800-2005標準。當時Verilog作為電氣電子工程師學會1364-2005標準尚獨立存在。2009年,SystemVerilog與的Verilog進行了合併,成為了新的電氣電子工程師學會1800-2009標準。現在的最新標準是電氣電子工程師學會1800-2012標準。

  對於電路設計工程師來說,SystemVerilog中有大部分內容繼承自Verilog,但是也提供了一些增強或者改進的特性。下面的章節主要講述SystemVerilog的這些特性。

  

  SystemVerilog定義了一種新的邏輯型(codice_1)變數。和Verilog中變數的宣告類似,以下程式碼描述了一個32位的邏輯型變數:  在傳統的Verilog中,變數主要分為線網型(codice_2)和暫存器型(codice_3)兩大型別。只有暫存器型變數才能夠在過程程式碼塊中被賦值,而線網型變數只能在過程程式碼塊之外被連續賦值。暫存器型變數的過程賦值和線網型變數的連續賦值使用了完全不同的語句結構。在Verilog中,二者的區分比較微妙,以至於有些專業的工程師也在設計中混淆二者。由於codice_4過程程式碼塊不僅可以描述時序邏輯電路,還可以通過將所有暫存器型的輸入變數新增到敏感列表來實現純組合邏輯電路,因此“暫存器型”這個帶有時序邏輯意義的術語本身也令人誤會。  SystemVerilog增強了暫存器型變數的功能,它可以像Verilog中線網型變數一樣由線網(如邏輯閘等模組的輸出)驅動(這樣的線網驅動暫存器的方式在Verilog中是不允許的)。這種增強的變數型別被命名為“邏輯型”,從而避免“暫存器型”在字面上給人帶來的誤會。在大多數情況中,SystemVerilog中的codice_1可以替代Verilog中的codice_3和codice_2,但是如果某個某個變數具有多個驅動源,那麼就不能使用codice_1,而要使用嚴格的codice_2來定義它。

  這種結構將Verilog中與暫存器、儲存器相關的概念進行了合併和擴充套件。  在Verilog中,變數名稱左邊的索引被用來表示二進位制變數的位寬,Verilog規定它只能是一維的。而這個陣列名稱右邊的索引用來表示以這種位寬變數組成陣列的元素個數,因為陣列可以是一維陣列、二維陣列或者多維陣列,因此這個索引可以是任意整數。在SystemVerilog中,如果在變數名稱左邊指定了由高至低的位寬(如8位訊號由codice_10表示),則稱之為“壓縮陣列”(packed array,有時也被譯為“合併陣列”)。壓縮陣列本身可以是多維的,即變數名稱左邊可以具有多維索引。如果在變數名稱右邊指定了陣列尺寸,則稱之為“非壓縮陣列”。下面用示例程式碼表示了一個由二維壓縮陣列構成的一維非壓縮陣列:  在上面的例子裡,非壓縮陣列陣列codice_11具有32個元素(這裡用到了類似C語言的陣列元素個數表示方法,這裡也可以寫成Verilog中常見的codice_12形式)。這個非壓縮陣列每一個元素本身又是壓縮陣列,即2個位寬為3的邏輯型變數,因此非壓縮陣列的每一個元素包含六位二進位制數的資訊。A variable of packed array type maps 1:1 onto an integer arithmetic quantity.

  SystemVerilog引入了列舉型變數,它使用一系列有實際字面意義的名稱來代表若干變數。如果不進行專門的資料型別轉換,一個列舉型變數不能直接賦值給另一個列舉型的變數。過去在Verilog中描述有限狀態機常常使用引數(關鍵字為codice_13),而在SystemVerilog中,使用列舉則更為方便。  上面的例子使用了typedef來建立了一個新的資料型別名稱,從而可以用它來建立一系列列舉資料。列舉型別的資料型別,為位寬為3的邏輯型變數。3位二進位制數能夠逐一指代六種顏色。使用程式碼codice_14建立了一個新的codice_15型變數,其值初始化為六種顏色中的綠色。系統函式codice_16的作用與Verilog相同,其引數是codice_17所屬函式codice_18的返回值,即當前列舉值的ASCII值。

  除了基本的邏輯型變數(codice_1),SystemVerilog正還提供了位元組型變數(codice_20,8位)、短整型變數(codice_21,16位)、整型變數(codice_22,32位)和長整型變數(codice_2364位)、位元型變數(codice_24,1位,僅具有兩個邏輯狀態,和邏輯型資料(codice_1)缺少了未知邏輯(codice_26)和高阻態(codice_27)。使用兩態邏輯可以提高邏輯模擬速度)。

  這兩種資料型別和C語言中的結構體和聯合體類似。在SystemVerilog中,與這兩種資料型別相關的增強特性為壓縮屬性(codice_28)和標籤屬性(codice_29)。壓縮屬性使得mapped 1:1 onto a packed array of bits,而標籤屬性允許跟蹤當前聯合體中實際被使用的成員。這些結構佔據了連續的儲存空間。

  當條件、選擇語句的路徑分支較為複雜時,設計人員稍不留意就可能造成程式碼所描述的行為違背設計人員預計的優先順序別,或者被判斷的表示式同時滿足多個分支條件,從而在模擬過程中產生無規律結果。  為此,SystemVerilog增強了條件、選擇語句的功能,允許設計人員為這分支流程的執行設定特別的約束。在多級條件、選擇語句中使用關鍵字codice_30,可以限定有且只有一個分支可能被執行到,否則將產生一個警告。而關鍵字codice_31則指出某些分支路徑具有更高的優先順序。過去,在傳統的Verilog中,要實現類似的功能,設計人員需要在可綜合程式碼中附帶一些特殊的註釋(例如: codice_32)來通知邏輯綜合工具產生正確的分支邏輯電路。不過,註釋並非SystemVerilog程式碼的正式組成部分,它們只是在邏輯綜合過程被特定的工具讀取,而不嚴謹的註釋很可能造成綜合後電路與綜合前模擬結果不同的情況。

  Verilog中的過程程式碼可以描述時序邏輯電路,也可以描述組合邏輯電路,這一點容易造成概念的混淆,如果程式碼不嚴謹,邏輯綜合很可能推斷出鎖存器,從而產生不符合預期的硬體模型。SystemVerilog除了繼續支援原來Verilog中的老式過程結構codice_4、codice_34,還在原有codice_4基礎上針對組合邏輯電路、觸發器、鎖存器設計了專用的codice_4結構。雖然它們顯得不夠通用,但是三類硬體模型的差異得到了明確地區分,避免使用老式codice_4時容易出現的鎖存器推斷:  三種專用的codice_4結構在使用時會檢查設計程式碼是否符合對應硬體模型的特徵。如果設計人員在過程程式碼中描述了與對應硬體不符合的行為(例如在codice_43的敏感列表中新增了定時器訊號的上升沿),那麼系統會發出警告。這是SystemVerilog種專用型過程結構的優越之處。  下面的例子使用codice_38來描述組合邏輯電路。在SystemVerilog中無需像Verilog中描述組合邏輯電路那樣寫出敏感列表,codice_38會告訴邏輯綜合工具這是一個組合邏輯電路,因此係統會預設對所有輸入訊號的電平敏感。在表示組合邏輯電路的過程程式碼中,一般使用阻塞賦值。  邏輯綜合工具會將codice_41推斷為同步時序邏輯,這裡需要寫明對什麼訊號的什麼邊緣(上升或者下降)敏感。在表示時序邏輯電路的過程程式碼中,一般使用非阻塞賦值。  邏輯綜合工具還會將codice_43推斷為電平敏感的鎖存器電路,對輸入訊號的電平敏感,但是具有訊號儲存特性:

  對於小型的設計,Verilog設計人員可以使用埠(port)來簡潔地描述模組與外部環境的連線情況。不過,在規模較大、抽象層次較多的設計中,處於樞紐地位的模組往往具有大量連線與外界的連通。為此,SystemVerilog引入了介面(interface)的概念,這個概念一方面減少了大量需要宣告的埠名稱,另一方面,它還方便設計人員將某些相關訊號的通道作為一捆相對獨立的線網組,這樣就使複雜的設計更加簡單、明晰。另一個概念是modport,它顯示了邏輯連線的方向。例如:

  隨著積體電路整合規模的不斷提高,電路的複雜程度也越來越大。在這種情況下,設計驗證在整個設計流程中所佔用的時間越來越高。SystemVerilog在Verilog基礎上增加了許多專門針對驗證的特性,使其成為一種傑出的硬體驗證語言。下面所提到的驗證程式碼通常是不可綜合的,它們的作用主要體現在測試平臺的搭建過程中。

  SystemVerilog引入了專門的字串型變數,用關鍵字codice_51表示,例如: 除了在設計中使用靜態陣列,SystemVerilog還提供了動態陣列、關聯陣列(associative array)和佇列(queues):  動態陣列的行為和非壓縮陣列相似,不過它允許模擬在執行時動態分配元素個數(正如上面例子所示)。壓縮陣列部分的元素個數(以往稱之為“位寬”)必須在編譯的時候已知(通過由常數或常數表示式直接確定),而非壓縮陣列的動態大小則可以在程式執行時,由另一個執行中的程式變數進行初始化,這樣就可以在執行中根據所需改變陣列的大小。

  SystemVerilog為驗證程式碼的編寫提供了物件導向程式設計的模型。  SystemVerilog支援類的單一繼承,即不允許一個類繼承多個基本類。需要注意的是, 雖然SystemVerilog裡提供了與Java中名稱相同的“介面”概念,但是二者的實際含義際ha卻大有不同,後者的介面能夠提供類似多繼承的功能。SystemVerilog的類可以自帶配置引數,這種類被稱為引數化的類,其功能與C++的模板類似,不過SystemVerilog不支援模板特化和函式模板。SystemVerilog的多型性和C++類似,在子類中被覆蓋的同名方法在基本類中必須使用關鍵字codice_52予以標識。SystemVerilog裡也有諸如codice_53、codice_54等關鍵字來管理資料、方法成員的可見性。預設情況下,所有方法、資料都是對外公有的。類的示例由建構函式codice_55來建立,而解構函式則無需驗證人員手動建立。如果某個物件沒有被任何控制代碼指向,系統會自動銷燬它。SystemVerilog的類是構建諸如通用驗證方法學類庫結構的基礎。

  可以對定義在類或者其他語句塊中的整數型變數進行隨機化,從而實現輸入激勵的隨機化,大大降低了驗證人員專門定義輸入激勵的複雜程度。這時使用SystemVerilog構建隨機驗證平臺的重要技術基礎。在類資料變數宣告前使用codice_56和codice_57這兩個關鍵字,可以讓系統得知這些變數在隨後被隨機化。codice_57產生的隨機數序列可以保證變數被再次賦值為同一數值之前,所有可能數值已經被遍歷,而宣告為codice_56的變數則在隨機化過程中沒有這一特性。  在上面這一例子中,資料成員codice_60未被宣告為隨機變數,而其他幾個資料成員則被宣告為隨機變數。在這個類中,緊隨變數宣告的是兩個對隨機化進行約束的語句塊,用關鍵字codice_61予以標識。例如第一個名為codice_62的約束要求資料成員codice_63(動態陣列)的大小在46和1500之間(包含這兩個邊界值)。如果沒有專門指定約束條件,則變數在可能的取值範圍內的隨機化不受任何約束。約束塊內程式碼的寫法有若干種,驗證人員可以設定更加複雜的約束關係,例如變數取得區間甲內某一數值的權重為某一定值,或者採用多個數學關係式來限定變數的隨機化取值。當然,這樣做的前提是數學上能夠找到數值來同時滿足這些約束。SystemVerilog的解析器會盡量產生符合條件的隨機數值,但是如果沒能夠成功,則會返回資訊告知驗證人員此隨機化過程失敗。

  每一個SystemVerilog類都有隱含的三個與隨機化有關的方法,它們是codice_64、codice_65和codice_66。其中,codice_65方法為整個隨機化過程中最重要的方法,驗證人員可以在過程程式碼中使用該方法來啟動變數的隨機化過程。注意該方法的主體是事務物件本身(在通用驗證方法學中,事務一般是一個具有codice_68型別或從它繼承而來的型別),因此需要用codice_69來呼叫該方法,每執行一次該方法,該物件所有的隨機變數將會得到滿足約束條件(如果有)的隨機數值。如果隨機化失敗,例如沒能找到滿足工程師定義約束的數值,則該方法將返回0表示隨機化存在問題。另外兩個方法codice_64和codice_66則可以被用來處理隨機化主過程之前、之後其他需要的事情。

  此外,SystemVerilog還提供了codice_72和codice_73這兩個方法來在過程程式碼中控制隨機化,前者用於臨時開啟或關閉一個約束,而後者則用於臨時開啟或關閉某個變數的隨機化。此外還有codice_74方法可以在該方法被呼叫時將花括號內的約束附加到原有的約束條件之上。

  與其他屬性規約語言類似,SystemVerilog具有斷言這一概念。在整個晶片驗證流程中,斷言檢查器會自動檢查定義的屬性是否得到滿足,如果違背,則會給出警告。SystemVerilog斷言由序列(codice_75)和屬性(codice_76)兩部分組成。屬性可以是多個序列在時間上的組合。序列主要用布林表示式和時序操作符來描述。  這一簡單序列的意思是,訊號codice_77會在訊號codice_78為高電平一個時鐘週期後也為高電平,如果這一情況沒有發生,則斷言失敗。SystemVerilog還提供其他一些時序操作符,例如重複、連續操作符。這些操作符可以讓驗證人員定義更加複雜的變數關係。在上面這個例子中,加入訊號codice_78為低電平,則這個斷言永遠都是失敗的。我們可以使用蘊含操作符codice_80來表示我們所需的情況。  上面這個例子顯示了蘊含(implication)操作符codice_80的使用。它左邊的子句稱為先行運算元(antecedent)而右邊的子句稱為後續運算元(consequent)。這時,如果codice_78未滿足高電平的要求,則後面的codice_77無論是高電平還是低電平,整個斷言都預設為成功;但是如果codice_78為高電平,則系統會根據codice_77的邏輯值來決定斷言是否成功。除此之外,SystemVerilog還支援斷言覆蓋。

  在硬體驗證中,功能覆蓋是指驗證過程中對人工定義訊號事件的資料取樣和收集過程。功能覆蓋率在某種程度上反映了被測設計在所給輸入激勵下,其內部功能正確與否被檢測到的百分比。功能覆蓋率越高,一般代表測試越完備。注意功能覆蓋率和程式碼覆蓋率不同,後者只是測量被測設計的所有程式碼有多少在模擬過程中被執行過。功能覆蓋的目的是確保設計中的所有邊界情況都能夠被經歷。  SystemVerilog覆蓋組(coverage group)內可以定義若干個倉(bins)來儲存相關變數取值在其範圍內的次數。交叉覆蓋(Cross-coverage)則可以進一步獲取多個變數分別在某一範圍內統計資料。通過使用覆蓋組的codice_86方法,可以啟動該覆蓋率的統計。  For example: 在這一例子中,驗證工程師重點關注廣播和單播幀的分佈以及負載大小。

  一個複雜的測試平臺往往是包含多個可重用驗證模組的環境,這些模組之間需要互相通訊。Verilog的事件(codice_87)允許不同語句塊之間相互觸發,不過這在複雜測試平臺的執行緒間通訊比較繁瑣。為此,SystemVerilog提供了兩種新的語言要素,信箱(codice_88)和旗語(codice_89)。信箱類似一個引數化的FIFO(意味著其內容的型別是可定義的),可以將符合其型別的物件“裝入”和“取出”信箱。而旗語則限定了對同一資源的訪問個數。

  除了前面提到的特性,SystemVerilog還在以下方面對傳統的Verilog進行了增強:
在現代的積體電路(尤其是超大規模積體電路)的設計和驗證流程中,SystemVerilog是一種由Verilog發展而來的硬體描述、硬體驗證統一語言,前一部分基本上是2005年版Verilog的擴充套件,而後一部分功能驗證特性則是一門物件導向程式設計語言。物件導向特性很好地彌補了傳統Verilog在晶片驗證領域的缺陷,改善了程式碼可重用性,同時可以讓驗證工程師在比暫存器傳輸級更高的抽象級別,以事務而非單個訊號作為監測物件,這些都大大提高了驗證平臺搭建的效率。