分层调用任务而不定义

时间:2016-02-26 19:59:29

标签: system-verilog uvm

我在我的层次结构深处实例化了供应商提供的BFM模块;让我们调用路径top.dut.u1.u2.bfm1。 BFM的API对我们的需求来说有点陈旧和混乱。我想写一个“对象”(类?接口?还有什么?),它将为任务提供一个更简单的调用接口,并且可以调用已经“链接”的特定BFM的任务。这是我无法弄清楚的“联系”。

我有一个简单的版本定义为模块,它使用`define来指定BFM的路径,类似于:

`define BFM top.dut.u1.u2.bfm1
module bfm_wrapper;
  ...
  task read_burst(...);
    ...
    `BFM.read_burst(...);
  endtask;
  ...
endmodule

显然这不是非常可重复使用的。如何用更便携或抽象的东西替换`BFM到更高的级别?

我是SystemVerilog的相对新手,我甚至还没有使用UVM,但如果有什么东西可以帮助的话,我会采取行动。任何帮助表示赞赏。

[更新] 我没有提及的一些限制:

  1. 我无法更改或替换供应商提供的BFM。我宁愿甚至不包装它(即,在我的包装器中实例化它)。
  2. 由于我不想进入这里的原因,需要在DUT内实例化BFM。改变这一点需要比现在投入更多的努力。

2 个答案:

答案 0 :(得分:0)

与抽象接口绑定将帮助您建立与BFM的连接。看看我的两篇DVCon论文

http://www.doulos.com/downloads/events/DVCon_08_abstractBFM_final.pdf

http://events.dvcon.org/2012/proceedings/papers/01P_3.pdf

[UPDATE]

package bfm_pkg;
interface class bfm_api;
   pure virtual task read_burst(...);
endclass
endpackage

module bfm_wrapper;
 import bfm_pkg::*;
  ...
  class wrapper extends bfm_api;
  task read_burst(...);
    `BFM.read_burst(...);
  endtask;
  endclass
  wrapper h = new();
endmodule

然后从你的课程开始,你可以写

import bfm_pkg;:*;
class someclass
  bfm_api h;
  task foo;
   ...
   h.read_burst(...);
  endtask
endclass

现在你只需要将bfm_wrapper中的h句柄移到对象foo中的h。如果你正在使用UVM,那么uvm_config_db会在这里提供帮助,否则你需要创建自己的机制来复制句柄h。

答案 1 :(得分:0)

最终答案(首先由@toolic和@Greg建议,后来由@ dave_59提出)是使用bind动态地将包装器放在可以找到供应商BFM的地方"向上名称引用&#34 34; (具体来说,将包装器放在供应商BFM中)。所以我上面的代码看起来像是:

`define BFM top.dut.u1.u2.bfm1
module top;
  ...
  // Instantiate my wrapper code inside of the vendor's BFM
  bind `BFM bfm_wrapper my_bfm();

  // BFM commands go here
  initial begin
    wait (`BFM.reset === 0) @(posedge `BFM.clk);
    `BFM.my_bfm.my_read_burst(...);
    ...
  end
endmodule

module bfm_wrapper;
  ...
  task my_read_burst(...);
    ...
    read_burst(...);
  endtask;
  ...
endmodule

如果有任何错别字,我道歉。我的代码并没有完全像这样。

请注意,我并没有完全摆脱define。这可能需要@ dave_59论文中更优雅的技巧。但我至少把它从代码的可重用部分中移除了,现在已经足够好了。