From 772f38ca1e1afcf55aa77b6c60ec80f6d1e97088 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 17 Jul 1999 18:06:02 +0000 Subject: [PATCH] Better handling of bit width of + operators. --- elaborate.cc | 23 +++++++++++++++++++++- netlist.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index a5d91dc62..b4f63585f 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.55 1999/07/17 03:08:31 steve Exp $" +#ident "$Id: elaborate.cc,v 1.56 1999/07/17 18:06:02 steve Exp $" #endif /* @@ -1218,6 +1218,15 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const if (dex) { string n = des->local_symbol(path); unsigned wid = msb - lsb + 1; + + if (! rv->set_width(wid)) { + cerr << rv->get_line() << ": Unable to match expression " + "width of " << rv->expr_width() << " to l-value" + " width of " << wid << "." << endl; + //XXXX delete rv; + return 0; + } + NetNet*tmp = new NetNet(n, NetNet::REG, wid); tmp->set_line(*this); des->add_signal(tmp); @@ -1251,6 +1260,15 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const if (mux == 0) { unsigned wid = msb - lsb + 1; + + if (! rv->set_width(wid)) { + cerr << rv->get_line() << ": Unable to match expression " + "width of " << rv->expr_width() << " to l-value" + " width of " << wid << "." << endl; + //XXXX delete rv; + return 0; + } + cur = new NetAssign(des->local_symbol(path), des, wid, rv); for (unsigned idx = 0 ; idx < wid ; idx += 1) connect(cur->pin(idx), reg->pin(idx+lsb)); @@ -1826,6 +1844,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.56 1999/07/17 18:06:02 steve + * Better handling of bit width of + operators. + * * Revision 1.55 1999/07/17 03:08:31 steve * part select in expressions. * diff --git a/netlist.cc b/netlist.cc index 0d868c3d4..53aca1c77 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.cc,v 1.43 1999/07/17 03:08:31 steve Exp $" +#ident "$Id: netlist.cc,v 1.44 1999/07/17 18:06:02 steve Exp $" #endif # include @@ -290,8 +290,9 @@ NetAssign::NetAssign(const string&n, Design*des, unsigned w, NetExpr*rv) { bool flag = rval_->set_width(w); if (flag == false) { - cerr << rv->get_line() << ": Expression bit width" << - " conflicts with l-value bit width." << endl; + cerr << rv->get_line() << ": Expression bit width of " << + rv->expr_width() << " conflicts with l-value bit width of " + << w << "." << endl; des->errors += 1; } } @@ -479,6 +480,24 @@ NetExpr* NetExpr::eval_tree() NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r) : op_(op), left_(l), right_(r) { + switch (op_) { + case '+': + case '-': + case '^': + case '&': + case '|': + case '%': + case '/': + if (l->expr_width() >= r->expr_width()) { + expr_width(l->expr_width()); + r->set_width(expr_width()); + } else { + expr_width(r->expr_width()); + l->set_width(expr_width()); + } + assert(l->expr_width() == r->expr_width()); + break; + } } NetEBinary::~NetEBinary() @@ -491,6 +510,11 @@ bool NetEBinary::set_width(unsigned w) { bool flag = true; switch (op_) { + case 'a': // logical and (&&) + assert(w == 1); + expr_width(w); + break; + /* Comparison operators allow the subexpressions to have their own natural width. However, I do need to make sure that the subexpressions have the same width. */ @@ -530,6 +554,20 @@ bool NetEBinary::set_width(unsigned w) case '+': case '-': + flag = true; + if (left_->expr_width() > right_->expr_width()) + right_->set_width(left_->expr_width()); + else + left_->set_width(right_->expr_width()); + + if (left_->expr_width() == w) + expr_width(w); + else if (left_->expr_width() == (w-1)) + expr_width(w); + else + flag = false; + break; + case '^': case '&': case '|': @@ -595,6 +633,7 @@ NetExpr* NetEBinary::eval_tree() NetEConcat::NetEConcat(unsigned cnt) : parms_(cnt) { + expr_width(0); } NetEConcat::~NetEConcat() @@ -608,6 +647,7 @@ void NetEConcat::set(unsigned idx, NetExpr*e) assert(idx < parms_.count()); assert(parms_[idx] == 0); parms_[idx] = e; + expr_width( expr_width() + e->expr_width() ); } bool NetEConcat::set_width(unsigned w) @@ -616,8 +656,8 @@ bool NetEConcat::set_width(unsigned w) for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) sum += parms_[idx]->expr_width(); + expr_width(sum); if (sum != w) return false; - expr_width(w); return true; } @@ -696,6 +736,7 @@ NetESignal::NetESignal(NetNet*n) NetESignal::NetESignal(const string&n, unsigned np) : NetExpr(np), NetNode(n, np) { + expr_width(pin_count()); } NetESignal::~NetESignal() @@ -708,10 +749,9 @@ NetESignal::~NetESignal() */ bool NetESignal::set_width(unsigned w) { - if (w < pin_count()) + if (w != pin_count()) return false; - expr_width(w); return true; } @@ -1316,6 +1356,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.44 1999/07/17 18:06:02 steve + * Better handling of bit width of + operators. + * * Revision 1.43 1999/07/17 03:08:31 steve * part select in expressions. *