Verilog HDL數(shù)字集成電路設(shè)計(jì)原理與應(yīng)用(第三版)課件 第8章 System Verilog設(shè)計(jì)與驗(yàn)證-_第1頁
Verilog HDL數(shù)字集成電路設(shè)計(jì)原理與應(yīng)用(第三版)課件 第8章 System Verilog設(shè)計(jì)與驗(yàn)證-_第2頁
Verilog HDL數(shù)字集成電路設(shè)計(jì)原理與應(yīng)用(第三版)課件 第8章 System Verilog設(shè)計(jì)與驗(yàn)證-_第3頁
Verilog HDL數(shù)字集成電路設(shè)計(jì)原理與應(yīng)用(第三版)課件 第8章 System Verilog設(shè)計(jì)與驗(yàn)證-_第4頁
Verilog HDL數(shù)字集成電路設(shè)計(jì)原理與應(yīng)用(第三版)課件 第8章 System Verilog設(shè)計(jì)與驗(yàn)證-_第5頁
已閱讀5頁,還剩63頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

8.1概述

8.2SystemVerilog程序設(shè)計(jì)語句

8.3基于SystemVerilog的仿真驗(yàn)證

8.4SystemVerilog與C語言接口8.1概述8.1.1SystemVerilog語言的發(fā)展由OVI(OpenVerilogInternational)和VI(VHDLInternatioanl)兩個(gè)國際標(biāo)準(zhǔn)化組織合作成立的Accellera組織一直致力于推出用于系統(tǒng)級芯片設(shè)計(jì)和驗(yàn)證的語言。2002年6月,Accellera發(fā)布了第一個(gè)SystemVerilog語言標(biāo)準(zhǔn)。最初在基于Verilog-2001擴(kuò)展的開發(fā)過程中,新加入的這些語言被稱為“Verilog++”,但最后決定命名為“SystemVerilog3.0”。從名稱可以看出,它不是一種完整的獨(dú)立語言,是VerilogHDL的擴(kuò)展,因而它被認(rèn)為是Verilog的第三代語言(Verilog-95是第一代,Verilog-2001是第二代)。SystemVerilog3.0在IEEE1364-2001Verilog的基礎(chǔ)上添加了高級的Verilog和“C”數(shù)據(jù)類型,對于設(shè)計(jì)和驗(yàn)證來說,這是向前邁進(jìn)了重要的一步,同時(shí)擴(kuò)展了Verilog可綜合性語言結(jié)構(gòu)并支持在更高層次上構(gòu)建硬件模型。2003年5月,Accellera發(fā)布SystemVerilog3.1標(biāo)準(zhǔn),該版本主要是擴(kuò)展了大量的驗(yàn)證結(jié)構(gòu)。它添加了C++風(fēng)格的“類”構(gòu)造、屬性、繼承,增加了允許約束隨機(jī)驗(yàn)證的功能,有增強(qiáng)的SystemVerilog斷言子集,添加了FunctionalCoverage子集等。Accellera通過與主要的EDA公司密切合作,繼續(xù)完善SystemVerilog3.1標(biāo)準(zhǔn),如Synopsys向SystemVerilog項(xiàng)目提供驗(yàn)證技術(shù),包括基于Vera、OpenVera斷言的測試臺(tái)構(gòu)造,VCSDirectC模擬C/C++接口,一個(gè)覆蓋應(yīng)用程序的編程接口等。2004年5月,Accellera批準(zhǔn)了SystemVerilog的最終草案,并將它命名為SystemVerilog3.1a。2004年6月,Accellera將SystemVerilog3.1a標(biāo)準(zhǔn)提交給IEEE標(biāo)準(zhǔn)協(xié)會(huì),希望SystemVerilog作為擴(kuò)展集添加到下一版本的IEEEVerilog1364標(biāo)準(zhǔn)中。然而,最終IEEEVerilog標(biāo)準(zhǔn)委員會(huì)決定不將SystemVerilog合并到Verilog1364標(biāo)準(zhǔn)中,而給它一個(gè)新的標(biāo)準(zhǔn)編號(hào)1800。2005年11月,IEEE1800-2005SystemVerilog標(biāo)準(zhǔn)正式向公眾發(fā)布。2009年,IEEE1800-2005SystemVerilog與IEEE1364-2005Verilog標(biāo)準(zhǔn)合并,作為IEEE1800-2009SystemVerilog標(biāo)準(zhǔn)發(fā)布。同時(shí),IEEE終止了舊的Verilog-1364標(biāo)準(zhǔn),“Verilog”的名稱正式被“SystemVerilog”替代。面對硬件設(shè)計(jì)和驗(yàn)證難度的不斷增加,SystemVerilog標(biāo)準(zhǔn)也在不斷發(fā)展,以跟上時(shí)代的步伐。2012年發(fā)布了IEEE1800-2012SystemVerilog標(biāo)準(zhǔn),增加了設(shè)計(jì)和驗(yàn)證增強(qiáng)功能。2017年發(fā)布了IEEE1800-2017SystemVerilog標(biāo)準(zhǔn),此版本并未在2012版標(biāo)準(zhǔn)中添加任何新的語言功能,僅修正了2012版標(biāo)準(zhǔn)中的勘誤表,并增加了對語言語法和語義規(guī)則的澄清。表8.1-1列出了SystemVerilog標(biāo)準(zhǔn)發(fā)展的主要?dú)v程。8.1.2SystemVerilog語言架構(gòu)SystemVerilog是一種系統(tǒng)級的硬件描述語言,它建立在VerilogHDL的基礎(chǔ)上,同時(shí)結(jié)合了VHDL、C/C++以及驗(yàn)證平臺(tái)語言和斷言語言,它是一種多語言的組合。得益于多個(gè)EDA公司的捐贈(zèng),SystemVerilog語言在VerilogHDL基礎(chǔ)上主要擴(kuò)展的組件包括:·SUPERLOG擴(kuò)展合成子集(SUPERLOGESS),來自Co-DesignAutomation公司;·OpenVERA驗(yàn)證語言,來自Synopsys公司;·PSL斷言,來自IBM公司(最初為Sugar斷言);

