System Verilog筆記總結(jié)_第1頁(yè)
System Verilog筆記總結(jié)_第2頁(yè)
System Verilog筆記總結(jié)_第3頁(yè)
System Verilog筆記總結(jié)_第4頁(yè)
System Verilog筆記總結(jié)_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、Systemverilog數(shù)據(jù)類型l合并數(shù)組和非合并數(shù)組1)合并數(shù)組:存儲(chǔ)方式是連續(xù)的,中間沒有閑置空間。例如,32bit的寄存器,可以看成是4個(gè)8bit的數(shù)據(jù),或者也可以看成是1個(gè)32bit的數(shù)據(jù)。表示方法:數(shù)組大小和位,必須在變量名前指定,數(shù)組大小必須是【msb:lsb】Bit3:0 7:0 bytes;2)二維數(shù)組和合并數(shù)組識(shí)別:合并數(shù)組:bit 3:0 7:0 arrys;大小在變量名前面放得,且降序二維數(shù)組:int arrays0:7 0:3 ;大小在變量名后面放得,可降序可升序位寬在變量名前面,用于識(shí)別合并和非合并數(shù)組,位寬在后面,用于識(shí)別數(shù)組中元素個(gè)數(shù)。3)非合并數(shù)組一般仿真器存

2、放數(shù)組元素時(shí)使用32bit的字邊界,byte、shortint、int都放在一個(gè)字中。非合并數(shù)組:字的地位存放變量,高位不用。表示方法:Bit7:0 bytes;4)合并數(shù)組和非合并數(shù)組的選擇(1)當(dāng)需要以字節(jié)或字為單位對(duì)存儲(chǔ)單元操作。(2)當(dāng)需要等待數(shù)組中變化的,則必須使用合并數(shù)組。例如測(cè)試平臺(tái)需要通過存儲(chǔ)器數(shù)據(jù)的變化來喚醒,需要用到,只能用于標(biāo)量或者合并數(shù)組。Bit3:0 7:0 barray3; 表示合并數(shù)組,合并數(shù)組中有3個(gè)元素,每個(gè)元素時(shí)8bit,4個(gè)元素可以組成合并數(shù)組可以使用barry0作敏感信號(hào)。l動(dòng)態(tài)數(shù)組隨機(jī)事物不確定大小。使用方法:數(shù)組在開始是空的,同時(shí)使用new來分配空間

3、,在newn指定元素的個(gè)數(shù)。Int dyn;Dyn = new5;/分配5個(gè)元素空間Dyn.delete() ;/釋放空間l隊(duì)列在隊(duì)列中增加或刪除元素比較方便。l關(guān)聯(lián)數(shù)組當(dāng)你需要建立一個(gè)超大容量的數(shù)組。關(guān)聯(lián)數(shù)組,存放稀疏矩陣中的值。表示方法:采用在方括號(hào)中放置數(shù)據(jù)類型的形式聲明:Bit63:0 assocbit63:0;l常量:1)Verilog 推薦使用文本宏。好處:全局作用范圍,且可以用于位段或類型定義缺點(diǎn):當(dāng)需要局部常量時(shí),可能引起沖突。2)Parameter作用范圍僅限于單個(gè)module3)Systemverilog:參數(shù)可以在多個(gè)模塊里共同使用,可以用typedef 代替單調(diào)乏味的宏

4、。過程語(yǔ)句l可以在for循環(huán)中定義變量,作用范圍僅在循環(huán)內(nèi)部for(int i=0;i10;i+)arrayi =i;l任務(wù)、函數(shù)及void函數(shù)1) 區(qū)別:Verilog中task 和function最重要的區(qū)別是:task可以消耗時(shí)間而函數(shù)不能。函數(shù)中不能使用#100的延時(shí)或的阻塞語(yǔ)句,也不能調(diào)用任務(wù);Systemverilog中函數(shù)可以調(diào)用任務(wù),但只能在forkjoinnone生成的線程中。2)使用:如果有一個(gè)不消耗時(shí)間的systemverilog任務(wù),應(yīng)該把它定義成void函數(shù);這樣它可以被任何函數(shù)或任務(wù)調(diào)用。從最大靈活性角度考慮,所有用于調(diào)用的子程序都應(yīng)該被定義成函數(shù)而非任務(wù),以便被任

