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)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(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ù)的,中間沒(méi)有閑置空間。例如,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;   大小在變量名前面放得,且

2、降序二維數(shù)組:  int arrays0:7 0:3 ;  大小在變量名后面放得,可降序可升序位寬在變量名前面,用于識(shí)別合并和非合并數(shù)組,位寬在后面,用于識(shí)別數(shù)組中元素個(gè)數(shù)。 3)非合并數(shù)組一般仿真器存放數(shù)組元素時(shí)使用32bit的字邊界,byte、shortint、int都放在一個(gè)字中。非合并數(shù)組:字的地位存放變量,高位不用。表示方法: Bit   7:0 bytes;        4)合并數(shù)組和非合并數(shù)組的選擇 

3、       (1)當(dāng)需要以字節(jié)或字為單位對(duì)存儲(chǔ)單元操作。        (2)當(dāng)需要等待數(shù)組中變化的,則必須使用合并數(shù)組。例如測(cè)試平臺(tái)需要通過(guò)存儲(chǔ)器數(shù)據(jù)的變化來(lái)喚醒,需要用到,只能用于標(biāo)量或者合并數(shù)組。      Bit3:0 7:0 barray3   表示合并數(shù)組,合并數(shù)組中有3個(gè)元素,每個(gè)元素時(shí)8bit,4個(gè)元素可以組成合并數(shù)組  

4、0;  可以使用barry0作敏感信號(hào)。 l       動(dòng)態(tài)數(shù)組隨機(jī)事物不確定大小。使用方法:數(shù)組在開(kāi)始是空的,同時(shí)使用new來(lái)分配空間,在newn指定元素的個(gè)數(shù)。Int dyn;   Dyn = new5;     /分配5個(gè)元素空間          Dyn.delete() ;   

5、;  /釋放空間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)需要

6、局部常量時(shí),可能引起沖突。2)Parameter   作用范圍僅限于單個(gè)module3)Systemverilog:   參數(shù)可以在多個(gè)模塊里共同使用,可以用typedef 代替單調(diào)乏味的宏。 過(guò)程語(yǔ)句l       可以在for循環(huán)中定義變量,作用范圍僅在循環(huán)內(nèi)部for(int i=0;i<10;i+)arrayi =i; l       任務(wù)、函數(shù)及void函數(shù)1)

7、區(qū)別:Verilog中task 和function最重要的區(qū)別是:task可以消耗時(shí)間而函數(shù)不能。函數(shù)中不能使用#100的延時(shí)或的阻塞語(yǔ)句,也不能調(diào)用任務(wù);Systemverilog中函數(shù)可以調(diào)用任務(wù),但只能在fork  joinnone生成的線程中。2)使用:   如果有一個(gè)不消耗時(shí)間的systemverilog任務(wù),應(yīng)該把它定義成void函數(shù);這樣它可以被任何函數(shù)或任務(wù)調(diào)用。  從最大靈活性角度考慮,所有用于調(diào)用的子程序都應(yīng)該被定義成函數(shù)而非任務(wù),以便被任何其它任務(wù)或函數(shù)調(diào)用。(因?yàn)槎x成任務(wù),函數(shù)調(diào)用任務(wù)很有限制)&#

8、160;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)方法讀寫(xiě)靜態(tài)變量,但是靜態(tài)方法不能讀寫(xiě)非靜態(tài)變量。l       

9、;ref高級(jí)的參數(shù)類型Ref 參數(shù)傳遞為引用而不是復(fù)制。Ref比 input 、output、inout更好用。Function void print_checksum(const ref bit 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ù)組的值,可

10、以使用const ref。3)       Ref參數(shù),用ref 傳遞變量;可以在任務(wù)里修改變量而且,修改結(jié)果對(duì)調(diào)用它的函數(shù)可見(jiàn),相對(duì)于指針的功能。 l       Return語(yǔ)句增加了return語(yǔ)句。Task任務(wù)由于發(fā)現(xiàn)了錯(cuò)誤而需要提前返回,如果不這樣,那么任務(wù)中剩下的語(yǔ)句就必須被放到一個(gè)else條件語(yǔ)句中。體會(huì)下Task load_array(int len. Ref int array );If(len<0)  