·OpenVERAAssertions(OVA),來自Synopsys公司;·VCSDirectC模擬C/C++?接口和覆蓋應(yīng)用程序編程接口(API),來自Synopsys公司;·獨(dú)立編譯和?$readmem擴(kuò)展,來自Mentor公司;·聯(lián)合和高級語言特性,來自BlueSpec公司。上述這些擴(kuò)展組件和VerilogHDL一起構(gòu)成了SystemVerilog語言,其架構(gòu)如圖8.1-1所示,包括在設(shè)計(jì)和驗(yàn)證部分的語言擴(kuò)展。SystemVerilog在設(shè)計(jì)上有助于編寫可綜合硬件電路的主要擴(kuò)展包括:(1)封裝通信和協(xié)議檢查的接口(interface);(2)增加類似C語言的數(shù)據(jù)類型(如int型)、用戶自定義數(shù)據(jù)類型typedef、枚舉類型enum、數(shù)據(jù)類型轉(zhuǎn)換等;(3)結(jié)構(gòu)體(struct)和聯(lián)合體(union);(4)可被多個(gè)設(shè)計(jì)塊共享的定義包(package);(5)增加類似C語言的運(yùn)算符及賦值操作符,如++、--、+=等;(6)顯示過程塊;(7)優(yōu)先級(priority)和唯一(unique)修飾符;(8)增加過程語句,如do-while、arrayassignments等。SystemVerilog在驗(yàn)證方面擴(kuò)展的子集主要包括:(1)產(chǎn)生測試激勵(lì)、驅(qū)動(dòng)、響應(yīng)及監(jiān)控等;(2)斷言子集(assertions):先進(jìn)的驗(yàn)證語言用于形式和半形式驗(yàn)證,檢查來自DUT的組合/順序邏輯響應(yīng);(3)功能覆蓋子集:測量設(shè)計(jì)的功能覆蓋率;(4)?C和C++?仿真接口(DirectProgrammingInterface,DPI)及覆蓋率應(yīng)用程序編程接口(API):直接用于C/C++?連接及AssertionAPI和CoverageAPI。相對于VerilogHDL在寄存器級、邏輯級、門級設(shè)計(jì)上的優(yōu)勢,SystemVerilog更適合于可重用可綜合IP和可重用驗(yàn)證IP設(shè)計(jì),以及特大型基于IP的系統(tǒng)級設(shè)計(jì)和驗(yàn)證。同時(shí),它和芯片驗(yàn)證方法學(xué)(如UVM)相結(jié)合,可作為實(shí)現(xiàn)方法學(xué)的一種語言工具,從而大大增強(qiáng)模塊復(fù)用性,提高芯片開發(fā)效率,縮短開發(fā)周期。8.2SystemVerilog程序設(shè)計(jì)語句8.2.1數(shù)據(jù)類型設(shè)計(jì)中常用的數(shù)據(jù)類型是整型。除了VerilogHDL已有的整型類型wire、reg和interger外,SystemVerilog從VHDL和C/C++語言中引入logic、int等數(shù)據(jù)類型,具體如表8.2-1所示。在VerilogHDL中,數(shù)值可取值0、1、x和z,四態(tài)數(shù)據(jù)主要面向RTL綜合,其中z值被用來表示無連接或三態(tài)設(shè)計(jì)邏輯,x值有助于檢測多驅(qū)動(dòng)設(shè)計(jì)錯(cuò)誤。但在更高級別的抽象建模中,如系統(tǒng)和事務(wù)級別,邏輯值z和x很少用到,因此SystemVerilog定義了雙態(tài)數(shù)據(jù)類型,即只能取0或1值。相對于四態(tài)數(shù)據(jù),雙態(tài)數(shù)據(jù)有利于加快仿真速度并減少內(nèi)存的使用。同時(shí),這些類似C語言的雙態(tài)數(shù)據(jù)可用于C/C++?的接口。SystemVerilog的DPI可將Verilog模型轉(zhuǎn)換為C或C++?模型;使用具有共同類型的數(shù)據(jù),可以簡單而高效地在兩種語言之間來回傳遞數(shù)據(jù)。logic類型是SystemVerilog中最常用的數(shù)據(jù)類型,下面就重點(diǎn)介紹logic類型的語義。SystemVerilog中的logic類型是變量類型,是對reg類型的擴(kuò)展。它既可以作為寄存器類型在過程塊中被賦值,也可以用在連續(xù)賦值語句和結(jié)構(gòu)描述中作為網(wǎng)線類型使用。在例8.2-1的VerilogHDL描述的模塊test(圖8.2-1)中,信號(hào)線atob連接了u1模塊的輸出端out和u2模塊的輸入端in。在實(shí)際的物理電路中,atob、u1.out和u2.in是同一個(gè)信號(hào),但由于它們處于不同模塊的不同端口或其不同的賦值方式,導(dǎo)致數(shù)據(jù)類型不同。在SystemVerilog描述中,信號(hào)atob、u1.out和u2.in都可用logic來定義,保證了同一個(gè)信號(hào)在模塊內(nèi)部、模塊外部和測試平臺(tái)中的一致性;它使得在任何抽象層次上建模都更加容易。除了常用的整型數(shù)據(jù)類型外,SystemVerilog還定義了實(shí)型數(shù)據(jù)類型,包括real類型(類似C語言中的double類型)、shortreal類型(類似C語言中的float類型)、realtime類型以及字符串類型(string)、靜態(tài)變量(static)等。SystemVerilog在基本數(shù)據(jù)類型的基礎(chǔ)上,引入C/C++語言中構(gòu)造類型的概念,設(shè)計(jì)了數(shù)組(array)、自定義(typedef)、枚舉(enum)、結(jié)構(gòu)體(struct)和聯(lián)合體(union)等靈活多樣的數(shù)據(jù)類型,以滿足不同抽象層次的建模。1.?dāng)?shù)組(array)在VerilogHDL中學(xué)習(xí)了數(shù)組類型的定義及賦值,如“reg[7:0]mem[1:256];”。Verilog中對數(shù)組不能整體訪問,必須使用數(shù)組名加上一個(gè)或多個(gè)索引地址的方式訪問數(shù)組中的每個(gè)元素。在SystemVerilog中同樣定義了數(shù)組,但將數(shù)組分成合并數(shù)組和非合并數(shù)組兩大類。(1)合并數(shù)組(packedarray),在數(shù)組名前聲明數(shù)組的大小。(2)非合并數(shù)組(unpackedarray),在數(shù)組名后聲明數(shù)組的大小。2.自定義(typedef)VerilogHDL不允許用戶定義新的數(shù)據(jù)類型,SystemVerilog則通過使用typedef提供了一種方法來定義新的數(shù)據(jù)類型。其語法為typedefexisting_typemytype_t;3.枚舉(enum)指令操作碼或狀態(tài)機(jī)中用VerilogHDL宏定義或參數(shù)定義來取代常數(shù),以提高代碼可讀性及維護(hù)性,但是需要單獨(dú)對每一個(gè)常數(shù)定義其對應(yīng)的宏名或參數(shù)名。SystemVerilog引入C/C++語言中的枚舉類型,可以自動(dòng)為列表中的每個(gè)名稱分配不同的數(shù)值。其基本語法為enumdata_type{enum_name0,enum_name1,…}變量名4.結(jié)構(gòu)體(struct)同C/C++類似,如果在設(shè)計(jì)中不同類型的變量具有邏輯關(guān)聯(lián)性,如接口協(xié)議中既有控制信號(hào),又有地址和數(shù)據(jù)總線,這時(shí)可利用結(jié)構(gòu)體將這些變量組合在一起并賦予一個(gè)共同的名稱。5.聯(lián)合體(union)同C/C++類似,聯(lián)合體和結(jié)構(gòu)體的區(qū)別在于任何一個(gè)時(shí)間內(nèi)只存在一個(gè)聯(lián)合體成員,所以聯(lián)合體變量所占位數(shù)由最大位寬成員決定。8.2.2操作符VerilogHDL提供了很多運(yùn)算符用于算術(shù)運(yùn)算、邏輯判斷及位操作等。SystemVerilog在此基礎(chǔ)上新增加了一些操作符,以方便更高層次的建模,見表8.2-2。SystemVerilog還增加了C/C++語言中的強(qiáng)制類型轉(zhuǎn)換功能,通過使用casting操作符“'”將變量數(shù)據(jù)類型、數(shù)據(jù)寬度及數(shù)據(jù)符號(hào)強(qiáng)制轉(zhuǎn)換成任意類型,很好地解決了變量類型或位寬不一致的錯(cuò)誤。8.2.3模塊的定義及調(diào)用在VerilogHDL中,連接到模塊端口的數(shù)據(jù)類型被限制為線網(wǎng)類型以及變量類型中的reg、integer類型。在SystemVerilog中則去除了這種限制,任何數(shù)據(jù)類型都可以通過端口傳遞,包括實(shí)數(shù)、數(shù)組和結(jié)構(gòu)體。在VerilogHDL結(jié)構(gòu)調(diào)用語句中,若使用名稱對應(yīng)法,則要寫明信號(hào)線和其連接的端口。SystemVerilog提供了調(diào)用語句的兩種簡化方式,如果信號(hào)名和端口名一樣,則可省略信號(hào)名。更加簡化的形式是“.*”,表示除了明確給出端口連接關(guān)系的,剩下的所有端口和與之連接的信號(hào)名字一樣。在模塊定義時(shí)使用參數(shù)可提高模塊的可配置性及重復(fù)使用率,SystemVerilog在傳統(tǒng)parameter基礎(chǔ)上擴(kuò)展,將數(shù)據(jù)類型參數(shù)化,8.2.4過程塊在VerilogHDL中使用always過程塊進(jìn)行電路設(shè)計(jì),仿真工具或綜合工具通過解析代碼來“推斷”或“猜測”always過程塊設(shè)計(jì)的是組合邏輯、latch,還是時(shí)序邏輯。不同EDA工具的“推斷”結(jié)果可能會(huì)不一樣,比如在組合電路設(shè)計(jì)中由于編程錯(cuò)誤產(chǎn)生不需要的latch,這種錯(cuò)誤在綜合后才能發(fā)現(xiàn),從而導(dǎo)致功能仿真和綜合后的時(shí)序仿真結(jié)果不一致。為了明確always過程塊設(shè)計(jì)的電路類型,SystemVerilog增加了三種always過程塊:always_comb(組合邏輯)、always_latch(latch塊)和always_ff(時(shí)序邏輯)。這樣EDA工具就不需要“推斷”設(shè)計(jì)者的意圖,同時(shí)當(dāng)這些過程塊的內(nèi)容與該類型邏輯不匹配時(shí),EDA工具就發(fā)出警告。

1.a(chǎn)lways_comb過程塊always_comb表明設(shè)計(jì)的電路是組合邏輯。2.a(chǎn)lways_latch過程塊always_latch類似always_comb,EDA工具會(huì)自動(dòng)推導(dǎo)出完整的事件敏感列表。但always_latch明確指出這個(gè)過程塊是基于latch的邏輯,因此會(huì)檢查內(nèi)部語句是否滿足latch特點(diǎn)。3.a(chǎn)lways_ff過程塊always_ff表明設(shè)計(jì)的是一個(gè)時(shí)序電路。8.2.5分支語句在VerilogHDL中用于RTL建模的高級程序語句主要是if-else和case,如果沒有遵循嚴(yán)格的編碼風(fēng)格,則它們會(huì)產(chǎn)生優(yōu)先級的選擇結(jié)構(gòu)或分支的非唯一性。在case語句中如果沒有正確使用full_case和parallel_case綜合指令,還會(huì)引起一些其他的錯(cuò)誤。SystemVerilog中對分支語句進(jìn)行了功能增強(qiáng),如在if或case關(guān)鍵字之前使用唯一性(unique)和優(yōu)先級(priority)決策修飾符,從而明確了分支是否唯一,或者結(jié)構(gòu)是否具有優(yōu)先級。1.if-else語句增強(qiáng)SystemVerilog中增加了unique或priority關(guān)鍵字用于if-else語句,以減少EDA工具決策的模糊性,并可以在早期設(shè)計(jì)階段就發(fā)現(xiàn)潛在的設(shè)計(jì)錯(cuò)誤。

