在本系列的第一部分中,介紹了SystemVerilog接口的基本概念,并描述了這些接口的參數化給測試平臺代碼帶來的問題。這篇文章將描述此問題的可能解決方法,但需要付出代價...
特洛伊木馬:偷襲方法
虛擬接口不支持多態性,因為它們與靜態設計元素相關聯。但是,SystemVerilog 類確實支持多態性,這一事實可用于創建接口訪問器類。
創建一個虛擬類,該類聲明在 SystemVerilog 接口上執行特定操作的純虛擬訪問器方法。然后,參數化類擴展此類以執行對強類型接口的實際訪問。VIP 代碼僅與非參數化基訪問器類交互,因此無需參數化 VIP 代碼即可使用強類型接口。測試平臺必須設置強類型訪問器類并將其傳遞給 VIP,但在此之后,無需參數化 VIP 即可執行與 VIP 的所有交互。以下代碼段演示如何進行此設置。
首先,我們定義參數化虛擬接口,該接口與上周代碼段中使用的接口相同:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
接下來,我們定義非參數化接口訪問器類和參數化以使用參數化接口的擴展類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//======================================================================= virtual class port_wrapper extends uvm_object;
pure virtual task do_write(logic[31:0] data);
pure virtual task do_read(output logic[31:0] data);
pure virtual task sync_driver_cb(); endclass //======================================================================= class port_wrapper_typed#(type vif_t=param_vif) extends port_wrapper;
vif_t vif;
function new(vif_t vif);
this.vif = vif;
endfunction
virtual task do_write(logic[31:0] data);
vif.active_cb.data <= data;
endtask
virtual task do_read(output logic[31:0] data);
data = vif.active_cb.data;
endtask
virtual task sync_driver_cb();
@(vif.active_cb);
endtask endclass |
在此之后,實現 VIP 代碼以使用此訪問器類,而不是直接訪問虛擬接口。下面的代碼段展示了驅動程序和代理類,并演示了必須使用訪問器方法的各個位置。關于此VIP代碼需要注意的一件事是,它通過配置數據庫而不是接口接受非參數化訪問器類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
//=======================================================================
class cust_driver extends uvm_driver#(cust_data);
`uvm_component_utils(cust_driver)
port_wrapper port;
task consume_from_seq_item_port();
forever begin
seq_item_port.get_next_item(req);
port.do_write(req.data);
port.sync_driver_cb(); …
task sample_signals();
forever begin
bit[31:0] sampled_data;
port.do_read(sampled_data);
port.sync_driver_cb(); …
function void build_phase(uvm_phase phase);
if (!uvm_config_db#(port_wrapper)::get(this, "", "port", port))
`uvm_fatal("build", "A valid port wrapper was not received."); …
//=======================================================================
class cust_agent extends uvm_agent;
`uvm_component_utils(cust_agent)
cust_driver driver;
function void build_phase(uvm_phase phase);
port_wrapper port;
if (!uvm_config_db#(port_wrapper)::get(this, "", "port", port))
`uvm_fatal("build", "A valid port wrapper was not received.");
uvm_config_db#(port_wrapper)::set(this, "driver", "port", port);
driver = cust_driver::type_id::create("driver", this); … |
最后,給出了測試平臺代碼。測試用例可以在不參數化的情況下訪問 VIP,但實例化接口的頂級模塊確實必須實現一些額外的步驟。它不僅必須實例化參數化接口,還必須創建參數化接口訪問器類并將其傳遞給 VIP 實例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//======================================================================= class cust_test extends uvm_test;
`uvm_component_utils(cust_test)
cust_agent agent8;
cust_agent agent16;
cust_agent agent32;
virtual function void build_phase(uvm_phase phase);
agent8 = cust_agent::type_id::create("agent8", this);
agent16 = cust_agent::type_id::create("agent16", this);
agent32 = cust_agent::type_id::create("agent32", this);
endfunction endclass //======================================================================= module test_top;
param_if#(8) if8();
param_if#(16) if16();
param_if#(32) if32();
initial begin
port_wrapper_typed#(virtual param_if#(8)) port_wrapper8;
port_wrapper_typed#(virtual param_if#(16)) port_wrapper16;
port_wrapper_typed#(virtual param_if#(32)) port_wrapper32;
port_wrapper8 = new(if8);
port_wrapper16 = new(if16);
port_wrapper32 = new(if32);
uvm_config_db#(port_wrapper)::set(uvm_root::get(), "uvm_test_top.agent8", "port", port_wrapper8);
uvm_config_db#(port_wrapper)::set(uvm_root::get(), "uvm_test_top.agent16", "port", port_wrapper16);
uvm_config_db#(port_wrapper)::set(uvm_root::get(), "uvm_test_top.agent32", "port", port_wrapper32);
run_test("cust_test");
end endmodule |
如您所見,此解決方案確實解決了參數化接口的使用模型問題。創建正確類型的端口包裝器需要一些額外的代碼,但是測試平臺編寫者可以訪問使用不同專用接口的代理,而無需知道這些接口是如何專用的。
但是,此解決方案對 VIP 如何使用虛擬接口施加了嚴格的限制。驅動程序和監視器類不能直接與接互,而必須將這些訪問推遲到強類型包裝類。通過將驅動程序和監視器類的大部分功能移動到強類型包裝類,可以抵消這種生產力損失;然而,這種更復雜的結構可能會令人困惑且不太靈活。上面的代碼段僅顯示了驅動程序類可能需要的幾個訪問方法,但在實際環境中,此列表可能會增長許多倍,并且監視器類也需要完整的訪問器方法。
經過反思,處理參數化接口的蠻力方法和特洛伊木馬方法都不是理想的。使用前一種方法,向類添加參數會使 VIP 的使用模型復雜化。在后面的方法中,必須提前規劃端口包裝類支持的訪問方法,并且對虛擬接口的 VIP 訪問受到限制。如果 VIP 代碼可以在不實際使用參數化接口的情況下啟用類似于參數化接口的功能,該怎么辦?
審核編輯:郭婷
-
接口
+關注
關注
33文章
8580瀏覽量
151044 -
監視器
+關注
關注
1文章
780瀏覽量
33130 -
Verilog
+關注
關注
28文章
1351瀏覽量
110078
發布評論請先 登錄
相關推薦
評論