11、;begin  $display(“Bad len”);  Returun;/任務(wù)中其它代碼    endtask l       局部數(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)l&#

12、160;      Interface背景  :一個(gè)信號(hào)可能連接幾個(gè)設(shè)計(jì)層次,如果增加一個(gè)信號(hào),必須在多個(gè)文件中定義和連接。接口可以解決這些問(wèn)題。好處:如果希望在接口中增加一個(gè)信號(hào),不需要改變其他模塊,如TOP模塊。使用方法:(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呢?這里的雙向,只是概念上的雙向,不想ve

13、rilog中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_if arbif);Always (posedge arbif.clk or negedge arbif.rst)  endmodule (2)DUT

14、 不采用接口,測(cè)試平臺(tái)中使用接口(推薦)    DUT 中源代碼不需要修改,只需要再top中,將接口連接到端口上。   Module top;       Bit clk;       Always #2 clk =clk;      Arb_if arbif(clk);     

15、; Arb_port al(.grant(arbif.grant),                .request(arbif.grant),                .rst(arbif.rst),     &

16、#160;          .clk(arbif.clk)                );      Test t1(arbif);   Endmodule l      &

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

18、或邊沿,也不需要修改測(cè)試代碼應(yīng)用:將測(cè)試平臺(tái)中的信號(hào),都放在clocking 中,并指定方向(以測(cè)試平臺(tái)為參考的方向)。并且在modprot test(clocking cb,   最完整的接口:Interface arb_if(input bit clk);Logic1:0 grant,request;Logic rst; Clocking cb (posedge clk);    Output request;    Input grant;Endclocking

19、0;Modport test (clocking cb,           Output rst);Modport dut (input clk, request,rst,           Output grant);   endinterface 變化:將request 和grant移動(dòng)到時(shí)鐘塊中去了,test中沒(méi)有使用了。

20、60;l       接口中的雙向信號(hào)Interface master_if(input bit clk);  /在類中為了,不使用有符號(hào)數(shù),常用bit定義變量   Wire 7:0 data;  Clocking cb(posedge clk);     Inout data;  Endclocking Modport TEST(clocking cb);endinterfa

21、ce program test(master_if mif);initial begin   mif.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;        /釋放總線&#

22、160;注:(1)interface 列表中clk 采用的是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ù)列表中方向和類型寫(xiě)一起),必須采用logic類型(4)現(xiàn)在的風(fēng)格,DUT 沒(méi)才用clocking cb ,測(cè)試平臺(tái)和DUT的時(shí)鐘如何統(tǒng)一?l   

23、;    激勵(lì)時(shí)序DUT和測(cè)試平臺(tái)之間時(shí)序必須密切配合。 l       測(cè)試平臺(tái)和設(shè)計(jì)間的競(jìng)爭(zhēng)狀態(tài)好的風(fēng)格:使用非阻塞賦值可以減少競(jìng)爭(zhēng)。systemverilog驗(yàn)證中initial 中都采用<= 賦值,而等待延遲采用arbif.cb等待一個(gè)周期來(lái)實(shí)現(xiàn)。而verilog中采用的風(fēng)格時(shí),initial 中采用 =阻塞賦值,沿時(shí)可以采用#2,等實(shí)現(xiàn)。因此時(shí)鐘發(fā)生器,只能放在module 中,而不能放在program中  l  

24、60;    Program中不能使用always塊測(cè)試平臺(tái)可以使用initial 但不能使用always,使用always 模塊不能正常工作。原因:測(cè)試平臺(tái)的執(zhí)行過(guò)程是進(jìn)過(guò)初始化、驅(qū)動(dòng)和響應(yīng)等步驟后結(jié)束仿真。如果確實(shí)需要一個(gè)always塊,可以使用initial forever 來(lái)完成。比如:在產(chǎn)生時(shí)鐘時(shí)。  類l       類中static變量背景:如果一個(gè)變量需要被其他對(duì)象所共享,如果沒(méi)有OPP,就需要?jiǎng)?chuàng)建全局變量,這樣會(huì)污染全局名字空間,導(dǎo)致你想定義局部變

