3

在我的测试台中,我有一个需要驱动的接口。该接口可以在 2 种不同的模式下驱动,每种模式都有自己的驱动协议和事务类型。

到目前为止,我已经分别设计了两个 uvm_agents。现在,我需要一种方法来交换一个或另一个,这取决于我正在运行的测试用例。我也想以最符合 UVM 理念的方式来做这件事。

我能想到的最好方法是:在我的 uvm_env 中,从测试中获取一个 uvm_db_config 参数,该参数显示“ModeA”或“ModeB”,并在此基础上将代理的 is_active 设置为“UVM_ACTIVE”和“UVM_PASSIVE” ”适当。

我想对这种方法发表意见。

向我建议的一种方法是保留一个通用的 uvm_agent,并根据配置实例化 uvm_driver/uvm_sequencer。不太确定这种方法,因为它看起来很乱。

4

2 回答 2

4

我还建议像 Tudor 一样只使用一种代理。但随后我会使用继承,声明 base_driver 和 base_sequencer(可能具有来自 ModeA 或 ModeB 驱动程序和/或定序器的共同功能),并且 ModeA 和 ModeB 单元将扩展这些基本单元。然后,在代理中,并使用每个测试中设置的 uvm_config_db 中的标志,您可以在实例化一个或另一个之间进行选择:

基础驱动:

class my_proj_base_driver extends uvm_driver#(my_proj_tr);
[...]

A模式驱动:

class my_proj_ModeA_driver extends my_proj_base_driver;
[...]

模式 B 驱动程序:

class my_proj_ModeB_driver extends my_proj_base_driver;
[...]

在代理中:

[...]

my_proj_base_driver driver;
bit modeAorB // 0 for A, 1 for B

[...]

if (!uvm_config_db#(bit)::get(this,"","modeAorB", modeAorB))
  `uvm_fatal("NOMODE","No mode set for this agent")

if(!modeAorB)
  driver = my_proj_ModeA_driver::type_id::create(.name("driver"), .parent(this));
else
  driver = my_proj_ModeB_driver::type_id::create(.name("driver"), .parent(this));

对于音序器也是如此。

于 2014-05-28T08:46:15.630 回答
2

我希望每个模式有一个通用代理类和一个具体类,然后根据我正在运行的测试进行类型覆盖。这样一来,很明显只有一个代理处理该接口(而不是 2 个,其中一个在根本不使用时被设置为被动)。一个代理类实例化一组驱动程序/序列器,另一个代理类实例化其他代理类。这样,您只需设置一种类型覆盖(在代理上)而不是 2(在驱动程序和定序器上)。

如果在两种模式下您都使用同一个监视器,那么最好采用一种代理方法,因为您只需将记分牌连接到一个监视器,而不是代理 A 中的一个或代理 B 中的另一个,具体取决于在模式上。

您的方法也很有效,我认为在这种情况下没有标准的 UVM 方法。我有一位同事为 GPIO 接口做了类似的事情,而且效果很好。

于 2014-05-28T08:09:47.197 回答