在圖8.2-2中,首先用傳統(tǒng)的if-else語句設(shè)計(jì)一個(gè)多路選擇器,如代碼a所示,EDA工具產(chǎn)生優(yōu)先級的選擇電路。對于這個(gè)選擇器,優(yōu)先級的順序并不重要,只是設(shè)計(jì)者在代碼編寫中碰巧列出了這樣的邏輯順序,因此在if前加上unique修飾符表示每個(gè)分支是唯一的,這樣EDA工具可以優(yōu)化出并行的電路結(jié)構(gòu),如代碼b所示。若在uniqueif中出現(xiàn)多個(gè)分支同時(shí)滿足的情況,如代碼c所示,則在編譯或仿真階段會(huì)報(bào)警。同時(shí)利用uniqueif還可以檢查是否產(chǎn)生了不需要的latch。對代碼b,當(dāng)sel等于1、2、4以外的其他數(shù)據(jù)時(shí),沒有一個(gè)分支條件滿足,因此對out沒有賦值更新,這時(shí)會(huì)產(chǎn)生latch,保持原值不變,EDA工具報(bào)警。

相對于unique代表各分支是獨(dú)立的,結(jié)構(gòu)上是并行的,關(guān)鍵字priority明確表示if-else具有優(yōu)先級。當(dāng)有多分支條件滿足時(shí),選擇優(yōu)先級高的分支完成相應(yīng)的賦值操作。2.case語句增強(qiáng)修飾符unique和priority也可用在case/casez/casex語句中,作為并行或優(yōu)先級結(jié)構(gòu)的指示。使用uniquecase結(jié)構(gòu)時(shí),EDA工具同樣檢查每個(gè)分支是否相互獨(dú)立,即沒有多個(gè)分支條件同時(shí)滿足的情況。在圖8.2-3的代碼a中,使用casez語句允許出現(xiàn)無關(guān)位或屏蔽位,這樣可以簡化譯碼電路,但是當(dāng)request信號(hào)的位中出現(xiàn)多個(gè)“1”時(shí),多個(gè)分支判斷同時(shí)成立。仿真工具對這個(gè)潛在問題不會(huì)告警,綜合工具可能會(huì)發(fā)現(xiàn)但沒有辦法判斷設(shè)計(jì)者的真實(shí)意圖。在代碼b中使用了uniquecase語句,明確告訴EDA工具case中的分支應(yīng)該是獨(dú)立并行的,不能多個(gè)分支同時(shí)成立,這樣在語句執(zhí)行時(shí)如果不滿足unique要求就會(huì)發(fā)出警告。使用priority修飾符允許多個(gè)分支同時(shí)成立,這時(shí)執(zhí)行第一個(gè)滿足要求的分支語句,如代碼c中優(yōu)先級最高的是slave1_grant分支。與if-else語句類似,在always_comb塊中使用上述兩種case結(jié)構(gòu)可以檢測不需要的latch。對于case語句,綜合工具雖然也提供了綜合指令parallel_case和full_case,但這可能會(huì)導(dǎo)致RTL級功能仿真和綜合后的門級仿真不一致。SystemVerilog語言新增的unique和priority修飾符是語言的一部分,它們會(huì)被所有仿真工具、綜合工具、形式驗(yàn)證工具等支持并按統(tǒng)一的規(guī)則檢查,確保了工具之間的一致性。8.2.6循環(huán)語句VerilogHDL支持的循環(huán)語句有for、repeat和while,SystemVerilog中增強(qiáng)了for語句的功能,同時(shí)又增加了新的循環(huán)用于RTL建模。1.for語句借鑒C語言中for的用法,SystemVerilog在傳統(tǒng)的for語句中增加了語句內(nèi)定義循環(huán)控制變量數(shù)據(jù)類型,對多個(gè)變量賦初值,有多條賦值語句,如下面代碼。注意,for內(nèi)部定義的變量i是一個(gè)局部變量,只能在循環(huán)體內(nèi)使用。for(inti=0;i<=15;i++)... //局部變量ifor(inti=0,j=15;j>0;i++,j--)... //多個(gè)循環(huán)控制變量2.do-while循環(huán)SystemVerilog增加了C語言中的do-while循環(huán),即先執(zhí)行后判斷。與while的區(qū)別是,do-while至少會(huì)執(zhí)行一次循環(huán)體。3.跳轉(zhuǎn)語句VerilogHDL提供disable語句控制代碼的執(zhí)行,可以中斷正在執(zhí)行的語句塊或任務(wù)。SystemVerilog引入了C語言中的跳轉(zhuǎn)語句break和continue,使循環(huán)控制更加靈活,代碼更加直觀和簡潔。語句continue指跳出或結(jié)束本次循環(huán),進(jìn)入到下一次循環(huán)的判斷中;而break語句是跳出或結(jié)束整個(gè)循環(huán)。8.2.7任務(wù)和函數(shù)SystemVerilog為VerilogHDL的任務(wù)和函數(shù)增強(qiáng)了一些功能,使復(fù)雜電路的設(shè)計(jì)和驗(yàn)證更加靈活高效,具體見表8.2-3。8.2.8包VerilogHDL中參數(shù)、任務(wù)和函數(shù)必須在模塊內(nèi)部定義,如果多個(gè)模塊中使用同樣的參數(shù)、任務(wù)或函數(shù),則不得不重復(fù)定義或使用`ifdef或`include編譯預(yù)處理指令,增加了代碼編寫量,同時(shí)代碼維護(hù)性也差。SystemVerilog通過增加用戶自定義的包(package)解決這一問題,package提供了一個(gè)聲明,它可以在任何模塊中引用。package可包含的內(nèi)容包括:·參數(shù)定義語句parameter/localparam;·常數(shù)定義語句const;·自定義數(shù)據(jù)類型typedef;·任務(wù)和函數(shù)定義task/function;·包的輸入語句import;·包的輸出語句export。在alu_types包中,包含了局部參數(shù)DELAY定義、自定義數(shù)據(jù)類型bus32_t和bus64_t定義、枚舉類型opcode_t和結(jié)構(gòu)體instr_t定義,以及函數(shù)parity_gen定義。包定義后可被多個(gè)模塊使用,其調(diào)用語法是:包名

::8.2.9接口VerilogHDL模塊之間的連接是通過模塊端口進(jìn)行的,SystemVerilog提供了一個(gè)較高層次抽象的模塊端口封裝機(jī)制,稱為接口(interface)。接口是將一組信號(hào)封裝在一起作為一個(gè)獨(dú)立的端口,它獨(dú)立于模塊。其語法如下:若在模塊內(nèi)部使用接口,使用前需將這個(gè)接口實(shí)例化,語法為接口名