25、量,但變量對(duì)每個(gè)人都是可見(jiàn)的。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變

26、量。如何用?當(dāng)你打算創(chuàng)建一個(gè)全局變量的時(shí)候,首先考慮創(chuàng)建一個(gè)類的靜態(tài)變量。2)static變量的引用句柄或類名加: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 &#

27、160;     靜態(tài)方法背景:當(dāng)使用更多靜態(tài)變量的時(shí)候,操作他們的代碼會(huì)很長(zhǎng)。作用:可以在類中創(chuàng)建一個(gè)靜態(tài)方法用于讀寫(xiě)靜態(tài)變量。注:systemverilog不允許,靜態(tài)方法讀寫(xiě)非靜態(tài)變量。l       類之外的方法背景:解決類太長(zhǎng)的問(wèn)題。類最好控制在一頁(yè)內(nèi),如果方法很都很長(zhǎng)。l       This背景:如果在類很深的底層作用域,卻想引用類一級(jí)的對(duì)象。在構(gòu)造函數(shù)中最常見(jiàn)。作用:this指向類一級(jí)變量l

28、       如何做類,類做多大?上限:類不能太大當(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ù)傳遞給方法。

29、實(shí)質(zhì)和作用:傳遞的是句柄。這個(gè)方法可以讀取對(duì)象中的值;也以改變對(duì)象中的值 2) 修改標(biāo)量變量的值背景:在方法的參數(shù)中,前面加ref;(用ref傳遞,ref傳遞的是變量的地址)。作用: 方法可以修改變量的值,并將修改的值,傳遞給主程序。  引申:方法可以改變對(duì)象,即使沒(méi)有使用ref 修飾句柄。    因?yàn)閭鬟f的是句柄,句柄是地址。不要將句柄和對(duì)象混為一談,如果傳遞的是對(duì)象,對(duì)象是單向的,那方法以外也不能傳遞回來(lái)??梢赃@樣理解吧。   讀寫(xiě)對(duì)象中的值:例:Task  t

30、ransmit(Transcation t);     Cbbus.rx_data <= t.data;     t.stats.startT  =  $time;     /在任務(wù)中,改變了對(duì)象endtask trancation t;initilal beignt = new();t.addr = 42;transmit(t);end   既然傳遞的是句柄,

31、那數(shù)據(jù)就沒(méi)傳過(guò)去,如何讀取值?   答:主程序中new()創(chuàng)建了一個(gè)對(duì)象,而句柄是指向?qū)ο蟮闹羔?,傳遞的是句柄,transmit中也指向了對(duì)象,所以transmit中可以讀寫(xiě)對(duì)象。  3) 在任務(wù)中修改句柄背景:在方法中,參數(shù)為句柄,前面加ref。作用:可以在方法中new()對(duì)象,并將初始化放在方法中;在主程序中僅僅調(diào)用。注意:正確的事物發(fā)生器,參數(shù)是帶ref的句柄Function void create(ref transaction tr)Endfunction   方法的參數(shù)是句柄,句柄前有ref 和沒(méi)ref

32、的差別:沒(méi)ref,在方法中不能new()該句柄的對(duì)象,因?yàn)闆](méi)ref,句柄是不能傳遞到主程序的; 有ref,可以在方法中new()該句柄的對(duì)象。  原因:沒(méi)ref傳遞的是句柄,不能修改句柄,有ref,傳遞的是句柄的地址,可以修改句柄。 例子:Function void create( Transcation tr)   tr = new();    不正確   tr.addr = 42;Endfunction Transcation t;Initial be

