SystemVerilog Interfaces

Prev: Interfaces | Next: Interface task and function

Ports of an Interface

Ports of an interface works similar to ports of a module. It has a direction (input, output or inout). The variable that is connected to the port inside the interface is accessible outside by its hierarchical name.

For example, we can declare clk as an input port of the interface intf_AB and then access it from within the modules moduleA and moduleB. This is shown below.

interface intf_AB(input bit clk); 
logic        ack;
logic        ready;
logic        send; 
logic [31:0] data;
   ... // actual interface definition here
endinterface   

module moduleA (intf_AB     intf1);
   ... 
   always @(posedge intf1.clk) // clk from intf_AB
      ...
endmodule

module moduleB (intf_AB     intf2);
   ... // actual module definition here
endmodule   

module top; 
...
   intf_AB  intf();           // the interface declaration
   clockgen CLOCKGEN (clk); // the clock generator

   moduleA  AA (.intf1  (intf));
   moduleB  BB (.intf2  (intf));
endmodule   

Modports

A legitimate question for you to ask at this point is 'if an interface is passed in the portlist of all the connected modules, how does a port behaves as an output of one module and inputs to the rest of the modules?' This problem is solved by the use of modports. Modports configure the directions of various variables inside an interface based on which module is passing the interface in its port list. For example, ack and ready are inputs to moduleA, but they are outputs from moduleB. How do we reflect that when we use intf_AB as an interface between them? The same goes true for ports send and data, which have a direction opposite to that of ack and ready.

To do this, we define two modports within intf_AB: source for moduleA and sink for moduleB.

 

interface intf_AB; 
logic        ack;
logic        ready;
logic        send; 
logic [31:0] data;
   modport source ( input ack, ready, output send, data);
   modport sink   (output ack, ready, input send, data );
endinterface  

Then we change the definitions of moduleA and moduleB as follows.
 

module moduleA (  input          bit clk 
                , intf_AB.source     intf1
		);
   ... // actual module definition here
endmodule

module moduleB (  input        bit clk
		, intf_AB.sink     intf2
		);
   ... // actual module definition here
endmodule   

Finally, in the top level, these two modules are instantiated as follows as usual.

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 

We mentioned earlier that an interface can have initial and always blocks as well as tasks and functions. Defining tasks and functions within an interface has special implications as we will see in the next page.

Prev: Interfaces | Next: Interface task and function

Share/Save/Bookmark



Verification Management
Join Verification Management Group


Talk UVM with Friends
Shop Amazon - Contract Cell Phones & Service Plans


Fun Stuffs!