Wednesday, February 11, 2015

SystemVerilog Interface

SystemVerilog Interfaces

Interfaces are created to encapsulate the communication between blocks, allowing a smooth refinement from abstract system-level through successive steps down to lower RTL and structural levels of the design. Interfaces also facilitate design re-use. Interfaces are hierarchical structures that can contain other interfaces.

advantages:
  • They encapsulate connectivity: an interface can be passed as a single item through a port, thus replacing a group of names by a single one. This reduces the amount of code needed to model port connections and improves its maintainability as well as readability.
  • They encapsulate functionality, isolated from the modules that are connected via the interface. So, the level of abstraction and the granularity of the communication protocol can be refined totally independent of the modules. 
  • They can contain parameters, constants, variables, functions and tasks, processes and continuous assignments, useful for both system-level modelling and testbench applications. 
  • They can help build applications such as functional coverage recording and reporting, protocol checking and assertions.
  • They can be used for port-less access: An interface can be instantiated directly as a static data object within a module. So, the methods used to access internal state information about the interface may be called from different points in the design to share information.
  • Flexibility: An interface may be parameterised in the same way as a module. Also, a module header can be created with an unspecified interface instantiation, called a Generic Interface. This interface can be specified later on, when the module is instantiated.
At its simplest, an interface is a named bundle of wires, similar to a struct, except that an interface is allowed as a module port, while a struct is not.
// Interface definition
interface Bus;
  logic [7:0] Addr, Data;
  logic RWn;
endinterface

// Using the interface
module TestRAM;
  Bus TheBus();                   // Instance the interface
  logic[7:0] mem[0:7];
  RAM TheRAM (.MemBus(TheBus));   // Connect it

  initial
  begin
    TheBus.RWn = 0;               // Drive and monitor the bus
    TheBus.Addr = 0;
    for (int I=0; I<7; I++)
      TheBus.Addr = TheBus.Addr + 1;
    TheBus.RWn = 1;
    TheBus.Data  = mem[0];
  end
endmodule

module RAM (Bus MemBus);
  logic [7:0] mem[0:255];

  always @*
    if (MemBus.RWn)
      MemBus.Data = mem[MemBus.Addr];
    else
      mem[MemBus.Addr] = MemBus.Data;
endmodule

Modports in Interfaces

A new construct related to Interface is also added: Modport. This provides direction information for module interface ports and controls the use of tasks and functions within certain modules. The directions of ports are those seen from the module.
This example includes modports, which are used to specify the direction of the signals in the interface. The directions are the ones seen from the module to which the modport is connected, in our case the RAM:
interface MSBus (input Clk);
  logic [7:0] Addr, Data;
  logic RWn;
  modport Slave (input Addr, inout Data);
endinterface

module TestRAM;
  logic Clk;
  MSBus TheBus(.Clk(Clk));
  RAM TheRAM (.MemBus(TheBus.Slave));
  ...
endmodule

module RAM (MSBus.Slave MemBus);
  // MemBus.Addr is an input of RAM
endmodule
http://www.doulos.com/knowhow/sysverilog/tutorial/interfaces/