33、gin  Create(t);$diasplay (t.addr);Endl       程序中修改對(duì)象背景:應(yīng)該在循環(huán)中,new()多個(gè)對(duì)象,而不是先new()對(duì)象再循環(huán)發(fā)送事物。作用:創(chuàng)建多個(gè)對(duì)象正確產(chǎn)生器,創(chuàng)建多個(gè)對(duì)象:Task generator (int n);Transaction t;Repeat(n) begin   t=new();   t.addr =$random();   transmit(t

34、);    endtask 將new()放在循環(huán)內(nèi),這樣創(chuàng)建了許多對(duì)象。 l       對(duì)象的復(fù)制目的:防止對(duì)象的方法修改原始對(duì)象的值?;蛟谝粋€(gè)發(fā)生器中保留約束。分兩種情況,類中不包含其他類的句柄和包含方法:1)  使用new復(fù)制一個(gè)對(duì)象簡(jiǎn)易復(fù)制(shallow copy)Transaction src,dst;Src = new()  /dst = new src  /復(fù)制局限:如果類中包含一個(gè)指向另外

35、一個(gè)類的句柄,那么只有最高一級(jí)的對(duì)象被new復(fù)制,下層的對(duì)象都不會(huì)被復(fù)制。會(huì)出現(xiàn)意想不到的錯(cuò)誤。當(dāng)前類中變量和句柄被復(fù)制,這樣兩個(gè)對(duì)象,都有指向另外一個(gè)類的對(duì)象statistic(會(huì)帶來(lái)意想不到的錯(cuò)誤),但是statistic沒(méi)有被復(fù)制。如果其中一個(gè)transaction對(duì)象,修改了statistic對(duì)象值,會(huì)影響到另一個(gè)transaction看到static的值。2) 簡(jiǎn)單的復(fù)制函數(shù)如何實(shí)現(xiàn):Copy函數(shù)一般放在類內(nèi)部,函數(shù)名為該類的一個(gè)句柄,copy函數(shù)中new()對(duì)象。局限:類中不包含其他類。3) 深層的復(fù)制函數(shù) 深層copy目的:解決類中包含另外一個(gè)類,copy帶來(lái)的問(wèn)題。實(shí)現(xiàn):在co

36、py函數(shù)中,將調(diào)用另一個(gè)類的copy函數(shù),賦值給該句柄;同時(shí)需要為statistic類和層次結(jié)構(gòu)中每一個(gè)類增加一個(gè)copy()方法;copy函數(shù)的ID域也要保持一致,copy函數(shù),copy本類,所以ID也要+. Copy.stats = stats.copy();Id =count+;  約束l       約束塊中,只能包含表達(dá)式,不能賦值。1)dist權(quán)重分布dist帶有一個(gè)值的列表及相應(yīng)的權(quán)重,中間用:= 或 :/分開(kāi)。值或權(quán)重可以是常量或變量。權(quán)重的和不必是100.  

37、; := 表示范圍內(nèi),每一個(gè)值的權(quán)重是相同的;   :/ 表示范圍內(nèi),權(quán)重要均勻分布2)Inside產(chǎn)生一個(gè)值的集合,在值的集合中取隨機(jī)值時(shí),機(jī)會(huì)相等。3)在集合中使用數(shù)組l         條件約束Systemverilog支持兩種關(guān)系操作 >和ifelse>可產(chǎn)生和case效果類似的語(yǔ)句塊,可以用于枚舉類型的表達(dá)式。l         雙向約束l &#

38、160;       控制多個(gè)約束塊作用:可以打開(kāi)或關(guān)閉某個(gè)約束可以使用內(nèi)建的Handle.constraint.constraint_mode()打開(kāi)或關(guān)閉。l         內(nèi)嵌約束背景:很多測(cè)試只會(huì)在代碼的一個(gè)地方隨機(jī)化對(duì)象,但是約束越來(lái)越復(fù)雜時(shí),Systemverilog可以使用randomized with 來(lái)增加額外的約束,這和在類里增加的約束是等效的。l     

39、0;   Pre_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  &#

40、160;      數(shù)組約束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來(lái)產(chǎn)生線程在調(diào)度其內(nèi)部語(yǔ)句時(shí),父線程繼續(xù)執(zhí)行。2) 使用forkjoin_any實(shí)現(xiàn)線程同步在調(diào)度塊內(nèi)

41、語(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è)線程。但是不能同時(shí)啟動(dòng),發(fā)送事物后,才能檢測(cè),否則還未產(chǎn)生數(shù)據(jù),就開(kāi)始檢測(cè);但是檢測(cè)又不能阻塞下一次發(fā)送事物的線程。所以forkjoin_none 放在了檢測(cè)task 任務(wù)(后作用的線程中)中, 例:測(cè)試平臺(tái)產(chǎn)生隨機(jī)事物并發(fā)送到DUT中,DUT把事物返回到測(cè)試平臺(tái)。測(cè)