實(shí)例名(端口連接);8.3基于SystemVerilog的仿真驗(yàn)證專用集成芯片設(shè)計(jì)的復(fù)雜度以指數(shù)形式增長,這使得驗(yàn)證工作成為芯片設(shè)計(jì)流程中的瓶頸,有關(guān)數(shù)據(jù)表明,接近70%~80%的設(shè)計(jì)時(shí)間花費(fèi)在了功能驗(yàn)證中。預(yù)測所有可能的極端情況并發(fā)現(xiàn)隱藏的設(shè)計(jì)錯(cuò)誤是功能驗(yàn)證的關(guān)鍵,同時(shí)在驗(yàn)證過程中希望能盡早發(fā)現(xiàn)這些錯(cuò)誤已滿足項(xiàng)目資源和上市時(shí)間的要求。SystemVerilog提供了用于描述復(fù)雜驗(yàn)證環(huán)境的語言結(jié)構(gòu),如增加約束隨機(jī)產(chǎn)生激勵(lì),覆蓋率統(tǒng)計(jì)分析提高自動(dòng)化驗(yàn)證效率,斷言驗(yàn)證檢測設(shè)計(jì)者意圖并診斷錯(cuò)誤,特別是引入了面向?qū)ο蟮木幊探Y(jié)構(gòu),有助于采用事務(wù)級的驗(yàn)證和提高驗(yàn)證的重用性。這些特性允許用戶開發(fā)生成各種驗(yàn)證場景的測試平臺(tái),一種典型的可重用測試平臺(tái)如圖8.3-1所示。在圖8.3-1中,信號(hào)發(fā)生器Generator產(chǎn)生不同輸入激勵(lì)送到驅(qū)動(dòng)模塊Driver中,接口Interface包含了所有的設(shè)計(jì)端口信號(hào),用于驅(qū)動(dòng)和監(jiān)控;驅(qū)動(dòng)Driver將產(chǎn)生的激勵(lì)信號(hào)通過Interface送給被測電路;監(jiān)視器Monitor通過監(jiān)控被測電路DUT的輸入/輸出信號(hào),從而捕獲電路行為;計(jì)分板ScoreBoard包含參考模型ReferenceModel和比較邏輯ComparisionLogic,參考模型接收激勵(lì)信號(hào)并產(chǎn)生期望值,比較邏輯將DUT輸出與期望值進(jìn)行比較。在成功比較后,計(jì)分板產(chǎn)生功能覆蓋。Environment包含上面提到的所有驗(yàn)證組件,構(gòu)成一個(gè)通用的測試環(huán)境。測試Test實(shí)例化Environment對象,生成一個(gè)特定的測試場景。下面介紹在上述測試平臺(tái)中需要用到的與測試相關(guān)的SystemVerilog語法。8.3.1面向?qū)ο蟮木幊踢^程編程語言如VerilogHDL、C的數(shù)據(jù)定義和對數(shù)據(jù)的操作是各自獨(dú)立的。例如,在VerilogHDL中,數(shù)據(jù)聲明和函數(shù)或任務(wù)可以獨(dú)立定義,沒有任何形式的聯(lián)系;一個(gè)函數(shù)可以對多個(gè)數(shù)據(jù)進(jìn)行操作,多個(gè)函數(shù)可以對同一個(gè)數(shù)據(jù)進(jìn)行操作。這種情況下,程序的功能會(huì)變得難以理解。在面向?qū)ο缶幊陶Z言中,數(shù)據(jù)和對數(shù)據(jù)的操作可以封裝到一個(gè)獨(dú)立的對象中。面向?qū)ο缶幊?Object-OrientedProgramming,OOP)是一種成熟的計(jì)算機(jī)編程模型,它是圍繞數(shù)據(jù)或者對象而不是功能邏輯來組織的,它能夠提高代碼可重用性和開發(fā)效率。SystemVerilog引入了C++?語言中“類”的概念。類描述的是一組有相同特性(屬性)和相同行為(方法)的對象。在程序中,類實(shí)際上就是數(shù)據(jù)類型,就像整型、實(shí)數(shù)型一樣。在驗(yàn)證平臺(tái)中,類和對象對于激勵(lì)的產(chǎn)生和數(shù)據(jù)的高層抽象很有幫助,如類可以用來封裝一個(gè)通用的操作,從而在驗(yàn)證平臺(tái)的不同地方重用。1.類的定義下面定義了一個(gè)名為“Packet”的類,類的內(nèi)部定義了數(shù)據(jù)變量(也稱為屬性)command/address/master_id/i,以及對這些數(shù)據(jù)變量(屬性)進(jìn)行處理的任務(wù)clean和函數(shù)new/get。其中new()函數(shù)被稱為構(gòu)造函數(shù)。構(gòu)造函數(shù)用于實(shí)例化類時(shí)為其初始化,如下面代碼中對變量command、address和master_id賦初值。類中的構(gòu)造函數(shù)只能有一個(gè),且沒有返回值。2.類的聲明(句柄的聲明)類就像用戶自定義的一種數(shù)據(jù)類型,在module/class/function/task等地方可以創(chuàng)建變量為某個(gè)類的類型。3.類的實(shí)例化(創(chuàng)建對象)通過構(gòu)造函數(shù)new()對句柄初始化,創(chuàng)建了類的對象,如下面的“my_packet=new();”,此時(shí)對象名即變量名,也是對象的實(shí)際句柄。通過new()這個(gè)構(gòu)造函數(shù)給對象分配內(nèi)存空間,并且把實(shí)際入口地址賦給對象的句柄my_packet。上述task端口變量myexample是obj_example類型,功能是判斷句柄myexample是否初始化,如果沒有初始化,則通過new創(chuàng)建新的對象,并且句柄myexample指向這個(gè)新的對象。如果在類的定義中,函數(shù)的參數(shù)和類屬性的命名相同,如下面Demo_this類中變量x既是類的屬性,也是函數(shù)new()的參數(shù),此時(shí)需要加“this”進(jìn)行區(qū)別。關(guān)鍵字this用于明確引用當(dāng)前對象的類屬性或方法。在new()函數(shù)中將形參x的數(shù)值賦給Demo_this對象中的變量x。4.使用對象就如Verilog中的層次化引用一樣,通過“.”操作符來訪問對象中的成員。例如:Packetmy_packet;//定義變量my_packet類型是Packet類5.類的繼承和多態(tài)繼承是類中一個(gè)非常重要的概念,是讓一個(gè)類(子類)獲得另一個(gè)類(父類)的屬性和方法的途徑。通過使用關(guān)鍵詞“extends”,子類不僅可以繼承并修改父類的所有屬性和方法,還可以創(chuàng)建自己的屬性和方法。在實(shí)際應(yīng)用中,將共性的屬性和方法放在父類中,子類只關(guān)注自己特有的屬性和方法,這樣提高了代碼的擴(kuò)展性。在下面的代碼中,類LinkedPacket是Packet的子類,它繼承了Packet中所有的屬性和方法,就像它們在自己類內(nèi)定義的一樣;同時(shí)LinkedPacket還有自己的函數(shù)get_next()和屬性j。子類對象是其父類的合法對象。每個(gè)LinkedPacket對象是一個(gè)完全合法的Packet對象,例如:LinkedPacketlp=new;Packetp=lp;LinkedPacket對象的句柄可以賦給Packet變量。在這種情況下,對p的引用可以訪問Packet類的方法和屬性。在下面的代碼中,子類LinkedPacket定義了一個(gè)和父類Packet同名的函數(shù)get()和成員i,通過p引用的這些被重寫的成員得到的是父類Packet類中的原始屬性和方法,因此變量j的值都為1。如果子類引用父類中的成員,特別是當(dāng)父類的成員被子類成員覆蓋時(shí),必須用關(guān)鍵字super來訪問父類成員。將上面LinkedPacket類改寫成:對象lp是子類LinkedPacket,用super.i獲取了父類Packet中定義的成員i,所以結(jié)果為-1。上面提到將一個(gè)子類句柄賦給一個(gè)父類句柄(向上轉(zhuǎn)型),這通常是合法的;但是將一個(gè)父類句柄賦值給一個(gè)子類句柄(向下轉(zhuǎn)型),需要利用關(guān)鍵字$cast強(qiáng)制轉(zhuǎn)換,如下所示,將Packet句柄pp強(qiáng)制轉(zhuǎn)換成LinkedPacket子類句柄lpp。6.抽象類和虛方法在類名前加上關(guān)鍵字virtual的類稱為抽象類,抽象類不能實(shí)例化,只能被繼承。若將Packet類定義的第一行改寫成“virtualclassPacket;”,這時(shí)用“Packetp=new;”就會(huì)報(bào)錯(cuò)。在解釋繼承時(shí)可知,將子類句柄賦給父類句柄后,若調(diào)用子類和父類中的同名方法,賦值后的父類句柄調(diào)用的方法還是父類的方法,這是因?yàn)槠胀ǚ椒ǖ恼{(diào)用取決于調(diào)用該方法的句柄類型,而不是句柄指向?qū)ο蟮念愋?。如果想在子類中覆蓋父類的方法,則可以在父類的方法前加上關(guān)鍵字virtual,也就是將父類方法變?yōu)樘摲椒?;對于虛方法的調(diào)用取決于句柄指向的對象類型,而非句柄類型。如下面代碼,將Packet中的函數(shù)get改成虛函數(shù),此時(shí)p.get()返回值是通過子類對象和方法計(jì)算得到的數(shù)值,即-2。在類中如果有接口定義,在接口名前面也可以加關(guān)鍵字virtual,即virtualinterface_name。當(dāng)它作為一種數(shù)據(jù)類型使用時(shí),保存著對實(shí)際接口的句柄,這意味著class可以使用virtualinterface來驅(qū)動(dòng)該interface,而不是直接應(yīng)用DUT接口信號(hào)。virtualinterface提供了一種將驗(yàn)證平臺(tái)抽象模型與設(shè)計(jì)的實(shí)際接口信號(hào)分開的機(jī)制,促進(jìn)了代碼的重用,對底層設(shè)計(jì)的接口更改不需要重寫使用virtualinterface的代碼。7.?dāng)?shù)據(jù)隱藏和封裝將類中的數(shù)據(jù)隱藏,并且通過方法來訪問的技術(shù)叫做封裝。在默認(rèn)情況下,類中的所有成員都可以通過對象的句柄來訪問,但是多個(gè)對象句柄訪問可能會(huì)破壞某些類成員的值。為了限制外部對象對類內(nèi)部成員的訪問,可以在成員名前加上前綴local或protected。通過聲明成員為local成員來避免對此類成員的外部訪問(父類的對象也不能訪問,這種訪問也屬于外部訪問),任何違規(guī)都可能導(dǎo)致編譯錯(cuò)誤,local成員對于子類來說也不可見,所以不能通過子類來訪問local成員。8.3.2隨機(jī)約束在VerilogHDL中使用$random系統(tǒng)函數(shù)產(chǎn)生隨機(jī)激勵(lì)來檢測隱藏的設(shè)計(jì)漏洞。但是純粹的隨機(jī)激勵(lì)需要很長時(shí)間才能產(chǎn)生有意義的效果,而且不一定符合芯片設(shè)計(jì)規(guī)范,如隨機(jī)產(chǎn)生的激勵(lì)可能不滿足總線接口時(shí)序規(guī)范。因此,在SystemVerilog中提出給隨機(jī)施加一定約束條件的思想,通過對隨機(jī)測試用例施加一定的約束,將隨機(jī)用例約束在仿真驗(yàn)證期望的區(qū)間內(nèi),從而提高隨機(jī)激勵(lì)的效率。對于不需要關(guān)心的測試空間,通過約束條件進(jìn)行關(guān)閉,可提高測試向量的有效性;利用隨機(jī)種子反復(fù)地運(yùn)行隨機(jī)激勵(lì),不同的隨機(jī)種子隨機(jī)出來的測試向量不同,從而覆蓋不同的測試空間。隨機(jī)約束不但可以減少編寫測試向量的數(shù)目和驗(yàn)證代碼的行數(shù),還可能覆蓋到事先沒有預(yù)料到的邊界測試空間(CornerCase),從而發(fā)現(xiàn)隱藏的錯(cuò)誤。但是隨機(jī)測試的驗(yàn)證環(huán)境比定向測試的復(fù)雜,需要隨機(jī)激勵(lì)、參考模型和比較邏輯(如圖8.3-1所示)。SystemVerilog提供一種緊湊的、聲明式的方式指定約束。下面介紹約束隨機(jī)測試所需的常用語法。1.隨機(jī)數(shù)產(chǎn)生系統(tǒng)函數(shù)和傳統(tǒng)VerilogHDL一樣,SystemVerilog也內(nèi)置了一些系統(tǒng)函數(shù)來產(chǎn)生隨機(jī)激勵(lì),如$urandom、$urandom_range,以及一些標(biāo)準(zhǔn)概率分布的系統(tǒng)函數(shù),如$random、$dist_uniform、$dist_normal等。2.隨機(jī)分支randcase和隨機(jī)序列randsequence關(guān)鍵字randcase引入了一個(gè)case語句,該語句隨機(jī)選擇它的一個(gè)分支。randcase項(xiàng)表達(dá)式是組成分支權(quán)值的非負(fù)整數(shù)值。一個(gè)分支的權(quán)重除以所有權(quán)重的和,就得到了選擇該分支的概率。3.面向?qū)ο蟮碾S機(jī)上節(jié)提到面向?qū)ο蟮木幊虡O大提高了驗(yàn)證的可擴(kuò)展性,SystemVerilog也可為對象的成員變量提供隨機(jī)激勵(lì)?;趯ο蟮碾S機(jī)生成包含了三個(gè)部分:定義隨機(jī)變量類型、指定約束條件(可選)、通過調(diào)用內(nèi)置randomize()方法產(chǎn)生隨機(jī)。隨機(jī)變量的類型有兩種:rand和randc。rand關(guān)鍵字聲明的變量是標(biāo)準(zhǔn)隨機(jī)變量,它們的值均勻地分布,如“randbit[7:0]y;”是一個(gè)8位無符號(hào)整數(shù),取值范圍是0~255。如果不受約束,則該變量應(yīng)被賦值為0~255的任意值,概率相等,即連續(xù)隨機(jī)化時(shí)重復(fù)相同值的概率是1/256。用randc關(guān)鍵字聲明的變量是隨機(jī)循環(huán)變量,只能是位類型或枚舉類型,并且可以限制最大值。其基本思想是randc隨機(jī)遍歷規(guī)定范圍內(nèi)的所有值,并且在一次遍歷中沒有重復(fù)值。當(dāng)遍歷結(jié)束時(shí),一個(gè)新的隨機(jī)遍歷自動(dòng)開始。如“randcbit[1:0]y;”,變量y可以取值0、1、2和3(范圍為0~3)。randomize計(jì)算y范圍內(nèi)的初始隨機(jī)排列,然后在后續(xù)調(diào)用中按順序返回這些值。當(dāng)返回一個(gè)排列的最后一個(gè)數(shù)值后,再計(jì)算一個(gè)新的隨機(jī)排列來重復(fù)這個(gè)過程。

