Skip to content

Commit b30a313

Browse files
authored
Merge pull request #268 from diffblue/parameter-types
Verilog: parameters may be typed
2 parents badff3f + c7f4dc7 commit b30a313

File tree

4 files changed

+74
-36
lines changed

4 files changed

+74
-36
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
localparam3.v
3+
--bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module main;
2+
3+
localparam [7:0] foo = 1;
4+
parameter [7:0] bar = 2;
5+
6+
always assert property1: $bits(foo) == 8;
7+
always assert property2: $bits(bar) == 8;
8+
9+
endmodule

src/verilog/parser.y

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,12 +849,16 @@ package_item:
849849

850850
local_parameter_declaration:
851851
TOK_LOCALPARAM data_type_or_implicit list_of_param_assignments
852-
{ init($$, ID_local_parameter_decl); swapop($$, $3); }
852+
{ init($$, ID_local_parameter_decl);
853+
stack_expr($$).type() = std::move(stack_type($2));
854+
swapop($$, $3); }
853855
;
854856

855857
parameter_declaration:
856858
TOK_PARAMETER data_type_or_implicit list_of_param_assignments
857-
{ init($$, ID_parameter_decl); swapop($$, $3); }
859+
{ init($$, ID_parameter_decl);
860+
stack_expr($$).type() = std::move(stack_type($2));
861+
swapop($$, $3); }
858862
;
859863

860864
specparam_declaration:

src/verilog/verilog_elaborate_constants.cpp

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -36,52 +36,55 @@ void verilog_typecheckt::elaborate_constants()
3636

3737
std::vector<irep_idt> to_be_elaborated;
3838

39-
auto add_parameter = [this, &to_be_elaborated](
40-
const verilog_parameter_declt::declaratort &declarator)
41-
{
42-
symbolt symbol;
43-
symbol.mode = mode;
44-
symbol.module = module_identifier;
45-
symbol.base_name = declarator.identifier();
46-
symbol.name = hierarchical_identifier(symbol.base_name);
47-
symbol.pretty_name = strip_verilog_prefix(symbol.name);
48-
symbol.is_macro = true;
49-
symbol.value = declarator.value();
50-
symbol.type = typet(ID_to_be_elaborated);
51-
symbol.location = declarator.source_location();
52-
53-
auto result = symbol_table.insert(std::move(symbol));
54-
55-
if(!result.second)
56-
{
57-
error().source_location = declarator.source_location();
58-
error() << "definition of symbol `" << declarator.identifier()
59-
<< "\' conflicts with earlier definition at "
60-
<< result.first.location << eom;
61-
throw 0;
62-
}
63-
64-
to_be_elaborated.push_back(result.first.name);
65-
};
39+
auto add_parameter =
40+
[this, &to_be_elaborated](
41+
const typet &type,
42+
const verilog_parameter_declt::declaratort &declarator) {
43+
symbolt symbol{
44+
hierarchical_identifier(declarator.identifier()),
45+
type_with_subtypet(ID_to_be_elaborated, type),
46+
mode};
47+
48+
symbol.module = module_identifier;
49+
symbol.base_name = declarator.identifier();
50+
symbol.pretty_name = strip_verilog_prefix(symbol.name);
51+
symbol.is_macro = true;
52+
symbol.value = declarator.value();
53+
symbol.location = declarator.source_location();
54+
55+
auto result = symbol_table.insert(std::move(symbol));
56+
57+
if(!result.second)
58+
{
59+
throw errort().with_location(declarator.source_location())
60+
<< "definition of symbol `" << declarator.identifier()
61+
<< "\' conflicts with earlier definition at "
62+
<< result.first.location;
63+
}
64+
65+
to_be_elaborated.push_back(result.first.name);
66+
};
6667

6768
// Gather the port declarations from the module source.
6869
auto &module_source =
6970
to_verilog_module_source(module_symbol.type.find(ID_module_source));
7071

7172
for(auto &decl : module_source.parameter_port_list())
72-
add_parameter(decl);
73+
add_parameter(typet(ID_nil), decl);
7374

7475
for(auto &item : module_source.module_items())
7576
{
7677
if(item.id() == ID_parameter_decl)
7778
{
78-
for(auto &decl : to_verilog_parameter_decl(item).declarations())
79-
add_parameter(decl);
79+
auto &parameter_decl = to_verilog_parameter_decl(item);
80+
for(auto &decl : parameter_decl.declarations())
81+
add_parameter(parameter_decl.type(), decl);
8082
}
8183
else if(item.id() == ID_local_parameter_decl)
8284
{
83-
for(auto &decl : to_verilog_local_parameter_decl(item).declarations())
84-
add_parameter(decl);
85+
auto &localparam_decl = to_verilog_local_parameter_decl(item);
86+
for(auto &decl : localparam_decl.declarations())
87+
add_parameter(localparam_decl.type(), decl);
8588
}
8689
}
8790

@@ -110,11 +113,26 @@ void verilog_typecheckt::elaborate_parameter(irep_idt identifier)
110113
if(symbol.type.id() == ID_to_be_elaborated)
111114
{
112115
// mark as "elaborating" to detect cycles
113-
symbol.type = typet(ID_elaborating);
116+
symbol.type.id(ID_elaborating);
114117

118+
// first elaborate the value
115119
convert_expr(symbol.value);
116120
symbol.value = elaborate_constant_expression(symbol.value);
117-
symbol.type = symbol.value.type();
121+
122+
// Now elaborate the type. It may be given or implicit.
123+
if(to_type_with_subtype(symbol.type).subtype().is_nil())
124+
{
125+
// It's implicit. Use type of value.
126+
symbol.type = symbol.value.type();
127+
}
128+
else
129+
{
130+
// It's given. Elaborate it, then cast value.
131+
auto elaborated_type =
132+
convert_type(to_type_with_subtype(symbol.type).subtype());
133+
symbol.type = elaborated_type;
134+
propagate_type(symbol.value, symbol.type);
135+
}
118136
}
119137
else if(symbol.type.id() == ID_elaborating)
120138
{

0 commit comments

Comments
 (0)