5、何其它任務(wù)或函數(shù)調(diào)用。(因?yàn)槎x成任務(wù),函數(shù)調(diào)用任務(wù)很有限制)l類靜態(tài)變量作用:1)類的靜態(tài)變量,可以被這個(gè)類的對(duì)象實(shí)例所共享。當(dāng)你想使用全局變量的時(shí)候,應(yīng)該先想到創(chuàng)建一個(gè)類的靜態(tài)變量靜態(tài)變量在聲明的時(shí)候初始化。2)類的每一個(gè)實(shí)例都需要從同一個(gè)對(duì)象獲取信息。l靜態(tài)方法作用:當(dāng)靜態(tài)變量很多的時(shí)候,操作它們的代碼是一個(gè)很大的程序,可以用在類中創(chuàng)建一個(gè)靜態(tài)方法讀寫靜態(tài)變量,但是靜態(tài)方法不能讀寫非靜態(tài)變量。lref高級(jí)的參數(shù)類型Ref 參數(shù)傳遞為引用而不是復(fù)制。Ref比 input 、output、inout更好用。Function void print_checksum(const ref bit

6、31:0 a );1)也可以不用ref進(jìn)行數(shù)組參數(shù)傳遞,這時(shí)數(shù)組會(huì)被復(fù)制到堆棧區(qū),代價(jià)很高。2)用帶ref 進(jìn)行數(shù)組參數(shù)傳遞,僅僅是引用,不需要復(fù)制;向子程序傳遞數(shù)組時(shí),應(yīng)盡量使用ref以獲得最佳性能,如果不希望子程序改變數(shù)組的值,可以使用const ref。3)Ref參數(shù),用ref 傳遞變量;可以在任務(wù)里修改變量而且,修改結(jié)果對(duì)調(diào)用它的函數(shù)可見,相對(duì)于指針的功能。lReturn語(yǔ)句增加了return語(yǔ)句。Task任務(wù)由于發(fā)現(xiàn)了錯(cuò)誤而需要提前返回,如果不這樣,那么任務(wù)中剩下的語(yǔ)句就必須被放到一個(gè)else條件語(yǔ)句中。體會(huì)下Task load_array(int len. Ref int arra

7、y );If(len0)begin$display(“Bad len”);Returun;/任務(wù)中其它代碼endtaskl局部數(shù)據(jù)存儲(chǔ) automatic作用Verilog中由于任務(wù)中局部變量會(huì)使靜態(tài)存儲(chǔ)區(qū),當(dāng)在多個(gè)地方調(diào)用同一個(gè)任務(wù)時(shí),不同線程之間會(huì)竄用這些局部變量。Systemverilog中,module和program塊中,缺省使用靜態(tài)存儲(chǔ);如果想使用自動(dòng)存儲(chǔ),需加入automatic關(guān)鍵詞。測(cè)試平臺(tái)lInterface背景 :一個(gè)信號(hào)可能連接幾個(gè)設(shè)計(jì)層次,如果增加一個(gè)信號(hào),必須在多個(gè)文件中定義和連接。接口可以解決這些問題。好處:如果希望在接口中增加一個(gè)信號(hào),不需要改變其他模塊,如TO

8、P模塊。使用方法:(1)接口中去掉信號(hào)的方向類型;(2)DUT 和測(cè)試平臺(tái)中,信號(hào)列表中采用接口名,例化一個(gè)名字注意:因?yàn)槿サ袅朔较蝾愋停涌谥胁恍枰紤]方向信號(hào),簡(jiǎn)單的接口,可以看做是一組雙向信號(hào)的集合。這些信號(hào)使用logic類型d1。雙向信號(hào)為何可以使用logic呢?這里的雙向,只是概念上的雙向,不想verilog中databus多驅(qū)動(dòng)的雙向。雙向信號(hào)如何做接口?(1)仲裁器的簡(jiǎn)單接口Interface arb_if( input bit clk);Logic 1:0 grant,request;Logic rst;EndinterfaceDUT 使用接口:Module arb(arb_i

9、f arbif);Always (posedge arbif.clk or negedge arbif.rst)endmodule(2)DUT 不采用接口,測(cè)試平臺(tái)中使用接口(推薦)DUT 中源代碼不需要修改,只需要再top中,將接口連接到端口上。Module top;Bit clk;Always #2 clk =clk;Arb_if arbif(clk);Arb_port al(.grant(arbif.grant),.request(arbif.grant),.rst(arbif.rst),.clk(arbif.clk);Test t1(arbif);EndmodulelModport背景

