user3383729
user3383729

Reputation: 27

virtual interface in system verilog also dynamic array cannot be used inside VI

1) Can someone please explain the concept of using virtual interface in SystemVerilog.

Even though in the LRM and other sites mention it can be used to drive the different instances of physical interface etc and since class is dynamic and DUT is static we need virtual interfaces.

But I am still not clear with this concept. Please explain me in simple way why we use virtual interfaces.

2) Can we use dynamic array inside the interface, why not? If not what is the alternative?

Upvotes: 2

Views: 6675

Answers (3)

Greg
Greg

Reputation: 19104

The virtual keyword is borrowed from C/C++. A virtual interface is a special type that links HDL (hardware descriptive language) and OOP (object oriented programming).

Quoting IEEE Std 1800-2012 § 25.9 Virtual interfaces:

Virtual interfaces provide a mechanism for separating abstract models and test programs from the actual signals that make up the design. A virtual interface allows the same subprogram to operate on different portions of a design and to dynamically control the set of signals associated with the subprogram. Instead of referring to the actual set of signals directly, users are able to manipulate a set of virtual signals. Changes to the underlying design do not require the code using virtual interfaces to be rewritten. By abstracting the connectivity and functionality of a set of blocks, virtual interfaces promote code reuse.

Dynamic arrays can exist inside an interface, the only side effect of doing so is it is no longer synthesizable. Interfaces that are intended to be synthesized must follow the same requirements of other synthesizable components. When the interface in not part of the design (for example acting ac the stimulus driver for a test bench) dynamic types can exist within the interface.

All about interface in IEEE Std 1800-2012 § 25 Interfaces

Example below and a runnable version here:

interface my_if();
  logic [15:0] data;
  int payload[];
endinterface : my_if

module my_dut(my_if pif);
  initial $monitor("%0t @ %m.pif :: data:%h payload:%p", $time, pif.data, pif.payload);
endmodule : my_dut

module testbench;
  class MyClass;
    virtual my_if vif;
    function new(virtual my_if vif);
      this.vif = vif;
    endfunction : new
    function void init(int size=4);
      vif.payload = new [size];
      for(int i=0; i<size; i++)
        vif.payload[i] = i;
    endfunction : init
    task send_payload();
      for(int i=0; i<vif.payload.size; i++)
        #10ns vif.data <= vif.payload[i];
    endtask : send_payload
  endclass : MyClass

  my_if pif();
  my_dut dut(pif);
  MyClass myc;

  initial begin
    myc = new(pif);
    #10ns myc.init();
    #10ns pif.payload.rsort();
    #10ns myc.send_payload();
    #10ns $finish();
  end
endmodule : testbench

Upvotes: 1

Tudor Timi
Tudor Timi

Reputation: 7573

1) Think of a virtual interface as a pointer to an actual instance of said interface.

2) An interface models a bundle of signals. It has no physical meaning to declare a dynamic array of signals. Think of it this way: a device has a fixed list of ports, none are created after it was built. If you want to declare an interface for a class of devices that have a variable number of signals, you need to use a parameter:

interface some_interface;
  parameter int WIDTH = 10;
  logic some_signals[WIDTH];
endinterface

module top;
  // instantiate an interface with 50 signals
  some_interface #(50) my_if();
  // the signals can then be referenced with
  //   my_if.some_signals[0]
  //   my_if.some_signals[1]
  //   ...
  //   my_if.some_signals[49]
endmodule

EDIT: As Greg mentioned, it is allowed to declare dynamic arrays in interfaces, but it won't be synthesizable.

Upvotes: 1

dave_59
dave_59

Reputation: 42673

Some good answers so far, but there seems to be some confusion in the use of the word dynamic and its relationship to a virtual interface.

First there are dynamic-ally sized types like arrays, strings, and queues. These are generic datatypes that are usually not synthesizable. but they could be if vendors were motivated enough. These types may be declared inside a module, interface, or class, but are not really relevant to the discussion of interfaces and virtual interfaces.

Then there are dynamically constructed class objects. Class objects are constructed by executing procedural code at run time, instead of statically elaborating them at compile time. Static elaboration also takes care of the port connections between modules by flattening out the hierarchy and creating direct reference to the signals connected by the ports. You can't do that with classes, so you need another mechanism besides port connections to communicate outside of the class object.

A simple solution is to use hierarchical references - just reach into the DUT with the hierarchical path you want to read or write. However this solution quickly becomes unworkable for a number of reasons. It is bad for re-usability. Whenever the hierarchy of your DUT changes, or you try to move from block level to SOC verification, you have to update the path in your testbench class. Many people try to manage this by using text macros like

`define PATH top.design.block1

and then the write `PATH.sig1 <= 1; in their 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. It works very similar to an abstract class reference without inheritance. A virtual interface variable can dynamically accept a handle to an actual interface instance. Then you can then dynamically reference members of that interface instance.

Upvotes: 3

Related Questions