Interface and Virtual Interface

 Interface Construct 


Interface construct are used to connect the design and testbench.

Connecting TestBench and DUT without Interface

Connecting TestBench and DUT with Interface

  • An interface is a named bundle of wires, aim of the interfaces 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;

  • Interface can have parameters, constants, variables, functions and tasks.

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

 Connecting testbench and design without interface construct, 


In the example below, testbench has design instance and testcase instance, both are connected through wires.
Inside Testcase, environment is created and  signals are passed to below hierarchy in order to drive/sample the stimulus, and it passing the signals down the hierarchy goes on.
For any addition or deletion of signal/signals need to add/delete in many places, This problem can be overcome by using 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, 


Interface will group the signals, handle to the 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

 Virtual Interface 


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

Syntax:
virtual interface_name instance_name;

example:
virtual mem_intf intf;

  • 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 virtual interface handle. i.e virtual_interface.variable