From 9f80ed32b690f61ec197aa7357676aefd8ec4029 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 5 Dec 2002 02:14:33 +0000 Subject: [PATCH] Support bit select in constant expressions. --- elab_pexpr.cc | 28 ++++++++++++++++++++------- eval_tree.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++- netlist.h | 6 +++++- 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/elab_pexpr.cc b/elab_pexpr.cc index 9e95f79e8..e38bfb7bf 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_pexpr.cc,v 1.17 2002/11/09 01:40:19 steve Exp $" +#ident "$Id: elab_pexpr.cc,v 1.18 2002/12/05 02:14:33 steve Exp $" #endif # include "config.h" @@ -145,15 +145,26 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const return 0; } - if (msb_ || lsb_ || idx_) { - cerr << get_line() << ": error: Cannot bit/part select " - "bits of parameters." << endl; - des->errors += 1; - } - NetExpr*res = new NetEParam(des, pscope, hname_t(name)); assert(res); delete name; + + assert(idx_ == 0); + if (msb_ && lsb_) { + cerr << get_line() << ": sorry: Cannot part select " + "bits of parameters." << endl; + des->errors += 1; + + } else if (msb_) { + + /* We have here a bit select. Insert a NetESelect node + to handle it. */ + NetExpr*tmp = msb_->elaborate_pexpr(des, scope); + if (tmp != 0) { + res = new NetESelect(res, tmp, 1); + } + } + return res; } @@ -217,6 +228,9 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const /* * $Log: elab_pexpr.cc,v $ + * Revision 1.18 2002/12/05 02:14:33 steve + * Support bit select in constant expressions. + * * Revision 1.17 2002/11/09 01:40:19 steve * Postpone parameter width check to evaluation. * diff --git a/eval_tree.cc b/eval_tree.cc index c1c7afa27..4ca99989f 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_tree.cc,v 1.43 2002/11/09 01:40:19 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.44 2002/12/05 02:14:33 steve Exp $" #endif # include "config.h" @@ -894,6 +894,53 @@ NetExpr* NetEParam::eval_tree() return res->dup_expr(); } +NetEConst* NetESelect::eval_tree() +{ + NetEConst*expr = dynamic_cast(expr_); + if (expr == 0) { + NetExpr*tmp = expr_->eval_tree(); + if (tmp != 0) { + delete expr_; + expr_ = tmp; + } + + expr = dynamic_cast(expr_); + } + + NetEConst*base = dynamic_cast(base_); + if (base == 0) { + NetExpr*tmp = base_->eval_tree(); + if (tmp != 0) { + delete base_; + base_ = tmp; + } + + base = dynamic_cast(base_); + } + + if (expr == 0) + return 0; + if (base == 0) + return 0; + + verinum eval = expr->value(); + verinum oval (verinum::V0, expr_width(), true); + long bval = base->value().as_long(); + + for (long idx = 0 ; idx < expr_width() ; idx += 1) { + if ((bval >= eval.len()) || (bval < 0)) + oval.set(idx, verinum::Vx); + else + oval.set(idx, eval.get(bval)); + + bval += 1; + } + + NetEConst*res = new NetEConst(oval); + return res; +} + + /* * A ternary expression evaluation is controlled by the condition * expression. If the condition evaluates to true or false, then @@ -1140,6 +1187,9 @@ NetEConst* NetEUReduce::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.44 2002/12/05 02:14:33 steve + * Support bit select in constant expressions. + * * Revision 1.43 2002/11/09 01:40:19 steve * Postpone parameter width check to evaluation. * diff --git a/netlist.h b/netlist.h index 62bcbf9d3..be9123eef 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.h,v 1.269 2002/11/09 01:40:19 steve Exp $" +#ident "$Id: netlist.h,v 1.270 2002/12/05 02:14:33 steve Exp $" #endif /* @@ -2494,6 +2494,7 @@ class NetESelect : public NetExpr { virtual bool set_width(unsigned w); virtual bool has_width() const; virtual void expr_scan(struct expr_scan_t*) const; + virtual NetEConst* eval_tree(); virtual NetESelect* dup_expr() const; private: @@ -3084,6 +3085,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.270 2002/12/05 02:14:33 steve + * Support bit select in constant expressions. + * * Revision 1.269 2002/11/09 01:40:19 steve * Postpone parameter width check to evaluation. *