10、:端口的連接方式包含了方向信息,編譯器依次來檢查連續(xù)錯(cuò)誤;接口使用無信號(hào)的連接方式。Modport將接口中信號(hào)分組并指定方向。例子:l在總線設(shè)計(jì)中使用modport并非接口中每個(gè)信號(hào)都必須連接。Data總線接口中就解決不了,個(gè)人覺得?因?yàn)閐ata是一個(gè)雙驅(qū)動(dòng)l時(shí)鐘塊作用:一旦定義了時(shí)鐘塊,測(cè)試平臺(tái)就可以采用arbif.cb等待時(shí)鐘,而不需要描述確切的時(shí)鐘信號(hào)和邊沿,即使改變了時(shí)鐘塊中的時(shí)鐘或邊沿,也不需要修改測(cè)試代碼應(yīng)用:將測(cè)試平臺(tái)中的信號(hào),都放在clocking 中,并指定方向(以測(cè)試平臺(tái)為參考的方向)。并且在modprot test(clocking cb,最完整的接口:Interface

11、 arb_if(input bit clk);Logic1:0 grant,request;Logic rst;Clocking cb (posedge clk);Output request;Input grant;EndclockingModport test (clocking cb,Output rst);Modport dut (input clk, request,rst,Output grant);endinterface變化:將request 和grant移動(dòng)到時(shí)鐘塊中去了,test中沒有使用了。l接口中的雙向信號(hào)Interface master_if(input bit cl

12、k);/在類中為了,不使用有符號(hào)數(shù),常用bit定義變量Wire 7:0 data;Clocking cb(posedge clk);Inout data;EndclockingModport TEST(clocking cb);endinterfaceprogram test(master_if mif);initial beginmif.cb.data = z;mif.cb;$display(mif.cb.data);/總線中讀數(shù)據(jù)mif.cb;Mif.cb.data = 8h5a;/驅(qū)動(dòng)總線mif.cb;Mif.cb.data = z;/釋放總線注:(1)interface 列表中clk

13、采用的是input bit clk;為什么要用bit?(2)時(shí)鐘塊 clocking cb 中,一般將testbench中需要的信號(hào),方向指定在這里;而在modprot 指定test信號(hào)方向的時(shí)候,采用clocking cb。(3)interface中信號(hào),不一定都用logic,也可采用wire(雙驅(qū)動(dòng));systemverilog中如果采用C代碼的風(fēng)格(參數(shù)列表中方向和類型寫一起),必須采用logic類型(4)現(xiàn)在的風(fēng)格,DUT 沒才用clocking cb ,測(cè)試平臺(tái)和DUT的時(shí)鐘如何統(tǒng)一?l激勵(lì)時(shí)序DUT和測(cè)試平臺(tái)之間時(shí)序必須密切配合。l測(cè)試平臺(tái)和設(shè)計(jì)間的競(jìng)爭(zhēng)狀態(tài)好的風(fēng)格:使用非阻塞賦值

14、可以減少競(jìng)爭(zhēng)。systemverilog驗(yàn)證中initial 中都采用= 賦值,而等待延遲采用arbif.cb等待一個(gè)周期來實(shí)現(xiàn)。而verilog中采用的風(fēng)格時(shí),initial 中采用 =阻塞賦值,沿時(shí)可以采用#2,等實(shí)現(xiàn)。因此時(shí)鐘發(fā)生器,只能放在module 中,而不能放在program中l(wèi)Program中不能使用always塊測(cè)試平臺(tái)可以使用initial 但不能使用always,使用always 模塊不能正常工作。原因:測(cè)試平臺(tái)的執(zhí)行過程是進(jìn)過初始化、驅(qū)動(dòng)和響應(yīng)等步驟后結(jié)束仿真。如果確實(shí)需要一個(gè)always塊,可以使用initial forever 來完成。比如:在產(chǎn)生時(shí)鐘時(shí)。類l類中s

15、tatic變量背景:如果一個(gè)變量需要被其他對(duì)象所共享,如果沒有OPP,就需要?jiǎng)?chuàng)建全局變量,這樣會(huì)污染全局名字空間,導(dǎo)致你想定義局部變量,但變量對(duì)每個(gè)人都是可見的。1)作用:類中static變量,將被這個(gè)類的所有實(shí)例(對(duì)象)所共享,使用范圍僅限于這個(gè)類。例:class transaction;Static int count=0;Int id;EndclassTrasaction tr1,tr2;Id不是靜態(tài)變量,所以每個(gè)trasaction對(duì)象都有自己的id;count 是靜態(tài)變量,所有對(duì)象只有一個(gè)count變量。如何用?當(dāng)你打算創(chuàng)建一個(gè)全局變量的時(shí)候,首先考慮創(chuàng)建一個(gè)類的靜態(tài)變量。2)sta

16、tic變量的引用句柄或類名加:4)static 變量的初始化static變量通常在聲明時(shí)初始化。不能在構(gòu)造函數(shù)中初始化,因?yàn)槊恳粋€(gè)新的對(duì)象都會(huì)調(diào)用構(gòu)造函數(shù)。l靜態(tài)句柄:背景:當(dāng)類的每一個(gè)對(duì)象,都需要從同一個(gè)對(duì)象(另一個(gè)類)中獲取信息的時(shí)候。如果定義成非靜態(tài)句柄,則每個(gè)對(duì)象都會(huì)有一份copy,造成內(nèi)存浪費(fèi)。l靜態(tài)方法背景:當(dāng)使用更多靜態(tài)變量的時(shí)候,操作他們的代碼會(huì)很長(zhǎng)。作用:可以在類中創(chuàng)建一個(gè)靜態(tài)方法用于讀寫靜態(tài)變量。注:systemverilog不允許,靜態(tài)方法讀寫非靜態(tài)變量。l類之外的方法背景:解決類太長(zhǎng)的問題。類最好控制在一頁(yè)內(nèi),如果方法很都很長(zhǎng)。lThis背景:如果在類很深的底層作用域,

17、卻想引用類一級(jí)的對(duì)象。在構(gòu)造函數(shù)中最常見。作用:this指向類一級(jí)變量l如何做類,類做多大?上限:類不能太大當(dāng)類中存在多處相同的代碼,你需要將這段代碼做成當(dāng)前類的一個(gè)成員函數(shù)或父類的成員函數(shù)。下限:類不能太小類太小,增加了層次。方法:如果一個(gè)小類只被例化了一次,可以將它合并到父類中去。l動(dòng)態(tài)對(duì)象概念區(qū)分:方法中修改對(duì)象 和修改句柄修改對(duì)象將對(duì)象的變量重新賦值。修改句柄在任務(wù)中new()對(duì)象。1) 當(dāng)你將對(duì)象傳遞給方法背景:句柄,new()后變成對(duì)象,在將其作為參數(shù)傳遞給方法。實(shí)質(zhì)和作用:傳遞的是句柄。這個(gè)方法可以讀取對(duì)象中的值;也以改變對(duì)象中的值2) 修改標(biāo)量變量的值背景:在方法的參數(shù)中,前面

