What is Interface?
An Interface encapsulate the connectivity between two or more modules.
To understand interfaces, consider two modules moduleA and
moduleB who talk to each other through their ports. The
definitions of moduleA and moduleB are shown below
along with the top-level wrapper top that encompasses them.
module moduleA ( input bit clk
, input logic ack
, input logic ready
, output logic send
, output logic [31:0] data
);
... // actual module definition here
endmodule
module moduleB ( input bit clk
, input logic send
, input logic [31:0] data
, output logic ack
, output logic ready
);
... // actual module definition here
endmodule
module top;
...
clockgen CLOCKGEN (clk); // the clock generator
moduleA AA (clk, ack, ready, send, data);
moduleB BB (clk, send, data, ack, ready);
endmodule
While this cetainly works (and indeed, so far any Verilog
design has been built using a similar configuration), one
can argue this configuration is tied intrinsically with the
communicating ports of the modules. For example, there is
no way one can test moduleA without building
moduleB (or a testbench equivalent) or, each time
either the communication protocol between the two modules
changes, either by addition or deletion of a signal, or
by change in the behavior of a signal, the two modules
must change simultaneously to reflect that. There is no way
to abstract the interface between the two modules independent
of the modules themselves.
Interfaces achieve this.
With interfaces, one can define the same design described
above as follows.
interface intf_AB;
logic ack;
logic ready;
logic send;
logic [31:0] data;
... // actual interface definition here
endinterface
module moduleA ( input bit clk
, intf_AB intf1
);
... // actual module definition here
endmodule
module moduleB ( input bit clk
, intf_AB intf2
);
... // actual module definition here
endmodule
module top;
...
intf_AB intf(); // the interface declaration
clockgen CLOCKGEN (clk); // the clock generator
moduleA AA ( .clk (clk )
,.intf1 (intf )
);
moduleB BB ( .clk (clk )
,.intf2 (intf )
);
endmodule
As the above example shows, now both the instances of moduleA
and moduleB are independent of the connectivity between the
two modules.
Now that we have some primary knowledge of how interfaces work, here
are some more information:
- Interfaces are defined just as modules but, unlike a module,
an interface may contain nested definitions of other interfaces.
- An interface instantiation is similar to a module instantiation,
and array of instances is permitted.The following example defines
8 instances of the same interface.
intf_AB intf[7:0]
Structures and Interfaces
At this point, I hear you saying, 'But, if all that an interface
provides is bundling of port, I could do all that using a
structure.' And, you would be
right if that's all interface offers.
But the fun part is that interface provides way more than just port
bundling as we will soon see. Some of the differences between a
structure and an interface are the following.
- An interface can contain initial and always
blocks, and hence it is possible for an interface to have blocks
of code that sends stimulii through its variables.
- Furthermore, an interface can have tasks and functions in it,
all of which are callable from outside the interface, providing
a mechanism to stimulate the connectivity that this interface
represents without ever writing any code.
- An interface can define the direction of a signal from a
module using a modport construct. Thus it is possible for
a single signal to be an output for one module and inputs for
others.
We will see more examples on these items in later parts.
Instantiating an Interface in a Module
We have already seen above an example of how to instantiate an interface
(intf_AB) in a module (top). This example shows
what's known as a Named bundle. Here, definitions of
both modules moduleA and moduleB have intf_AB
as ports.
In stead, one or both modules can have, what is called a Generic
bundle in their portlists. For instance, our example above can
have the following for the portlist of module moduleA. Note
that in this case the portlist only contain a generic definition
of the interface.
module moduleA ( input bit clk
, interface intf1
);
... // actual module definition here
endmodule
The rest of the methods, including how module instances are done,
remain unchanged.
Note that the clock signal clk in all our examples so far
is not part of the interface. This is because the clock signal comes
from an external module CLOCKGEN. However, the main reason
for the signal to be there is to synchronize the connectivity
between the two modules. We see how to do this in the next page.
Next: Instantiating Interfaces