For a data type such as a class, the type definition and actual parameter
values are sufficient to determine the types of all components. For a design
unit this is not the case, because defparam statements may be used to alter
parameters. Furthermore, a design unit does not exist independently of its
instances, whereas a class exists before any instances (objects) are
created. Configurations can replace design units but not classes. The
generate construct means that elaboration depends very much upon parameters
to design units.
Virtual interfaces present a unique problem in that they have a data type
that refers to a design unit. A virtual interface may be assigned to
various interface instances in turn, and consequently the data types of the
interface components accessed can only be determined at run time. Run time
type determination creates an unacceptable overhead, so one of the interface
instances, with the same actual parameter values, is usually selected for
elaboration time type determination.
A better method would be for a virtual interface to have an "interface to an
interface" that has component data types which are determined at elaboration
time like those in a class. A modport is already a kind of "interface to an
interface". However it does not exist outside its interface and it does not
include data types. Jonathan Bromley has proposed stand-alone modports with
parameters and data typed ports:
"The new stand-alone declaration syntax closely follows the existing syntax
for declaring a
modport within an interface, except that each modport item must have its
data type specified.
Note how this differs from modports in Std.1800-2005 interfaces; the modport
items in such
modports are invariably references to things of known data type that already
exist within the
interface. In an abstract (stand-alone) modport declaration the modport
items cannot refer to an
existing thing, and therefore they must be explicitly typed.
A modport declaration may optionally have type parameters and value
parameters. These
parameters act in much the same way as parameters associated with a class
declaration, in the
sense that they may be overridden to create a specialisation of the modport.
Parameters of the
modport may be used in the modport_typed_items, for example to specify bit
widths, item data
types, or the argument types of subprograms.
There shall be at least one modport_typed_item in a modport declaration. A
modport_typed_item
can be a list of port connections, import/export subprogram prototypes, or
clocking blocks."
"package P_3_2;
// Modport suitable for connection to an RS-232 serial link
modport rs_232 (
input logic RXD, DSR, CTS, DCD,
output logic TXD, RTS, DTR );
// Modport representing a general-purpose test point of any type
modport testpoint #(parameter type T = logic) (output T TP);
endpackage : P_3_2"
"A modport that has been declared stand-alone can be used to create a
modport connector in an
interface, exposing items in the interface through the connector. When the
interface is instanced,
such a modport connector can then be used to meet the obligation represented
by a modport
receptacle in an instance of some other module.
Every item in the modport connector must be associated with an expression of
equivalent type in
the enclosing interface. Each modport item merely provides visibility of a
data object in the
enclosing interface. The connector does not create any new data objects for
its modport items.
Items of the modport connector are associated with expressions using the
same syntax as port
connection lists on a module instance. The connection shorthand .name is
acceptable as an
abbreviation for the association .name(name), and the connection shorthand
.* is acceptable
for wildcard association of all items not otherwise associated.
Items can be explicitly specified to have no association by using the empty
association syntax
.name().
interface I_4_4();
import P_4_3::*; // makes declaration of mp_4_3 visible
logic R, W, Lire, Ecrire; // data objects in the interface
mp_4_3 rw_conn1( .W(Ecrire), .R ); // .R(R) is implied
mp_4_3 rw_conn2( .*, .R(Lire) ); // .W(W) is implied
endinterface : I_4_4"
"An import task or function in a modport provides access, through a modport
port in a
client module, to a subprogram declared in the module or interface enclosing
the modport
connector.
Standalone modport declarations (i.e. those in a package) must fully specify
the prototype of any
imported subprogram item:
package P_6_2;
modport MP_6_2 ( import function int MP_F ( input byte B ) );
endpackage : P_6_2
When such a modport is used to create a connector, the enclosing interface
must provide a
suitable subprogram. It is not necessary for the actual subprogram to have
the same name as
the corresponding modport item, because the name can be mapped through the
extended form
of modport expression:
interface I_6_2;
import P_6_2::*;
function int f ( input byte B );
...
endfunction : f
MP_6_2 f_conn ( .MP_F(f) ); // expose function f() to modport
endinterface : I_6_2"
Such modports could be considered to be like data types and allowed in
packages, but they are not real data types and are not allowed with new.
Modport instances in interfaces could be used with hierarchical names in
expressions. This would require the user to create local names and data
types in modports for such expressions, and the types would be checked at
interface instance elaboration. The local names would have to be used
instead of hierarchical names in code to access interface components.
A clocking block in a modport can be considered to be in a hierarchical
modport. Since a stand-alone modport in a package would not have access to
a clocking block, another modport should be used to provide the names, data
types and directions. This should then be linked to a clocking block in the
interface instance to which it is connected.
package P_6;
modport CP_6 (input bit[3:0] I .);
modport MP_6 ( modport CP_6 mp_cb );
endpackage : P_6
interface I_6_1 ( input bit clk );
import P_6::*;
clocking intf_cb @(posedge clk);
input bit[3:0] I ...
endclocking : intf_cb
MP_6 mp ( .mp_cb(intf_cb) );
endinterface : I_6_1;
Another example (modified from DVCon 09 paper)
package pkg;
modport Abstract ( output logic [3:0] L );
endpackage
interface AI;
import pkg::*;
logic [7:0] Vec;
Abstract a_mp(.L(Vec[5:2]));
endinterface
module CE3 import pkg::*;
(Abstract P);
initial P.L = 4'b0;
endmodule
Syntax changes:
package_item ::=
package_or_generate_item_declaration
| anonymous_program
| package_export_declaration
| timeunits_declaration
| package_modport_declaration
package_modport_declaration ::=
{attribute_instance} modport [parameter_port_list]
( package_modport_item { , package modport_item } ) ;
package_modport_item ::=
modport_identifier ( package_modport_ports_declaration
{ , package_modport_ports_declaration } )
package_modport_ports_declaration ::=
{attribute_instance} list_of_port_declarations
| {attribute_instance} import_export method_prototype
{ , method_prototype }
| {attribute_instance} modport modport_identifier port_identifier
{ unpacked_dimension }
interface_or_generate_item ::=
{ attribute_instance } module_common_item
| { attribute_instance } modport_declaration
| { attribute_instance } extern_tf_declaration
| { attribute_instance } modport_instantiation
modport_instantiation ::=
modport_identifier [ parameter_value_assignment ] modport_instance {
, modport_instance } ;
modport_instance ::=
name_of_instance ( list_of_modport_connections )
list_of_modport_connections ::=
ordered_modport_connection { , ordered_modport_connection }
named_modport_connection { , named_modport_connection }
ordered_modport_connection ::=
{ attribute_instance } [ net_lvalue ]
| {attribute_instance } tf_identifier
| {attribute_instance } clocking_identifier
| {attribute_instance } name_of_instance
named_modport_connection ::=
{ attribute_instance } . port_identifier [ ( [ net_lvalue ] ) ]
| {attribute_instance } . port_identifier [ ( [ tf_identifier ])]
| .*
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Fri Jan 28 13:04:00 2011
This archive was generated by hypermail 2.1.8 : Fri Jan 28 2011 - 13:04:17 PST