18、加ref;(用ref傳遞,ref傳遞的是變量的地址)。作用:方法可以修改變量的值,并將修改的值,傳遞給主程序。引申:方法可以改變對(duì)象,即使沒有使用ref 修飾句柄。因?yàn)閭鬟f的是句柄,句柄是地址。不要將句柄和對(duì)象混為一談,如果傳遞的是對(duì)象,對(duì)象是單向的,那方法以外也不能傳遞回來。可以這樣理解吧。讀寫對(duì)象中的值:例:Tasktransmit(Transcation t);Cbbus.rx_data 和ifelse可產(chǎn)生和case效果類似的語(yǔ)句塊,可以用于枚舉類型的表達(dá)式。l雙向約束l控制多個(gè)約束塊作用:可以打開或關(guān)閉某個(gè)約束可以使用內(nèi)建的Handle.constraint.constraint_m

19、ode()打開或關(guān)閉。l內(nèi)嵌約束背景:很多測(cè)試只會(huì)在代碼的一個(gè)地方隨機(jī)化對(duì)象,但是約束越來越復(fù)雜時(shí),Systemverilog可以使用randomized with 來增加額外的約束,這和在類里增加的約束是等效的。lPre_randomize 和post_randomize函數(shù)有時(shí)候需要再調(diào)用randomize()之前或之后立即執(zhí)行一些操作。隨機(jī)化前:設(shè)置類里的一些非隨機(jī)變量(如上下限、權(quán)重),隨機(jī)化后:計(jì)算數(shù)據(jù)的誤差矯正值。l約束的技巧1)約束中使用變量2)使用非隨機(jī)值如果一套約束在已產(chǎn)生了幾乎所有想要的激勵(lì)向量,但還缺少幾種。可以使用rand_mode把這些變量設(shè)置為非隨機(jī)變量。l數(shù)組約束

20、Systemverilog可以用foreach對(duì)數(shù)組中的每一個(gè)元素進(jìn)行約束。線程及線程間的通信l測(cè)試平臺(tái)使用許多并發(fā)執(zhí)行的線程。測(cè)試平臺(tái)隸屬于程序塊。Systemverilog引入兩種新的創(chuàng)建線程的方法forkjoin_none和forkjoin_any1) 使用forkjoin_none來產(chǎn)生線程在調(diào)度其內(nèi)部語(yǔ)句時(shí),父線程繼續(xù)執(zhí)行。2) 使用forkjoin_any實(shí)現(xiàn)線程同步在調(diào)度塊內(nèi)語(yǔ)句,當(dāng)?shù)谝粋€(gè)語(yǔ)句執(zhí)行完,父線程才繼續(xù)執(zhí)行。l動(dòng)態(tài)線程Systemverilog中可以動(dòng)態(tài)創(chuàng)建線程。用法:forkjoin_none放在了任務(wù)中,而不是包含兩個(gè)線程。原因:主程序中有連個(gè)線程:發(fā)送和檢測(cè)線程。

21、但是不能同時(shí)啟動(dòng),發(fā)送事物后,才能檢測(cè),否則還未產(chǎn)生數(shù)據(jù),就開始檢測(cè);但是檢測(cè)又不能阻塞下一次發(fā)送事物的線程。所以forkjoin_none 放在了檢測(cè)task 任務(wù)(后作用的線程中)中,例:測(cè)試平臺(tái)產(chǎn)生隨機(jī)事物并發(fā)送到DUT中,DUT把事物返回到測(cè)試平臺(tái)。測(cè)試平臺(tái)必須等到事物完成,但同時(shí)不希望停止隨機(jī)事物的發(fā)送。Program automatic test(bus_ifc.Tbbus);Taskcheck_trans(Transaction tr);ForkBeginWait(bus.cb.addr = tr.addr);EndJoin_noeEndtaskInitial beginRepr

