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