Support struct member part selects in l-values.

This commit is contained in:
Stephen Williams 2019-09-27 13:51:51 -07:00
parent 65aff65344
commit d7ee6bb6bb
1 changed files with 38 additions and 12 deletions

View File

@ -1253,7 +1253,9 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
if (!member_comp.index.empty()) if (!member_comp.index.empty())
use_sel = member_comp.index.back().sel; use_sel = member_comp.index.back().sel;
if (use_sel != index_component_t::SEL_NONE && use_sel != index_component_t::SEL_BIT) { if (use_sel != index_component_t::SEL_NONE
&& use_sel != index_component_t::SEL_BIT
&& use_sel != index_component_t::SEL_PART) {
cerr << get_fileline() << ": sorry: Assignments to part selects of " cerr << get_fileline() << ": sorry: Assignments to part selects of "
"a struct member are not yet supported." << endl; "a struct member are not yet supported." << endl;
des->errors += 1; des->errors += 1;
@ -1293,26 +1295,42 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index); bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index);
ivl_assert(*this, rc); ivl_assert(*this, rc);
// Evaluate the last index expression into a constant long. if (debug_elaborate) {
NetExpr*texpr = elab_and_eval(des, scope, member_comp.index.back().msb, -1, true); cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
long tmp; << "prefix_indices.size()==" << prefix_indices.size()
if (texpr == 0 || !eval_as_long(tmp, texpr)) { << ", mem_packed_dims.size()==" << mem_packed_dims.size()
cerr << get_fileline() << ": error: " << " (netvector_t context)"
"Array index expressions must be constant here." << endl; << endl;
des->errors += 1;
return false;
} }
delete texpr; long tail_off = 0;
unsigned long tail_wid = 0;
rc = calculate_part(this, des, scope, member_comp.index.back(), tail_off, tail_wid);
ivl_assert(*this, rc);
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
<< "calculate_part for tail returns tail_off=" << tail_off
<< ", tail_wid=" << tail_wid
<< endl;
}
// Now use the prefix_to_slice function to calculate the // Now use the prefix_to_slice function to calculate the
// offset and width of the addressed slice of the member. // offset and width of the addressed slice of the member.
long loff; long loff;
unsigned long lwid; unsigned long lwid;
prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid); prefix_to_slice(mem_packed_dims, prefix_indices, tail_off, loff, lwid);
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
<< "Calculate loff=" << loff << " lwid=" << lwid
<< " tail_off=" << tail_off << " tail_wid=" << tail_wid
<< " off=" << off << " use_width=" << use_width
<< endl;
}
off += loff; off += loff;
use_width = lwid; use_width = lwid * tail_wid;
} }
// The netvector_t only has atom elements, to // The netvector_t only has atom elements, to
@ -1346,6 +1364,14 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index); bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index);
ivl_assert(*this, rc); ivl_assert(*this, rc);
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: "
<< "prefix_indices.size()==" << prefix_indices.size()
<< ", mem_packed_dims.size()==" << mem_packed_dims.size()
<< " (netparray_t context)"
<< endl;
}
// Evaluate the last index expression into a constant long. // Evaluate the last index expression into a constant long.
NetExpr*texpr = elab_and_eval(des, scope, member_comp.index.back().msb, -1, true); NetExpr*texpr = elab_and_eval(des, scope, member_comp.index.back().msb, -1, true);
long tmp; long tmp;