22、eat(10)beginTr= new();Assert.(tr.randomize();/把事物發(fā)送到DUT中Transmit(tr);/等待DUT的回復(fù)Check_trans(tr);End#100;Endendprograml并發(fā)線程中務(wù)必使用自動(dòng)變量來保持?jǐn)?shù)值。l#0 延遲,使得當(dāng)前線程必須等到forkjoin_none語(yǔ)句中產(chǎn)生的線程執(zhí)行完后,才得以運(yùn)行。l停止線程1)停止單個(gè)線程使用fork .join_any 后加disable。3) 停止多個(gè)線程Disable fork能停止從當(dāng)前線程中衍生出來得所有子線程。應(yīng)該使用fork .join 把目標(biāo)代碼包含起來,以限制Disable

23、 fork的作用范圍。l事件背景:Verilog中當(dāng)一個(gè)線程在一個(gè)事件上發(fā)生阻塞的同時(shí),正好另一個(gè)線程觸發(fā)了這個(gè)事件,則競(jìng)爭(zhēng)就出現(xiàn)了。如果觸發(fā)線程先于阻塞線程,則觸發(fā)無效(觸發(fā)是一個(gè)零寬度的脈沖)。解決方法:Systemverilog 引入了triggered()函數(shù),用于檢測(cè)某個(gè)事件是否已被觸發(fā)過,包括正在觸發(fā)。線程可以等待這個(gè)結(jié)果,而不用在操作符上阻塞。例子:Event e1,e2;Initial begin-e1;e2;EndInitial begin-e2;e1;End上面的代碼,假設(shè)先執(zhí)行第一個(gè)塊,再執(zhí)行第二個(gè)塊。第一個(gè)塊會(huì)阻塞在e2(阻塞先執(zhí)行),直到e2觸發(fā),再運(yùn)行(觸發(fā)后執(zhí)行)

24、;在執(zhí)行第二個(gè)塊時(shí),會(huì)阻塞在e1,但是e1已經(jīng)觸發(fā)(觸發(fā)先執(zhí)行,阻塞后執(zhí)行,觸發(fā)是個(gè)零寬度的脈沖,會(huì)錯(cuò)過第一個(gè)事件而鎖?。┙鉀Q方法:用wait(e1.triggered()來代替阻塞el,如果先觸發(fā),也可以執(zhí)行。l等待多個(gè)事件最好的辦法是:采用線程計(jì)數(shù)器來等待多個(gè)線程。l旗語(yǔ)Get()可以獲取一個(gè)或多個(gè)鑰匙,put()可以返回一個(gè)或多個(gè)鑰匙。Try_get()獲取一個(gè)旗語(yǔ)而不被阻塞。l信箱背景:如何在兩個(gè)線程中傳遞信息?考慮發(fā)生器需要?jiǎng)?chuàng)建很多事物并傳遞給驅(qū)動(dòng)器的情況。問題:如果使用發(fā)生器的線程去調(diào)用驅(qū)動(dòng)器的任務(wù)。這樣,發(fā)生器需要知道驅(qū)動(dòng)器的層次化路徑(類的層次化),降低了代碼的可重用性;還迫使

25、發(fā)生器和驅(qū)動(dòng)器同一速率運(yùn)行,當(dāng)一個(gè)發(fā)生器需控制多個(gè)驅(qū)動(dòng)器時(shí)會(huì)發(fā)生同步問題。解決辦法:把驅(qū)動(dòng)器和發(fā)生器當(dāng)成各個(gè)處理事物的對(duì)象,之間通過信道交換數(shù)據(jù)。信道允許驅(qū)動(dòng)器和發(fā)生器異步操作;引入問題:你可能傾向于僅僅使用一個(gè)共享的數(shù)據(jù)或隊(duì)列,但這樣,編寫實(shí)現(xiàn)線程間的讀寫和阻塞代碼會(huì)很困難。解決辦法:可以使用systemverilog中的信箱。把信箱看出一個(gè)具有源端和收端的FIFO.操作:1)信箱的容量可以指定,new(size),size限制信箱中的條目,size為0,或沒指定,則信箱是無限大。2)Put()放數(shù)據(jù),get()可以移出數(shù)據(jù)。Peek()可以獲取信箱中數(shù)據(jù)的copy而不移出。3)信箱中可以放

26、句柄,而不是對(duì)象。漏洞:在循環(huán)外只創(chuàng)建一個(gè)對(duì)象,然后使用循環(huán)對(duì)對(duì)象隨機(jī)化,信箱中是句柄,最終得到的是一個(gè)含有多個(gè)句柄的信箱,多個(gè)句柄都指向同一個(gè)對(duì)象。解決辦法:在循環(huán)中,創(chuàng)建多個(gè)對(duì)象。l異步線程間使用信箱背景:很多情況下,由信箱連接的兩個(gè)線程應(yīng)該步調(diào)一致,這樣生產(chǎn)方 才不至于跑到消費(fèi)方前。 好處:最好層的generator需要等待低層的數(shù)據(jù)發(fā)完后才能結(jié)束。測(cè)試平臺(tái)能精確知道所有激勵(lì)發(fā)出去的時(shí)間。兩種情況兩個(gè)線程同步,需要額外的握手信號(hào)。否則,出現(xiàn)生產(chǎn)方運(yùn)行到結(jié)束,消費(fèi)方還啟動(dòng)。1)信箱容量為1,兩個(gè)線程同步因阻塞,連個(gè)線程不需要握手信箱3)容量不為1,線程間同步需要使用握手信號(hào),以使produ

27、cer不超前于consumer;如果consumer超前于prodecer會(huì)阻塞。解決辦法1)使用定容信箱和peek實(shí)現(xiàn)線程同步:(比較好)消費(fèi)方:consumer 使用信箱方法peek()獲取信箱里的數(shù)據(jù)的copy而不將其移出,當(dāng)consumer處理完數(shù)據(jù)后,便使用get()移出數(shù)據(jù)。特點(diǎn):信箱容量定義為1,不需要握手信號(hào)。CalssconsumerRepeat(n)beginMbx.peek(i);$display(“consumer:after get( )”,i);Mbx.get(i);Endendcalss如果直接使用get()替代peek(),那么事務(wù)會(huì)被立刻移出,這樣可能會(huì)在co

