我們知道,不論是哪一級的驗證,最終都是通過 pin 連接到 DUT 上向其施加激勵,對于 UVM 驗證平臺中,使用虛接口來實現 DUT 和驗證平臺的通信。
為了簡化模塊之間的連接和實現類和模塊之間的通信,以實現測試平臺的可重用性, SV 定義了接口的語法結構。總體來說,接口就是在 testbench 這邊定義了訪問的 DUT 的管腳的集合,通過對接口中管腳信號的操作,來實現對 DUT 的管腳的操作, 這樣能夠實現驗證平臺和待測模塊的分離。
驗證工程師和設計工程師只要定義好接口關系,就可以分別開展工作。 同時如果設計管腳發生變化,無需改變 testbench 這邊的虛接口,只需要在例化待測模塊時,給接口綁定對應的待測接口即可。
Testbench 和 DUT 是通過接口進行數據交互的。接口僅僅是信號的一個集合,因此我們可以將 X_MAC 的所有信號定義為一個統一的接口,也可以將一個信號定義一個接口,這樣對于 X_MAC 模塊,就會有許許多多的接口。另外要注意的是,一個接口要對應一個 driver,因此,接口過多的話,就需要定義很多個 driver。
同樣的,如果接口數量過少的話,就只需要定義較少的 driver。接口數量過多或過少,都不利于后期驗證工作的開展。為了方面后續的工作,接口的個數合適為宜,總的原則是:
**1. 將相互關系緊密的信號放到同一個接口中。
****2. 要將同一個時鐘周期的信號放到同一個接口中。
****3. 將和同一個模塊連接的信號要放到同一個接口中。
**上面的三點基本上表達的是同一個意思, 這樣有利于后期方便激勵。
在接口的定義中需要注意的一個問題是:對于同一個信號,其方向(input/output)對于 DUT 和對于 testbench 來說是相反的, 在接口中需要定義信號的方向是針對 testbench 的方向, 這一點需要注意。
下面是一個接口示例。
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 模塊中例化接口和待測 DUT,在例化 DUT 的時候,將 DUT 的接口和接口中定義的管腳綁定即可。如下圖所示:
module hello_tb_top;
import uvm_pkg::*;
import hello_pkg::*;
reg clk;
hello_if my_hello_if(clk,clk);//實例化接口
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)
);//實例化 DUT,并將 DUT 的輸入輸出端口和 my_hello_if 連接在一起
initial begin//產生 DUT 需要的時鐘
clk = 0;
forever begin
#10;clk = ~clk;
end
end
//assign physical interface to virtual interface
initial begin//通過 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();//啟動 UVM
end
endmodule
在例化 dut 時,我們將 dut 的管腳和虛接口的管腳綁定在一起。這樣,我們在 testbench 中對虛接口進行操作,也就對 DUT 的管腳進行了操作。在 testbench 中只有 driver 和 monitor 會對 DUT 進行激勵的加載和監聽,那么在 driver 和 monitor 那里如何訪問到這里的接口?
首先我們看到上面的代碼中有如下的語句
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);
我們在 uvm_top 模塊中,通過 uvm_config_db 的 set 語句將定義在 driver 中的虛接口和 uvm_top 模塊中的接口連接起來。在 driver 中首先需要定義一個虛接口:
virtual hello_if vif;
這里的虛接口的意思是,這個接口在 driver 這里是不存在的,這里只是一個句柄,通過虛接口, testbench 能訪問到 uvm_top 中定義的實體接口,從而訪問到DUT。隨后在 driver 中通過 uvm_config_db 的 get 操作將 driver 中的虛接口和uvm_top 中的實體接口連接起來。
if(!uvm_config_db#(virtual hello_if)::get(this,"","hello_if", vif))
`uvm_fatal("hello_driver","Error in Geting interface");
這樣, driver 通過虛接口實現了對 DUT 的操作。
-
UVM
+關注
關注
0文章
181瀏覽量
19144 -
PIN
+關注
關注
1文章
303瀏覽量
24239 -
DUT
+關注
關注
0文章
189瀏覽量
12348
發布評論請先 登錄
相關推薦
評論