Contact / Report an issue

SystemVerilog Virtual Interface

SystemVerilog Interface


In Verilog, the communication between blocks is specified using module ports. SystemVerilog adds the interface construct which encapsulates the communication between blocks. An interface is a bundle of signals or nets through which a testbench communicates with a design. A virtual interface is a variable that represents an interface instance. this section describes the interface, interface over traditional method and virtual interface.

Interface Construct


The interface construct is used to connect the design and testbench.

Interface
without Interface
Above diagram shows connecting design and testbench without interface.

SystemVerilog Interface
SystemVerilog Interface
Above diagram shows connecting design and testbench with the interface.

  • An interface is a named bundle of wires, the interfaces aim is to encapsulate communication.
  • Also specifies the,
    • directional information, i.e modports
    • timing information, i.e clocking blocks
  • An interface can have parameters, constants, variables, functions, and tasks.
      modports and clocking blocks are explained in later chapters.
  • A simple interface declaration is,
              interface interface_name;
                ...
                interface_items
                ...
              endinterface
  • An interface can be instantiated hierarchically like a module, with or without ports.
              interface_name inst_name;

  • An interface can have parameters, constants, variables, functions, and tasks.

Advantages of the interface over the traditional connection,



  • allows the number of signals to be grouped together and represented as a single port, the single port handle is passed instead of multiple signal/ports.
  • interface declaration is made once and the handle is passed across the modules/components.
  • addition and deletion of signals are easy.

Connecting testbench and design without interface construct,


In the example below,

  • Testbench has a design instance and testcase instance, both are connected through wires.
  • Inside Testcase, the environment is created and signals are passed to below hierarchy (To drive/sample the stimulus).
  • env again passes signals down the hierarchy, and it goes on.
  • For any addition or deletion of signal/signals, it is required to add/delete in many places. This problem can be overcome by using an interface construct


//-------------------------------------------------------------------------
// Verilog Design
//-------------------------------------------------------------------------
module memory ( clk, addr, wr_rd, wdata, rdata);
  input        clk;
  input  [7:0] addr;
  input        wr_rd;
  input  [7:0] wdata;
  output [7:0] rdata;
  ……
endmodule

//-------------------------------------------------------------------------
// TestCase
//-------------------------------------------------------------------------
program testcase ( input bit clk, bit [7:0] addr,bit wr_rd,bit [7:0] wdata,output bit [7:0] rdata);
  environment env; //declaring environment
  initial begin
    env = new(clk, addr, wr_rd, wdata, rdata);
  end
  ……
endprogram

//-------------------------------------------------------------------------
// TestBench Top
//-------------------------------------------------------------------------
module tbench_top;
  //wire declaration
  wire       clk;
  wire [7:0] w_addr;
  wire       w_wr_rd;
  wire [7:0] w_wdata;
  wire [7:0] w_rdata;

  //DUT(Design Under Test) instance
  memory dut(
      .clk(clk),
      .addr(w_addr),
      .wr_rd(w_wr_rd),
      .wdata(w_wdata),
      .rdata(r_data)
      );

  //TestCase Instance
  testcase test(
      .clk(clk),
      .addr(w_addr),
      .wr_rd(w_wr_rd),
      .wdata(w_wdata),
      .rdata(r_data)
  );
 ……
endmodule




Connecting testbench and design with interface construct,


In the below example,
  • The interface will group the signals, the handle of an interface is passed across the hierarchy
  • Changes made to interface will reflect everywhere

//-------------------------------------------------------------------------
// Verilog Design
//-------------------------------------------------------------------------
module memory ( clk, addr, wr_rd, wdata, rdata);
  input        clk;
  input  [7:0] addr;
  input        wr_rd;
  input  [7:0] wdata;
  output [7:0] rdata;
endmodule

//-------------------------------------------------------------------------
// Interface
//-------------------------------------------------------------------------
interface mem_intf;
  logic      clk;
  logic [7:0] addr;
  logic       wr_rd;
  logic [7:0] wdata;
  logic [7:0] rdata;
endinterface

//-------------------------------------------------------------------------
// TestCase
//-------------------------------------------------------------------------
program testcase (interface  intf);
  environment env;
  initial begin
    env = new(intf);
  end
  ……
endprogram

//-------------------------------------------------------------------------
// TestBench Top
//-------------------------------------------------------------------------
module tbench_top;
  //Interface instance
  mem_intf intf();

  //DUT(Design Under Test) instance
  memory dut(
    .clk(intf.clk),
    .addr(intf.addr),
    .wr_rd(intf.wr_rd),
    .wdata(intf.wdata),
    .rdata(intf.rdata)
      );
 
  //TestCase Instance
  testcase test(intf);
  ……
endmodule




Interface example


The below example shows the writing interface, declaration of an interface, connecting the interface with design, and accessing interface signals.

Writing interface


interface intf;
  
  //declaring the signals
  logic [3:0] a;
  logic [3:0] b;
  logic [6:0] c;
  
endinterface

Interface declaration


//creatinng instance of interface
intf i_intf();

Connecting interface with design


//DUT instance
adder DUT (
  .a(i_intf.a),
  .b(i_intf.b),
  .c(i_intf.c)
);

Accessing interface signal


i_intf.a = 6;
i_intf.b = 4;
  
$display("Value of a = %0d, b = %0d",i_intf.a,i_intf.b);
#5;
$display("Sum of a and b, c = %0d",i_intf.c);

 Simulator Output 

Value of a = 6, b = 4
Sum of a and b, c = 10

Execute the above code on 

Virtual Interface


A virtual interface is a variable that represents an interface instance.

  • The virtual interface must be initialized before using it. i.e, Virtual interface must be connected/pointed to the actual interface.
  • accessing the uninitialized virtual interface result in a run-time fatal error.
  • Virtual interfaces can be declared as class properties, which can be initialized procedural or by an argument to new().
  • Virtual interface variables can be passed as arguments to the tasks, functions, or methods.
  • All the interface variables/Methods can be accessed via a virtual interface handle. i.e virtual_interface.variable

Syntax


virtual interface_name instance_name;

Virtual interface example


virtual mem_intf intf;