Section 19.1

LRM-176

Change (changes in red and blue):

The communication between blocks of a digital system is a critical area that can affect everything from ease of RTL coding, to hardware-software partitioning to performance analysis to bus implementation choices and protocol checking. The interface construct in SystemVerilog was created specifically created to encapsulate the communication between blocks, allowing a smooth migration from abstract system-level design through successive refinement down to lower-level register-transfer and structural views of the design. By encapsulating the communication between blocks, the interface construct also facilitates design re-use. The inclusion of interface capabilities is one of the major advantages of SystemVerilog.

 

At its lowest level, an interface is a named bundle of nets or variables. The interface is instantiated in a design and can be passed accessed through a port as a single item, and the component nets or variables referenced where needed. A significant proportion of a Verilog design often consists of port lists and port connection lists, which are just repetitions of names. The ability to replace a group of names by a single name can significantly reduce the size of a description and improve its maintainability.

Section 19.2

LRM-172

Change in Syntax 19-1 (changes in red and blue):

modport_tf_port ::=

  task named_task_proto { , named_task_proto }

| function named_function_proto { , named_function_proto }

| task_or_function_identifier tf_identifier { , task_or_function_identifier tf_identifier }

LRM-172

Change in Syntax 19-1 (changes in red and blue):

interface_instantiation ::=                                                   // from Annex A.4.1.2

interface_identifier [ parameter_value_assignment ] module_instance hierarchical_instance { , module_instance hierarchical_instance } ;

LRM-176

Change (changes in red and blue):

The interface construct provides a new hierarchical structure. It can contain smaller interfaces and can be passed accessed through ports.

 

The aim of interfaces is to encapsulate communication. At the lower level, this means bundling variables and wires in interfaces, and bundling ports may impose access restrictions with port directions in modports. The modules can be made generic so that the interfaces can be changed. The following examples show these features. At a higher level of abstraction, communication can be done by tasks and functions. Interfaces can include task and function definitions, or just task and function prototypes  (see section 19.6.1 An example of using tasks in an interface) with the definition in one module (server/slave) and the call in another (client/master).

 

A simple interface declaration is as follows (see Syntax 19-1 for the complete syntax):

 

interface identifier;

...

interface_items

...

endinterface [ : identifier ]

 

An interface can be instantiated hierarchically like a module, with or without ports. For example:

 

myinterface #(100) scalar1, vector[9:0];

 

In this example, 11 instances of the interface of type "myinterface" have been instantiated and the first parameter within each interface is changed to 100. One myinterface instance is instantiated with the name "scalar1", and an array of 10 myinterface interfaces are instantiated with instance names vector[9] to vector[0].

Section 19.2.2

LRM-176

Change (changes in red and blue):

The simplest form of a SystemVerilog interface is a bundled collection of variables or nets. When an interface is used referenced as a port, the variables and nets in it are assumed to be have ref and inout ports access, respectively. The following interface example shows the basic syntax for defining, instantiating and connecting an interface. Usage of the SystemVerilog interface capability can significantly reduce the amount of code required to model port connections.

 

interface simple_bus; // Define the interface

logic req, gnt;

logic [7:0] addr, data;

logic [1:0] mode;

logic start, rdy;

endinterface: simple_bus

 

module memMod(simple_bus a, // Use Access the simple_bus interface

input bit clk);

logic avail;

// When memMod is instantiated in module top, a.req is the req

// signal in the sb_intf instance of thesimple_bus’ interface

always @(posedge clk) a.gnt <= a.req & avail;

endmodule

Section 19.2.3

LRM-176

Change (changes in red and blue):

A module header can be created with an unspecified interface instantiation reference as a place-holder for an interface to be selected when the module itself is instantiated. The unspecified interface is referred to as a “generic” interface port reference.

 

This generic interface port reference can only be declared by using the list of port declaration style port declaration style of reference. It shall be illegal to declare such a generic interface port reference using the old Verilog-1995 list of port style.

 

