[英]SystemVerilog macro through task
How to send macros as parameters through a task?如何通过任务将宏作为参数发送?
In the testbench:在测试台中:
`define CPU1 tb.top.dual_processor_db_wrapper_i.dual_processor_db_i.cpu1.inst
`define CPU2 tb.top.dual_processor2_db_wrapper_i.dual_processor2_db_i.cpu2.inst
initial begin
fork
cpu_init(`CPU1);
cpu_init(`CPU2);
join
// Other stuff with `CPU1 and `CPU2
`CPU1.write_data(addr, 4, data, resp); // Works
end
task cpu_init(cpu);
cpu.por_srstb_reset(1'b1); // Does not work
// Other init stuff
endtask
Error when compiling:编译时出错:
ERROR: [VRFC 10-2991] 'por_srstb_reset' is not declared under prefix 'cpu'错误:[VRFC 10-2991] 'por_srstb_reset' 未在前缀 'cpu' 下声明
The type of the `CPUs is unknown (to me). `CPU 的类型(对我来说)是未知的。 Perhaps Xilinx has a type for it, since it references their MPSoC VIP?也许 Xilinx 有它的类型,因为它引用了他们的 MPSoC VIP?
I assume por_srstb_reset
and write_data
are tasks or functions from Xilinx MPSoC VIP, but I'm not sure.我假设por_srstb_reset
和write_data
是 Xilinx MPSoC VIP 的任务或函数,但我不确定。
I general, it is possible to pass a macro as an argument to a task
.我一般来说,可以将宏作为参数传递给task
。 However, it is not possible to pass a hierarchical reference as an argument to a task
(it is illegal).但是,不可能将层次结构引用作为参数传递给task
(这是非法的)。
Operations on hierarchical references are very limited, in general.通常,对层次引用的操作非常有限。
Your task
declaration is equivalent to the following:您的task
声明等同于以下内容:
task cpu_init (input logic cpu);
The cpu
variable is a 1-bit type. cpu
变量是 1 位类型。 So, the following is legal:所以,以下是合法的:
`define CPU1 1'b1
cpu_init(`CPU1);
The type of the argument must match between the declaration and the task call.参数的类型必须在声明和任务调用之间匹配。
There is another approach to this problem by using bind
and abstract/concrete classes通过使用bind
和抽象/具体类,还有另一种解决此问题的方法
package pkg;
interface class abstract_init;
pure virtual task init; // prototype for each method you need
endclass
abstract_init lookup[string]; // database of concrete classes for each instance
endpackage
module bind_module #(string lookup_name);
import pkg::*;
class concrete_init implements abstract_init;
function new;
lookup[lookup_name] = this; // register this instance
endfunction
virtual task init;
processor.reset(); // upwards reference
endtask
endclass
concrete_init c = new; // each instance of this module gets registered in lookup
endmodule
`define cpu1 top.dut.cpu1
`define cpu2 top.dut.cpu2
// macro turns any argument into a quoted string
`define Q(arg) `"arg`"
module top;
dut dut();
bind `cpu1 bind_module #(.lookup_name(`Q(`cpu1))) b();
bind `cpu2 bind_module #(.lookup_name(`Q(`cpu2))) b();
initial fork
pkg::lookup[`Q(`cpu1)].init;
pkg::lookup[`Q(`cpu2)].init;
join
endmodule
module dut;
processor cpu1();
processor cpu2();
endmodule
module processor;
initial $display("Starting %m");
task reset;
#1 $display("executing reset on %m");
endtask
endmodule
This is described more detail in my DVCon paper: The Missing Link: The Testbench to DUT Connection .这在我的 DVCon 论文中有更详细的描述: 缺失的链接:测试台到 DUT 的连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.