UVM的树形结构
UVM通过uvm_component来实现树形结构。所有的UVM树的结点本质上都是一个uvm_component。每个uvm_component在new的时候,需要指定一个类型为uvm_component、名字是parent的变量。
UVM树的根
- 如上图所示,UVM中的树根为uvm_top,其为uvm_root的一个实例(也是唯一一个),且uvm_top本质上是一个uvm_component。
- uvm_test_top的parent是uvm_top,而uvm_top的parent为null;如果一个component在实例化的时候parent被设置为null,那么这个component的parent会被设置为系统中唯一的uvm_root的实例uvm_top。
- 一般在test层例化env,在env里例化scoreboard、reference model、agent,在agent里例化sequencer、driver和monitor。
层次结构相关函数
- get_parent函数,用于得到当前实例的parent:
extern virtual function uvm_component get_parent();
- get_child函数,由于一个component可能有多个child,所以需要指定name参数:
extern virtual function uvm_component get_child(string name);
- get_children函数,用于得到所有的child:
extern virtual void get_children(ref uvm_component children[$]);
//还可以使用get_first_child和get_next_child来依次得到所有的child
string name;
uvm_component child;
if(comp.get_first_child(name)
do begin
child = comp.get_child(name);
child.print();
end while(comp.get_next_child(name));
- get_num_children函数,用于返回当前component所拥有的child的数量:
extern function int get_num_children();
uvm_component与uvm_object
下图为UVM中常见类的继承关系:
uvm_component派生自uvm_object,而在uvm_component中,有两大特性是uvm_object不具备的:
(1)通过在new的时候指定parent参数来形成一种树形的组织结构。
(2)有phase的自动执行的特点。
《UVM实战》将二者的关系比喻为:uvm_object是一个分子,用这个分子可以搭建成
各种各样的东西。uvm_component就是由其搭建成的一种高级生命,而sequence_item则是由其搭建成的血液,它流通在各个高级生命(uvm_component)之间,sequence则是众多sequence_item的组合,config则是由其搭建成的用于规范高级生命(uvm_component)行为方式的准则。
派生自uvm_object的类
- uvm_sequence_item:我们定义的transaction就是从uvm_sequence_item派生而来的,之所以不从uvm_transaction派生是因为uvm_sequence_item派生自uvm_transaction,其添加了很多实用的成员变量以及函数任务。
- uvm_sequence:sequence即sequence_item的集合。
- config:config的主要功能即规范验证平台的行为方式。区别于config_db,这里的config其实是将所有的参数放在一个object中,然后通过config_db的方式设置给所有需要这些参数的component。
- uvm_phase:控制uvm_component的行为方式,使得uvm_component在各个不同的phase之间依次运转。
- uvm_reg_item、uvm_reg_map、uvm_mem、uvm_reg_field、uvm_reg、uvm_reg_file、uvm_reg_block等,用于register model。
派生自uvm_component的类
- uvm_driver:向sequencer索要sequence_item(transaction),然后将sequence_item里的信息驱动到DUT端口上。完成从transaction级别到DUT能够接受的端口级别信息的转换。
- uvm_monitor:与driver相反,monitor从DUT上接收数据,并且把接收到的数据转换成transaction级别的sequence_item,再把转换后的数据发送给scoreboard。
- uvm_sequencer:组织管理sequence。
- uvm_scoreboard:比较reference model和monitor分别发来的数据,根据比较结果来判断DUT是否正确工作。
- reference model:模仿DUT,完成与DUT相同的功能。DUT是用verilog写成的时序电路,而reference model则可以直接使用system verilog高级语言的特性。
- uvm_agent:根据is_active参数来决定封装driver、monitor、sequencer还是只封装monitor。
- uvm_env:将验证平台上的固定不变的component都封装在一起。
- uvm_test:任何一个从uvm_test中派生出来的测试用例中,都要例化env,只有这样才能把数据正常地发送给DUT,并正常地接收DUT的数据。
clone及copy函数
- 在uvm_object中有clone函数,用于分配一块内存空间,并把另一个实例复制到这块新的内存空间中。在使用clone函数时,目标实例可以只是一个空指针,但是在使用copy函数前,目标实例必须已经使用new函数分配好了内存空间,即clone = new + copy。
- 虽然uvm_component无法使用clone函数,但是可以使用copy函数,因为在调用copy之前,目标实例已经完成了实例化,其parent参数已经指定了。