The following interface example shows how to specify a generic interface port reference in a module definition.

 

// memMod and cpuMod can use any interface

module memMod (interface a, input bit clk);

...

endmodule

 

module cpuMod(interface b, input bit clk);

...

endmodule

 

interface simple_bus; // Define the interface

logic req, gnt;

logic [7:0] addr, data;

logic [1:0] mode;

logic start, rdy;

endinterface: simple_bus

 

module top;

logic clk = 0;

 

simple_bus sb_intf(); // Instantiate the interface

 

// Connect Reference the sb_intf instance of the simple_bus

// interface to from the generic interfaces of the

// memMod and cpuMod modules

memMod mem (.a(sb_intf), .clk(clk));

cpuMod cpu (.b(sb_intf), .clk(clk));

 

endmodule

 

An implicit port cannot be used to connect to reference a generic interface. A named port must be used to connect to reference a generic interface, as shown below.

Section 19.3

LRM-176

Change (changes in red and blue):

module top;

logic clk = 0;

 

simple_bus sb_intf1(clk); // Instantiate the interface

simple_bus sb_intf2(clk); // Instantiate the interface

 

memMod mem1(.a(sb_intf1)); // Connect Reference simple bus 1 to memory 1

cpuMod cpu1(.b(sb_intf1));

memMod mem2(.a(sb_intf2)); // Connect Reference simple bus 2 to memory 2

cpuMod cpu2(.b(sb_intf2));

endmodule

Section 19.4

LRM-176

Change (changes in red and blue):

 

To bundle module ports restrict interface access within a module, there are modport lists with directions declared within the interface. The keyword modport indicates that the directions are declared as if inside the module.

 

interface i2;

wire a, b, c, d;

modport master (input a, b, output c, d);

modport slave (output a, b, input c, d);

endinterface

 

The In this example, the  modport list name (master or slave) can be specified in the module header, where the modport name acts as a direction and the interface name as a type  interface name selects an interface and the modport name selects the appropriate directional information for the interface signals accessed in the module header.

 

module m (i2.master i);

...

endmodule

 

module s (i2.slave i);

...

endmodule

 

module top;

i2 i();

 

m u1(.i(i));

s u2(.i(i));

endmodule

 

The syntax of interface_name.modport_name reference_name  gives a local name for a hierarchical reference. Note that this can be generalized to any interface with a given modport name by writing interface.modport_name reference_name.

 

The modport list name (master or slave) can also be specified in the port connection with the module instance, where the modport name is hierarchical from the interface instance.

 

module m (i2 i);

...

endmodule

 

module s (i2 i);

...

endmodule

 

module top;

i2 i();

 

m u1(.i(i.master));

s u2(.i(i.slave));

endmodule

 

The syntax of interface_name.modport_name instance_name is really a hierarchical type followed by an instance. Note that this can be generalized to any interface with a given modport name by writing interface.modport_name instance_name.

 

In a hierarchically nested  interface, the directions in a modport declaration can themselves be modport plus name.

 

interface i1;

interface i3;

wire a, b, c, d;

modport master (input a, b, output c, d);

modport slave (output a, b, input c, d);

endinterface

i3 ch1(), ch2();

modport master2 (ch1.master, ch2.master);

endinterface

 

All of the names used in a modport declaration shall be declared by the same interface as is the modport itself. In particular, the names used shall not be those declared by another enclosing interface, and a modport declaration shall not implicitly declare new ports. No hierarchical references shall be permitted within a modport.

Section 19.4.2

LRM-176

Change (changes in red and blue):

This interface example shows how to use modports to control signal directions restrict interface signal access and control their direction. It uses the modport name in the module instantiation.

Section 19.8

LRM-163

Change (changes in red and blue):

EDITOR’S NOTE: I made several minor editorial changes in the following paragraphs, which are indicated by strike-through text with the replacement text immediately following the strike-through text.