Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I prefer to write testbench and tests as top-level modules so I can compile all of them and elaborate/optimize the testbench and test that I need to run. However, I am not sure how I can pass the instance of the interface in the testbench to the test. In the example below dut_tb is the top-level testbech and dut_tb_intf is the interface instantiated in the testbench. The test dut_tb_test uses functions in the interface that I can reference using the complete path but was wondering if I could pass the interface instance in dut_tb to the test or a better way to do this.

Please see the example below.

module dut(input data, input clk, input rst_n, output logic inv_data);
  logic inv_data_d;
  assign inv_data_d = ~data;

  always_ff @(posedge clk or negedge rst_n)
      if (~rst_n)
        inv_data <= '0;
      else
        inv_data <= inv_data_d;
endmodule

package dut_tb_pkg;
logic clk;
logic rst_n;
logic data;
logic inv_data;
endpackage

module dut_tb();

  import dut_tb_pkg::*;

  dut_tb_intf dut_tb_intf();

  //logic data;
  //logic inv_data;

  assign data = dut_tb_intf.data_i;
  assign dut_tb_intf.data_inv = inv_data;
  assign clk = dut_tb_intf.aclk;

  initial
    begin
       rst_n = '0;
       @(posedge clk);
       rst_n = '1;
    end

  dut dut (.clk (clk), .rst_n(rst_n), .data (data), .inv_data(inv_data));

endmodule

//module dut_tb_test( dut_tb.dut_tb_intf intf_inst); // DOES NOT WORK**
module dut_tb_test();

  import dut_tb_pkg::*;

  logic in, out;

  initial 
    begin
    @(posedge clk);
     #30;
    @(posedge clk);
     in = 1'b0;
     dut_tb.dut_tb_intf.inv_data (in, out);

     //intf_inst.inv_data (in, out); // DOES NOT WORK**

   end  
  initial 
    begin
    @(posedge clk);
    @(posedge clk);
     $display ("INFO_0: in is %b and out is %b
", in, out);
     #300;
     $display ("INFO_1: in is %b and out is %b
", in, out);
     #100;
     $finish;
    end

endmodule

interface dut_tb_intf; 

logic aclk; 
logic data_i;
logic data_inv;

   initial
     begin
        aclk = '0;
        forever #5 aclk = ~aclk;
     end

task inv_data(input i, output logic d);

 data_i = i;;
 @(posedge aclk);
 @(posedge aclk);
 d = data_inv;

endtask

modport utils (import inv_data);

endinterface
question from:https://stackoverflow.com/questions/65855825/if-the-testbench-and-test-are-top-modules-how-to-pass-the-instance-of-the-interf

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
809 views
Welcome To Ask or Share your Answers For Others

1 Answer

In your approach you can not pass interface between two modules. Interfaces are passed to modules through instantiation ports. In classical verilog approach you need to have yet another top module to instantiate all of it:

module tb(MyInterface i);
...
endmodule 

module test(MyInteface i);
...
endmodule

interface MyInterface;
...
endinterface

module top();
   MyInterface myIntf;
   tb tb(myIntf);
   test test(myIntf);
endmodule

It is possible to go a bit ugly and instantiate your interface inside tb and pass it to the test as the following

module top();
    tb tb();
    test test (tb.myIntf);
endmodule

The other approach is to instantiate your test within the testbench. This will save you all the above trouble and you can naturally pass the interface to it:

module test...

module tb();
   MyInterface myIf;
   test test(myIf);
   ...
endmodule

Or even better, in system verilog you can design your test as a class and pass virtual interfaces around.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...