在面向?qū)ο蟮碾S機(jī)變量中,通常加上約束條件限制隨機(jī)變量的數(shù)值范圍。約束條件也稱為約束塊,它是類中的獨(dú)立成員,類似于類任務(wù)、函數(shù)和變量,約束塊名在類中必須是唯一的。其基本語法為約束條件及隨機(jī)過程控制通常有下面幾種機(jī)制:(1)集合成員約束:用inside操作符產(chǎn)生一個(gè)隨機(jī)數(shù)的集合,隨機(jī)變量在這個(gè)集合中選取,且每個(gè)值取到的概率相同。(2)概率分布約束:dist操作符帶有一個(gè)值的列表以及相應(yīng)的權(quán)重,中間用“:=”或“:/”分開?!?=”操作符表示范圍內(nèi)的每個(gè)值的權(quán)重是相同的,“:/”表示權(quán)重要均分到每一個(gè)值。(3)條件約束:使用指示運(yùn)算符或if-else結(jié)構(gòu)。(4)函數(shù)約束:有時(shí)約束條件很難用簡單的隨機(jī)種子或范圍來描述,因此SystemVerilog提供了用函數(shù)來描述約束。(5)迭代約束:使用關(guān)鍵字“foreach”,允許循環(huán)變量和索引表達(dá)式以參數(shù)化的方式約束數(shù)組變量。8.3.3覆蓋率上一節(jié)中基于約束的隨機(jī)激勵(lì)測試可以檢測隱藏的設(shè)計(jì)漏洞或設(shè)計(jì)邊角情況,提高驗(yàn)證的狀態(tài)或功能點(diǎn)數(shù),但這些功能點(diǎn)可能是局部的。通常驗(yàn)證必須是全面的,因此覆蓋率被提出來并作為衡量驗(yàn)證是否通過或滿足要求的標(biāo)準(zhǔn)。覆蓋率有代碼覆蓋率和功能覆蓋率兩種。本節(jié)主要討論功能覆蓋率統(tǒng)計(jì)方法。功能覆蓋率是一個(gè)用戶自定義的度量,用以度量有多少設(shè)計(jì)規(guī)范已經(jīng)被執(zhí)行,如測試計(jì)劃中的測試用例。它用于度量有效場景、角落用例、規(guī)范不變性或其他應(yīng)用設(shè)計(jì)條件是否已經(jīng)被觀察、驗(yàn)證和測試。功能覆蓋率有兩個(gè)重要的特征:它是用戶自定義的,不是由設(shè)計(jì)自動(dòng)推斷的;它建立在設(shè)計(jì)規(guī)范的基礎(chǔ)上,但又獨(dú)立于設(shè)計(jì)代碼和設(shè)計(jì)結(jié)構(gòu)。因?yàn)楣δ芨采w是完全由用戶指定的,所以它需要更多的前期工作(如編寫覆蓋模型);同時(shí)也需要結(jié)構(gòu)化的驗(yàn)證方法。SystemVerilog基于上述原因,提供兩種類型的功能覆蓋率:(1)面向控制的功能覆蓋率:通過cover對斷言中的sequence或者property作統(tǒng)計(jì),這個(gè)將在8.3.4節(jié)中討論。(2)面向數(shù)據(jù)的功能覆蓋率:在特定的時(shí)間點(diǎn)對某些數(shù)據(jù)值使用coverpoint和covergroup作采樣統(tǒng)計(jì)分析。本節(jié)就簡要介紹這種功能覆蓋率。

