Moberg
Moberg

Reputation: 5493

Input a reference to another module in a module instantiation? (SystemVerilog)

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

Answers (1)

dave_59
dave_59

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

Related Questions