UVM派生自uvm_component的常用类

常用的派生自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_intuvm_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

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!