From 3080f5730d581afb6b6b3df25ff1f9f481c454f3 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 8 Jun 2015 20:27:38 +0100 Subject: [PATCH] Better implementation of assignment lval concatenation synthesis. --- synth2.cc | 55 +++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/synth2.cc b/synth2.cc index 2f8bf7fb2..f877a2215 100644 --- a/synth2.cc +++ b/synth2.cc @@ -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()) {