42、試平臺(tái)必須等到事物完成,但同時(shí)不希望停止隨機(jī)事物的發(fā)送。Program automatic test(bus_ifc.Tbbus);Task  check_trans(Transaction tr);Fork     Begin      Wait(bus.cb.addr = tr.addr);     EndJoin_noeEndtask Initial begin   &#

43、160;Repreat(10)  begin        Tr= new();        Assert.(tr.randomize();        /把事物發(fā)送到DUT中        Transmit(tr);   &

44、#160;   /等待DUT的回復(fù)       Check_trans(tr);    End#100;Endendprogram l         并發(fā)線程中務(wù)必使用自動(dòng)變量來(lái)保持?jǐn)?shù)值。l         #0 延遲,使得當(dāng)前線程必須等到forkjoin_none語(yǔ)

45、句中產(chǎn)生的線程執(zhí)行完后,才得以運(yùn)行。   l         停止線程1)       停止單個(gè)線程使用fork .join_any 后加disable。3) 停止多個(gè)線程Disable fork  能停止從當(dāng)前線程中衍生出來(lái)得所有子線程。應(yīng)該使用fork .join 把目標(biāo)代碼包含起來(lái),以限制Disable fork的作用范圍。 l   

46、0;     事件背景:Verilog中當(dāng)一個(gè)線程在一個(gè)事件上發(fā)生阻塞的同時(shí),正好另一個(gè)線程觸發(fā)了這個(gè)事件,則競(jìng)爭(zhēng)就出現(xiàn)了。如果觸發(fā)線程先于阻塞線程,則觸發(fā)無(wú)效(觸發(fā)是一個(gè)零寬度的脈沖)。解決方法:Systemverilog 引入了triggered()函數(shù),用于檢測(cè)某個(gè)事件是否已被觸發(fā)過(guò),包括正在觸發(fā)。線程可以等待這個(gè)結(jié)果,而不用在操作符上阻塞。例子:Event e1,e2;Initial begin     ->e1;     e2;E

47、nd Initial begin     ->e2;     e1;End 上面的代碼,假設(shè)先執(zhí)行第一個(gè)塊,再執(zhí)行第二個(gè)塊。第一個(gè)塊會(huì)阻塞在e2(阻塞先執(zhí)行),直到e2觸發(fā),再運(yùn)行(觸發(fā)后執(zhí)行);在執(zhí)行第二個(gè)塊時(shí),會(huì)阻塞在e1,但是e1已經(jīng)觸發(fā)(觸發(fā)先執(zhí)行,阻塞后執(zhí)行,觸發(fā)是個(gè)零寬度的脈沖,會(huì)錯(cuò)過(guò)第一個(gè)事件而鎖?。?#160;解決方法:用wait(e1.triggered()來(lái)代替阻塞el,如果先觸發(fā),也可以執(zhí)行。  l  

48、60;      等待多個(gè)事件最好的辦法是:采用線程計(jì)數(shù)器來(lái)等待多個(gè)線程。 l         旗語(yǔ)Get()可以獲取一個(gè)或多個(gè)鑰匙,put()可以返回一個(gè)或多個(gè)鑰匙。Try_get()獲取一個(gè)旗語(yǔ)而不被阻塞。 l         信箱背景:如何在兩個(gè)線程中傳遞信息?考慮發(fā)生器需要?jiǎng)?chuàng)建很多事物并傳遞給驅(qū)動(dòng)器的情況。問(wèn)題:如果使用發(fā)生器的線

