Merge pull request #764 from larsclausen/module-port-list-default
Support default port values in port declarations lists
This commit is contained in:
commit
fa0217af87
|
|
@ -0,0 +1,22 @@
|
|||
// Check that it is an error to specify a default value for inout port
|
||||
// declarations.
|
||||
|
||||
module M (
|
||||
inout [31:0] x, y = 1 // inout ports do not support default values
|
||||
);
|
||||
initial begin
|
||||
$display("FAILED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
wire [31:0] x, y;
|
||||
|
||||
M i_m (
|
||||
.x(x),
|
||||
.y(y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that it is possible to specify a default port value for each port in a
|
||||
// input port declaration list.
|
||||
|
||||
module M (
|
||||
input [31:0] x = 1, y = 2
|
||||
);
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d): %s, expected %0h got %0h", `__LINE__, `"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
reg failed = 1'b0;
|
||||
|
||||
initial begin
|
||||
`check(x, 1)
|
||||
`check(y, 2)
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
M i_m ();
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that it is possible to specify a default port value for each port in a
|
||||
// output port declaration list.
|
||||
|
||||
module M (
|
||||
output [31:0] x = 1, y = 2
|
||||
);
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d): %s, expected %0h got %0h", `__LINE__, `"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
reg failed = 1'b0;
|
||||
|
||||
initial begin
|
||||
`check(x, 1)
|
||||
`check(y, 2)
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
M i_m ();
|
||||
|
||||
endmodule
|
||||
|
|
@ -78,6 +78,7 @@ br_gh567 normal ivltests
|
|||
check_constant_3 normal ivltests
|
||||
function4 normal ivltests
|
||||
module_inout_port_type normal ivltests
|
||||
module_input_port_list_def normal,-g2005-sv ivltests
|
||||
module_input_port_type normal ivltests
|
||||
parameter_in_generate1 normal ivltests
|
||||
parameter_no_default normal ivltests
|
||||
|
|
|
|||
|
|
@ -651,7 +651,9 @@ mixed_width_case normal ivltests
|
|||
modparam normal ivltests top # Override parameter via passed down value
|
||||
module3.12A normal ivltests main
|
||||
module3.12B normal ivltests
|
||||
module_inout_port_list_def CE ivltests # inout ports do not support default values
|
||||
module_inout_port_type CE ivltests
|
||||
module_input_port_list_def CE ivltests # input ports only support default values in SV
|
||||
module_input_port_type CE ivltests
|
||||
module_nonansi_integer1 normal ivltests
|
||||
module_nonansi_integer2 normal ivltests
|
||||
|
|
@ -659,6 +661,7 @@ module_nonansi_time1 normal ivltests
|
|||
module_nonansi_time2 normal ivltests
|
||||
module_nonansi_vec1 normal ivltests
|
||||
module_nonansi_vec2 normal ivltests
|
||||
module_output_port_list_def normal ivltests
|
||||
module_output_port_var1 normal ivltests
|
||||
module_output_port_var2 normal ivltests
|
||||
module_port_range_mismatch CE ivltests
|
||||
|
|
|
|||
130
parse.y
130
parse.y
|
|
@ -602,7 +602,6 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
|||
%type <perm_strings> udp_port_list
|
||||
%type <wires> udp_port_decl udp_port_decls
|
||||
%type <statement> udp_initial udp_init_opt
|
||||
%type <expr> udp_initial_expr_opt
|
||||
|
||||
%type <wire> net_variable
|
||||
%type <wires> net_variable_list
|
||||
|
|
@ -621,7 +620,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
|||
%type <mports> list_of_ports module_port_list_opt list_of_port_declarations module_attribute_foreign
|
||||
%type <value_range> parameter_value_range parameter_value_ranges
|
||||
%type <value_range> parameter_value_ranges_opt
|
||||
%type <expr> tf_port_item_expr_opt value_range_expression
|
||||
%type <expr> value_range_expression
|
||||
|
||||
%type <named_pexprs> enum_name_list enum_name
|
||||
%type <data_type> enum_data_type enum_base_type
|
||||
|
|
@ -648,8 +647,8 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
|||
%type <pform_name> hierarchy_identifier implicit_class_handle class_hierarchy_identifier
|
||||
%type <expr> assignment_pattern expression expr_mintypmax
|
||||
%type <expr> expr_primary_or_typename expr_primary
|
||||
%type <expr> class_new dynamic_array_new let_default_opt
|
||||
%type <expr> var_decl_initializer_opt
|
||||
%type <expr> class_new dynamic_array_new
|
||||
%type <expr> var_decl_initializer_opt initializer_opt
|
||||
%type <expr> inc_or_dec_expression inside_expression lpvalue
|
||||
%type <expr> branch_probe_expression streaming_concatenation
|
||||
%type <expr> delay_value delay_value_simple
|
||||
|
|
@ -1778,11 +1777,15 @@ list_of_variable_decl_assignments /* IEEE1800-2005 A.2.3 */
|
|||
}
|
||||
;
|
||||
|
||||
var_decl_initializer_opt
|
||||
initializer_opt
|
||||
: '=' expression { $$ = $2; }
|
||||
| { $$ = nullptr; }
|
||||
;
|
||||
|
||||
var_decl_initializer_opt
|
||||
: initializer_opt
|
||||
| '=' class_new { $$ = $2; }
|
||||
| '=' dynamic_array_new { $$ = $2; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
variable_decl_assignment /* IEEE1800-2005 A.2.3 */
|
||||
|
|
@ -2342,7 +2345,7 @@ tf_port_declaration /* IEEE1800-2005: A.2.7 */
|
|||
|
||||
tf_port_item /* IEEE1800-2005: A.2.7 */
|
||||
|
||||
: port_direction_opt K_var_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt
|
||||
: port_direction_opt K_var_opt data_type_or_implicit IDENTIFIER dimensions_opt initializer_opt
|
||||
{ std::vector<pform_tf_port_t>*tmp;
|
||||
NetNet::PortType use_port_type = $1;
|
||||
if ((use_port_type == NetNet::PIMPLICIT) && (gn_system_verilog() || ($3 == 0)))
|
||||
|
|
@ -2379,6 +2382,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
|||
|
||||
$$ = tmp;
|
||||
if ($6) {
|
||||
pform_requires_sv(@6, "Task/function default argument");
|
||||
assert(tmp->size()==1);
|
||||
tmp->front().defe = $6;
|
||||
}
|
||||
|
|
@ -2393,16 +2397,6 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
|||
}
|
||||
;
|
||||
|
||||
/* This rule matches the [ = <expression> ] part of the tf_port_item rules. */
|
||||
|
||||
tf_port_item_expr_opt
|
||||
: '=' expression
|
||||
{ pform_requires_sv(@$, "Task/function default argument");
|
||||
$$ = $2;
|
||||
}
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
tf_port_list /* IEEE1800-2005: A.2.7 */
|
||||
: { port_declaration_context.port_type = gn_system_verilog() ? NetNet::PINPUT : NetNet::PIMPLICIT;
|
||||
port_declaration_context.data_type = 0;
|
||||
|
|
@ -2572,21 +2566,13 @@ attribute_list
|
|||
|
||||
|
||||
attribute
|
||||
: IDENTIFIER
|
||||
: IDENTIFIER initializer_opt
|
||||
{ named_pexpr_t*tmp = new named_pexpr_t;
|
||||
tmp->name = lex_strings.make($1);
|
||||
tmp->parm = 0;
|
||||
tmp->parm = $2;
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| IDENTIFIER '=' expression
|
||||
{ PExpr*tmp = $3;
|
||||
named_pexpr_t*tmp2 = new named_pexpr_t;
|
||||
tmp2->name = lex_strings.make($1);
|
||||
tmp2->parm = tmp;
|
||||
delete[]$1;
|
||||
$$ = tmp2;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
|
@ -2786,42 +2772,22 @@ pos_neg_number
|
|||
;
|
||||
|
||||
enum_name
|
||||
: IDENTIFIER
|
||||
: IDENTIFIER initializer_opt
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
delete[]$1;
|
||||
$$ = make_named_number(name);
|
||||
$$ = make_named_number(name, $2);
|
||||
}
|
||||
| IDENTIFIER '[' pos_neg_number ']'
|
||||
| IDENTIFIER '[' pos_neg_number ']' initializer_opt
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
long count = check_enum_seq_value(@1, $3, false);
|
||||
$$ = make_named_numbers(name, 0, count-1, $5);
|
||||
delete[]$1;
|
||||
$$ = make_named_numbers(name, 0, count-1);
|
||||
delete $3;
|
||||
}
|
||||
| IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']'
|
||||
| IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']' initializer_opt
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
$$ = make_named_numbers(name, check_enum_seq_value(@1, $3, true),
|
||||
check_enum_seq_value(@1, $5, true));
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
delete $5;
|
||||
}
|
||||
| IDENTIFIER '=' expression
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
delete[]$1;
|
||||
$$ = make_named_number(name, $3);
|
||||
}
|
||||
| IDENTIFIER '[' pos_neg_number ']' '=' expression
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
long count = check_enum_seq_value(@1, $3, false);
|
||||
$$ = make_named_numbers(name, 0, count-1, $6);
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
}
|
||||
| IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']' '=' expression
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
$$ = make_named_numbers(name, check_enum_seq_value(@1, $3, true),
|
||||
check_enum_seq_value(@1, $5, true), $8);
|
||||
check_enum_seq_value(@1, $5, true), $7);
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
delete $5;
|
||||
|
|
@ -4327,14 +4293,10 @@ list_of_port_identifiers
|
|||
;
|
||||
|
||||
list_of_variable_port_identifiers
|
||||
: IDENTIFIER dimensions_opt
|
||||
{ $$ = make_port_list($1, $2, 0); }
|
||||
| IDENTIFIER dimensions_opt '=' expression
|
||||
{ $$ = make_port_list($1, $2, $4); }
|
||||
| list_of_variable_port_identifiers ',' IDENTIFIER dimensions_opt
|
||||
{ $$ = make_port_list($1, $3, $4, 0); }
|
||||
| list_of_variable_port_identifiers ',' IDENTIFIER dimensions_opt '=' expression
|
||||
{ $$ = make_port_list($1, $3, $4, $6); }
|
||||
: IDENTIFIER dimensions_opt initializer_opt
|
||||
{ $$ = make_port_list($1, $2, $3); }
|
||||
| list_of_variable_port_identifiers ',' IDENTIFIER dimensions_opt initializer_opt
|
||||
{ $$ = make_port_list($1, $3, $4, $5); }
|
||||
;
|
||||
|
||||
|
||||
|
|
@ -4380,13 +4342,29 @@ list_of_port_declarations
|
|||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
| list_of_port_declarations ',' IDENTIFIER
|
||||
| list_of_port_declarations ',' IDENTIFIER initializer_opt
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($3);
|
||||
ptmp = pform_module_port_reference(@3, name);
|
||||
std::vector<Module::port_t*>*tmp = $1;
|
||||
tmp->push_back(ptmp);
|
||||
|
||||
if ($4) {
|
||||
switch (port_declaration_context.port_type) {
|
||||
case NetNet::PINOUT:
|
||||
yyerror(@4, "error: Default port value not allowed for inout ports.");
|
||||
break;
|
||||
case NetNet::PINPUT:
|
||||
pform_requires_sv(@4, "Default port value");
|
||||
ptmp->default_value = $4;
|
||||
break;
|
||||
case NetNet::POUTPUT:
|
||||
pform_make_var_init(@3, name, $4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Get the port declaration details, the port type
|
||||
and what not, from context data stored by the
|
||||
last port_declaration rule. */
|
||||
|
|
@ -4534,7 +4512,7 @@ port_declaration
|
|||
}
|
||||
ptmp = pform_module_port_reference(@2, name);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, $4, $1);
|
||||
port_declaration_context.port_type = NetNet::PINOUT;
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = use_type;
|
||||
port_declaration_context.data_type = $4;
|
||||
|
||||
|
|
@ -5260,19 +5238,12 @@ let_port_list
|
|||
|
||||
// FIXME: What about the attributes?
|
||||
let_port_item
|
||||
: attribute_list_opt let_formal_type IDENTIFIER dimensions_opt let_default_opt
|
||||
: attribute_list_opt let_formal_type IDENTIFIER dimensions_opt initializer_opt
|
||||
{ perm_string tmp3 = lex_strings.make($3);
|
||||
$$ = pform_make_let_port($2, tmp3, $4, $5);
|
||||
}
|
||||
;
|
||||
|
||||
let_default_opt
|
||||
: '=' expression
|
||||
{ $$ = $2; }
|
||||
|
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
let_formal_type
|
||||
: data_type_or_implicit
|
||||
{ $$ = $1; }
|
||||
|
|
@ -5446,15 +5417,9 @@ parameter_assign_list
|
|||
;
|
||||
|
||||
parameter_assign
|
||||
: IDENTIFIER parameter_value_ranges_opt
|
||||
: IDENTIFIER initializer_opt parameter_value_ranges_opt
|
||||
{ pform_set_parameter(@1, lex_strings.make($1), param_is_local,
|
||||
param_data_type, 0, $2);
|
||||
delete[]$1;
|
||||
}
|
||||
| IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||
{ PExpr*tmp = $3;
|
||||
pform_set_parameter(@1, lex_strings.make($1), param_is_local,
|
||||
param_data_type, tmp, $4);
|
||||
param_data_type, $2, $3);
|
||||
delete[]$1;
|
||||
}
|
||||
;
|
||||
|
|
@ -6986,11 +6951,6 @@ udp_port_list
|
|||
|
||||
udp_reg_opt: K_reg { $$ = true; } | { $$ = false; };
|
||||
|
||||
udp_initial_expr_opt
|
||||
: '=' expression { $$ = $2; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
udp_input_declaration_list
|
||||
: K_input IDENTIFIER
|
||||
{ std::list<perm_string>*tmp = new std::list<perm_string>;
|
||||
|
|
@ -7027,7 +6987,7 @@ udp_primitive
|
|||
names and declarations are all in the parameter list. */
|
||||
|
||||
| K_primitive IDENTIFIER
|
||||
'(' K_output udp_reg_opt IDENTIFIER udp_initial_expr_opt ','
|
||||
'(' K_output udp_reg_opt IDENTIFIER initializer_opt ','
|
||||
udp_input_declaration_list ')' ';'
|
||||
udp_body
|
||||
K_endprimitive label_opt
|
||||
|
|
|
|||
Loading…
Reference in New Issue