From 1c41f8ebd21ef32bfc4bbc66a1ea8b38a78eb810 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 23 Sep 1999 00:21:54 +0000 Subject: [PATCH] Move set_width methods into a single file, Add the NetEBLogic class for logic expressions, Fix error setting with of && in if statements. --- Makefile.in | 3 +- elaborate.cc | 13 ++- eval_tree.cc | 12 ++- netlist.cc | 225 ++++----------------------------------------- netlist.h | 26 +++++- set_width.cc | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 321 insertions(+), 213 deletions(-) create mode 100644 set_width.cc diff --git a/Makefile.in b/Makefile.in index cc547489e..19931db35 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.17 1999/09/20 02:21:10 steve Exp $" +#ident "$Id: Makefile.in,v 1.18 1999/09/23 00:21:54 steve Exp $" # # SHELL = /bin/sh @@ -63,6 +63,7 @@ FF = nobufz.o propinit.o sigfold.o xnfio.o xnfsyn.o O = main.o cprop.o design_dump.o elaborate.o elab_expr.o emit.o eval.o \ eval_tree.o functor.o \ lexor.o mangle.o netlist.o parse.o parse_misc.o pform.o pform_dump.o \ +set_width.o \ verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \ PTask.o PFunction.o PWire.o Statement.o \ $(FF) $(TT) diff --git a/elaborate.cc b/elaborate.cc index c6e898758..7b965c3ec 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.96 1999/09/22 21:25:42 steve Exp $" +#ident "$Id: elaborate.cc,v 1.97 1999/09/23 00:21:54 steve Exp $" #endif /* @@ -1333,6 +1333,12 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const tmp->set_line(*this); break; + case 'a': + case 'o': + tmp = new NetEBLogic(op_, lp, rp); + tmp->set_line(*this); + break; + case '^': case '&': case '|': @@ -2625,6 +2631,11 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.97 1999/09/23 00:21:54 steve + * Move set_width methods into a single file, + * Add the NetEBLogic class for logic expressions, + * Fix error setting with of && in if statements. + * * Revision 1.96 1999/09/22 21:25:42 steve * Expand bits in delayed assignments. * diff --git a/eval_tree.cc b/eval_tree.cc index b55bb4ecc..2ce28b989 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: eval_tree.cc,v 1.2 1999/09/21 00:13:40 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.3 1999/09/23 00:21:54 steve Exp $" #endif # include "netlist.h" @@ -106,6 +106,11 @@ NetExpr* NetEBComp::eval_tree() } } +NetExpr* NetEBLogic::eval_tree() +{ + return 0; +} + NetExpr* NetEConcat::eval_tree() { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { @@ -186,6 +191,11 @@ NetExpr* NetEParam::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.3 1999/09/23 00:21:54 steve + * Move set_width methods into a single file, + * Add the NetEBLogic class for logic expressions, + * Fix error setting with of && in if statements. + * * Revision 1.2 1999/09/21 00:13:40 steve * Support parameters that reference other paramters. * diff --git a/netlist.cc b/netlist.cc index 53ac5c6fb..327d2524b 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.67 1999/09/21 00:13:40 steve Exp $" +#ident "$Id: netlist.cc,v 1.68 1999/09/23 00:21:54 steve Exp $" #endif # include @@ -703,17 +703,6 @@ const NetFuncDef* NetEUFunc::definition() const return func_; } -/* - * XXXX FIX ME: For now, just take whatever the caller says as my - * width. What I really need to do is note the width of the output - * parameter of the function definition and take that into account. - */ -bool NetEUFunc::set_width(unsigned wid) -{ - expr_width(wid); - return true; -} - NetEUFunc* NetEUFunc::dup_expr() const { assert(0); @@ -738,14 +727,6 @@ NetExpr::~NetExpr() { } -bool NetExpr::set_width(unsigned w) -{ - cerr << typeid(*this).name() << ": set_width(unsigned) " - "not implemented." << endl; - expr_width(w); - return false; -} - NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r) : NetEBinary(op, l, r) { @@ -771,29 +752,6 @@ NetEBAdd::~NetEBAdd() { } -/* - * The bitwise logical operators have operands the same size as the - * result. Anything else is a mess. - */ -bool NetEBAdd::set_width(unsigned w) -{ - bool 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; - - return flag; -} - NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r) : NetEBinary(op, l, r) { @@ -803,21 +761,6 @@ NetEBBits::~NetEBBits() { } -/* - * The bitwise logical operators have operands the same size as the - * result. Anything else is a mess. - */ -bool NetEBBits::set_width(unsigned w) -{ - bool flag = true; - - flag = left_->set_width(w) && flag; - flag = right_->set_width(w) && flag; - expr_width(w); - - return flag; -} - NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r) : NetEBinary(op, l, r) { @@ -828,24 +771,6 @@ NetEBComp::~NetEBComp() { } -/* - * 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. - */ -bool NetEBComp::set_width(unsigned w) -{ - bool flag = true; - - assert(w == 1); - expr_width(w); - flag = left_->set_width(right_->expr_width()); - if (!flag) - flag = right_->set_width(left_->expr_width()); - - return flag; -} - NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r) : op_(op), left_(l), right_(r) { @@ -879,47 +804,21 @@ NetEBinary::~NetEBinary() delete right_; } -bool NetEBinary::set_width(unsigned w) -{ - bool flag = true; - switch (op_) { - case 'a': // logical and (&&) - case 'o': // logical or (||) - expr_width(1); - flag = false; - break; - - case 'l': // left shift (<<) - case 'r': // right shift (>>) - flag = left_->set_width(w); - expr_width(w); - break; - - /* The default rule is that the operands of the binary - operator might as well use the same width as the - output from the binary operation. */ - default: - expr_width(left_->expr_width() > right_->expr_width() - ? left_->expr_width() : right_->expr_width()); - cerr << "NetEBinary::set_width(): Using default for " << - op_ << "." << endl; - flag = false; - - case '%': - case '/': - flag = left_->set_width(w) && flag; - flag = right_->set_width(w) && flag; - expr_width(w); - break; - } - return flag; -} - NetEBinary* NetEBinary::dup_expr() const { assert(0); } +NetEBLogic::NetEBLogic(char op, NetExpr*l, NetExpr*r) +: NetEBinary(op, l, r) +{ + expr_width(1); +} + +NetEBLogic::~NetEBLogic() +{ +} + NetEConcat::NetEConcat(unsigned cnt, unsigned r) : parms_(cnt), repeat_(r) { @@ -940,29 +839,6 @@ void NetEConcat::set(unsigned idx, NetExpr*e) expr_width( expr_width() + repeat_*e->expr_width() ); } -/* - * Add up the widths from all the expressions that are concatenated - * together. This is the width of the expression, tough luck if you - * want it otherwise. - * - * If during the course of elaboration one of the sub-expressions is - * broken, then don't count it in the width. This doesn't really - * matter because the null expression is indication of an error and - * the compiler will not go beyond elaboration. - */ -bool NetEConcat::set_width(unsigned w) -{ - unsigned sum = 0; - for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) - if (parms_[idx] != 0) - sum += parms_[idx]->expr_width(); - - sum *= repeat_; - expr_width(sum); - if (sum != w) return false; - return true; -} - NetEConcat* NetEConcat::dup_expr() const { NetEConcat*dup = new NetEConcat(parms_.count(), repeat_); @@ -986,17 +862,6 @@ NetEConst::~NetEConst() { } -bool NetEConst::set_width(unsigned w) -{ - if (w > value_.len()) - return false; - - assert(w <= value_.len()); - value_ = verinum(value_, w); - expr_width(w); - return true; -} - NetEConst* NetEConst::dup_expr() const { NetEConst*tmp = new NetEConst(value_); @@ -1046,15 +911,6 @@ void NetMemory::set_attributes(const map&attr) attributes_ = attr; } -bool NetEMemory::set_width(unsigned w) -{ - if (w != mem_->width()) - return false; - - expr_width(w); - return true; -} - NetEMemory* NetEMemory::dup_expr() const { assert(0); @@ -1074,11 +930,6 @@ NetEParam::~NetEParam() { } -bool NetEParam::set_width(unsigned) -{ - return false; -} - NetEParam* NetEParam::dup_expr() const { return 0; @@ -1103,18 +954,6 @@ NetESignal::~NetESignal() { } -/* - * The signal should automatically pad with zeros to get to th desired - * width. Do not allow signal bits to be truncated, however. - */ -bool NetESignal::set_width(unsigned w) -{ - if (w != pin_count()) - return false; - - return true; -} - NetESignal* NetESignal::dup_expr() const { assert(0); @@ -1138,12 +977,6 @@ NetESubSignal* NetESubSignal::dup_expr() const assert(0); } -bool NetESubSignal::set_width(unsigned w) -{ - if (w != 1) return false; - return true; -} - NetETernary::NetETernary(NetExpr*c, NetExpr*t, NetExpr*f) : cond_(c), true_val_(t), false_val_(f) { @@ -1177,42 +1010,11 @@ NetETernary* NetETernary::dup_expr() const assert(0); } -bool NetETernary::set_width(unsigned w) -{ - bool flag = true; - flag = flag && true_val_->set_width(w); - flag = flag && false_val_->set_width(w); - expr_width(true_val_->expr_width()); - return flag; -} - NetEUnary::~NetEUnary() { delete expr_; } -bool NetEUnary::set_width(unsigned w) -{ - bool flag = true; - switch (op_) { - case '~': - case '-': - flag = expr_->set_width(w); - break; - case '&': - case '!': - if (w != 1) { - flag = false; - } - break; - default: - flag = false; - break; - } - expr_width(w); - return flag; -} - NetEUnary* NetEUnary::dup_expr() const { assert(0); @@ -1819,6 +1621,11 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.68 1999/09/23 00:21:54 steve + * Move set_width methods into a single file, + * Add the NetEBLogic class for logic expressions, + * Fix error setting with of && in if statements. + * * Revision 1.67 1999/09/21 00:13:40 steve * Support parameters that reference other paramters. * diff --git a/netlist.h b/netlist.h index af68f47a1..9ab93ca6c 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.69 1999/09/22 16:57:23 steve Exp $" +#ident "$Id: netlist.h,v 1.70 1999/09/23 00:21:55 steve Exp $" #endif /* @@ -1230,6 +1230,25 @@ class NetEBComp : public NetEBinary { }; +/* + * The binary logical operators are those that return boolean + * results. The supported operators are: + * + * a -- Logical AND (&&) + */ +class NetEBLogic : public NetEBinary { + + public: + NetEBLogic(char op, NetExpr*l, NetExpr*r); + ~NetEBLogic(); + + virtual bool set_width(unsigned w); + virtual NetExpr* eval_tree(); + + private: +}; + + /* * This expression node supports the concat expression. This is an * operator that just glues the results of many expressions into a @@ -1618,6 +1637,11 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.70 1999/09/23 00:21:55 steve + * Move set_width methods into a single file, + * Add the NetEBLogic class for logic expressions, + * Fix error setting with of && in if statements. + * * Revision 1.69 1999/09/22 16:57:23 steve * Catch parallel blocks in vvm emit. * diff --git a/set_width.cc b/set_width.cc new file mode 100644 index 000000000..1994457e7 --- /dev/null +++ b/set_width.cc @@ -0,0 +1,255 @@ +/* + * Copyright (c) 1999 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: set_width.cc,v 1.1 1999/09/23 00:21:55 steve Exp $" +#endif + +/* + * This file contains set_width methods for the various NetExpr + * classes. The set_width method is used by elaboration to ask the + * expression to resize itself. If the expression can't, then the + * set_width method will return false and the caller will arrange for + * whatever is needed to deal with the size mismatch. + */ +# include "netlist.h" +# include + + +bool NetExpr::set_width(unsigned w) +{ + cerr << typeid(*this).name() << ": set_width(unsigned) " + "not implemented." << endl; + expr_width(w); + return false; +} + +bool NetEBinary::set_width(unsigned w) +{ + bool flag = true; + switch (op_) { + + case 'l': // left shift (<<) + case 'r': // right shift (>>) + flag = left_->set_width(w); + expr_width(w); + break; + + /* The default rule is that the operands of the binary + operator might as well use the same width as the + output from the binary operation. */ + default: + expr_width(left_->expr_width() > right_->expr_width() + ? left_->expr_width() : right_->expr_width()); + cerr << "NetEBinary::set_width(): Using default for " << + op_ << "." << endl; + flag = false; + + case '%': + case '/': + flag = left_->set_width(w) && flag; + flag = right_->set_width(w) && flag; + expr_width(w); + break; + } + return flag; +} + +/* + * The bitwise logical operators have operands the same size as the + * result. Anything else is a mess. + */ +bool NetEBAdd::set_width(unsigned w) +{ + bool 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; + + return flag; +} + +/* + * The bitwise logical operators have operands the same size as the + * result. Anything else is a mess. + */ +bool NetEBBits::set_width(unsigned w) +{ + bool flag = true; + + flag = left_->set_width(w) && flag; + flag = right_->set_width(w) && flag; + expr_width(w); + + return flag; +} + +/* + * 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. + */ +bool NetEBComp::set_width(unsigned w) +{ + bool flag = true; + + assert(w == 1); + expr_width(w); + flag = left_->set_width(right_->expr_width()); + if (!flag) + flag = right_->set_width(left_->expr_width()); + + return flag; +} + +bool NetEBLogic::set_width(unsigned w) +{ + bool flag; + flag = left_->set_width(right_->expr_width()); + if (!flag) + flag = right_->set_width(left_->expr_width()); + return (w == 1); +} + +/* + * Add up the widths from all the expressions that are concatenated + * together. This is the width of the expression, tough luck if you + * want it otherwise. + * + * If during the course of elaboration one of the sub-expressions is + * broken, then don't count it in the width. This doesn't really + * matter because the null expression is indication of an error and + * the compiler will not go beyond elaboration. + */ +bool NetEConcat::set_width(unsigned w) +{ + unsigned sum = 0; + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) + if (parms_[idx] != 0) + sum += parms_[idx]->expr_width(); + + sum *= repeat_; + expr_width(sum); + if (sum != w) return false; + return true; +} + +bool NetEConst::set_width(unsigned w) +{ + if (w > value_.len()) + return false; + + assert(w <= value_.len()); + value_ = verinum(value_, w); + expr_width(w); + return true; +} + +bool NetEMemory::set_width(unsigned w) +{ + if (w != mem_->width()) + return false; + + expr_width(w); + return true; +} + +bool NetEParam::set_width(unsigned) +{ + return false; +} + +/* + * The signal should automatically pad with zeros to get to th desired + * width. Do not allow signal bits to be truncated, however. + */ +bool NetESignal::set_width(unsigned w) +{ + if (w != pin_count()) + return false; + + return true; +} + +bool NetESubSignal::set_width(unsigned w) +{ + if (w != 1) return false; + return true; +} + +bool NetETernary::set_width(unsigned w) +{ + bool flag = true; + flag = flag && true_val_->set_width(w); + flag = flag && false_val_->set_width(w); + expr_width(true_val_->expr_width()); + return flag; +} + +/* + * XXXX FIX ME: For now, just take whatever the caller says as my + * width. What I really need to do is note the width of the output + * parameter of the function definition and take that into account. + */ +bool NetEUFunc::set_width(unsigned wid) +{ + expr_width(wid); + return true; +} + +bool NetEUnary::set_width(unsigned w) +{ + bool flag = true; + switch (op_) { + case '~': + case '-': + flag = expr_->set_width(w); + break; + case '&': + case '!': + if (w != 1) { + flag = false; + } + break; + default: + flag = false; + break; + } + expr_width(w); + return flag; +} + + +/* + * $Log: set_width.cc,v $ + * Revision 1.1 1999/09/23 00:21:55 steve + * Move set_width methods into a single file, + * Add the NetEBLogic class for logic expressions, + * Fix error setting with of && in if statements. + * + */ +