51做图片的网站,佛山网站建设企业推荐,网站怎么做文件下载,网址大全2345 下载这?在验证平台中加入monitor时#xff0c;看到driver和monitor之间的联系#xff1a;两者之间的代码高度相似。其本质是因为二者 处理的是同一种协议#xff0c;在同样一套既定的规则下做着不同的事情。由于二者的这种相似性#xff0c;UVM中通常将二者封装在一起#xff0c;… 在验证平台中加入monitor时看到driver和monitor之间的联系两者之间的代码高度相似。其本质是因为二者 处理的是同一种协议在同样一套既定的规则下做着不同的事情。由于二者的这种相似性UVM中通常将二者封装在一起成为 一个agent。因此不同的agent就代表了不同的协议。
class my_agent extends uvm_agent ;my_driver drv;my_monitor mon;function new(string name, uvm_component parent);super.new(name, parent);endfunction extern virtual function void build_phase(uvm_phase phase);extern virtual function void connect_phase(uvm_phase phase);uvm_component_utils(my_agent)
endclass function void my_agent::build_phase(uvm_phase phase);super.build_phase(phase);if (is_active UVM_ACTIVE) begindrv my_driver::type_id::create(drv, this);endmon my_monitor::type_id::create(mon, this);
endfunction function void my_agent::connect_phase(uvm_phase phase);super.connect_phase(phase);
endfunction 所有的agent都要派生自uvm_agent类且其本身是一个component应该使用uvm_component_utils宏来实现factory注册。 这里最令人困惑的可能是build_phase中为何根据is_active这个变量的值来决定是否创建driver的实例。is_active是uvm_agent的一 个成员变量从UVM的源代码中可以找到它的原型如下
uvm_active_passive_enum is_active UVM_ACTIVE; 而uvm_active_passive_enum是一个枚举类型变量其定义为
typedef enum bit { UVM_PASSIVE0, UVM_ACTIVE1 } uvm_active_passive_enum; 这个枚举变量仅有两个值UVM_PASSIVE和UVM_ACTIVE。在uvm_agent中is_active的值默认为UVM_ACTIVE在这种模 式下是需要实例化driver的。那么什么是UVM_PASSIVE模式呢以本章的DUT为例如图2-5所示在输出端口上不需要驱动任 何信号只需要监测信号。在这种情况下端口上是只需要monitor的所以driver可以不用实例化。 在把driver和monitor封装成agent后在env中需要实例化agent而不需要直接实例化driver和monitor了
class my_env extends uvm_env;my_agent i_agt;my_agent o_agt;function new(string name my_env, uvm_component parent);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);i_agt my_agent::type_id::create(i_agt, this);o_agt my_agent::type_id::create(o_agt, this);i_agt.is_active UVM_ACTIVE;o_agt.is_active UVM_PASSIVE;endfunctionuvm_component_utils(my_env)
endclass 完成i_agt和o_agt的声明后在my_env的build_phase中对它们进行实例化后需要指定各自的工作模式是active模式还是passive 模式。现在整棵UVM树变为了如图2-6所示形式。 由于agent的加入driver和monitor的层次结构改变了在top_tb中使用config_db设置virtual my_if时要注意改变路径
initial beginuvm_config_db#(virtual my_if)::set(null, uvm_test_top.i_agt.drv, vif, input_if);uvm_config_db#(virtual my_if)::set(null, uvm_test_top.i_agt.mon, vif, input_if);uvm_config_db#(virtual my_if)::set(null, uvm_test_top.o_agt.mon, vif, output_if);
end 在加入了my_agent后UVM的树形结构越来越清晰。首先只有uvm_component才能作为树的结点像my_transaction这种使 用uvm_object_utils宏实现的类是不能作为UVM树的结点的。其次在my_env的build_phase中创建i_agt和o_agt的实例是在 build_phase中在agent中创建driver和monitor的实例也是在build_phase中。按照前文所述的build_phase的从树根到树叶的执行顺 序可以建立一棵完整的UVM树。UVM要求UVM树最晚在build_phase时段完成如果在build_phase后的某个phase实例化一个 component
class my_env extends uvm_env;…virtual function void build_phase(uvm_phase phase);super.build_phase(phase);endfunctionvirtual task main_phase(uvm_phase phase);i_agt my_agent::type_id::create(i_agt, this);o_agt my_agent::type_id::create(o_agt, this);i_agt.is_active UVM_ACTIVE;o_agt.is_active UVM_PASSIVE;endtask
endclass 如上所示将在my_env的build_phase中的实例化工作移动到main_phase中UVM会给出如下错误提示
UVM_FATAL 0: i_agt [ILLCRT] It is illegal to create a component (i_agt under uvm_test_top) after 那么是不是只能在build_phase中执行实例化的动作呢答案是否定的。其实还可以在new函数中执行实例化的动作。如可以在 my_agent的new函数中实例化driver和monitor
function new(string name, uvm_component parent);super.new(name, parent);if (is_active UVM_ACTIVE) begindrv my_driver::type_id::create(drv, this);endmon my_monitor::type_id::create(mon, this);
endfunction这样引起的一个问题是无法通过直接赋值的方式向uvm_agent传递is_active的值。在my_env的build_phase或者new函数中向i_agt和o_agt的is_active赋值根本不会产生效果。因此i_agt和o_agt都工作在active模式is_active的默认值是UVM_ACTIVE 这与预想差距甚远。要解决这个问题可以在my_agent实例化之前使用config_db语句传递is_active的值
class my_env extends uvm_env;virtual function void build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(uvm_active_passive_enum)::set(this, i_agt, is_active, UVM_ACTIVE);uvm_config_db#(uvm_active_passive_enum)::set(this, o_agt, is_active, UVM_PASSIVE);i_agt my_agent::type_id::create(i_agt, this);o_agt my_agent::type_id::create(o_agt, this);endfunction
endclassclass my_agent extends uvm_agent ;function new(string name, uvm_component parent);super.new(name, parent);uvm_config_db#(uvm_active_passive_enum)::get(this, , is_active, is_active);if (is_active UVM_ACTIVE) begindrv my_driver::type_id::create(drv, this);endmon my_monitor::type_id::create(mon, this);endfunction
endclass只是UVM中约定俗成的还是在build_phase中完成实例化工作。因此强烈建议仅在build_phase中完成实例化。