From: Michael McNamara (mac@surefirev.com)
Date: Fri Jan 08 1999 - 18:40:34 PST
Here is the proposal in text format. I have tried to highlight the new
BNF by underlining it with ^^^^^ or enclosing the new stuff in
START NEW
END NEW
regions.
Perhaps better is to use netscape or whatever on the html version!
<p>ANSI Port Declarations
This proposal adds an alternate method for declaring module, task and
function ports to the Verilog Hardware Description Language.
<p><p>Port Declarations
<p><p>At present, the Verilog language requires that the ports of a module be
listed, by name, in parenthetical list just after the module name. Further,
it is required that each port be again declared somewhere in the module as
one of an input, output or inout. Optionally the port may again be declared
as a wire (the default) or as a reg.
module_declaration ::= module_keyword module_identifier [ list_of_ports
] ; { module_item } endmodule
module_keyword ::= module | macromodule
list_of_ports ::= ( port { , port } )
port ::= [ port_expression ]
| . port_identifier ( [ port_expression ] )
port_expression ::= port_reference
| { port_reference { , port_reference } }
port_reference ::= port_identifier
| port_identifier [ constant_expression ]
| port_identifier [ msb_constant_expression :
lsb_constant_expression ]
And then as a module item we have:
module_item ::= module_item_declaration
module_item_declaration ::= parameter_declaration
| input_declaration
| output_declaration
| inout_declaration
| net_declaration
| reg_declaration
...
input_declaration ::= input [ range ] list_of_port_identifiers ;
output_declaration ::= output [ range ] list_of_port_identifiers ;
inout_declaration ::= inout [ range ] list_of_port_identifiers ;
Of course this is very similar to the original C Programming Language,
(affectionately known as K&R C), which was enhanced by simpler port
declarations in ANSI C.
Further, at present declarations of tasks and functions do not support a
parenthetical list of ports. Instead the inputs, locals, and in the case of
tasks, outputs and inouts of the tasks must be listed after the task or
function name declaration.
function_declaration ::= function [range_or_type]
function_identifier ;
function_item_declaration
{function_item_declaration}
statement
endfunction
function_item_declaration ::= block_item_declaration
| input_declaration
task_declaration ::= task task_identifier ;
task_item_declaration {task_item_declaration}
statement
endtask
task_item_declaration ::= block_item_declaration
| input_declaration
| output_declaration
| inout_declaration
After some discussion in the Verilog-1364 Behavioral Task Force, and later
in the entire Verilog-1364 working group, consensus emerged supporting an
extension to the Verilog language closely following that of ANSI C's
enhancement to K&R C, as follows.
For module, task and function declarations, users can either continue to use
the existing syntax, or they can use the new parenthetical port declaration
production.
This proposal does the following, with the BNF below:
1. enhances the input_declaration, output_declaration, and
inout_declaration to allow specification of net or reg type and
signedness.
2. allows input_declarations, output_declarations and inout_declarations
to be used as port_references.
3. introduces a function_port_list and task_port_list that can be used as
an alternative to the current function and task declaration syntax.
4. introduces a parameter__port_list that can be used to define parameters
of modules where the parameters are used to size the width of input,
output and inout ports.
5. introduces the semantic restriction that a module, task or function
declaration must either use the existing 1364-1995 port declaration
syntax, or the new syntax; but may not mix both styles in the same
declaration. A given design may use modules, tasks and functions, where
some are declaraed in the old syntax, and some in the new syntax.
module_declaration ::= module_keyword module_identifier
[ parameter_port_list ] [ list_of_ports ] ;
^^^^^^^^^^^^^^^^^^^^^^^
{ module_item } endmodule
module_keyword ::= module | macromodule
parameter_port_list ::= # ( parameter_declaration { parameter_declaration } )
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
list_of_ports ::= ( port { , port } )
port ::= [ port_expression ]
| . port_identifier ( [ port_expression ] )
port_expression ::= port_reference
| { port_reference { , port_reference } }
port_reference ::= port_identifier
| port_identifier [ constant_expression ]
| port_identifier [ msb_constant_expression :
lsb_constant_expression ]
| port_identifier [ constant_expression ]
| input_declaration
^^^^^^^^^^^^^^^^^^^
| output_declaration
^^^^^^^^^^^^^^^^^^^^
| inout_declaration
^^^^^^^^^^^^^^^^^^^
...
input_declaration ::= input [ signed ] [ net_type ] [ range ] list_of_port_identifiers
^^^^^^^^^^^^^^^^^^^^^^^
output_declaration ::= output [ signed ] [ net_type ] [ range ] list_of_port_identifiers
^^^^^^^^^^^^^^^^^^^^^^^
output_declaration ::= output [ signed ] [ reg_type ] [ range ] list_of_port_identifiers
^^^^^^^^^^^^^^^^^^^^^^^
inout_declaration ::= inout [ signed ] [ net_type ] [ range ] list_of_port_identifiers
^^^^^^^^^^^^^^^^^^^^^^^
function_declaration ::= function [range_or_type]
function_identifier ;
function_item_declaration
{function_item_declaration}
statement
endfunction
START NEW
| function [range_or_type] function_identifier
( function_port_list ) ;
block_item_declaration {block_item_declaration}
statement
endfunction
function_item_declaration ::= block_item_declaration
| input_declaration
function_port_list ::= input_declaration { input_declaration }
END NEW
task_declaration ::= task task_identifier ;
task_item_declaration {task_item_declaration}
statement
endtask
START NEW
| task task_identifier ( task_port_list ) ;
block_item_declaration {block_item_declaration}
statement
endtask
task_port_list ::= task_port_item { task_port_item }
task_port_item ::= input_declaration
| output_declaration
| inout_declaration
END NEW
task_item_declaration ::= block_item_declaration
| input_declaration
| output_declaration
| inout_declaration
<p>Note that a separate proposal is adding the keyword signed to the language;
and the optional keyword signed is merely included here to show that should
signed constructs be introduced, it would be legal to include the
declaration in the port_reference production
Given this syntax, the following two module declarations are equivalent:
module acc_fsm( CLK, RST, IT_IL_RQ, IT_RQ_VLD, RdMsg,
WrMsg, AccessOK, XX_IL_PIODONE, OM_IL_GT,
RespVld, IL_IT_GT, CaptureAddress, CaptureData,
IL_XX_PIORD, IL_XX_PIOWR, IL_OM_RQ,
SelectResp, SetRespVld, ClrRespVld);
parameter DATAWIDTH=64;
input CLK, RST;
input IT_IL_RQ,
IT_RQ_VLD,
RdMsg,
WrMsg,
AccessOK,
XX_IL_PIODONE;
input OM_IL_GT,
RespVld;
output [31:0] CaptureAddress;
output [DATAWIDTH-1:0] CaptureData;
output IL_IT_GT,
IL_XX_PIORD,
IL_XX_PIOWR,
IL_OM_RQ,
SelectResp,
SetRespVld,
ClrRespVld;
reg [31:0] CaptureAddress;
reg [DATAWIDTH-1:0] CaptureData,
reg [2:0] LE_NxtState,
LE_State;
reg IL_IT_GT,
IL_XX_PIORD;
reg IL_XX_PIOWR,
IL_OM_RQ,
SelectResp,
SetRespVld,
ClrRespVld;
and
module acc_fsm #( parameter DATAWIDTH=64)
( input wire CLK, RST, IT_IL_RQ, IT_RQ_VLD, RdMsg,
WrMsg, AccessOK, XX_IL_PIODONE,
OM_IL_GT, RespVld;
output reg [31:0] CaptureAddress;
output reg [DATAWIDTH-1:0] CaptureData;
output reg IL_IT_GT, IL_XX_PIORD, IL_XX_PIOWR,
IL_OM_RQ, SelectResp, SetRespVld, ClrRespVld;
);
reg [ 2 : 0] LE_NxtState,
LE_State;
Things to note:
1. The second module declaration is much more compact.(38 words instead of
70). Also note that this is a small example; many datapath modules
contain as many as a thousand ports, each which may need to be declared
three times.
2. The second module declaration is much easier to reuse: changing the
width of the CaptureAddress bus to 48 bits requires modifying one
location, instead of two, which potentially are many lines apart.
3. With the second module declaration local variables are clearly distinct
from port variables.
4. With the second module declaration global analysis can examine just the
port list in order to determine all necessary information about the
input output characteristics of a module.
5. Declaring the modifiable parameter declarations in a separate list,
with the list enclosed in '#(' and )' looks just like the module
instance parameter override syntax. This also encapsulates and focuses
attention the interface nature of these parameters.
6. Overall, the new module declaration centers the information that a user
of this module must look at to successfully interface to the module in
one place, at the top of the module. The details of the implementation
are listed later. Hence Verilog becomes more object oriented.
7. There has been some suggestion that using constant functions in module
i/o declarations to define widths would require that the definition of
the constant function precede the use; however private discussion has
cleared this up. The value of the parameters at the point of the 'call'
to the constant function are all that is needed to determine its value.
An exaple is useful:
module acc_fsm #( parameter DATAWIDTH=8, TSIZE=cf_tsize(DATAWIDTH) )
( input wire CLK, RST,
output reg [TSIZE-1:0] CaptureDataOut;
input wire [TSIZE-1:0] CaptureDataIn;
);
reg [ 2 : 0] LE_NxtState,
LE_State;
parameter B=DATAWIDTH*2;
function [31:0] cf_tsize(input [31:0] w);
cf_tsize = w**B;
endfunction
endmodule
The parameter B is not yet defined at the location that TSIZE is
assigned the value of the constant function cf_tsize, and hence this
usage is illegal. The fix would be to move the definition of the
parameter B into the parameter port list.
<p>Michael McNamara
Last modified: Fri Jan 8 18:16:27 PST 1999
This archive was generated by hypermail 2.1.4
: Mon Jul 08 2002 - 12:53:24 PDT
and
sponsored by Boyd Technology, Inc.