Introduction
A simple interface is a named bundle of signals which can be referenced throughout a design to
simplify hierarchical connections and module instantiation. More complex interfaces can contain
functional code to encapsulate communication between design blocks.
Verilog Example
A bus connection between two modules may be composed of many ports. Both modules must separately
declare each port and when the modules are instantiated, a separately defined signal must be
mapped to each port to connect the design blocks. Consider the following example:-
module mem (input logic clk, req, start,
logic [7:0] addr,
output logic [7:0] data,
logic gnt, rdy);
...
module cpu (input logic clk, gnt, rdy,
logic [7:0] data,
output logic req, start,
logic [7:0] addr);
...
module top;
logic req, gnt, start, rdy;
logic clk = 0;
logic [7:0] addr;
wire [7:0] data;
mem m1 (clk, req, start,
addr, data, gnt, rdy);
cpu c1 (clk, gnt, rdy, data,
req, start, addr);
...
Here a connection between the modules mem and cpu is
composed of the signals reg, gnt, start, rdy, mode, addr and
data. Each of these connections must be declared in modules
mem, cpu and top.
As each port must be declared in several places, initial construction of the hierarchy is
time-consuming and maintenance is difficult, as multiple alternations are required to multiple
modules if the bus changes.
Creating a SystemVerilog Interface
SystemVerilog allows the bus to be declared once as an interface.
An interface is a design unit in SystemVerilog like a module, i.e. it is declared in a separate file and compiled
separately.
// interface declaration
interface bus_if;
logic req, start, gnt, rdy;
logic [7:0] addr, data;
endinterface : bus_if
Here the signals reg, gnt, start, rdy, mode, addr and data are declared in an
interface named bus_if.
The interface name is then used as a type for a port declaration in a module port list. Since a single
interface can contain both input and output ports, the interface port is directionless.
module mem (input logic clk,
bus_if bus);
...
module cpu (input logic clk,
bus_if bus);
...
A port of type bus_if and name bus is added to
modules mem and cpu.
The interface is then instantiated in the module top and the
instantiated interface name mapped to the interface ports of the modules.
module top;
logic clk = 0;
bus_if busA(); // interface instantiation
mem m1 (clk, busA);
cpu c1 (clk, busA);
...
An interface named busA of type bus_if is instantiated
and mapped to the interface ports of mem and cpu in the module instantiations.
Note that the interface instantiation makes the interface signals visible in module
top, so we only need to declare clk.

Accessing Interface Signals
For a module with an interface as a port, interface objects can be referenced using the interface port name.
module mem ( input logic clk,
bus_if bus );
...
assign read = (bus.gnt && (bus.mode == 0) );
always @(posedge clk)
if (read)
bus.data = mem[bus.addr];
...
endmodule
Here module mem has an interface port named bus.
For a module with an interface as an instance, interface objects can be referenced using the interface
instance name.
module top;
logic clk;
bus_if busA(); // interface instantiation
mem m1 (clk, busA);
cpu c1 (clk, busA);
...
always @(busA.rdy)
if (busA.mode == 0)
...
endmodule : top
Here module top has an interface instantiation named busA.
With interfaces, design hierarchy is easier to create as signals in a complex bus need only be declared
once in the interface. Maintenance is also easier, as all the information for a bus is declared in one
location.
Interfaces can also contain functional code such as continuous assignments, task, functions and other
interface instantiations (nested interfaces).
Interface Ports
External signals can also be brought into the interface by adding input or output ports to the
declaration.
interface bus_if (input logic clk);
logic req, start, gnt, rdy;
logic [1:0] mode;
logic [7:0] addr;
wire [7:0] data;
endinterface : bus_if
Interface ports are mapped in the interface instantiation:-
module top;
logic clk = 0;
simple_bus busA(clk);
mem m1 (busA);
cpu c1 (busA);
...
Since clk is now part of the interface, modules mem
and cpu do not require a separate clk port.
Modports
A simple interface does not contain any direction information for the interface signals.
Therefore a module to which the interface is connected can read or write to any interface signal.
Typically a bus connection between 2 modules will have a direction associated with it – a signal
will be an input to one module and an output of the other. This gives us 2 views of the bus signal.
These views can be defined in an interface using modports.
In the next tutorial we will examine the use of modports in interfaces.
Back to top