Better implementation of assignment lval concatenation synthesis.

This commit is contained in:
Martin Whitaker 2015-06-08 20:27:38 +01:00
parent 4068c172f4
commit 3080f5730d
1 changed files with 27 additions and 28 deletions

View File

@ -70,6 +70,33 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
NexusSet&nex_map, NetBus&nex_out,
NetBus&accumulated_nex_out)
{
/* If the lval is a concatenation, synthesise each part
separately. */
if (lval_->more ) {
/* Temporarily set the lval_ and rval_ fields for each
part in turn and recurse. Restore them when done. */
NetAssign_*full_lval = lval_;
NetExpr*full_rval = rval_;
unsigned offset = 0;
while (lval_) {
unsigned width = lval_->lwidth();
NetEConst*base = new NetEConst(verinum(offset));
base->set_line(*this);
rval_ = new NetESelect(full_rval->dup_expr(), base, width);
rval_->set_line(*this);
eval_expr(rval_, width);
NetAssign_*more = lval_->more;
lval_->more = 0;
synth_async(des, scope, nex_map, nex_out,
accumulated_nex_out);
lval_ = lval_->more = more;
offset += width;
}
lval_ = full_lval;
rval_ = full_rval;
return true;
}
NetNet*rsig = rval_->synthesize(des, scope, rval_);
assert(rsig);
@ -100,34 +127,6 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
<< ", nex_out.pin_count()==" << nex_out.pin_count() << endl;
}
if (lval_->more ) {
unsigned base = 0, width = 1;
unsigned i = 0;
NetAssign_ *lval = lval_;
while (lval) {
NetNet *llsig = lval->sig();
width = lval->lwidth();
ivl_variable_type_t tmp_data_type = llsig->data_type();
netvector_t *tmp_type = new netvector_t(tmp_data_type, llsig->vector_width()-1, 0);
NetNet *tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
tmp->local_flag(true);
NetPartSelect *ps = new NetPartSelect(rsig, base, width, NetPartSelect::VP);
ps->set_line(*this);
des->add_node(ps);
connect(tmp->pin(0), ps->pin(0));
connect(nex_out.pin(i), tmp->pin(0));
base += width;
i++;
lval->turn_sig_to_wire_on_release();
lval = lval->more;
}
return true;
}
// Here we note if the l-value is actually a bit/part
// select. If so, generate a NetPartSelect to perform the select.
if ((lval_->lwidth()!=lsig->vector_width()) && !scope->loop_index_tmp.empty()) {