Reputation: 5493
I have dedicated testbench module for printing/tracing information about the DUT in my testbench. I would like to avoid having to wire all the interesting (internal) signals down into the tb module.
As an example let's say I have an internal signal a
in my DUT. How can I access it in printer.sv
without having to create a matching input? Sketch:
/---- TB.sv -----------------------------------------\
| |
| /--dut.sv--\ /--printer.sv-------------\ |
| | wire a; | -> | always @(posedge clk) | |
| | | | $display("a is %d", a); | |
| \----------/ \-------------------------/ |
| |
\----------------------------------------------------/
I have been looking at the bind
keyword to see if it could help me, but I don't understand it.
The number of signals needed by the printer.vs is large, so I would really like to avoid having to declare everything as inputs, it's very tedious.
Is there some way to pass in a hierarchical reference to the instantiated dut module?
Upvotes: 1
Views: 2128
Reputation: 42616
You can use an upwards reference in the bound printer module.
module DUT(input clk);
wire a;
function void hello;
$display("Hello from %m");
endfunction
endmodule
module printer(input clk);
always @(posedge clk)
$display("a is %d", DUT.a);
initial DUT.hello;
endmodule
module TB;
reg clock;
DUT d1(clock);
DUT d2(clock);
bind DUT printer p(clk);
endmodule
Not that upwards name referencing is a feature of Verilog independent of bind
. The bind feature works exactly as if you had written the instance inside the DUT. It the same reason you can use the top-level module name as the beginning of a reference.
module DUT(input clk);
wire a;
function void hello;
$display("Hello from %m");
endfunction
printer p(clk); // what bind is actually doing
endmodule
module printer(input clk);
always @(posedge clk)
$display("a is %d", DUT.a);
initial DUT.hello;
endmodule
module TB;
reg clock;
DUT d1(clock);
DUT d2(clock);
endmodule
Upvotes: 3