Skip to content

Commit 00206c1

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 ada2100 commit 00206c1

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/verilog/verilog_synthesis.cpp

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,56 @@ exprt verilog_synthesist::synth_expr(exprt expr, symbol_statet symbol_state)
405405

406406
/*******************************************************************\
407407
408+
Function: verilog_synthesist::synth_lhs_expr
409+
410+
Inputs:
411+
412+
Outputs:
413+
414+
Purpose:
415+
416+
\*******************************************************************/
417+
418+
exprt verilog_synthesist::synth_lhs_expr(exprt expr)
419+
{
420+
if(expr.id() == ID_symbol)
421+
{
422+
return expr; // leave as is
423+
}
424+
else if(expr.id() == ID_concatenation)
425+
{
426+
for(auto &op : expr.operands())
427+
op = synth_lhs_expr(op);
428+
429+
return expr;
430+
}
431+
else if(expr.id() == ID_verilog_non_indexed_part_select)
432+
{
433+
auto &part_select = to_verilog_non_indexed_part_select_expr(expr);
434+
part_select.src() = synth_lhs_expr(part_select.src());
435+
// The indices are expected to be constants.
436+
return expr;
437+
}
438+
else if(
439+
expr.id() == ID_verilog_indexed_part_select_plus ||
440+
expr.id() == ID_verilog_indexed_part_select_minus)
441+
{
442+
auto &part_select = to_verilog_indexed_part_select_plus_or_minus_expr(expr);
443+
part_select.src() = synth_lhs_expr(part_select.src());
444+
// The index need not be a constant, and is _not_ an lhs.
445+
part_select.index() =
446+
synth_expr(part_select.index(), symbol_statet::CURRENT);
447+
return expr;
448+
}
449+
else
450+
{
451+
DATA_INVARIANT_WITH_DIAGNOSTICS(
452+
false, "unexpected lhs during synthesis", to_string(expr));
453+
}
454+
}
455+
456+
/*******************************************************************\
457+
408458
Function: verilog_synthesist::value_mapt::guarded_expr
409459
410460
Inputs:
@@ -2283,9 +2333,10 @@ void verilog_synthesist::synth_assign(const verilog_assignt &statement)
22832333
<< "unexpected assignment statement";
22842334
}
22852335

2286-
const exprt &lhs = statement.lhs();
2287-
exprt rhs = statement.rhs();
2336+
exprt lhs = statement.lhs();
2337+
lhs = synth_lhs_expr(lhs);
22882338

2339+
exprt rhs = statement.rhs();
22892340
rhs = synth_expr(rhs, symbol_statet::CURRENT);
22902341

22912342
irep_idt compound_id = irep_idt{};

src/verilog/verilog_synthesis_class.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ class verilog_synthesist:
177177

178178
exprt guarded_expr(exprt) const;
179179
};
180-
180+
181+
// expressions
182+
[[nodiscard]] exprt synth_lhs_expr(exprt expr);
183+
181184
exprt current_value(
182185
const value_mapt::mapt &map,
183186
const symbolt &symbol,

0 commit comments

Comments
 (0)