49、程去調(diào)用驅(qū)動(dòng)器的任務(wù)。這樣,發(fā)生器需要知道驅(qū)動(dòng)器的層次化路徑(類的層次化),降低了代碼的可重用性;還迫使發(fā)生器和驅(qū)動(dòng)器同一速率運(yùn)行,當(dāng)一個(gè)發(fā)生器需控制多個(gè)驅(qū)動(dòng)器時(shí)會(huì)發(fā)生同步問(wèn)題。 解決辦法:把驅(qū)動(dòng)器和發(fā)生器當(dāng)成各個(gè)處理事物的對(duì)象,之間通過(guò)信道交換數(shù)據(jù)。信道允許驅(qū)動(dòng)器和發(fā)生器異步操作;引入問(wèn)題:你可能傾向于僅僅使用一個(gè)共享的數(shù)據(jù)或隊(duì)列,但這樣,編寫(xiě)實(shí)現(xiàn)線程間的讀寫(xiě)和阻塞代碼會(huì)很困難。解決辦法:可以使用systemverilog中的信箱。把信箱看出一個(gè)具有源端和收端的FIFO. 操作:1)信箱的容量可以指定,new(size),size限制信箱中的條目,size為0,或沒(méi)指定,

50、則信箱是無(wú)限大。2)Put()放數(shù)據(jù),get()可以移出數(shù)據(jù)。Peek()可以獲取信箱中數(shù)據(jù)的copy而不移出。3)信箱中可以放句柄,而不是對(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ā)完后才能

51、結(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),以使producer不超前于consumer;如果consumer超前于prodecer會(huì)阻塞。解決辦法1)  使用定容信箱和peek實(shí)現(xiàn)線程同步:(比較好)消費(fèi)方:consumer 使用信箱方法peek()獲取信箱里的數(shù)據(jù)的copy而不

52、將其移出,當(dāng)consumer處理完數(shù)據(jù)后,便使用get()移出數(shù)據(jù)。特點(diǎn):信箱容量定義為1,不需要握手信號(hào)。 Calss  consumer      Repeat(n)begin         Mbx.peek(i);         $display(“consumer:after get( )”,i); 

53、60;       Mbx.get(i);      Endendcalss 如果直接使用get()替代peek(),那么事務(wù)會(huì)被立刻移出,這樣可能會(huì)在consumer完成事務(wù)前,producer生成新的數(shù)據(jù)。-2)使用信箱和事件實(shí)現(xiàn)線程同步     使用邊沿敏感的阻塞語(yǔ)句handshake 代替電平觸發(fā)wait(handshake.triggered()。    因

54、為:線程中任務(wù)run()使用循環(huán),事件阻塞只能使用handshake。局限:如果遇到producer線程的阻塞和consumer線程的觸發(fā)同時(shí)發(fā)生,則可能出現(xiàn)次序上的問(wèn)題。3)使用兩個(gè)信箱實(shí)現(xiàn)線程同步使用另一個(gè)信箱把consumer的完成信息發(fā)回給producer。目的:在producer線程中,處理完事物后,用一個(gè)get()來(lái)阻塞。特點(diǎn):信箱容量大于1.Maibox  mbx,rtn; Class prodecerFor(int i=0; i<4;i+) begin.Mbx.put(i);Rtn.get(i);   EndEn

55、dclassClass consumerRepeat(3) begin.Mbx.get(i);Rtn.put(-i);   EndEndclass說(shuō)明:信箱的構(gòu)造函數(shù)中Mbx =new();Rtn =new(),信箱容量為無(wú)窮大。如何實(shí)現(xiàn)同步?雖然信箱容量為無(wú)窮大,producer線程發(fā)完一個(gè)數(shù)據(jù)后遇到get()會(huì)阻塞,不能放入第二個(gè)數(shù)據(jù);等到consumer得到第一個(gè)數(shù)據(jù)并且處理完后,通過(guò)另一個(gè)信箱返回一個(gè)數(shù)據(jù),producer才繼續(xù)放第二個(gè)數(shù)據(jù)。因?yàn)間et()得到數(shù)據(jù)后,將信箱中數(shù)據(jù)取出。表象:信箱容量定義為無(wú)窮大,但是實(shí)際上也是producer放一個(gè)數(shù)據(jù),c

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

57、0;     Wait(handshake.triggered()和handshake 使用范圍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)。下

