張 靜,卜 剛
(南京航空航天大學(xué) 電子信息工程學(xué)院,江蘇 南京 211106)
芯片的驗(yàn)證[1-7],是提高芯片流片成功的關(guān)鍵。驗(yàn)證工作與設(shè)計(jì)仿真工作不同,仿真是為了證明設(shè)計(jì)方案的正確性,而驗(yàn)證是為了證明方案中不存在錯(cuò)誤。設(shè)計(jì)錯(cuò)誤很容易造成芯片完全不能工作,而修正錯(cuò)誤再重新流片不但需要額外的費(fèi)用,更會延遲芯片上市時(shí)間,這對芯片開發(fā)造成了巨大的風(fēng)險(xiǎn)?,F(xiàn)如今,芯片制造工藝更加精細(xì),芯片制造費(fèi)用的增加,芯片功能變得越來越復(fù)雜,驗(yàn)證的重要性也在不斷增加。
目前來說,SystemVerilog[3,6-11]已經(jīng)成為比較主流的驗(yàn)證語言,SystemVerilog語言具有許多優(yōu)點(diǎn),諸如隨機(jī)約束[12]、功能覆蓋率[2,13]、斷言技術(shù)和利用面向?qū)ο笏枷霕?gòu)建驗(yàn)證平臺的一般方法。這些優(yōu)點(diǎn)能極大提高芯片驗(yàn)證的效率,保障芯片設(shè)計(jì)的正確率,縮短芯片上市時(shí)間。
此處介紹的驗(yàn)證技術(shù),專注于受約束的隨機(jī)測試,它利用功能覆蓋率來衡量進(jìn)度并指導(dǎo)驗(yàn)證。SystemVerilog最有意義的優(yōu)點(diǎn)在于,它允許用戶在多個(gè)項(xiàng)目中使用連續(xù)一貫的語法來構(gòu)造可靠并且可重復(fù)的驗(yàn)證環(huán)境。SystemVerilog提供了一種建模語言,簡化了自頂向下的設(shè)計(jì),可以在SystemVerilog中創(chuàng)建模型,然后在下一層重新定義每個(gè)模塊,初始的系統(tǒng)級模型也可以被重新用作參考模型,不僅如此,它還引入了直接編程接口(DPI),能更加簡單地連接C、C++或者其他非Verilog編程語言。
相比于硬件描述語言(HDL),SystemVerilog硬件驗(yàn)證語言(hardware verification language,HVL)[5,14]具有典型的性質(zhì):
●受約束的隨機(jī)激勵(lì)生成;
●功能覆蓋率;
●更高層次的結(jié)構(gòu),尤其是面向?qū)ο缶幊蹋?/p>
●多線程及線程的通信;
●支持HDL數(shù)據(jù)類型,例如Verilog的四狀態(tài)數(shù)值;
●集成了事件仿真器,便于對設(shè)計(jì)施加控制。
還有其他很多有用的性質(zhì),但上述特性已經(jīng)能夠支撐創(chuàng)建高度抽象的測試平臺。
采用隨機(jī)測試[14]的原因如圖1所示。
圖1 隨機(jī)測試與定向測試的時(shí)間比較
圖1是傳統(tǒng)驗(yàn)證的定向測試方法和高級驗(yàn)證的隨機(jī)測試方法的比較[15],對這兩種方法所用的驗(yàn)證周期以及功能覆蓋率進(jìn)行對比。采用定向測試方法時(shí),使用的時(shí)間與功能覆蓋率呈線性關(guān)系。隨著增加定向測試?yán)木帉憯?shù)量,功能覆蓋率穩(wěn)步上升。采用隨機(jī)測試方法時(shí),由于需要準(zhǔn)備隨機(jī)驗(yàn)證環(huán)境,開始時(shí)會有一段覆蓋率沒有增加的時(shí)間段。當(dāng)隨機(jī)驗(yàn)證環(huán)境準(zhǔn)備完畢,運(yùn)行隨機(jī)測試?yán)?,可以隨機(jī)產(chǎn)生大量激勵(lì),功能覆蓋率會有大幅增加。當(dāng)覆蓋率增加不明顯時(shí),分析未覆蓋情況,加緊約束或添加定向測試?yán)?,對未覆蓋的情況進(jìn)行覆蓋,直至功能覆蓋率達(dá)到100%。由圖可以看出,雖然采用隨機(jī)測試的方法會有一段覆蓋率為零的時(shí)間段,但從整個(gè)驗(yàn)證周期來看,隨機(jī)測試方法會比定向測試方法更具優(yōu)勢,尤其是隨著集成電路規(guī)模和復(fù)雜度的增加,這種基于覆蓋率驅(qū)動的受約束隨機(jī)激勵(lì)方法會更符合驗(yàn)證的需要。
圖2中的DUT是由兩個(gè)子模塊構(gòu)成的具有兩級流水的系統(tǒng)模塊[16],第一級為一個(gè)預(yù)處理器模塊(EXECUTE PREPROCESSOR),第二級為一個(gè)算術(shù)邏輯運(yùn)算單元(ALU)模塊:
圖2 DUT結(jié)構(gòu)
●預(yù)處理器:對外部輸入的數(shù)據(jù)和控制信號進(jìn)行處理,并產(chǎn)生對應(yīng)的ALU可接受的數(shù)據(jù)和控制信號。
●算數(shù)邏輯運(yùn)算單元:根據(jù)輸入的opselect,operation和shift_number信號執(zhí)行相關(guān)算數(shù)邏輯運(yùn)算。
這兩個(gè)子模塊都可以具有各自獨(dú)立的時(shí)鐘和復(fù)位信號,文中這兩個(gè)子模塊的時(shí)鐘和復(fù)位信號是一致的。
基本功能描述:
●復(fù)位:復(fù)位時(shí),所有的時(shí)序邏輯輸出都為0,這些信號包括:預(yù)處理輸出信號中的aluin1,aluin2,operation_out,opselect_out,shift_number enable_arith,enable_shift以及ALU輸出的信號aluout,carry。
●預(yù)處理器功能描述:所有時(shí)序邏輯的輸出只有在enable_ex==1的條件下才會發(fā)生變化。
●ALU:所有指令信號只在以下兩個(gè)條件成立之一才有效:enable_arith==1 or enable_shift=1。這些信號均在時(shí)鐘的上升沿處進(jìn)入ALU子模塊,ALU可執(zhí)行移位操作和算數(shù)邏輯運(yùn)算,以及數(shù)據(jù)傳輸。
SystemVerilog平臺如圖3所示。
組件搭建描述[15]:
將數(shù)據(jù)信息封裝進(jìn)入Packet類,利用隨機(jī)化和相關(guān)約束產(chǎn)生隨機(jī)數(shù)據(jù),創(chuàng)建兩個(gè)packet對象,一個(gè)包在DUT輸入端輸入,另一個(gè)包和DUT輸出的數(shù)據(jù)相參照。
圖3 SystemVerilog平臺
隨機(jī)化的部分代碼:
rand reg[`REGISTER_WIDTH-1:0] src1;
rand reg[`REGISTER_WIDTH-1:0] src2;
rand reg[`REGISTER_WIDTH-1:0] imm;
…………………….
相關(guān)約束的部分代碼:
constraint Limit {
src1 inside{[0∶65534]}
src2 inside{[0∶65534]};
imm inside{[0∶65534]};
mem_data inside{[0∶65534]};
opselect_gen inside {[0∶1],[4∶5]};
封裝了gen()任務(wù)和一個(gè)start()方法,其中start()方法的循環(huán)由系統(tǒng)全局變量number_packets控制。如果number_packets≤0,則這個(gè)循環(huán)是無限的。如果number_packets>0,則這個(gè)循環(huán)在循環(huán)這么多次后會停止。在調(diào)用gen()之后,會創(chuàng)建一個(gè)隨機(jī)化packet對象(pkt2send)的拷貝,并且通過out_box郵箱發(fā)送到Driver。
連接驗(yàn)證平臺和DUT的端口。但是在類里面不可直接定義interface,須使用virtual來定義。
其中in_box將會用來從Generator向Driver接收Packet對象。out_box將用來從Driver向Scoreboard發(fā)送Packet對象。in_box和out_box都是pkt_mbox的類型。在Driver中start()方法是在一個(gè)無限的循環(huán)中執(zhí)行的。在這個(gè)循環(huán)的每一次執(zhí)行中,都會從in_box中獲取一個(gè)Packet對象。這個(gè)數(shù)據(jù)包對象的內(nèi)容將會通過send()發(fā)送經(jīng)過DUT。一旦這個(gè)Packet對象的發(fā)送過程完成后,這個(gè)Packet對象會被發(fā)送到scoreboard。
Generator到Driver的mailbox的代碼:
typedef mailbox#(Packet) in_box_type;
in_box_type in_box=new;
Driver到Scoreboard的mailbox的代碼:
typedef mailbox#(Packet) out_box_type;
out_box_type out_box=new;
調(diào)用recv()來從DUT中重新獲取Packet對象,將從DUT中獲取的Packet對象復(fù)制一份到out_box中去,在receiver中有start()方法,它將會執(zhí)行一個(gè)非阻塞的無限循環(huán)。每次循環(huán)中,都會從DUT中重新構(gòu)建一個(gè)Packet對象。一旦重新獲取后,這個(gè)Packet對象將會通過發(fā)出郵箱(out mailbox)發(fā)送到scoreboard。
Receiver連接到Scoreboard的mailbox的代碼:
typedef mailbox#(Packet) rx_box_type;
rx_box_type rx_out_box;
封裝check()任務(wù),實(shí)現(xiàn)Scoreboard,Driver和Receiver之間的通信。Driver在發(fā)送數(shù)據(jù)包對象到DUT中時(shí),也會將它發(fā)送到driver_mbox郵箱。一個(gè)Receiver在從DUT接收到數(shù)據(jù)時(shí),也會發(fā)送Packet對象到receiver_mbox郵箱中去。
利用driver_mbox.num()和receiver_mbox.num()查看是否有包傳入,如果存在利用get()函數(shù)將從Driver傳入的包放入pkt2send,receiver傳入的包放入pkt2cmp,之后利用check()函數(shù)作比較。在Scoreboard這個(gè)類中還定義了coveragegroup來收集覆蓋率,定義DUT的各個(gè)功能點(diǎn)比如ALU的算術(shù)和移位功能,采用交叉覆蓋率,用sample()采樣,最后用get_coverage()收集覆蓋率。
Scoreboard用來連接Driver的mailbox的代碼:
typedef mailbox#(Packet) out_box_type;
out_box_type driver_mbox;
Scoreboard用來連接Receiver的mailbox的代碼:
typedef mailbox #(OutputPacket) rx_box_type;
rx_box_typereceiver_mbox;
覆蓋率功能點(diǎn)定義部分代碼:
covergroup Arith_Cov_Ver2;
coverpoint pkt_sent.imm;
src1_cov:coverpoint pkt_sent.src1 ;
……………………………………
opselect_cov2:coverpoint pkt_sent.opselect_gen {
bins shift={0};
bins arith={1};
bins mem={[4∶5]};
}
…………………………………
cross src1_cov, src2_cov;
endgroup
covergroup的例化與采樣:
Arith_Cov_Ver1=new();
……………………………………
Arith_Cov_Ver1.sample();
……………………………………
覆蓋率的收集:
coverage_value1=Arith_Cov_Ver1.get_coverage();
………………………………………….
聲明并例化各組件,正確連接郵箱,調(diào)用每個(gè)類的start()方法,設(shè)置reset()任務(wù)。
部分代碼:
組件的聲明:
Driver drv;
………………………
組件的例化:
drv=new();
………………………..
組件的啟動:
drv.start();
………………………..
聲明接口,實(shí)現(xiàn)DUT和平臺互連,設(shè)置時(shí)鐘信號。
部分代碼:
平臺互連:
Top dut(.clock(top_if.clock),.enable_ex(top_if.enable_ex),………………………);
設(shè)置時(shí)鐘信號:
#(simulation_cycle/2)
Clock = ~Clock;
編寫完SystemVerilog代碼后開始進(jìn)行平臺驗(yàn)證,主要采用questamsim軟件進(jìn)行仿真驗(yàn)證,使用命令啟動平臺、生成打印信息報(bào)告以及收集覆蓋率報(bào)告。
根據(jù)輸出的波形圖和生成的驗(yàn)證報(bào)告來比較DUT功能的正確與否,并查看輸出的功能覆蓋率報(bào)告來檢查各功能點(diǎn)的實(shí)現(xiàn)狀況。
圖4 信息打印
由圖4可以發(fā)現(xiàn)DUT的輸出和模型的輸出是一致的,DUT的設(shè)計(jì)滿足功能實(shí)現(xiàn),圖4還打印出各個(gè)功能點(diǎn)的覆蓋率狀況以便于分析如何添加測試用例來使功能覆蓋率達(dá)到100%。
波形圖中定位處由隨機(jī)輸入的信號來看實(shí)現(xiàn)的是算數(shù)邏輯,即將aluin2的低十六位賦值給aluout的高十六位,并將aluout的低十六位置零。由圖中aluin2為32’h00003a1e,aluout為32’h00000000可得運(yùn)算是正確的,且各使能信號也正確無誤。
圖5 DUT部分波形(1)
圖5檢測了DUT的算數(shù)邏輯,只是DUT其中一個(gè)功能點(diǎn)。圖6列出了DUT基于隨機(jī)激勵(lì)測試的所有功能點(diǎn)實(shí)現(xiàn)的波形圖,查看整體波形,檢查每個(gè)功能點(diǎn)實(shí)現(xiàn)的具體情況,可以發(fā)現(xiàn)DUT的設(shè)計(jì)是沒問題的。
圖6 DUT部分波形(2)
圖7描述了此DUT的功能覆蓋率,可見覆蓋率還未達(dá)到100%,尤其是算數(shù)和移位運(yùn)算單元比較低,因此可以修改約束條件增加測試用例來使功能覆蓋率提高,從而保證驗(yàn)證的完備性。
圖7 功能覆蓋率(1)
由圖8可知,通過增加測試用例以及修改相關(guān)約束條件,可以發(fā)現(xiàn)覆蓋率有了明顯的提高,所有的覆蓋率都達(dá)到了100%,說明該測試點(diǎn)已經(jīng)得到了充分的驗(yàn)證。由此可見,增加定向測試激勵(lì)配合隨機(jī)激勵(lì)可以大幅提高功能覆蓋率,由圖8可見所有的測試點(diǎn)的覆蓋率都達(dá)到了100%。因此可得,基于SV語言的優(yōu)點(diǎn),可以減少驗(yàn)證時(shí)間并提高驗(yàn)證效率。
圖8 功能覆蓋率(2)
定向測試每次只能測試一個(gè)特性,而無法模擬設(shè)備在實(shí)際應(yīng)用中所面對的復(fù)雜的激勵(lì)和配置,為了得到穩(wěn)健的設(shè)計(jì),使用受約束的隨機(jī)激勵(lì)加上功能覆蓋率,才能在最大限度內(nèi)創(chuàng)建出最廣泛的激勵(lì)。文中演示了如何使用SV語言面向?qū)ο缶幊痰姆椒ń⒁粋€(gè)由覆蓋率驅(qū)動并且受約束的隨機(jī)分層測試平臺。基于SV的驗(yàn)證,充分利用了SV語言中提供的隨機(jī)約束和斷言機(jī)制,改變了傳統(tǒng)的直接測試的方法,基于覆蓋率驅(qū)動的驗(yàn)證極大提高了驗(yàn)證的效率和完備性,有效縮短了驗(yàn)證周期。