28、nsumer完成事務(wù)前,producer生成新的數(shù)據(jù)。-2)使用信箱和事件實(shí)現(xiàn)線程同步使用邊沿敏感的阻塞語(yǔ)句handshake 代替電平觸發(fā)wait(handshake.triggered()。因?yàn)椋壕€程中任務(wù)run()使用循環(huán),事件阻塞只能使用handshake。局限:如果遇到producer線程的阻塞和consumer線程的觸發(fā)同時(shí)發(fā)生,則可能出現(xiàn)次序上的問題。3)使用兩個(gè)信箱實(shí)現(xiàn)線程同步使用另一個(gè)信箱把consumer的完成信息發(fā)回給producer。目的:在producer線程中,處理完事物后,用一個(gè)get()來阻塞。特點(diǎn):信箱容量大于1.Maiboxmbx,rtn;Class pro

29、decerFor(int i=0; i4;i+) begin.Mbx.put(i);Rtn.get(i);EndEndclassClass consumerRepeat(3) begin.Mbx.get(i);Rtn.put(-i);EndEndclass說明:信箱的構(gòu)造函數(shù)中Mbx =new();Rtn =new(),信箱容量為無窮大。如何實(shí)現(xiàn)同步?雖然信箱容量為無窮大,producer線程發(fā)完一個(gè)數(shù)據(jù)后遇到get()會(huì)阻塞,不能放入第二個(gè)數(shù)據(jù);等到consumer得到第一個(gè)數(shù)據(jù)并且處理完后,通過另一個(gè)信箱返回一個(gè)數(shù)據(jù),producer才繼續(xù)放第二個(gè)數(shù)據(jù)。因?yàn)間et()得到數(shù)據(jù)后,將信箱中數(shù)

30、據(jù)取出。表象:信箱容量定義為無窮大,但是實(shí)際上也是producer放一個(gè)數(shù)據(jù),consumer取一個(gè)數(shù)據(jù);然后producer再放第二個(gè)數(shù)據(jù),依次類推。這樣確保producer不會(huì)超前于consumer線程,而將數(shù)據(jù)都寫入信箱。4) 其他的同步技術(shù)通過變量或旗語(yǔ)阻塞也可以實(shí)現(xiàn)握手。事件是最簡(jiǎn)單的結(jié)構(gòu),其次是通過變量阻塞。旗語(yǔ)相當(dāng)于第2個(gè)信箱,但是沒有交換信息。Systemverilog中的信箱比其他技術(shù)要差,原因是無法在producer放入第一個(gè)事務(wù)時(shí),讓它阻塞。Producer一直比consumer提前一個(gè)事務(wù)的時(shí)間。lWait(handshake.triggered()和handshake

31、 使用范圍1)Wait(handshake.triggered(),用于等待一個(gè)事件;2)循環(huán)中等待事件,只能用handshake3)兩個(gè)線程的同步,一般任務(wù)run()使用循環(huán),所以只能使用handshake。注意事項(xiàng):1)在循環(huán)中,等待事件不能用Wait(handshake.triggered(),因?yàn)槿绻录|發(fā)一次,wait()語(yǔ)句一直為真,進(jìn)入不斷的循環(huán)。下一次循環(huán)中,不會(huì)阻塞。2)handshake 如果觸發(fā)事件,先于等待事件。會(huì)等不到事件,因?yàn)椋ㄊ录|發(fā),是一個(gè)零寬度的脈沖)OPP的高級(jí)編程技巧l繼承背景:為總線事務(wù)增加一個(gè)錯(cuò)誤功能并帶可變延時(shí)的復(fù)雜類。方法如下:1)使用合成,即在

32、類中例化另一個(gè)類型的類。有時(shí)候很難將功能分成獨(dú)立的部分。如果使用合成,則需要為正確和錯(cuò)誤事務(wù)分別創(chuàng)建不同的類,正確類的測(cè)試平臺(tái)需要重寫以處理錯(cuò)誤類的對(duì)象。2)使用擴(kuò)展類作用:當(dāng)需要增加事務(wù),而對(duì)現(xiàn)有的測(cè)試代碼修改越少越好,。例如增加錯(cuò)誤注入功能。擴(kuò)展類和類合成區(qū)別:擴(kuò)展類解決,增加新事務(wù),使用類合成中,大量修改代碼的麻煩。如何使用:擴(kuò)展類共享基類的變量和子程序。1)基本類中的方法,需標(biāo)記為virtual,這樣擴(kuò)展類中才可以重新定義。擴(kuò)展類中函數(shù),和基類中函數(shù)名一樣時(shí),通過supper.函數(shù)名,調(diào)用基類中函數(shù)。Systemverilog中不允許supper.supper.new方式經(jīng)行多層調(diào)用。