1.覆蓋點(diǎn)覆蓋點(diǎn)(coverpoint)就是針對變量或者表達(dá)式的數(shù)值進(jìn)行采樣的地方。SystemVerilog會(huì)為每個(gè)覆蓋點(diǎn)創(chuàng)建對應(yīng)的一組倉(bin)來記錄每個(gè)數(shù)據(jù)被采集到的次數(shù)。如果采樣的變量是1bit位寬,最多有兩個(gè)bin被創(chuàng)建,即“0”倉和“1”倉。為了計(jì)算覆蓋率,首先需要確定每個(gè)覆蓋點(diǎn)上所有可能產(chǎn)生的數(shù)值個(gè)數(shù),如采樣的變量是3bit位寬,就有8個(gè)不同的數(shù)值,創(chuàng)建8個(gè)倉。如果在仿真過程中有7個(gè)倉的值被采樣到,那么這個(gè)測試點(diǎn)的覆蓋率就是7/8。coverpoint的基本語法為coverpoint<變量/表達(dá)式1>iff(表達(dá)式2)其中,iff是可選項(xiàng),表示當(dāng)表達(dá)式2成立時(shí),不作覆蓋率統(tǒng)計(jì)。上面語法產(chǎn)生的倉數(shù)及倉名是系統(tǒng)自動(dòng)創(chuàng)建的,自動(dòng)創(chuàng)建倉的最大個(gè)數(shù)由auto_bin_max確定,默認(rèn)是64。如果一個(gè)變量是16位,有2^16?=?65?536個(gè)數(shù)值,數(shù)值超過了倉的個(gè)數(shù)時(shí),會(huì)將值域范圍平均分到每個(gè)倉內(nèi),即每個(gè)倉都覆蓋了1024個(gè)數(shù)值。在如此龐大的倉內(nèi)尋找沒有被覆蓋的點(diǎn)其工作量無疑是巨大的,因此SystemVerilog提供了用戶自定義倉來限制倉的個(gè)數(shù)或者創(chuàng)建有意義的倉,基本語法為bins/ignore_bins/illegal_bins倉名={數(shù)值集或數(shù)值轉(zhuǎn)換}iff(表達(dá)式2);其中,關(guān)鍵字bins表示創(chuàng)建一個(gè)倉,ignore_bins表示倉中的所有值都被排除在覆蓋范圍之外,illegal_bins表示所有與非法倉相關(guān)的值都被排除在覆蓋范圍之外;如果發(fā)生illegal,則發(fā)出運(yùn)行錯(cuò)誤警示。非法倉優(yōu)先于任何其他倉,也就是說,即使它們也包含在另一個(gè)倉中,發(fā)生時(shí)也會(huì)導(dǎo)致運(yùn)行錯(cuò)誤。在自創(chuàng)建倉內(nèi),倉內(nèi)除了有不同的數(shù)值外,還可以定義一個(gè)或多個(gè)數(shù)值轉(zhuǎn)換或數(shù)值序列,判斷這些數(shù)值序列是否被覆蓋、忽略或非法,如判斷value1=>value2=>value3=>value4這個(gè)數(shù)值序列。2.覆蓋組(covergroup)在同一采樣時(shí)間點(diǎn)上將多個(gè)覆蓋點(diǎn)組合在一起就構(gòu)成了覆蓋組covergroup。類似class,covergroup也是一個(gè)用戶自定義類型,在module/program/interface/class/package等結(jié)構(gòu)內(nèi)定義,通過new構(gòu)造實(shí)現(xiàn)多次實(shí)例化,其基本語法為覆蓋組可以定義形式參數(shù)列表,在new實(shí)例化時(shí)將實(shí)參傳遞給形參;可以明確定義功能覆蓋組的采樣條件,若不定義時(shí)鐘采樣條件,則通過默認(rèn)的sample函數(shù)采樣;通過coverpoint和cross語句定義采樣對象。3.交叉覆蓋點(diǎn)覆蓋組內(nèi)可以通過關(guān)鍵字cross對兩個(gè)或者多個(gè)覆蓋點(diǎn)指定交叉覆蓋點(diǎn)。若cross指定的交叉覆蓋點(diǎn)中的成員是一個(gè)變量,但沒有用coverpoint定義,則系統(tǒng)會(huì)自動(dòng)為該變量創(chuàng)建對應(yīng)的覆蓋點(diǎn);但成員不能是沒有用coverpoint定義的表達(dá)式,這種情況必須先為表達(dá)式定義覆蓋點(diǎn)。8.3.4SystemVerilog斷言1.什么是斷言?傳統(tǒng)的驗(yàn)證基本原理是根據(jù)電路需求編寫激勵(lì)信號(hào)或測試向量,將測試向量連接到被驗(yàn)證模塊的輸入端,在其輸出端收集數(shù)據(jù),并進(jìn)行時(shí)序或者數(shù)據(jù)分析,達(dá)到查找設(shè)計(jì)缺陷的目的。這種方法根本上是屬于覆蓋率驅(qū)動(dòng)的動(dòng)態(tài)仿真。隨著系統(tǒng)級芯片設(shè)計(jì)復(fù)雜度的不斷提高,上述傳統(tǒng)驗(yàn)證方法的弊端越來越明顯,比如為了滿足覆蓋率的要求,需要編寫運(yùn)行大量的測試向量來查找設(shè)計(jì)中的缺陷,消耗大量的人力資源和仿真資源;驗(yàn)證工程師需要通過分析波形和日志文件來檢查及定位設(shè)計(jì)中的錯(cuò)誤,這種分析方法在系統(tǒng)級驗(yàn)證中效率低下,不利于產(chǎn)品上市周期。設(shè)計(jì)能力與驗(yàn)證能力之間差距的不斷增大,迫使人們?nèi)ヌ骄啃碌尿?yàn)證方法以彌補(bǔ)現(xiàn)有驗(yàn)證方法的不足,因此基于斷言的驗(yàn)證技術(shù)(Assertion_BasedVerification,ABV)被提出并應(yīng)用在系統(tǒng)級電路驗(yàn)證中。斷言(assertion)是對設(shè)計(jì)屬性(property)(行為)的描述,它并不是一個(gè)全新的概念,最初在軟件設(shè)計(jì)中得以應(yīng)用。斷言的概念最早出現(xiàn)于1949年AlanTuring在高速自動(dòng)計(jì)算機(jī)器(HighSpeedAutomaticCalculatingMachines)會(huì)議論文中所提及的一段敘述:“Inorderthatthemanwhochecksmaynothavetoodifficultatask,theprogrammershouldmakeanumberofdefiniteassertionswhichcanbecheckedindividually,andfromwhichthecorrectnessofthewholeprogrameasilyflows.”(為了降低驗(yàn)證難度,程序員應(yīng)該設(shè)計(jì)一些明確的斷言,這些斷言可以單獨(dú)檢查,并且很容易從中判斷整個(gè)程序是否正確。)斷言總是和靜態(tài)仿真工具結(jié)合在一起使用,對電路進(jìn)行形式驗(yàn)證。形式驗(yàn)證是通過數(shù)學(xué)的方法遍歷所有工作狀態(tài),它克服了傳統(tǒng)動(dòng)態(tài)仿真難以窮舉所有可能的測試序列去完全覆蓋狀態(tài)的缺點(diǎn)?;跀嘌缘尿?yàn)證方法如圖8.3-6所示。首先根據(jù)設(shè)計(jì)規(guī)范制定測試場景,從測試場景中抽象出屬性(行為)并用斷言表示,這些斷言可以插入到設(shè)計(jì)文件中,也可以單獨(dú)編成一個(gè)斷言文件;將設(shè)計(jì)文件和對應(yīng)的斷言文件送入形式驗(yàn)證工具中仿真驗(yàn)證,在仿真過程中,斷言就類似一個(gè)監(jiān)控器,監(jiān)視那些屬性;如果一個(gè)被描述的屬性不是期望的那樣,這個(gè)斷言就會(huì)失敗,并給出反例用于驗(yàn)證者核查錯(cuò)誤,進(jìn)而修改設(shè)計(jì)或進(jìn)一步約束屬性,使其更精確地描述設(shè)計(jì)行為。斷言包括用戶自定義的斷言和專門的斷言庫(如OVL(OpenVerificationLibrary)),能夠進(jìn)行屬性描述、接口約束、激勵(lì)序列產(chǎn)生、功能覆蓋率檢查及形式驗(yàn)證分析等。使用斷言的驗(yàn)證技術(shù)的優(yōu)點(diǎn)有如下幾點(diǎn)。(1)提高了驗(yàn)證效率:用簡潔的語言結(jié)構(gòu)描述了復(fù)雜準(zhǔn)確的時(shí)序關(guān)系;一旦發(fā)生設(shè)計(jì)錯(cuò)誤,斷言能立即檢測及定位,提高驗(yàn)證的可觀察性;致命錯(cuò)誤發(fā)生后,斷言可以終止仿真,提高驗(yàn)證的可控性。(2)提升了功能覆蓋率:斷言作為設(shè)計(jì)屬性(行為)的描述,通過對斷言執(zhí)行情況的覆蓋統(tǒng)計(jì),可以將傳統(tǒng)的代碼覆蓋率提升到功能覆蓋率,與仿真環(huán)境中原有的功能覆蓋點(diǎn)相結(jié)合,構(gòu)建完整的功能覆蓋機(jī)制。(3)可重用性強(qiáng):基于“黑盒子”的斷言技術(shù)與具體電路實(shí)現(xiàn)無關(guān),一般寫在單獨(dú)的斷言文件中,用來描述電路輸入/輸出應(yīng)滿足的設(shè)計(jì)要求;尤其是針對標(biāo)準(zhǔn)協(xié)議編寫的斷言,它們可以面向不同的設(shè)計(jì)。(4)支持跨時(shí)鐘域的時(shí)序驗(yàn)證:現(xiàn)在大多數(shù)的設(shè)計(jì)是基于多時(shí)鐘域的,當(dāng)跨越不同的時(shí)鐘域時(shí),使用多個(gè)時(shí)鐘斷言屬性對于數(shù)據(jù)完整性檢查非常有幫助。用之前學(xué)習(xí)的VerilogHDL可以實(shí)現(xiàn)斷言的功能,如下面的Verilog代碼設(shè)計(jì)了一個(gè)斷言。當(dāng)定義宏名DEBUG時(shí),這個(gè)檢驗(yàn)器生效并產(chǎn)生一個(gè)斷言,即信號(hào)a和b不能同時(shí)為高電平,如果發(fā)生了上述情況,則打印錯(cuò)誤信息。雖然VerilogHDL代碼結(jié)合系統(tǒng)任務(wù)或函數(shù)可以實(shí)現(xiàn)一些檢驗(yàn)任務(wù),但是VerilogHDL本質(zhì)上是一種過程性語言,其設(shè)計(jì)目的是用于硬件電路設(shè)計(jì),而不是電路的仿真驗(yàn)證,因此它不能很好地控制產(chǎn)生復(fù)雜時(shí)序。要描述復(fù)雜的時(shí)序關(guān)系,VerilogHDL需要編寫冗長的代碼,如例8.3-8所示的時(shí)序(見圖8.3-7):在時(shí)鐘上升沿判斷信號(hào)a是否為高;延時(shí)1個(gè)時(shí)鐘周期,判斷信號(hào)b是否為高;再延時(shí)2個(gè)時(shí)鐘周期,判斷信號(hào)c是否為高。這樣復(fù)雜的時(shí)序代碼編寫容易出錯(cuò)且不易維護(hù);由于VerilogHDL的過程性,使得它很難檢測同一時(shí)間段發(fā)生的所有并行事件;更糟糕的是,用VeilogHDL編寫的斷言可能與它們要驗(yàn)證功能的實(shí)現(xiàn)方式相同并包含相同的錯(cuò)誤,從而無法檢測到共同錯(cuò)誤。鑒于VerilogHDL編寫斷言可能存在的以上問題,SystemVerilog開發(fā)了編寫斷言的專用語言SystemVerilogAssertion。2.SystemVerilog斷言的建立過程SystemVerilogAssertion(SVA)是一種描述性的語言,它提供了一種強(qiáng)大的替代方法為設(shè)計(jì)編寫約束、檢查器和覆蓋點(diǎn);同時(shí)語言本身也簡單,易于管理。如例8.3-8中需要驗(yàn)證的時(shí)序關(guān)系,用SVA描述,只需一行代碼:

