Featured post

Transaction Recording In Verilog Or System Verilog

As there is not yet a standard for transaction recording in Verilog or VHDL, ModelSim includes a set of system tasks to perform transac...

Monday, 31 December 2012

SystemVerilog Interface

Interfaces are a major new construct in SystemVerilog, created specifically 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.

There are several advantages when using an Interface:

  • 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;

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

    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];

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

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

Interface Ports

An interface can also have input, output or inout ports. Only the variables or nets declared in the port list of an interface can be connected externally by name or position when the interface is instantiated, and therefore can be shared with other interfaces.  The ports are declared using the ANSI-style.

Here is an example showing an interface with a clock port:

interface ClockedBus (input Clk);
  logic[7:0] Addr, Data;
  logic RWn;
module RAM (ClockedBus Bus);
  always @(posedge Bus.Clk)
    if (Bus.RWn)
      Bus.Data = mem[Bus.Addr];
      mem[Bus.Addr] = Bus.Data;

// Using the interface
module Top;
  reg Clock;

  // Instance the interface with an input, using named connection
  ClockedBus TheBus (.Clk(Clock));
  RAM TheRAM (.Bus(TheBus));

Parameterised Interface

This is a simple example showing a parameterised interface:

interface Channel #(parameter N = 0)
    (input bit Clock, bit Ack, bit Sig);
  bit Buff[N-1:0];
    for (int i = 0; i < N; i++)
      Buff[i] = 0;
  always @ (posedge Clock)       
   if(Ack = 1)
     Sig = Buff[N-1];
     Sig = 0;

Tasks in Interfaces

Tasks and functions can be defined in interfaces, to allow a more abstract level of modelling.

The next example shows two tasks in an interface being used to model bus functionality. The tasks are called inside the testRAM module:

interface MSBus (input Clk);
  logic [7:0] Addr, Data;
  logic RWn;

  task MasterWrite (input logic [7:0] waddr,
                    input logic [7:0] wdata);
    Addr = waddr;
    Data = wdata;
    RWn = 0;
    #10ns RWn = 1;
    Data = 'z;
  task MasterRead (input  logic [7:0] raddr,
                   output logic [7:0] rdata);
    Addr = raddr;
    RWn = 1;
    #10ns rdata = Data;
module TestRAM;
  logic Clk;
  logic [7:0] data;
  MSBus TheBus(.Clk(Clk));
  RAM TheRAM (.MemBus(TheBus));
    // Write to the RAM
    for (int i = 0; i<256; i++)

    // Read from the RAM
    for (int i = 0; i<256; i++)
      ReadCheck : assert (data === i[7:0])
        else $error("memory read error");

No comments:

Post a comment

Please provide valuable comments and suggestions for our motivation. Feel free to write down any query if you have regarding this post.