33、2)如果基類構(gòu)造函數(shù)new()有參數(shù),那么擴(kuò)展類,必須有一個(gè)構(gòu)造函數(shù),并在構(gòu)造函數(shù)的第一行調(diào)用基類的構(gòu)造函數(shù)。Class baselFunction new(inputint var);this.var = var;endfunctionendclassclassextendedextends baselfunction new(input int var);super.new(var);endfunctionendclass3)OPP規(guī)則指出:基類的句柄,也可以指向擴(kuò)展類的對(duì)象。(好好體會(huì))l藍(lán)圖模式1)背景:一個(gè)簡(jiǎn)單的發(fā)生器,通過信箱將數(shù)據(jù)傳遞給驅(qū)動(dòng)器。class generatormai

34、lboxgen2drv;transaction tr;function new(input mailbox gen2drv)this.gen2drv = gen2drv;endfunctiontask run;forever begintr = new();assert(tr.randmize);gen2drv.put(tr);/mail.put(x)endendtaskendclass存在問題:這個(gè)例子在循環(huán)內(nèi)部創(chuàng)建事務(wù)對(duì)象,而不是在循環(huán)外部,避免了測(cè)試平臺(tái)常見的錯(cuò)誤。New()放在循環(huán)外部,錯(cuò)誤原因是,mailbox中放入的是句柄,而不能是對(duì)象,所有的句柄都指向同一個(gè)對(duì)象。(1)任務(wù)Run

35、創(chuàng)建了一個(gè)事物并立即隨機(jī)化,意味著事務(wù)使用了默認(rèn)的所有約束。要修改,必須要修改transaction類。(2)無法使用擴(kuò)展解決辦法:將tr的創(chuàng)建和初始化分開,使用藍(lán)圖模式。另一個(gè)問題:如果簡(jiǎn)單的把創(chuàng)建和初始化分開,而放在循環(huán)外部,而避免測(cè)試平臺(tái)錯(cuò)誤(P200),如何解決?藍(lán)圖模式如何解決2)藍(lán)圖模式概念:首先構(gòu)建一個(gè)對(duì)象藍(lán)圖(金屬模),然后修改它的約束,甚至可以用擴(kuò)展對(duì)象替換它,隨機(jī)化這個(gè)藍(lán)圖時(shí),就得到想賦予的隨機(jī)值;然后復(fù)制這個(gè)對(duì)象,將copy發(fā)給下游。藍(lán)圖:是一個(gè)鉤子,允許你改變發(fā)生器類的行為而無需修改其類代碼。藍(lán)圖對(duì)象在一個(gè)地方構(gòu)建(new(),在另一個(gè)地方(任務(wù)run)使用3)P200

36、與P221相對(duì)比分析:重要藍(lán)圖模式,也就比new()在循環(huán)外地generator多了一個(gè)copy函數(shù)。問題(1)藍(lán)圖模式,new()在循環(huán)外,也只有一個(gè)對(duì)象,而mailbox中放入的只能是句柄,如何解決常見的平臺(tái)錯(cuò)誤?因?yàn)閏opy,是對(duì)象的復(fù)制,而不是句柄的復(fù)制。這樣藍(lán)圖模式只有一個(gè)句柄,但是隨機(jī)化后,copy,相當(dāng)于再循環(huán)中創(chuàng)建了許多對(duì)象。而測(cè)試平臺(tái)常見錯(cuò)誤的本質(zhì)是,只創(chuàng)建了一個(gè)對(duì)象。這樣就避免了問題。(2)藍(lán)圖模式下,因?yàn)橹挥幸粋€(gè)ID號(hào),那么任務(wù)run循環(huán)中,下發(fā)了許多數(shù)據(jù),這些只有一個(gè)ID號(hào)了?因?yàn)閏opy是對(duì)象的復(fù)制,所以在copy中ID號(hào)也會(huì)增加。下發(fā)的每個(gè)數(shù)據(jù),都有各自的ID號(hào)。l

37、使用擴(kuò)展的transaction為了注入錯(cuò)誤,需要將藍(lán)圖對(duì)象transaction變成Badtransaction(改變藍(lán)圖)。必須在環(huán)境的創(chuàng)建和運(yùn)行階段之間完成這個(gè)操作。注意:所有的badTr引用都在這一個(gè)文件中,這樣就不需要改變environment類或generator類。Env.build();BeginBadtr bad = new();Env.gen.blueprint = bad;EndEnv.run目的是:將一個(gè)對(duì)象取代另一個(gè)對(duì)象。New()后都是對(duì)象了,將對(duì)象賦值給對(duì)象,這是什么寫法?不是復(fù)制呀?復(fù)制本質(zhì)是將一個(gè)句柄指向一個(gè)對(duì)象。解釋:上述是句柄的復(fù)制,將擴(kuò)展類句柄bad賦值

38、給基類句柄blueprint,這樣基類句柄指向擴(kuò)展類對(duì)象,后面的代碼調(diào)用的時(shí)候,就直接指向擴(kuò)展類bad了,改變了藍(lán)圖。lEnv.new()和nev.build()區(qū)別Env.new()僅僅new()函數(shù)nev.build()是將各個(gè)模塊new(),并傳達(dá)一些參數(shù),通過這些參數(shù)將環(huán)境的各個(gè)模塊,連接起來。P213l$cast 作類型向下轉(zhuǎn)換背景:基類句柄可以指向擴(kuò)展類對(duì)象,不需要額外的代碼; 擴(kuò)展類句柄指向基類對(duì)象,一般情況下會(huì)出錯(cuò),但有時(shí)候是可以的,前提是基類句柄指向了它的一個(gè)擴(kuò)展類對(duì)象。作用:擴(kuò)展類句柄指向基類對(duì)象時(shí),使用$cast()函數(shù)。在非法的情況下,不會(huì)編譯報(bào)錯(cuò),會(huì)返回了一個(gè)0.$c