abc_ast:assertproperty(@(posedgeclk)a|->##1b##2c);同時(shí)從例8.3-8中看出,時(shí)序驗(yàn)證的失敗和成功的結(jié)論必須在VerilogHDL中額外用$display定義,而SVA中斷言失敗會(huì)自動(dòng)顯示錯(cuò)誤信息。

SVA的建立過程如圖8.3-8所示,包括布爾表達(dá)式、序列(Sequence)、屬性(Property)、斷言(AssertProperty)和覆蓋語句(CoverProperty)。1)布爾表達(dá)式布爾表達(dá)式位于最底層,和VerilogHDL中沒有差別,如“a&&b;”。2)序列在任何設(shè)計(jì)中,序列都是由多個(gè)邏輯事件組合而成的。這些事件可以是同一時(shí)鐘沿被求值的簡單布爾表達(dá)式,也可以是經(jīng)過多個(gè)時(shí)鐘周期后求值計(jì)算得到的事件。SVA使用關(guān)鍵字sequence(序列)來表示這些事件,其基本語法為3)屬性許多序列可以被有序地組合起來形成設(shè)計(jì)的屬性,用關(guān)鍵字property來表示屬性。屬性也可以由表達(dá)式構(gòu)成。屬性是在模擬過程中被驗(yàn)證的單元,只有在斷言中被調(diào)用,才能真正發(fā)揮作用。其基本語法為4)斷言斷言是對特定屬性或者序列進(jìn)行行為檢查,其基本語法為assertion_name:assertproperty(property_name);其執(zhí)行方式與過程if語句相同,即如果表達(dá)式的計(jì)算結(jié)果為X、Z或0,那么表達(dá)式被解釋為假,斷言失??;否則,表達(dá)式被解釋為真,斷言成功。5)覆蓋為了保證驗(yàn)證的完備性,需要統(tǒng)計(jì)功能覆蓋率信息,在SVA中提供關(guān)鍵字cover來實(shí)現(xiàn)這一功能,其基本語法為cover_name:coverproperty(property_name);其中,property_name是需要覆蓋的屬性名。覆蓋語句執(zhí)行結(jié)束后,可得到的信息包括屬性驗(yàn)證的次數(shù)、屬性成功的次數(shù)、屬性失敗的次數(shù)及屬性“空成功”(VacuousSuccess)的次數(shù)。3.?dāng)嘌缘姆N類SystemVerilog語言中定義了兩種斷言:即時(shí)斷言(ImmediateAssertion)和并發(fā)斷言(ConcurrentAssertion)。1)即時(shí)斷言即時(shí)斷言基于事件的變化,表達(dá)式的計(jì)算就像VerilogHDL中的組合邏輯賦值一樣,是立即被求值判斷的,而不是時(shí)序相關(guān)的。它放在過程塊的定義中,主要用于動(dòng)態(tài)仿真。2)并發(fā)斷言一般的,斷言是基于時(shí)序邏輯的,單純進(jìn)行組合邏輯的斷言很少,因此在這里重點(diǎn)介紹面向時(shí)序檢查的并發(fā)斷言所涉及的常用語法。并發(fā)斷言的一般規(guī)則是“time+sequence”,首先要指定斷言被觸發(fā)執(zhí)行的時(shí)刻,一般情況是用時(shí)鐘上升(下降沿)來觸發(fā),即@(posedgeclk)或@(negedgeclk)。并發(fā)斷言可以放在always或initial過程塊中,也可以像連續(xù)賦值語句一樣單獨(dú)成行。并發(fā)斷言可以在靜態(tài)(形式化)驗(yàn)證工具和動(dòng)態(tài)(仿真)驗(yàn)證工具中使用。

