在本文中,我們將進一步實現(xiàn)monitor和coverage collector components,以便在仿真期間收集功能覆蓋信息。
實現(xiàn)monitor
為了在驗證環(huán)境中進行檢查或覆蓋率收集,我們首先需要完成monitor的實現(xiàn)。與前文driver代碼的生成實現(xiàn)類似,我們使用template files指示uvm代碼生成器包含我們的任務。
Filename include/clkndata_do_mon.sv
task clkndata_monitor::do_mon();
forever @(posedge vif.clk)
begin
m_trans = data_tx::create("m_trans");
m_trans.data = vif.data;
analysis_port.write(m_trans);
end
endtask
和driver一樣,任務的命名需要以agent接口為前綴。do_mon任務應monitor DUT 接口,然后組裝成一個事務m_trans,最后通過analysis_port發(fā)送出去。
Filename clkndata.tpl ... driver_inc = clkndata_do_drive.sv monitor_inc = clkndata_do_mon.sv ...
實現(xiàn)Covergroup
uvm代碼生成器將生成一個subscriber component,該組件連接到monitor的analysis_port。默認情況下,此subscriber將使用covergroup對任何接收到的事務值進行采樣。自動生成的代碼如下所示:
Filename clkndata_coverage.sv class clkndata_coverage extends uvm_subscriber #(data_tx); `uvm_component_utils(clkndata_coverage) bit m_is_covered; data_tx m_item; covergroup m_cov; option.per_instance = 1; cp_data: coverpoint m_item.data; endgroup extern function new(string name, uvm_component_parent); extern function void write(input data_tx t); endclass function clkndata_coverage::new(string name, uvm_component_parent); super.new(name, parent); m_is_covered = 0; m_cov = new; endfunction function void clkndata_coverage::write(input data_tx t); m_item = t; m_cov.sample(); if (m_cov.get_inst_coverage() >= 100) m_is_covered = 1; endfunction ...
為了完成覆蓋模型,可以在include文件中提供一組用戶定義的coverpoints,例如:
Filename include/clkndata_cover_inc.sv
covergroup m_cov;
option.per_instance = 1;
cp_data: coverpoint m_item.data {
bins zero = {0};
bins one = {1};
bins negative = { [-128:-1] };
bins positive = { [1:127] };
option.at_least = 16;
}
endgroup
同樣,必須使用正確的命名約定。文件名前綴為agent interface,必須將covergroup 命名為 m_cov,并且引用輸入事務的變量名稱必須為m_item。
Filename clkndata.tpl ... driver_inc = clkndata_do_drive.sv monitor_inc = clkndata_do_mon.sv agent_cover_inc = clkndata_cover_inc.sv ...
生成的subscriber component現(xiàn)在包括剛剛提供的covergroup:
Filename clkndata_coverage.sv class clkndata_coverage extends uvm_subscriber #(data_tx); ... data_tx m_item; `include "clkndata_cover_inc.sv" ... extern function void write(input data_tx t); ... endclass
進一步擴展生成的代碼
上述文件 clkndata_cover_inc.sv 僅包含一個covergroup。生成的代碼實例化該covergroup,并包含一個用于對covergroup進行sample的write方法。但是,如果你需要subscriber 采取除samplecovergroup之外或而不是采樣的其他操作怎么辦?答案是,不僅可以include covergroup,還可以從一組include文件中提取類的所有內(nèi)容。如果要自己提供 new 和 write 方法,則還需要禁止自動生成它們。為此,你需要更改 interface template file,如下所示:
Filename clkndata.tpl ... #agent_cover_inc = clkndata_cover_inc.sv agent_cover_inc_inside_class = clkndata_cover_inc_inside.sv agent_cover_inc_after_class = clkndata_cover_inc_after.sv agent_cover_generate_methods_inside_class = no agent_cover_generate_methods_after_class = no ...
生成的subscriber 組件現(xiàn)在如下所示:
classclkndata_coverageextendsuvm_subscriber#(data_tx); `uvm_component(clkndata_coverage) `include"clkndata_cover_inc_inside.sv" endclass `include "clkndata_cover_inc_after.sv"
然后,可以提供以下兩個include文件:
Filename include/clkndata_cover_inc_inside.sv
covergroup m_cov;
option.per_instance = 1;
cp_data: coverpoint m_item.data {
bins zero = {0};
bins one = {1};
bins negative = { [-128:-1] };
bins positive = { [1:127] };
option.at_least = 16;
}
endgroup
extern function new(string name, uvm_component_parent);
extern function void write(input data_tx t);
Filename include/clkndata_cover_inc_after.sv
function clkndata_coverage::new(string name, uvm_component_parent);
super.new(name, parent);
m_cov = new;
endfunction
function void clkndata_coverage::write(input data_tx t);
m_item = t;
m_cov.sample();
endfunction: write
你現(xiàn)在可以靈活地在這兩個include文件中提供任何代碼。你可以讓用戶定義的代碼插入到生成的代碼中,而不是代碼生成器寫出 'include 指令,如下所示:
Filename clkndata.tpl ... agent_cover_inc_inside_class = clkndata_cover_inc_inside.sv inline agent_cover_inc_after_class = clkndata_cover_inc_after.sv inline ...
Override a Sequence
正如我們在前面的文章中看到的,生成的代碼包含一個top-level virtual sequence:
文件名 top_seq_lib.sv
Filename top_seq_lib.sv
...
task top_default_seq::body();
super.body();
...
clkndata_default_seq seq;
seq = clkndata_default_seq::create("seq");
seq.randomize();
seq.start(m_clkndata_agent.m_sequencer, this);
endtask
...
可以通過擴展創(chuàng)建和啟動的任何default sequence,例如
Filename my_clkndata_seq.sv
class my_clkndata_seq extends clkndata_default_seq;
...
task body();
...
for (int i = 0; i < 16; i++)
begin
req = data_tx::create("req");
start_item(req);
if ( !req.randomize() with { data == i; })
...
finish_item(req);
end
endtask
endclass
然后,需要在interface template file中標識該文件,并將用戶定義的sequence作為default sequence:
Filename clkndata.tpl ... agent_cover_inc = clkndata_cover_inc.sv agent_seq_inc = myclkndata_seq.sv agent_factory_set = clkndata_default_seq my_clkndata_seq
然后,uvm代碼生成器會使用工廠機制覆蓋整個default sequence:
Filenametop_test.sv function void top_test::build_phase(uvm_phase phase); ... clkndata_default_seq::get_type()); ... endfunction
審核編輯:劉清
-
UVM
+關注
關注
0文章
183瀏覽量
19892 -
生成器
+關注
關注
7文章
322瀏覽量
22440 -
DUT
+關注
關注
0文章
192瀏覽量
13308
原文標題:Easier UVM Code Generator Part 2:添加用戶定義的代碼
文章出處:【微信號:芯片驗證工程師,微信公眾號:芯片驗證工程師】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
Companion Transport Layer RTL Code Generator Tool
Code Generator Tool 用戶手冊 RX API Reference Rev.1.00
e2 studio Code Generator 集成開發(fā)環(huán)境 用戶手冊:RL78 API Reference
CS+ Code Generator Tool 集成開發(fā)環(huán)境 用戶手冊: Pin View Rev.1.10
e2 studio Code Generator 用戶手冊: RX API Reference
[e2studio] Renesas Starter Kit for RX130 Code Generator Tutorial 手冊
Easier UVM Code Generator Part 1: 運行仿真
Easier UVM Code Generator Part 4:生成層次化的驗證環(huán)境
Code Generator Tool 用戶手冊 RX API Reference Rev.1.00
e2 studio Code Generator 集成開發(fā)環(huán)境 用戶手冊:RL78 API Reference
CS+ Code Generator Tool 集成開發(fā)環(huán)境 用戶手冊: Pin View Rev.1.10
e2 studio Code Generator 用戶手冊: RX API Reference
[e2studio] Renesas Starter Kit for RX130 Code Generator Tutorial 手冊
[e2studio] Renesas Starter Kit for RX23T Code Generator Tutorial 手冊
[e2studio] Renesas Starter Kit+ for RX64M Code Generator Tutorial 手冊

Easier UVM Code Generator Part 2:添加用戶定義的代碼
評論