Skip to content

Commit

Permalink
Merge pull request #349 from diffblue/verilog-declaratort
Browse files Browse the repository at this point in the history
Verilog: use declaratort instead of symbol_exprt
  • Loading branch information
kroening authored Jan 16, 2024
2 parents 3f82882 + 9be1cd4 commit 8f0a473
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 123 deletions.
34 changes: 26 additions & 8 deletions src/verilog/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,7 @@ type_declaration:
init($$, ID_decl);
stack_expr($$).set(ID_class, ID_typedef);
addswap($$, ID_type, $2);
stack_expr($3).id(ID_declarator);
mto($$, $3);
}
;
Expand All @@ -1186,7 +1187,8 @@ list_of_net_names:
net_name: net_identifier packed_dimension_brace
{
$$=$1;
stack_expr($$).add(ID_type)=stack_expr($2);
stack_expr($$).id(ID_declarator);
addswap($$, ID_type, $2);
}
;

Expand Down Expand Up @@ -1456,9 +1458,15 @@ delay_value:

list_of_genvar_identifiers:
genvar_identifier
{ init($$); mto($$, $1); }
{ init($$);
stack_expr($1).id(ID_declarator);
mto($$, $1);
}
| list_of_genvar_identifiers ',' genvar_identifier
{ $$=$1; mto($$, $3); }
{ $$=$1;
stack_expr($3).id(ID_declarator);
mto($$, $3);
}
;

defparam_assignment:
Expand All @@ -1482,9 +1490,13 @@ list_of_variable_decl_assignments:

list_of_variable_identifiers:
variable_identifier
{ init($$); mto($$, $1); }
{ init($$);
stack_expr($1).id(ID_declarator);
mto($$, $1); }
| list_of_variable_identifiers ',' variable_identifier
{ $$=$1; mto($$, $3); }
{ $$=$1;
stack_expr($3).id(ID_declarator);
mto($$, $3); }
;

// This rule is more permissive that the grammar in the standard
Expand Down Expand Up @@ -1603,9 +1615,15 @@ automatic_opt:

list_of_port_identifiers:
port_identifier unpacked_dimension_brace
{ init($$); stack_expr($1).type().swap(stack_expr($2)); mto($$, $1); }
{ init($$);
stack_expr($1).id(ID_declarator);
addswap($1, ID_type, $2);
mto($$, $1); }
| list_of_port_identifiers ',' port_identifier unpacked_dimension_brace
{ $$=$1; stack_expr($3).type().swap(stack_expr($4)); mto($$, $3); }
{ $$=$1;
stack_expr($3).id(ID_declarator);
addswap($3, ID_type, $4);
mto($$, $3); }
;

range_opt:
Expand All @@ -1624,7 +1642,7 @@ net_decl_assignment: net_identifier '=' expression

