我在我的层次结构深处实例化了供应商提供的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,但如果有什么东西可以帮助的话,我会采取行动。任何帮助表示赞赏。
[更新] 我没有提及的一些限制:
答案 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论文中更优雅的技巧。但我至少把它从代码的可重用部分中移除了,现在已经足够好了。