From 2b40c7ce114ce6205cfeea886b1efc1ddbaccc5a Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 28 Apr 2000 18:43:23 +0000 Subject: [PATCH] integer division in expressions properly get width. --- elab_expr.cc | 11 ++++++++++- eval_tree.cc | 11 ++++++++++- expr_synth.cc | 13 ++++++++++++- netlist.cc | 26 +++++++++++++++++++++++++- netlist.h | 22 +++++++++++++++++++++- set_width.cc | 14 +++++++++++++- t-vvm.cc | 7 ++++++- 7 files changed, 97 insertions(+), 7 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 0f4da9fcd..548494c9b 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_expr.cc,v 1.20 2000/03/29 04:06:28 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.21 2000/04/28 18:43:23 steve Exp $" #endif @@ -93,6 +93,12 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des, tmp->set_line(*this); break; + case '/': + case '%': + tmp = new NetEBDiv(op_, lp, rp); + tmp->set_line(*this); + break; + case 'l': case 'r': tmp = new NetEBShift(op_, lp, rp); @@ -450,6 +456,9 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const /* * $Log: elab_expr.cc,v $ + * Revision 1.21 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.20 2000/03/29 04:06:28 steve * Forgot to return elaborate result (Dan Nelsen) * diff --git a/eval_tree.cc b/eval_tree.cc index b3bc6ddd1..51f79077c 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) && !defined(macintosh) -#ident "$Id: eval_tree.cc,v 1.9 2000/03/08 04:36:53 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.10 2000/04/28 18:43:23 steve Exp $" #endif # include "netlist.h" @@ -132,6 +132,12 @@ NetEConst* NetEBComp::eval_tree() } } +NetEConst* NetEBDiv::eval_tree() +{ + eval_sub_tree_(); + return 0; +} + NetEConst* NetEBLogic::eval_tree() { eval_sub_tree_(); @@ -269,6 +275,9 @@ NetExpr* NetEParam::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.10 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.9 2000/03/08 04:36:53 steve * Redesign the implementation of scopes and parameters. * I now generate the scopes and notice the parameters diff --git a/expr_synth.cc b/expr_synth.cc index 380e0a633..acf600212 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: expr_synth.cc,v 1.12 2000/04/20 00:28:03 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.13 2000/04/28 18:43:23 steve Exp $" #endif # include "netlist.h" @@ -201,6 +201,14 @@ NetNet* NetEBComp::synthesize(Design*des) return osig; } +NetNet* NetEBDiv::synthesize(Design*des) +{ + cerr << get_line() << ": internal error: cannot synthesize division: " + << *this << endl; + des->errors += 1; + return 0; +} + NetNet* NetEConcat::synthesize(Design*des) { assert(repeat_ == 1); @@ -309,6 +317,9 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.13 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.12 2000/04/20 00:28:03 steve * Catch some simple identity compareoptimizations. * diff --git a/netlist.cc b/netlist.cc index a02bfd979..ab4d9a1c3 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) && !defined(macintosh) -#ident "$Id: netlist.cc,v 1.118 2000/04/23 03:45:24 steve Exp $" +#ident "$Id: netlist.cc,v 1.119 2000/04/28 18:43:23 steve Exp $" #endif # include @@ -1964,6 +1964,27 @@ NetEBComp* NetEBComp::dup_expr() const return result; } +NetEBDiv::NetEBDiv(char op, NetExpr*l, NetExpr*r) +: NetEBinary(op, l, r) +{ + unsigned w = l->expr_width(); + if (r->expr_width() > w) + w = r->expr_width(); + + expr_width(w); +} + +NetEBDiv::~NetEBDiv() +{ +} + +NetEBDiv* NetEBDiv::dup_expr() const +{ + NetEBDiv*result = new NetEBDiv(op_, left_->dup_expr(), + right_->dup_expr()); + return result; +} + NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r) : op_(op), left_(l), right_(r) { @@ -2516,6 +2537,9 @@ bool NetUDP::sequ_glob_(string input, char output) /* * $Log: netlist.cc,v $ + * Revision 1.119 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.118 2000/04/23 03:45:24 steve * Add support for the procedural release statement. * diff --git a/netlist.h b/netlist.h index f537f08d5..981b66350 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) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.131 2000/04/28 16:50:53 steve Exp $" +#ident "$Id: netlist.h,v 1.132 2000/04/28 18:43:23 steve Exp $" #endif /* @@ -1790,6 +1790,23 @@ class NetEBAdd : public NetEBinary { virtual NetNet* synthesize(Design*); }; +/* + * This class represents the integer division operators. + * / -- Divide + * % -- Modulus + */ +class NetEBDiv : public NetEBinary { + + public: + NetEBDiv(char op, NetExpr*l, NetExpr*r); + ~NetEBDiv(); + + virtual bool set_width(unsigned w); + virtual NetEBDiv* dup_expr() const; + virtual NetEConst* eval_tree(); + virtual NetNet* synthesize(Design*); +}; + /* * The bitwise binary operators are represented by this class. This is * a specialization of the binary operator, so is derived from @@ -2451,6 +2468,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.132 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.131 2000/04/28 16:50:53 steve * Catch memory word parameters to tasks. * diff --git a/set_width.cc b/set_width.cc index 8542532aa..19cb1d53f 100644 --- a/set_width.cc +++ b/set_width.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: set_width.cc,v 1.11 2000/04/26 03:33:32 steve Exp $" +#ident "$Id: set_width.cc,v 1.12 2000/04/28 18:43:23 steve Exp $" #endif /* @@ -129,6 +129,15 @@ bool NetEBComp::set_width(unsigned w) return (w == 1); } +/* + * There is nothing we can do to the operands of a division to make it + * confirm to the requested width. Force the context to pad or truncate. + */ +bool NetEBDiv::set_width(unsigned w) +{ + return w == expr_width(); +} + bool NetEBLogic::set_width(unsigned w) { bool flag; @@ -286,6 +295,9 @@ bool NetEUnary::set_width(unsigned w) /* * $Log: set_width.cc,v $ + * Revision 1.12 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.11 2000/04/26 03:33:32 steve * Do not set width too small to hold significant bits. * diff --git a/t-vvm.cc b/t-vvm.cc index a9a72d4b2..33a07a88d 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-vvm.cc,v 1.140 2000/04/26 18:35:11 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.141 2000/04/28 18:43:23 steve Exp $" #endif # include @@ -476,6 +476,8 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) expr->right()->expr_scan(this); string rres = result; + assert(expr->expr_width() != 0); + result = make_temp(); os_ << " // " << expr->get_line() << ": expression node." << endl; os_ << " vpip_bit_t " << result<<"_bits[" << expr->expr_width() @@ -2687,6 +2689,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.141 2000/04/28 18:43:23 steve + * integer division in expressions properly get width. + * * Revision 1.140 2000/04/26 18:35:11 steve * Handle assigning small values to big registers. *