我們知道,不論是哪一級(jí)的驗(yàn)證,最終都是通過(guò) pin 連接到 DUT 上向其施加激勵(lì),對(duì)于 UVM 驗(yàn)證平臺(tái)中,使用虛接口來(lái)實(shí)現(xiàn) DUT 和驗(yàn)證平臺(tái)的通信。
為了簡(jiǎn)化模塊之間的連接和實(shí)現(xiàn)類(lèi)和模塊之間的通信,以實(shí)現(xiàn)測(cè)試平臺(tái)的可重用性, SV 定義了接口的語(yǔ)法結(jié)構(gòu)??傮w來(lái)說(shuō),接口就是在 testbench 這邊定義了訪問(wèn)的 DUT 的管腳的集合,通過(guò)對(duì)接口中管腳信號(hào)的操作,來(lái)實(shí)現(xiàn)對(duì) DUT 的管腳的操作, 這樣能夠?qū)崿F(xiàn)驗(yàn)證平臺(tái)和待測(cè)模塊的分離。
驗(yàn)證工程師和設(shè)計(jì)工程師只要定義好接口關(guān)系,就可以分別開(kāi)展工作。 同時(shí)如果設(shè)計(jì)管腳發(fā)生變化,無(wú)需改變 testbench 這邊的虛接口,只需要在例化待測(cè)模塊時(shí),給接口綁定對(duì)應(yīng)的待測(cè)接口即可。
Testbench 和 DUT 是通過(guò)接口進(jìn)行數(shù)據(jù)交互的。接口僅僅是信號(hào)的一個(gè)集合,因此我們可以將 X_MAC 的所有信號(hào)定義為一個(gè)統(tǒng)一的接口,也可以將一個(gè)信號(hào)定義一個(gè)接口,這樣對(duì)于 X_MAC 模塊,就會(huì)有許許多多的接口。另外要注意的是,一個(gè)接口要對(duì)應(yīng)一個(gè) driver,因此,接口過(guò)多的話,就需要定義很多個(gè) driver。
同樣的,如果接口數(shù)量過(guò)少的話,就只需要定義較少的 driver。接口數(shù)量過(guò)多或過(guò)少,都不利于后期驗(yàn)證工作的開(kāi)展。為了方面后續(xù)的工作,接口的個(gè)數(shù)合適為宜,總的原則是:
**1. 將相互關(guān)系緊密的信號(hào)放到同一個(gè)接口中。
****2. 要將同一個(gè)時(shí)鐘周期的信號(hào)放到同一個(gè)接口中。
****3. 將和同一個(gè)模塊連接的信號(hào)要放到同一個(gè)接口中。
**上面的三點(diǎn)基本上表達(dá)的是同一個(gè)意思, 這樣有利于后期方便激勵(lì)。
在接口的定義中需要注意的一個(gè)問(wèn)題是:對(duì)于同一個(gè)信號(hào),其方向(input/output)對(duì)于 DUT 和對(duì)于 testbench 來(lái)說(shuō)是相反的, 在接口中需要定義信號(hào)的方向是針對(duì) testbench 的方向, 這一點(diǎn)需要注意。
下面是一個(gè)接口示例。
interface hello_if(input logic rxc,input logic txc);
logic [7:0] rxd_1;
logic [7:0] rxd_2;
logic rx_dv;
logic [7:0] txd;
logic tx_en;
//from model to DUT
clocking drv_cb @(posedge rxc);
output #1 rxd_1,rxd_2,rx_dv;
endclocking
clocking mon_cb @(posedge txc);
input #1 txd,tx_en;
endclocking
endinterface
首先,我們需要在 tb_top 模塊中例化接口和待測(cè) DUT,在例化 DUT 的時(shí)候,將 DUT 的接口和接口中定義的管腳綁定即可。如下圖所示:
module hello_tb_top;
import uvm_pkg::*;
import hello_pkg::*;
reg clk;
hello_if my_hello_if(clk,clk);//實(shí)例化接口
dut my_dut(.clk(clk),
.rxd_1(my_hello_if.rxd_1),
.rxd_2(my_hello_if.rxd_2),
.rx_dv(my_hello_if.rx_dv),
.txd(my_hello_if.txd),
.tx_en(my_hello_if.tx_en)
);//實(shí)例化 DUT,并將 DUT 的輸入輸出端口和 my_hello_if 連接在一起
initial begin//產(chǎn)生 DUT 需要的時(shí)鐘
clk = 0;
forever begin
#10;clk = ~clk;
end
end
//assign physical interface to virtual interface
initial begin//通過(guò) config_db 的 set 方式將 my_if 通知 driver 和 monitor
//從而 Driver 和 monitor 可以直接和 DUT 通信。
uvm_config_db#(virtual hello_if)::set(null,"uvm_test_top.env.input_agt.drv","hello_if",my_hello_if);
uvm_config_db#(virtual hello_if)::set(null,"uvm_test_top.env.output_agt.mon","hello_if",my_hello_if);
run_test();//啟動(dòng) UVM
end
endmodule
在例化 dut 時(shí),我們將 dut 的管腳和虛接口的管腳綁定在一起。這樣,我們?cè)?testbench 中對(duì)虛接口進(jìn)行操作,也就對(duì) DUT 的管腳進(jìn)行了操作。在 testbench 中只有 driver 和 monitor 會(huì)對(duì) DUT 進(jìn)行激勵(lì)的加載和監(jiān)聽(tīng),那么在 driver 和 monitor 那里如何訪問(wèn)到這里的接口?
首先我們看到上面的代碼中有如下的語(yǔ)句
uvm_config_db#(virtual hello_if)::set(null,"uvm_test_top.env.input_agt.drv","hello_if",my_hello_if);
uvm_config_db#(virtual hello_if)::set(null,"uvm_test_top.env.output_agt.mon","hello_if",my_hello_if);
我們?cè)?uvm_top 模塊中,通過(guò) uvm_config_db 的 set 語(yǔ)句將定義在 driver 中的虛接口和 uvm_top 模塊中的接口連接起來(lái)。在 driver 中首先需要定義一個(gè)虛接口:
virtual hello_if vif;
這里的虛接口的意思是,這個(gè)接口在 driver 這里是不存在的,這里只是一個(gè)句柄,通過(guò)虛接口, testbench 能訪問(wèn)到 uvm_top 中定義的實(shí)體接口,從而訪問(wèn)到DUT。隨后在 driver 中通過(guò) uvm_config_db 的 get 操作將 driver 中的虛接口和uvm_top 中的實(shí)體接口連接起來(lái)。
if(!uvm_config_db#(virtual hello_if)::get(this,"","hello_if", vif))
`uvm_fatal("hello_driver","Error in Geting interface");
這樣, driver 通過(guò)虛接口實(shí)現(xiàn)了對(duì) DUT 的操作。
-
UVM
+關(guān)注
關(guān)注
0文章
182瀏覽量
19171 -
PIN
+關(guān)注
關(guān)注
1文章
304瀏覽量
24311 -
DUT
+關(guān)注
關(guān)注
0文章
189瀏覽量
12386
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論