58、一次循環(huán)中,不會(huì)阻塞。2)  handshake 如果觸發(fā)事件,先于等待事件。會(huì)等不到事件,因?yàn)椋ㄊ录|發(fā),是一個(gè)零寬度的脈沖) OPP的高級(jí)編程技巧l         繼承背景:為總線事務(wù)增加一個(gè)錯(cuò)誤功能并帶可變延時(shí)的復(fù)雜類。方法如下:1)  使用合成,即在類中例化另一個(gè)類型的類。有時(shí)候很難將功能分成獨(dú)立的部分。如果使用合成,則需要為正確和錯(cuò)誤事務(wù)分別創(chuàng)建不同的類,正確類的測(cè)試平臺(tái)需要重寫(xiě)以處理錯(cuò)誤類的對(duì)象。2)使用擴(kuò)展類作用:當(dāng)需要增加事務(wù),而對(duì)現(xiàn)有的

59、測(cè)試代碼修改越少越好,。例如增加錯(cuò)誤注入功能。擴(kuò)展類和類合成區(qū)別:擴(kuò)展類解決,增加新事務(wù),使用類合成中,大量修改代碼的麻煩。如何使用:擴(kuò)展類共享基類的變量和子程序。1)基本類中的方法,需標(biāo)記為virtual,這樣擴(kuò)展類中才可以重新定義。擴(kuò)展類中函數(shù),和基類中函數(shù)名一樣時(shí),通過(guò)supper.函數(shù)名,調(diào)用基類中函數(shù)。Systemverilog中不允許supper.supper.new方式經(jīng)行多層調(diào)用。2)如果基類構(gòu)造函數(shù)new()有參數(shù),那么擴(kuò)展類,必須有一個(gè)構(gòu)造函數(shù),并在構(gòu)造函數(shù)的第一行調(diào)用基類的構(gòu)造函數(shù)。     Class basel

60、0;    Function new(input  int var);          this.var = var;     endfunction     endclassclass  extended   extends basel    f

61、unction new(input int var);      super.new(var);    endfunctionendclass3)OPP規(guī)則指出:基類的句柄,也可以指向擴(kuò)展類的對(duì)象。(好好體會(huì))   l         藍(lán)圖模式1)背景:一個(gè)簡(jiǎn)單的發(fā)生器,通過(guò)信箱將數(shù)據(jù)傳遞給驅(qū)動(dòng)器。class generatormailbox   

62、gen2drv;transaction tr; function new(input mailbox gen2drv)    this.gen2drv = gen2drv;endfunction task run;   forever begin       tr = new();       assert(tr.randmize);   

63、;    gen2drv.put(tr);   /mail.put(x)  endendtask    endclass        存在問(wèn)題:這個(gè)例子在循環(huán)內(nèi)部創(chuàng)建事務(wù)對(duì)象,而不是在循環(huán)外部,避免了測(cè)試平臺(tái)常見(jiàn)的錯(cuò)誤。New()放在循環(huán)外部,錯(cuò)誤原因是,mailbox中放入的是句柄,而不能是對(duì)象,所有的句柄都指向同一個(gè)對(duì)象。(1)任務(wù)Run創(chuàng)建了一個(gè)事物并立即隨機(jī)化,意味著事務(wù)使用了

64、默認(rèn)的所有約束。要修改,必須要修改transaction類。(2)無(wú)法使用擴(kuò)展解決辦法:將tr的創(chuàng)建和初始化分開(kāi),使用藍(lán)圖模式。另一個(gè)問(wèn)題:如果簡(jiǎn)單的把創(chuàng)建和初始化分開(kāi),而放在循環(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ā)生器類的行為而無(wú)需修改其類代碼。藍(lán)圖對(duì)象在一個(gè)地方構(gòu)建(new(),在另一個(gè)地方(任務(wù)run)使用   3)P200與P22

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

66、opy是對(duì)象的復(fù)制,所以在copy中ID號(hào)也會(huì)增加。下發(fā)的每個(gè)數(shù)據(jù),都有各自的ID號(hào)。    l         使用擴(kuò)展的transaction為了注入錯(cuò)誤,需要將藍(lán)圖對(duì)象transaction變成Badtransaction(改變藍(lán)圖)。必須在環(huán)境的創(chuàng)建和運(yùn)行階段之間完成這個(gè)操作。注意:所有的badTr引用都在這一個(gè)文件中,這樣就不需要改變environment類或generator類。 Env.build();Begin  

