[sv-bc] Proposal for amending extern module


Subject: [sv-bc] Proposal for amending extern module
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Mon Mar 17 2003 - 15:09:46 PST



Using ';' as the terminal makes it very awkward to extend the syntax of the forward declaration
to include tasks, functions or nodes (reachable by hierarchical reference), I'm therefore proposing
changing it to terminate the same way as a regular module declaration does so that the extra
items can be included in future releases of SV in a backward compatible manner:

(changes from previous posting in red
                                 http://www.eda.org/sv-bc/hm/att-0466/01-extern_proposal.txt
                                 http://www.eda.org/sv-bc/hm/0558.html)

Text:
...

    At the end of 12.7.4 ADD:

    To support separate compilation, extern declarations of a
    module can be used to declare the ports on a module without defining
    the module itself.  An extern module declaration
    consists of the keyword extern followed by the module name,
    the list of ports for the module, a semicolon and the keyword
    endmodule
.  Both list of ports syntax (possibly with parameters), and
    original Verilog style port declarations may be used.  Note that the potential
    existence of defparams precludes the checking of the
    port connection information prior to elaboration time even for
    list of ports style declarations.

    The following example demonstrates the usage of extern
    module declarations.

    extern module m (a,b,c,d); endmodule
        extern module a #(parameter size= 8, parameter type TP = logic[7:0])
                       (input [size:0] a, output TP b); endmodule

    module top ();
        wire [8:0] a;
        logic [7:0] b;

        m m (.*);
        a a (.*);
    endmodule

    Modules m and a are then assumed to be instantiated as:

    module top ();
        m m (a,b,c,d);
        a a (a,b);
    endmodule

    If an extern declaration exists for a module, it is possible to
    use .* as the ports of the module.   This usage will be equivalent
    to placing the ports (and possibly parameters) of the extern
    declaration on the module.  For example,

    extern module m (a,b,c,d); endmodule
        extern module a #(parameter size= 8, parameter type TP = logic[7:0])
                       (input [size:0] a, output TP b); endmodule
   
    module m (.*);
        input a,b,c;
        output d;
    endmodule

    module a (.*);
    endmodule

    is equivalent to writing:

    module m (a,b,c,d);
        input a,b,c;
        output d;
    endmodule

    module a #(parameter size= 8, parameter type TP = logic[7:0])
                       (input [size:0] a, output TP b);
    endmodule

    Extern module declarations can appear at any level of the
    instantiation hierarchy, but are visible only within the level of
    hierarchy in which they are declared.  It shall be an error for
    the module definition to not exactly match the extern module
    declaration.

    The keyword extern can be used in the same manner with interfaces
    and  primitive declarations.


BNF:

In A.1.3:

module_declaration ::=
        { attribute_instance } module_keyword module_identifier [parameter_port_list ]
            list_of_ports ; [ timeunits_declaration ] { module_item }
            endmodule
        | {attribute_instance } module_keyword module_identifier [parameter_port_list ]
            [ list_of_port_declarations ] ; [ timeunits_declaration ] {non_port_module_item }
            endmodule

module_nonansi_header ::=
        { attribute_instance } module_keyword module_identifier [parameter_port_list ]
            list_of_ports ;
module_ansi_header ::=
        {attribute_instance } module_keyword module_identifier [ parameter_port_list ]
            [ list_of_port_declarations ] ;
module_declaration ::=
        module_nonansi_header [ timeunits_declaration ] { module_item } endmodule
        | module_ansi_header [ timeunits_declaration ] { non_port_module_item } endmodule
        | { attribute_instance } module_keyword module_identifier ( .* ) ;
            [ timeunits_declaration ] { module_item } endmodule
        | extern module_nonansi_header endmodule
        | extern module_ansi_header        endmodule

interface_declaration ::=
        { attribute_instance } interface interface_identifier [ parameter_port_list ]
            list_of_ports ; [ timeunits_declaration ] { interface_item }
            endinterface [ :interface_identifier ]
        | {attribute_instance } interface interface_identifier [ parameter_port_list ]
        [ list_of_port_declarations ] ; [ timeunits_declaration ] {non_port_interface_item }
            endinterface [ :interface_identifier ]

interface_nonansi_header ::=
        { attribute_instance } interface interface_identifier [ parameter_port_list ]
        list_of_ports ;
interface_ansi_header ::=
        {attribute_instance } interface interface_identifier [ parameter_port_list ]
        [ list_of_port_declarations ] ;
interface_declaration ::=
        interface_nonansi_header [ timeunits_declaration ] { interface_item }
        endinterface [ :interface_identifier ]
        | interface_ansi_header [ timeunits_declaration ] {non_port_interface_item }
        endinterface [ :interface_identifier ]
        | { attribute_instance } interface_keyword interface_identifier ( .* ) ;
        [ timeunits_declaration ] { interface_item } endinterface [:interface_identifier ]
        | extern interface_nonansi_header endinterface
        | extern interface_ansi_header        endinterface

In A.5.1
REPLACE:
udp_declaration ::=
        { attribute_instance } primitive udp_identifier ( udp_port_list) ;
            udp_port_declaration { udp_port_declaration }
            udp_body
            endprimitive
        | { attribute_instance } primitive udp_identifier (udp_declaration_port_list) ;
            udp_body
            endprimitive

WITH:
udp_nonansi_declaration ::=
                { attribute_instance } primitive udp_identifier ( udp_port_list) ;
udp_ansi_declaration ::=
                { attribute_instance } primitive udp_identifier (udp_declaration_port_list) ;
udp_declaration ::=
        udp_nonansi_declaration udp_port_declaration { udp_port_declaration }
            udp_body
            endprimitive
        | udp_ansi_declaration udp_body primitive
        | extern udp_nonansi_declaration endprimitive
        | extern udp_ansi_declaration        endprimitive
        | { attribute_instance } primitive udp_identifier ( .*) ;
            {udp_port_declaration} udp_body endprimitive


Note: I havn't added it but you could add port direction etc. to the BNF for the non-ansi forward
declarations (if anyone wants it).

Regards,
Kev.

-- 
National Semiconductor, Tel: (408) 721 3251
2900 Semiconductor Drive, Mail Stop D3-500, Santa Clara, CA 95052-8090



This archive was generated by hypermail 2b28 : Mon Mar 17 2003 - 15:10:55 PST