Recently I've came across following issue: in Quartus software I've defined my Verilog module as follows:
module module_name(
input [w1-1:0] in1,
input [w2-1:0] in2,
output [w1-1:0] out1
);
parameter w1 = 16;
parameter w2 = 8;
...
endmodule
This module compiled without any issues. But, when I tried to simulate that code in Modelsim(-Altera) 10.3d, I got following errors:
(vlog-2730) Undefined variable: 'w1'.
(vlog-2388) 'in1' already declared in this scope (module_name)
(vlog-2730) Undefined variable: 'w2'.
...
Identifier must be declared with a port mode: in1
Identifier must be declared with a port mode: in2
I found the way to bypass this issue with following code:
module module_name(
in1,
in2,
out1
);
parameter w1 = 16;
parameter w2 = 8;
input [w1-1:0] in1;
input [w2-1:0] in2;
output [w1-1:0] out1;
...
endmodule
The other way is also to use the following construct:
module module_name #(parameter w1 = 16, parameter w2 = 8)(
input [w1-1:0] in1,
input [w2-1:0] in2,
output [w1-1:0] out1
);
...
endmodule
But: is it illegal (Quartus suggests it's not) to define parameters after input/output signals that uses this parameters?
IEEE Std 1800-2012 § 23.2.1 Module header definition state two header types:
There are two styles of module header definitions, the non-ANSI header and the ANSI header.
The non-ANSI header style separates the definition of the module header from the declarations of the module ports and internal data. The informal syntax of a non-ANSI style module header is as follows:
module_name ( port_list ) ;
parameter_declaration_list
port_direction_and_size_declarations
port_type_declarations
The module header definition is syntactically completed by the semicolon after the closing parenthesis of the port list. Declarations that define the characteristics of the ports (direction, size, data type, signedness, etc.)
are local definitions within the module.
The ANSI header style makes the declarations of the port characteristics part of the module header (which is still terminated by a semicolon). The informal general syntax of an ANSI style module header is as follows:
module_name #( parameter_port_list )
( port_direction_and_type_list ) ;
There is no mentioning of a header syntax matching:
module_name ( port_direction_and_type_list ) ;
parameter_declaration_list
Based on the LRM, your sample header is non complaint. Anything that supports that syntax would be from outside the standard.
It is legal to define parameter
s and localparam
s after the header with with ANSI style headers so long as the header does not references them. Example in IEEE Std 1800-2012 § 23.10 Overriding module parameters