常用的派生自uvm_component的类
与uvm_object相比,派生自uvm_component
的类比较少。
uvm_driver:所有的driver都要派生自uvm_driver。driver的功能主要就是向sequencer索要sequence_item(transaction)
,并且将sequence_item里的信息驱动到DUT的端口上,这相当于完成了从transaction级别到DUT能够接受的端口级别信息的转换。与uvm_component相比,uvm_driver多了如下几个成员变量:
来源:UVM源代码
uvm_seq_item_pull_port #(REQ, RSP) seq_item_port;
uvm_seq_item_pull_port #(REQ, RSP) seq_item_prod_if; // alias
uvm_analysis_port #(RSP) rsp_port;
REQ req;
RSP rsp;
在函数/任务上,uvm_driver并没有做过多的扩展。
uvm_monitor:所有的monitor都要派生自uvm_monitor。monitor做的事情与driver相反,driver向DUT的pin上发送数据,而monitor则是从DUT的pin上接收数据,并且把接收到的数据转换成transaction级别的sequence_item,再把转换后的数据发送给scoreboard,供其比较。与uvm_component相比,uvm_monitor几乎没有做任何扩充。uvm_monitor的定义如下:
来源:UVM源代码
virtual class uvm_monitor extends uvm_component;
…
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
const static string type_name = "uvm_monitor";
virtual function string get_type_name ();
return type_name;
endfunction
endclass
虽然从理论上来说所有的monitor要从uvm_monitor派生。但是实际上如果从uvm_ component派生,也没有任何问题。
uvm_sequencer:所有的sequencer都要派生自uvm_sequencer。sequencer的功能就是组织管理sequence,当driver要求数据时,它就把sequence生成的sequence_item转发给driver。与uvm_component相比,uvm_sequencer做了相当多的扩展。
uvm_scoreboard:一般的scoreboard都要派生自uvm_scoreboard。scoreboard的功能就是比较reference model和monitor分别发送来的数据,根据比较结果判断DUT是否正确工作。与uvm_monitor类似,uvm_scoreboard也几乎没有在uvm_component的基础上做扩展:
来源:UVM源代码
virtual class uvm_scoreboard extends uvm_component;
…
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
const static string type_name = "uvm_scoreboard";
virtual function string get_type_name ();
return type_name;
endfunction
endclass
所以,当定义自己的scoreboard时,可以直接从uvm_component派生。
reference model:UVM中并没有针对reference model定义一个类。所以通常来说,reference model都是直接派生自uvm_component。reference model的作用就是模仿DUT,完成与DUT相同的功能。DUT是用Verilog写成的时序电路,而reference model则可以直接使用SystemVerilog高级语言的特性,同时还可以通过DPI等接口调用其他语言来完成与DUT相同的功能。
uvm_agent:所有的agent要派生自uvm_agent。与前面几个比起来,uvm_agent的作用并不是那么明显。它只是把driver和monitor封装在一起,根据参数值来决定是只实例化monitor还是要同时实例化driver和monitor。agent的使用主要是从可重用性的角度来考虑的。如果在做验证平台时不考虑可重用性,那么agent其实是可有可无的。与uvm_ component相比,uvm_agent的最大改动在于引入了一个变量is_active:
来源:UVM源代码
virtual class uvm_agent extends uvm_component;
uvm_active_passive_enum is_active = UVM_ACTIVE;
…
function void build_phase(uvm_phase phase);
int active;
super.build_phase(phase);
if(get_config_int("is_active", active)) is_active = uvm_active_passive_
enum' (active);
endfunction
get_config_int
是uvm_config_db#(int)::get
的另一种写法,这种写法最初出现在OVM中。由于is_active是一个枚举变量,从代码可以看出,其两个取值为固定值0或者1。所以在上面的代码中可以以int类型传递给uvm_agent,并针对传递过来的数据做强制类型转换。
uvm_env:所有的env(environment的缩写)要派生自uvm_env。env将验证平台上用到的固定不变的component都封装在一起。这样,当要运行不同的测试用例时,只要在测试用例中实例化此env即可。uvm_env也并没有在uvm_component的基础上做过多扩展:
来源:UVM源代码
virtual class uvm_env extends uvm_component;
…
function new (string name="env", uvm_component parent=null);
super.new(name,parent);
endfunction
const static string type_name = "uvm_env";
virtual function string get_type_name ();
return type_name;
endfunction
endclass
uvm_test:所有的测试用例要派生自uvm_test或其派生类,不同的测试用例之间差异很大,所以从uvm_test派生出来的类各不相同。任何一个派生出的测试用例中,都要实例化env,只有这样,当测试用例在运行的时候,才能把数据正常地发给DUT,并正常地接收DUT的数据。uvm_test也几乎没有做任何扩展:
来源:UVM源代码
virtual class uvm_test extends uvm_component;
…
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction
const static string type_name = "uvm_test";
virtual function string get_type_name ();
return type_name;
endfunction
endclass
酷客网相关文章:
评论前必须登录!
注册