67、60;Badtr bad = new();   Env.gen.blueprint = bad;End Env.run目的是:將一個(gè)對(duì)象取代另一個(gè)對(duì)象。New()后都是對(duì)象了,將對(duì)象賦值給對(duì)象,這是什么寫(xiě)法?不是復(fù)制呀?復(fù)制本質(zhì)是將一個(gè)句柄指向一個(gè)對(duì)象。解釋:上述是句柄的復(fù)制,將擴(kuò)展類句柄bad賦值給基類句柄blueprint,這樣基類句柄指向擴(kuò)展類對(duì)象,后面的代碼調(diào)用的時(shí)候,就直接指向擴(kuò)展類bad了,改變了藍(lán)圖。  l         Env.

68、new()和nev.build()區(qū)別Env.new()僅僅new()函數(shù)nev.build()是將各個(gè)模塊new(),并傳達(dá)一些參數(shù),通過(guò)這些參數(shù)將環(huán)境的各個(gè)模塊,連接起來(lái)。P213 l         $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. 

69、 $cast做任務(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)圖,不改過(guò)多代碼,增加功能Transaction tr; /基類句柄BadTr  bad;  /擴(kuò)展類句柄Bad = new();Tr  = bad;  / 基類句柄指向擴(kuò)展類對(duì)象tr.display;  

70、  /掉用的是擴(kuò)展類的方法2) 擴(kuò)展類句柄指向基類對(duì)象出現(xiàn)情況:基類virtual 方法copy函數(shù),它的繼承類中copy函數(shù)將基類句柄賦值給擴(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ì)被通過(guò)。因?yàn)橛行傩栽诨愔?/p>

71、不存在;但是擴(kuò)展類句柄指向基類句柄不總是非法的(見(jiàn)下面代碼,是可以的),當(dāng)基類句柄指向一個(gè)擴(kuò)展類對(duì)象時(shí)是允許的。       Transcation tr;       BadTr bad,bad2;                 Bad= new();   

72、;     Tr = bad;          /基類句柄指向擴(kuò)展類對(duì)象       $cast(bad2,tr);      /擴(kuò)展類句柄指向基類對(duì)象   if(!$cast(bad2,tr);     $display(“cannot

73、 assign tr to bad2”);   $display(bad2.bad_crc); l         句柄類型和對(duì)象類型差異(書(shū)中翻譯的不準(zhǔn),type of handdle 和 object)個(gè)人理解:Transaction tr;  句柄tr類型是transaction句柄類型:關(guān)鍵字對(duì)象類型:類中成員的類型差異 l         

74、;虛方法和多態(tài)多態(tài):多個(gè)程序使用一個(gè)共同的名字的現(xiàn)象。多態(tài)解決問(wèn)題:計(jì)算機(jī)建構(gòu)面臨的一個(gè)問(wèn)題。讓物理內(nèi)存很小的情況下,讓處理器能夠?qū)艽蟮牡刂房臻g尋址。針對(duì)這個(gè)問(wèn)題引入了虛擬內(nèi)存。虛擬方法繼承劣勢(shì):基類使用了虛擬方法,擴(kuò)展類也必須使用相同的“簽名”,擴(kuò)展類中虛擬子程序不能增加或刪除參數(shù),這意味著必須提前做好規(guī)劃。      l         對(duì)象復(fù)制1)  因?yàn)槭莢irtual 函數(shù),擴(kuò)展類中copy方法也必須是transa

75、ction型的,但是要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;    Copy.dst = dst;  

76、0; Copy.data = data;    Copy.crc  = crc;EndfunctionEndclass 帶有copy的擴(kuò)展類Calss badtr extends transaction    Rand bit bad_crc; Virtual function badtr copy();  /錯(cuò)誤Virtual function transaction copy();   Badtr  bad;   Bad = new();   Bad.src = src;   bad.dst = dst;   bad.data = data;   bad.crc  = crc;   Bad.bad_crc = bad_crc;Retur

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論