From a288b0180c6fbae8a7c7d60b47bfe2ab1552a943 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 19 Nov 2008 13:28:50 -0800 Subject: [PATCH] Fix concatenations losing track of its repeat values. In some cases, it was possible for the NetEConcat expression to lose track of the repeat expression, causing the output result to have a broken concatenation expression. This also adds some internal checks that the concatenation widths add up properly. --- expr_synth.cc | 10 ++++++++++ net_expr.cc | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/expr_synth.cc b/expr_synth.cc index fcd690eaa..89fd2d2b8 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -745,6 +745,7 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope) des->add_node(concat); connect(concat->pin(0), osig->pin(0)); + unsigned count_input_width = 0; unsigned cur_pin = 1; for (unsigned rpt = 0; rpt < repeat(); rpt += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { @@ -752,9 +753,18 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope) ivl_assert(*this, tmp[concat_item]); connect(concat->pin(cur_pin), tmp[concat_item]->pin(0)); cur_pin += 1; + count_input_width += tmp[concat_item]->vector_width(); } } + if (count_input_width != osig->vector_width()) { + cerr << get_fileline() << ": internal error: " + << "NetEConcat input width = " << count_input_width + << ", expecting " << osig->vector_width() + << " (repeat=" << repeat() << ")" << endl; + des->errors += 1; + } + delete[]tmp; return osig; } diff --git a/net_expr.cc b/net_expr.cc index 9dd6b59b1..ff5482418 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -380,7 +380,8 @@ void NetEConcat::set(unsigned idx, NetExpr*e) NetEConcat* NetEConcat::dup_expr() const { - NetEConcat*dup = new NetEConcat(parms_.count(), repeat_); + NetEConcat*dup = new NetEConcat(parms_.count(), 0); + dup->set_line(*this); for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) if (parms_[idx]) { NetExpr*tmp = parms_[idx]->dup_expr(); @@ -389,7 +390,11 @@ NetEConcat* NetEConcat::dup_expr() const } + dup->repeat_ = repeat_? repeat_->dup_expr() : 0; + dup->repeat_value_ = repeat_value_; + dup->repeat_calculated_ = repeat_calculated_; dup->expr_width(expr_width()); + return dup; }