Skip to content

Commit 2e3ac27

Browse files
committed
Verilog: separate synthesis for LHS expressions
The left-hand side of assignments requires special-case synthesis; the symbol to be assigned must not be replaced by its value, but any array indices must be.
1 parent dc3a36b commit 2e3ac27

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

src/verilog/verilog_synthesis.cpp

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,80 @@ verilog_synthesist::synthesis_constant(const exprt &expr)
440440

441441
/*******************************************************************\
442442
443+
Function: verilog_synthesist::synth_lhs_expr
444+
445+
Inputs:
446+
447+
Outputs:
448+
449+
Purpose:
450+
451+
\*******************************************************************/
452+
453+
exprt verilog_synthesist::synth_lhs_expr(exprt expr)
454+
{
455+
// case-split on possible expressions on the LHS of an assignment
456+
if(expr.id() == ID_symbol)
457+
{
458+
return expr; // leave as is
459+
}
460+
else if(expr.id() == ID_concatenation)
461+
{
462+
for(auto &op : expr.operands())
463+
op = synth_lhs_expr(op);
464+
465+
return expr;
466+
}
467+
else if(expr.id() == ID_verilog_non_indexed_part_select)
468+
{
469+
auto &part_select = to_verilog_non_indexed_part_select_expr(expr);
470+
part_select.src() = synth_lhs_expr(part_select.src());
471+
// The indices are expected to be constants.
472+
return expr;
473+
}
474+
else if(
475+
expr.id() == ID_verilog_indexed_part_select_plus ||
476+
expr.id() == ID_verilog_indexed_part_select_minus)
477+
{
478+
auto &part_select = to_verilog_indexed_part_select_plus_or_minus_expr(expr);
479+
part_select.src() = synth_lhs_expr(part_select.src());
480+
// The index need not be a constant, and is _not_ an lhs.
481+
part_select.index() =
482+
synth_expr(part_select.index(), symbol_statet::CURRENT);
483+
return expr;
484+
}
485+
else if(expr.id() == ID_index)
486+
{
487+
auto &index_expr = to_index_expr(expr);
488+
// The array is an 'lhs' but the index is not.
489+
index_expr.array() = synth_lhs_expr(index_expr.array());
490+
index_expr.index() = synth_expr(index_expr.index(), symbol_statet::CURRENT);
491+
return expr;
492+
}
493+
else if(expr.id() == ID_extractbit)
494+
{
495+
auto &extractbit_expr = to_extractbit_expr(expr);
496+
// The vector is an 'lhs' but the bit index is not.
497+
extractbit_expr.src() = synth_lhs_expr(extractbit_expr.src());
498+
extractbit_expr.index() =
499+
synth_expr(extractbit_expr.index(), symbol_statet::CURRENT);
500+
return expr;
501+
}
502+
else if(expr.id() == ID_member)
503+
{
504+
auto &member_expr = to_member_expr(expr);
505+
member_expr.struct_op() = synth_lhs_expr(member_expr.struct_op());
506+
return expr;
507+
}
508+
else
509+
{
510+
DATA_INVARIANT_WITH_DIAGNOSTICS(
511+
false, "unexpected lhs during synthesis", expr.pretty());
512+
}
513+
}
514+
515+
/*******************************************************************\
516+
443517
Function: verilog_synthesist::value_mapt::guarded_expr
444518
445519
Inputs:
@@ -2318,9 +2392,10 @@ void verilog_synthesist::synth_assign(const verilog_assignt &statement)
23182392
<< "unexpected assignment statement";
23192393
}
23202394

2321-
const exprt &lhs = statement.lhs();
2322-
exprt rhs = statement.rhs();
2395+
exprt lhs = statement.lhs();
2396+
lhs = synth_lhs_expr(lhs);
23232397

2398+
exprt rhs = statement.rhs();
23242399
rhs = synth_expr(rhs, symbol_statet::CURRENT);
23252400

23262401
irep_idt compound_id = irep_idt{};

src/verilog/verilog_synthesis_class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class verilog_synthesist:
179179
};
180180

181181
// expressions
182+
[[nodiscard]] exprt synth_lhs_expr(exprt expr);
182183
[[nodiscard]] std::optional<mp_integer> synthesis_constant(const exprt &);
183184

184185
exprt current_value(

0 commit comments

Comments
 (0)