Friday, February 5, 2016

Why we need virtual interface? If I don't want to use it what is an alternate method.

Interface is static entity. We can not use it in dynamic entity like class. So we have a new type called virtual interface. We can bind interface with virtual interface in top module. Virtual interface will be treated like a class handle.

Let me explain.

Classes in system verilog are created at run time. Port connection between modules and creating direct reference to the dut signals are done at elaboration time. We can not do direct connection with DUT signals like that with class because as I said class are created at run time.

We need another mechanism to do that. To do the same thing work at compile and elaboration time we can use hierarchical defines. Like ,
`define PATH top.design.block1
and then the write `PATH.sig1 <= 1; in the testbench. This approach does not work when there are multiple instances of testbench objects that need to communicate multiple paths of the DUT. Another problem is that most classes are written inside SystemVerilog packages, and packages are not supposed to have any outside dependencies other than other package imports. 

So SystemVerilog, which already has dynamic references to class objects, added a dynamic reference to an interface instance and called it a virtual interface.
virtual interface variable can dynamically accept a handle to an actual interface instance. Then you can then dynamically reference members of that interface instance.

Still if you don't like virtual interface, here is another method you can use. :)

To create a class inside interface and use it. How? Let me show



package abstract_pkg;
  virtual class abstract_intf #(int awidth);
    pure virtual function void set_address(
    input logic [awidth-1:0] a);
    pure virtual task posedge_clock;
  endclass
endpackage

interface dut_itf#(int dwidth, awidth);
 logic clock,reset;
 wire [dwidth-1:0] data;
 logic [awidth-1:0] address;
  import abstract_pkg::*;
  class concrete_intf#(int width) extends abstract_intf#(width);
    function void set_address(
      input logic [width-1:0] a);
      address = a;
    endfunction
    task posedge_clock;
      @(posedge clock);
    endtask
  endclass
  concrete_intf#(awidth) c = new();
endinterface

package my_pkg;
 import abstract_pkg::*;
  class driver;
    abstract_intf#(16) c_h;
    task run;
      forever begin
      c_h.posedge_clock;
      c_h.set_address(‘h1234);
      end
    endtask
  endclass
endpackage

module testTop;
  dut_itf #(8,16) i1();
  DUT d1(.itf(i1));
  TEST t1(.itf(i1));
endmodule

module TEST();
  import my_pkg::*;
  driver d;
  initial begin
  d = (new);
  d.c_h = i1.c;
  d.run;
  end
endmodule

Here c_h is class defined in interface, which we used in driver and from it we can toggle or use interface signal. 

No comments:

Post a Comment