1)首先定義純虛類Sv_object,主要實現下邊兩個function:
定義local static 變量nextobjectID;
虛方法 virtual function void copy(St_object that, CloneType clone_type = DEEP);在基類中復制都可以通過super.copy來迭代copy。
2)在Sv_object的基礎上,實現對mailbox和event的封裝。產生兩個基類Sv_mailbox_wrapper與Sv_event_wrapper。其中event多用在進程的控制
(wait(event), event(trigger)等形式放在function內),mailbox主要用在transaction的傳遞。
3)在Sv_object的基礎上,建立一個Sv_testobject的純虛類,來作為驗證環境中各個組件的基類,在該基類中實現4個funciton,start,stop,main,reset。利用
event將這幾個funciton聯系起來。這樣便有了一個基本的控制流程。
4)Transaction類的建立,這個類不算驗證環境中的構件,所以用Sv_object來extends。不過同樣要在Sv_transaction這個類中建立基本的流程,比如:
generate,execute,check。分別作用在generator段,driver, monitor,DUT段,check段。同樣通過event來實現,可以實現三個function來控制這
三個event,在上層調用實現callback。這都是針對一個tranaction來說的流程。
5)Generator基類的建立,在Sv_testobject的基礎上extends,要重新定義一個generate的function,來讓testcase中的generator來重定義,完成randomized
和一些例外的constrain,或其他的回調函數。
6)Driver基類的建立,在Sv_testobject的基礎上extends,因為需要加入額外額reset信號,所以在Sv_testobject的基礎上,加入另外兩個優先級更高的
function,這里的優先級也就是通過event阻塞來實現的,wait_for_reset, reset。
7)Monitor基類的建立,在Sv_testobject的基礎上extends,主要是在Sv_testobject的基礎上定義一個receive_trans的function,來接收從DUT發出的信號。
8)Check基類的建立,在Sv_testobject的基礎上extends,這個類與具體的test相關較大,基類中只需定義一些event來表示start和done。
9)Test基類的建立,在Sv_testobject的基礎上extends,這個類主要是完成流程的控制,可以分為GenConfig(), ConfigDut, Build(), start(), stop, report,
總體先配置好環境,在配置DUT,而后clock, reset, 信號進來完成初始化,而后start驗證平台的各個模塊開始工作,在這個階段再根據Transaction的三個
function來細分控制。
10)test_trans類的建立,在Transaction的基礎上extends,主要是針對一些DUT中的信號的randmize定義和constrain,還需要建立一個param_trans的
function,主要是傳遞transaction,這樣可以在最頂層直接例化function之后將相應的mailbox聯系起來。
11)test_generator類的建立,在Generator基類的基礎上extends,主要是重定義generator這個function,也就是完成randomized和一些例外的constrain,或
其他的回調函數。同樣建立一個param_trans的function,接收來自test_trans的transaction。頂層例化,mailbox連接。
12)test_driver類的建立,在Driver基類的基礎上extends,主要加入reset的控制,重定義driver基類中的wait_for_reset和reset這兩個function。同樣建立一個
param_trans的function,接收來自test_generator的transaction和clk, reset, DUT的interface虛接口。頂層例化,mailbox連接。
13)test_Monitor基類的建立,在Monitor基類的基礎上extends,主要是收集DUT的部分信號。同樣建立一個param_trans的function,可以將收集到的信號組成
一個transaction發送給test_check,還可以引入一些clk, reset的interface虛接口。頂層例化,mailbox連接。
14)test_check類的建立,在check基類的基礎上extends,定義一些很細節的function,來根據收到的transaction與預想的行為進行比對。同樣建立param_trans
的function,來接受Monitor發來的transaction。頂層例化,mailbox連接。
15)testcase類的建立,在test基類的基礎上extends,主要是配置驗證環境,重定義GenConfig(), ConfigDut這兩個function,並且在build這個function中,例化
各個組件的param_trans這個function,來將各個mailbox連接起來。
16)定義一個Testbench_top的module,主要例化 DUT_module, DUT_if, clk_if, reset_if等RTL文件。
16)定義一個program,例化 testcase.sv, top。在initial中通過調用一個testcase中的GenConfig()來開始,整個環境開始執行。
最后還需要加入cover_file.sv和assert_file.sv,這兩個文件不需要很復雜的繼承,直接按testcase定義就好,一般還需要相應的interface信號,來與DUT進行連
接。cover_file_if, assert_file_if。直接通過bind top綁定到頂層就好。需要修改覆蓋率和SVA的時候可以直接修改,他們不影響整個驗證環境。
額外定義reset和clock的模塊,放在module中。它們的cover_file和assert_file,也最好單獨驗證。
DUT中register的值得獲取,通過Apb總線,在Driver中進行配置。
register值得獲得,可以通過monitor來得到,其中test_regif是通過bind xxxx 來定位到DUT中寄存器所在的那一級module 。
當然這只是一些最基本的模塊,還有log文件在這個環境中怎么設計,腳本的問題等。
在SV中通過DPI來介入C/C++的函數,
聲明:import “DPI-C” function int factorial(input bit i)
program automatic test;
initial begin
for(int i=1; i<=10; i++)
$display("%0d = %0d", i, factorial(i));
end
endprogram
input表示從SV到C,還支持output/inout,但是不支持ref。
對於C++的引用,SV只支持靜態的方法,所以不能調用class 例化的對象中的function