variable_decl_assignment:
variable_identifier variable_dimension_brace
{ $$ = $1; stack_expr($$).type().swap(stack_expr($2)); }
{ $$ = $1; stack_expr($$).id(ID_declarator); addswap($$, ID_type, $2); }
| variable_identifier variable_dimension_brace '=' expression
{ $$ = $1; stack_expr($$).id(ID_declarator);
addswap($$, ID_type, $2);
Expand Down
38 changes: 13 additions & 25 deletions src/verilog/verilog_elaborate_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,11 @@ void verilog_typecheckt::collect_symbols(const verilog_declt &decl)
// Typedef?
if(decl_class == ID_typedef)
{
for(auto &declarator : decl.operands())
for(auto &declarator : decl.declarators())
{
auto symbol_expr = [](const exprt &declarator) -> const symbol_exprt & {
if(declarator.id() == ID_symbol)
return to_symbol_expr(declarator);
else
DATA_INVARIANT(false, "failed to find symbol in declarator");
}(declarator);

auto base_name = symbol_expr.get_identifier();
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

auto base_name = declarator.base_name();
auto full_identifier = hierarchical_identifier(base_name);

symbolt symbol{
Expand Down Expand Up @@ -203,25 +197,19 @@ void verilog_typecheckt::collect_symbols(const verilog_declt &decl)

for(auto &declarator : decl.declarators())
{
if(declarator.id() == ID_symbol)
{
symbol.base_name = declarator.identifier();
symbol.location = declarator.source_location();

if(declarator.type().is_nil())
symbol.type = type;
else if(declarator.type().id() == ID_array)
symbol.type = array_type(declarator.type(), type);
else
{
throw errort().with_location(declarator.source_location())
<< "unexpected type on declarator";
}
}
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

symbol.base_name = declarator.identifier();
symbol.location = declarator.source_location();

if(declarator.type().is_nil())
symbol.type = type;
else if(declarator.type().id() == ID_array)
symbol.type = array_type(declarator.type(), type);
else
{
throw errort().with_location(declarator.source_location())
<< "unexpected declaration: " << declarator.id();
<< "unexpected type on declarator";
}

if(symbol.base_name.empty())
Expand Down
5 changes: 5 additions & 0 deletions src/verilog/verilog_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ class verilog_parameter_declt : public verilog_module_itemt
return static_cast<exprt &>(add(ID_value));
}

bool has_value() const
{
return find(ID_value).is_not_nil();
}

// helper to generate a symbol expression
symbol_exprt symbol_expr() const
{
Expand Down
59 changes: 18 additions & 41 deletions src/verilog/verilog_interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,29 +310,18 @@ void verilog_typecheckt::interface_function_or_task_decl(const verilog_declt &de

for(auto &declarator : decl.declarators())
{
if(declarator.id() == ID_symbol)
{
symbol.base_name = declarator.identifier();
symbol.type=type;
}
else if(declarator.id() == ID_array)
{
symbol.base_name = declarator.identifier();
symbol.type = array_type(declarator, type);
}
else
{
throw errort().with_location(declarator.source_location())
<< "unexpected declaration: " << declarator.id();
}
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

if(symbol.base_name=="")
symbol.base_name = declarator.base_name();

if(symbol.base_name.empty())
{
error().source_location = decl.source_location();
error() << "empty symbol name" << eom;
throw 0;
throw errort().with_location(decl.source_location())
<< "empty symbol name";
}

symbol.type = type;

symbol.name = hierarchical_identifier(symbol.base_name);

symbol.pretty_name=strip_verilog_prefix(symbol.name);
Expand Down Expand Up @@ -451,32 +440,20 @@ void verilog_typecheckt::interface_module_decl(

for(auto &declarator : decl.declarators())
{
if(declarator.id() == ID_symbol)
{
symbol.base_name = declarator.identifier();
symbol.location = declarator.source_location();
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

if(declarator.type().is_nil())
symbol.type=type;
else if(declarator.type().id() == ID_array)
symbol.type = array_type(declarator.type(), type);
else
{
error().source_location = symbol.location;
error() << "unexpected type on declarator" << eom;
throw 0;
}
}
else if(declarator.id() == ID_declarator)
{
symbol.base_name = declarator.base_name();
symbol.location = declarator.source_location();
symbol.base_name = declarator.base_name();
symbol.location = declarator.source_location();

if(declarator.type().is_nil())
symbol.type=type;
}
else if(declarator.type().id() == ID_array)
symbol.type = array_type(declarator.type(), type);
else
{
throw errort().with_location(declarator.source_location())
<< "unexpected declaration: " << declarator.id();
error().source_location = symbol.location;
error() << "unexpected type on declarator" << eom;
throw 0;
}

if(symbol.base_name.empty())
Expand Down
30 changes: 16 additions & 14 deletions src/verilog/verilog_synthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1482,29 +1482,31 @@ void verilog_synthesist::synth_decl(const verilog_declt &statement) {
// Look for supply0 and supply1 port class.
if(statement.get_class() == ID_supply0 || statement.get_class() == ID_supply1)
{
for(auto &op : statement.operands())
for(auto &declarator : statement.declarators())
{
if(op.id() == ID_symbol)
{
const symbolt &symbol = ns.lookup(to_symbol_expr(op));
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

if(!symbol.is_state_var)
{
// much like a continuous assignment
const auto value =
make_supply_value(statement.get_class(), op.type());
verilog_continuous_assignt assign(equal_exprt(op, value));
assign.add_source_location() = op.source_location();
synth_continuous_assign(assign);
}
auto symbol_expr = declarator.symbol_expr();
const symbolt &symbol = ns.lookup(symbol_expr);

if(!symbol.is_state_var)
{
// much like a continuous assignment
const auto value =
make_supply_value(statement.get_class(), symbol_expr.type());
verilog_continuous_assignt assign(equal_exprt(symbol_expr, value));
assign.add_source_location() = declarator.source_location();
synth_continuous_assign(assign);
}
}
}

for(auto &declarator : statement.declarators())
{
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

// This is reg x = ... or wire x = ...
if(declarator.id() == ID_declarator)
if(declarator.has_value())
{
// These are only allowed for module-level declarations,
// not block-level.
Expand Down
56 changes: 21 additions & 35 deletions src/verilog/verilog_typecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,41 +467,32 @@ void verilog_typecheckt::convert_decl(verilog_declt &decl)

for(auto &declarator : decl.declarators())
{
if(declarator.id() == ID_symbol)
{
auto &symbol_expr = to_symbol_expr(declarator);

// in a named block?
irep_idt named_block;
if(!named_blocks.empty())
named_block = named_blocks.back();
DATA_INVARIANT(declarator.id() == ID_declarator, "must have declarator");

// fix the type and identifier
irep_idt full_identifier;
// in a named block?
irep_idt named_block;
if(!named_blocks.empty())
named_block = named_blocks.back();

if(!function_or_task_name.empty())
full_identifier = id2string(function_or_task_name) + "." +
id2string(named_block) +
id2string(symbol_expr.get_identifier());
else
full_identifier = id2string(module_identifier) + "." +
id2string(named_block) +
id2string(symbol_expr.get_identifier());
// fix the type and identifier
irep_idt full_identifier;

symbol_expr.set_identifier(full_identifier);
if(!function_or_task_name.empty())
full_identifier = id2string(function_or_task_name) + "." +
id2string(named_block) +
id2string(declarator.base_name());
else
full_identifier = id2string(module_identifier) + "." +
id2string(named_block) +
id2string(declarator.base_name());

symbolt &symbol = symbol_table_lookup(full_identifier);
declarator.type() = symbol.type;
}
else if(declarator.id() == ID_declarator)
{
const irep_idt identifier =
id2string(module_identifier) + "." + id2string(declarator.base_name());
symbolt &symbol = symbol_table_lookup(full_identifier);
declarator.type() = symbol.type;

symbolt &symbol=symbol_table_lookup(identifier);
declarator.type() = symbol.type;
declarator.identifier(identifier);
declarator.identifier(full_identifier);

if(declarator.has_value())
{
auto &rhs = declarator.value();
convert_expr(rhs);
propagate_type(rhs, symbol.type);
Expand All @@ -514,15 +505,10 @@ void verilog_typecheckt::convert_decl(verilog_declt &decl)
if(!symbol.value.is_nil())
{
throw errort().with_location(declarator.source_location())
<< "Net " << identifier << " is assigned twice";
<< "Net " << symbol.display_name() << " is assigned twice";
}
}
}
else
{
throw errort().with_location(declarator.source_location())
<< "unexpected declarator " << declarator.id();
}
}
}

Expand Down

0 comments on commit 8f0a473

Please sign in to comment.