Skip to content

Commit 4e12acf

Browse files
committed
Verilog: module port declarations with default value
This fixes the grammar to allow ANSI module port declarations that have a default value. This adds support for module ports (ANSI and non-ANSI) that have a default value to the type checker.
1 parent 0e0fa44 commit 4e12acf

File tree

6 files changed

+45
-1
lines changed

6 files changed

+45
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
port_with_value2.sv
3+
4+
^file .* line 2: output ports must not have a default value$
5+
^EXIT=2$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// output ports must not have a default value
2+
module M(output [31:0] o = 4567);
3+
4+
endmodule
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
port_with_value3.sv
3+
4+
^file .* line 2: expected constant expression, but got `M\.a'$
5+
^EXIT=2$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// default values for inputs must be constants
2+
module M(input a, input b = a);
3+
4+
endmodule

src/verilog/parser.y

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,14 +899,15 @@ ansi_port_declaration_brace:
899899

900900
// append to last one -- required to make
901901
// the grammar LR1
902-
| ansi_port_declaration_brace ',' port_identifier
902+
| ansi_port_declaration_brace ',' port_identifier ansi_port_initializer_opt
903903
{ $$=$1;
904904
exprt decl(ID_decl);
905905
decl.add_to_operands(std::move(stack_expr($3)));
906906
// grab the type and class from previous!
907907
const irept &prev=stack_expr($$).get_sub().back();
908908
decl.set(ID_type, prev.find(ID_type));
909909
decl.set(ID_class, prev.find(ID_class));
910+
decl.set(ID_value, stack_expr($4));
910911
stack_expr($$).move_to_sub(decl);
911912
}
912913
;
@@ -935,6 +936,7 @@ ansi_port_declaration:
935936
// and the unpacked_array_type goes onto the declarator.
936937
stack_expr($$).type() = std::move(stack_expr($1).type());
937938
addswap($2, ID_type, $3);
939+
stack_expr($2).set(ID_value, stack_expr($4));
938940
mto($$, $2); /* declarator */ }
939941
| variable_port_header port_identifier unpacked_dimension_brace ansi_port_initializer_opt
940942
{ init($$, ID_decl);
@@ -946,6 +948,7 @@ ansi_port_declaration:
946948
// and the unpacked_array_type goes onto the declarator.
947949
stack_expr($$).type() = std::move(stack_expr($1).type());
948950
addswap($2, ID_type, $3);
951+
stack_expr($2).set(ID_value, stack_expr($4));
949952
mto($$, $2); /* declarator */ }
950953
;
951954

src/verilog/verilog_elaborate.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ void verilog_typecheckt::collect_port_symbols(const verilog_declt &decl)
6262
new_symbol.base_name = base_name;
6363
new_symbol.pretty_name = strip_verilog_prefix(new_symbol.name);
6464

65+
// When using ANSI style, input ports may have an
66+
// elaboration-time constant default value
67+
auto &default_value = declarator.value();
68+
if(default_value.is_not_nil())
69+
{
70+
if(new_symbol.is_output)
71+
throw errort{}.with_location(default_value.source_location())
72+
<< "output ports must not have a default value";
73+
74+
auto value = default_value;
75+
convert_expr(value);
76+
auto elaborated_value = elaborate_constant_expression_check(value);
77+
new_symbol.value = elaborated_value;
78+
}
79+
6580
add_symbol(std::move(new_symbol));
6681
}
6782
}

0 commit comments

Comments
 (0)