39、ast做任務(wù)使用時(shí),systemverilog會(huì)在運(yùn)行時(shí),檢查源對(duì)象類型和目的對(duì)象類型不匹配,會(huì)報(bào)錯(cuò);$cast 做函數(shù)使用時(shí),運(yùn)行時(shí),仍做類型檢查,在不匹配時(shí),不會(huì)報(bào)錯(cuò),$函數(shù)返回0.前面所述:基類句柄可以指向任何它的擴(kuò)展類的對(duì)象、1) 基類句柄指向擴(kuò)展類對(duì)象出現(xiàn)情況:修改藍(lán)圖,不改過多代碼,增加功能Transaction tr; /基類句柄BadTrbad;/擴(kuò)展類句柄Bad = new();Tr= bad;/ 基類句柄指向擴(kuò)展類對(duì)象tr.display;/掉用的是擴(kuò)展類的方法2) 擴(kuò)展類句柄指向基類對(duì)象出現(xiàn)情況:基類virtual 方法copy函數(shù),它的繼承類中copy函數(shù)將基類句柄賦值

40、給擴(kuò)展類句柄,使擴(kuò)展類句柄指向基類對(duì)象,一般編譯器會(huì)出錯(cuò),不能運(yùn)行,所以非常小心;只有基類句柄指向擴(kuò)展類對(duì)象時(shí),再將擴(kuò)展類句柄指向基類對(duì)象時(shí),不出錯(cuò)。為了檢測(cè)基類句柄是否指向了擴(kuò)展對(duì)象,并且不讓編譯器報(bào)錯(cuò),可以使用$cast()函數(shù)檢測(cè)。當(dāng)把擴(kuò)展類句柄指向基類對(duì)象時(shí),發(fā)生什么?Tr= new();Bad = tr;/擴(kuò)展類句柄指向基類句柄上述會(huì)發(fā)生錯(cuò)誤,編譯不會(huì)被通過。因?yàn)橛行傩栽诨愔胁淮嬖?;但是擴(kuò)展類句柄指向基類句柄不總是非法的(見下面代碼,是可以的),當(dāng)基類句柄指向一個(gè)擴(kuò)展類對(duì)象時(shí)是允許的。Transcation tr;BadTr bad,bad2;Bad= new();Tr = ba

41、d;/基類句柄指向擴(kuò)展類對(duì)象$cast(bad2,tr);/擴(kuò)展類句柄指向基類對(duì)象if(!$cast(bad2,tr);$display(“cannot assign tr to bad2”);$display(bad2.bad_crc);l句柄類型和對(duì)象類型差異(書中翻譯的不準(zhǔn),type of handdle 和 object)個(gè)人理解:Transaction tr;句柄tr類型是transaction句柄類型:關(guān)鍵字對(duì)象類型:類中成員的類型差異l虛方法和多態(tài)多態(tài):多個(gè)程序使用一個(gè)共同的名字的現(xiàn)象。多態(tài)解決問題:計(jì)算機(jī)建構(gòu)面臨的一個(gè)問題。讓物理內(nèi)存很小的情況下,讓處理器能夠?qū)艽蟮牡刂房臻g尋

42、址。針對(duì)這個(gè)問題引入了虛擬內(nèi)存。虛擬方法繼承劣勢(shì):基類使用了虛擬方法,擴(kuò)展類也必須使用相同的“簽名”,擴(kuò)展類中虛擬子程序不能增加或刪除參數(shù),這意味著必須提前做好規(guī)劃。l對(duì)象復(fù)制1)因?yàn)槭莢irtual 函數(shù),擴(kuò)展類中copy方法也必須是transaction型的,但是要copy的是badtr類型的,所以要new一個(gè)bad帶有copy 的事物基類。Class transaction ;Rand bit31:0 src,dst,data8;Bit31:0 crc;Virtual function transaction copy ();Copy= new();Copy.src = s rc;Cop

43、y.dst = dst;Copy.data = data;Copy.crc= crc;EndfunctionEndclass帶有copy的擴(kuò)展類Calss badtr extends transactionRand bit bad_crc;Virtual function badtr copy();/錯(cuò)誤Virtual function transaction copy();Badtrbad;Bad = new();Bad.src = src;bad.dst = dst;bad.data = data;bad.crc= crc;Bad.bad_crc = bad_crc;Returnbad;Rendfunctionendclass2)優(yōu)化途徑一,創(chuàng)建一個(gè)獨(dú)立的函數(shù)copy_data,這樣每個(gè)類只負(fù)責(zé)copy其局部變量,即擴(kuò)展類中的copy函數(shù)用super.copy_data(tr),代替了基類中變量的復(fù)制。代碼的重用性提高。P8.2

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論