4.?dāng)嘌远x中常用的語法結(jié)構(gòu)下面介紹在斷言定義中常用的一些語法結(jié)構(gòu)。1)斷言失效在驗(yàn)證中,當(dāng)某些條件滿足時(shí),不用進(jìn)行斷言的檢測,如當(dāng)復(fù)位信號(hào)有效時(shí),讓斷言不工作;SVA提供了關(guān)鍵詞“disableiff”來實(shí)現(xiàn)驗(yàn)證在某些情況下的失效,其基本語法為disableiff(expression)property_expr;如在異步復(fù)位觸發(fā)器中判斷輸出信號(hào)q是否等于輸入信號(hào)d,若直接編寫斷言@(posedgeclk)(q==$past(d)),則當(dāng)復(fù)位信號(hào)有效時(shí)就會(huì)報(bào)錯(cuò),因此需要改寫成當(dāng)復(fù)位信號(hào)無效時(shí)進(jìn)行斷言的判斷,將上句重新改寫為@(posedgeclk)disableiff(!rst_n)(q==$past(d))//rst_n是低電平有效時(shí)鐘clk上升沿到來,首先判斷復(fù)位信號(hào)rst_n是否為低電平,如果rst_n是低電平,則不進(jìn)行q==$past(d)的判斷;rst_n為高電平,才進(jìn)行輸出信號(hào)q是否等于上一個(gè)時(shí)鐘輸入信號(hào)d數(shù)值的判斷。2)蘊(yùn)含結(jié)構(gòu)上述時(shí)序驗(yàn)證只是在每個(gè)時(shí)鐘有效沿檢查對應(yīng)的布爾表達(dá)式是否成立,但在復(fù)雜時(shí)序的檢驗(yàn)中,往往需要驗(yàn)證若干個(gè)時(shí)鐘周期內(nèi)發(fā)生的多個(gè)事件,而且這些事件存在時(shí)序先后關(guān)系。比如在時(shí)鐘信號(hào)clk上升沿時(shí),首先判斷事件A是否成立,如果不成立,則斷言失??;如果成立,再判斷事件B是否成立,這就相當(dāng)于一個(gè)if-else結(jié)構(gòu):其中,事件A稱為“先行算子”(antecedent),事件B稱為“后續(xù)算子”(consequent)。當(dāng)先行算子成功時(shí),后續(xù)算子才會(huì)被計(jì)算判斷。如果先行算子不成功,那么整個(gè)屬性默認(rèn)為“空成功”。這種由先行事件觸發(fā)后續(xù)事件的結(jié)構(gòu)在SVA中稱為蘊(yùn)含結(jié)構(gòu),它包括兩種類型:交疊蘊(yùn)含(OverlappedImplication)和非交疊蘊(yùn)含(Non-OverlappedImplication)。(1)交疊蘊(yùn)含。交疊蘊(yùn)含用符號(hào)“|->”表示,含義是如果先行算子成功,則在同一個(gè)時(shí)鐘周期計(jì)算并判斷后續(xù)算子是否成功。(2)非交疊蘊(yùn)含。非交疊蘊(yùn)含用符號(hào)“|=>”表示,含義是如果先行算子成功,則在下一個(gè)時(shí)鐘周期計(jì)算并判斷后續(xù)算子是否成功,即后續(xù)算子的判斷相對先行算子會(huì)有一個(gè)時(shí)鐘周期的延時(shí)。在一些復(fù)雜時(shí)序的設(shè)計(jì)中,先行算子和后續(xù)算子的發(fā)生往往不在同一時(shí)鐘周期或僅一個(gè)時(shí)鐘周期延時(shí),可能后續(xù)算子的發(fā)生相對于先行算子有若干個(gè)時(shí)鐘周期的延時(shí),因此SVA提供了帶有延時(shí)的蘊(yùn)含,時(shí)鐘延時(shí)用“##”表示,具體形式如下:3)重復(fù)運(yùn)算符在時(shí)序設(shè)計(jì)中往往需要某個(gè)信號(hào)或序列重復(fù)發(fā)生,如下面的序列:@(posedgeclk)$rose(start)|->##1a##1a##1a##1stop;表示在時(shí)鐘上升沿,若信號(hào)start發(fā)生了上跳變,則從下一個(gè)時(shí)鐘起,信號(hào)a保持在3個(gè)連續(xù)時(shí)鐘周期內(nèi)為高電平,然后在下一個(gè)時(shí)鐘周期,信號(hào)stop為高。如果信號(hào)a要在多個(gè)時(shí)鐘周期保持高電平,上述寫法會(huì)使代碼冗長,因此SVA中提供了3種不同機(jī)制的重復(fù)運(yùn)算符。(1)連續(xù)重復(fù):判斷信號(hào)或序列是否在指定的n個(gè)時(shí)鐘周期內(nèi)連續(xù)發(fā)生,其基本語法為signalorsequence[*n](2)跟隨重復(fù):判斷信號(hào)或序列是否發(fā)生了n次,但這些序列不一定是在連續(xù)時(shí)鐘周期內(nèi)發(fā)生的,但要求重復(fù)序列的最后一次發(fā)生應(yīng)該在整個(gè)序列結(jié)束之前。其基本語法為signalorsequence[->n](3)非連續(xù)重復(fù):與跟隨重復(fù)相似,但它并不要求重復(fù)序列的最后一次發(fā)生應(yīng)該在整個(gè)序列結(jié)束之前。其基本語法為signal[=n]如序列“start##1a[=3]##1stop”表示在信號(hào)stop為高電平之前,信號(hào)a要連續(xù)或間接地出現(xiàn)3個(gè)高電平,但在信號(hào)stop為高電平的前一個(gè)時(shí)鐘周期,信號(hào)a不一定為高電平。上面定義的重復(fù)次數(shù)是固定值,利用[*min:max]語法可以定義重復(fù)次數(shù)的范圍,其中min代表最小重復(fù)次數(shù),min可以為0,代表一次也不發(fā)生;如果沒有重復(fù)次數(shù)的限制,可以將右邊最大重復(fù)次數(shù)max用“$”表示。4)局部變量的使用局部變量是SVA語言中重要的特性之一,它使得檢查設(shè)計(jì)中復(fù)雜的流水線行為成為可能。SVA中的局部變量是動(dòng)態(tài)變量,也就是說,它在序列啟動(dòng)時(shí)動(dòng)態(tài)創(chuàng)建,在序列結(jié)束時(shí)自動(dòng)刪除。局部變量在序列或?qū)傩詢?nèi)部定義并賦值。局部變量的定義是單獨(dú)語句,但變量的賦值語句必須和子序列結(jié)合,并放在子序列的后面,用逗號(hào)隔開。如果子序列匹配成功,則變量才能被賦予新值。5)多時(shí)鐘域檢測SVA允許序列或者屬性使用多個(gè)時(shí)鐘域來采樣信號(hào)及檢測子序列。多時(shí)鐘域序列是通過使用單時(shí)鐘域子序列連接延時(shí)操作符##1或##0來構(gòu)建的。6)斷言系統(tǒng)函數(shù)SVA提供總線斷言函數(shù)和時(shí)序檢查的系統(tǒng)函數(shù)來快速有效建立斷言,表8.3-1列舉了一些常用斷言函數(shù)。5.SVA與功能覆蓋斷言中也提供了測量覆蓋率的工具,關(guān)鍵字為“cover”。其基本語法為cover_name:coverproperty(property_spec);其中,cover_name表示覆蓋名稱,property_spec表示要覆蓋的屬性。6.SVA輸入約束在形式驗(yàn)證中,形式工具會(huì)盡可能地遍歷所有的合法輸入空間。為了降低形式驗(yàn)證復(fù)雜度,提高驗(yàn)證有效性,在斷言中提供可對設(shè)計(jì)輸入約束的語法assume。其基本語法為assume_name:assume(property_spec)其中,assume_name表示約束名稱,property_spec表示要約束的屬性。7.?SVA與設(shè)計(jì)的連接將SVA連接到對應(yīng)的設(shè)計(jì)中有如下兩種方法:(1)在模塊(module)定義中斷言檢驗(yàn)器,稱之為內(nèi)部斷言;(2)將斷言檢驗(yàn)器與模塊、模塊的一個(gè)或多個(gè)實(shí)例綁定,稱之為外部斷言。1)內(nèi)部斷言斷言放在設(shè)計(jì)模塊的內(nèi)部,方便在仿真時(shí)查看異常情況。當(dāng)異常出現(xiàn)時(shí),斷言會(huì)自動(dòng)報(bào)警,其具體結(jié)構(gòu)如下:模塊內(nèi)部斷言一般用在內(nèi)部信號(hào)或時(shí)序的判斷上,一般將它和關(guān)系密切的RTL代碼放在一起,以保持一致性。需要注意的是,編寫的RTL代碼不能破壞斷言的正確執(zhí)行,若斷言自身存在和它想要驗(yàn)證的行為相同的錯(cuò)誤,則斷言將無法檢測這些錯(cuò)誤。內(nèi)部斷言最好放在`ifdef塊中,當(dāng)工具不支持或設(shè)計(jì)(仿真)者不使用內(nèi)部斷言時(shí),可通過取消相應(yīng)預(yù)處理宏名的定義來自動(dòng)去掉斷言。內(nèi)部斷言一般由設(shè)計(jì)工程師編寫插入,基于電路的具體實(shí)現(xiàn)來設(shè)計(jì),類似“白盒”技術(shù);有效的內(nèi)部斷言可以提高設(shè)計(jì)的可觀察性,能及時(shí)發(fā)現(xiàn)設(shè)計(jì)的錯(cuò)誤,并能降低仿真調(diào)試時(shí)間。2)外部斷言為了保證設(shè)計(jì)代碼的完整性,SystemVerilog在斷言中提供了bind功能,將斷言單獨(dú)做成子模塊,并通過bind把斷言子模塊與設(shè)計(jì)模塊連接起來,使得兩者互不影響。這樣做的好處是:(1)即使設(shè)計(jì)代碼有微小的改動(dòng),驗(yàn)證工程師也能夠基于原來的環(huán)境進(jìn)行驗(yàn)證。(2)提供了一個(gè)簡便機(jī)制來使驗(yàn)證斷言IP能迅速添加到一個(gè)子模塊中。(3)不會(huì)使斷言產(chǎn)生任何語義上的改變,這相當(dāng)于使用分級路徑名將斷言寫入模塊外部,保證了程序的穩(wěn)定性和可靠性。bind的基本語法為bind模塊名

斷言子模塊名

斷言實(shí)例名(端口列表);8.4SystemVerilog與C語言接口VerilogHDL編程語言接口(ProgramLanguageInterface,PLI)為VerilogHDL和其他編程語言提供了一個(gè)交互機(jī)制。SystemVerilog對PLI進(jìn)行擴(kuò)展,形成了一種新的Verilog代碼和其他編程語言(通常是C/C++)相互通信的接口方式,稱為直接編程接口DPI(DirectProgrammingInterface)。DPI相對于傳統(tǒng)的PLI,最大的優(yōu)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論