diff --git a/design_dump.cc b/design_dump.cc index af7f680bd..6bf89046f 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: design_dump.cc,v 1.166 2006/06/18 04:15:50 steve Exp $" +#ident "$Id: design_dump.cc,v 1.167 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -991,6 +991,9 @@ void NetEBinary::dump(ostream&o) const case 'O': o << "~|"; break; + case 'p': + o << "**"; + break; case 'r': o << ">>"; break; @@ -1180,6 +1183,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.167 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.166 2006/06/18 04:15:50 steve * Add support for system functions in continuous assignments. * diff --git a/elab_expr.cc b/elab_expr.cc index ed47a1b01..384216a03 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_expr.cc,v 1.106 2006/07/07 04:06:37 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.107 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -101,6 +101,11 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des, tmp->set_line(*this); break; + case 'p': + tmp = new NetEBPow(op_, lp, rp); + tmp->set_line(*this); + break; + case '*': tmp = new NetEBMult(op_, lp, rp); tmp->set_line(*this); @@ -1382,6 +1387,9 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, /* * $Log: elab_expr.cc,v $ + * Revision 1.107 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.106 2006/07/07 04:06:37 steve * Fix context determined with of constants. * diff --git a/eval_tree.cc b/eval_tree.cc index 896f80403..29298376a 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.68 2006/03/18 22:52:27 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.69 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -937,6 +937,80 @@ NetExpr* NetEBMult::eval_tree() return new NetEConst(lval * rval); } +NetExpr* NetEBPow::eval_tree_real_() +{ + verireal lval; + verireal rval; + + switch (left_->expr_type()) { + case IVL_VT_REAL: { + NetECReal*lc = dynamic_cast (left_); + if (lc == 0) return 0; + lval = lc->value(); + break; + } + + case IVL_VT_BOOL: + case IVL_VT_LOGIC: { + NetEConst*lc = dynamic_cast(left_); + if (lc == 0) return 0; + verinum tmp = lc->value(); + lval = verireal(tmp.as_long()); + break; + } + + default: + assert(0); + } + + switch (right_->expr_type()) { + case IVL_VT_REAL: { + NetECReal*rc = dynamic_cast (right_); + if (rc == 0) return 0; + rval = rc->value(); + break; + } + + case IVL_VT_BOOL: + case IVL_VT_LOGIC: { + NetEConst*rc = dynamic_cast(right_); + if (rc == 0) return 0; + verinum tmp = rc->value(); + rval = verireal(tmp.as_long()); + break; + } + + default: + assert(0); + } + + + NetECReal*res = new NetECReal( pow(lval,rval) ); + res->set_line(*this); + return res; +} + +NetExpr* NetEBPow::eval_tree() +{ + eval_sub_tree_(); + + if (expr_type() == IVL_VT_REAL) + return eval_tree_real_(); + + assert(expr_type() == IVL_VT_LOGIC); + + NetEConst*lc = dynamic_cast(left_); + if (lc == 0) return 0; + NetEConst*rc = dynamic_cast(right_); + if (rc == 0) return 0; + + verinum lval = lc->value(); + verinum rval = rc->value(); + + return new NetEConst( pow(lval,rval) ); + +} + /* * Evaluate the shift operator if possible. For this to work, both * operands must be constant. @@ -1589,6 +1663,9 @@ NetEConst* NetEUReduce::eval_tree() /* * $Log: eval_tree.cc,v $ + * Revision 1.69 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.68 2006/03/18 22:52:27 steve * Properly handle signedness in compare. * diff --git a/expr_synth.cc b/expr_synth.cc index e5a9483aa..185844495 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: expr_synth.cc,v 1.78 2006/07/08 21:48:46 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.79 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -234,6 +234,14 @@ NetNet* NetEBComp::synthesize(Design*des) return osig; } +NetNet* NetEBPow::synthesize(Design*des) +{ + cerr << get_line() << ": internal error: Do not yet know how to handle" + << " power operator in this context." << endl; + des->errors += 1; + return 0; +} + NetNet* NetEBMult::synthesize(Design*des) { NetNet*lsig = left_->synthesize(des); @@ -882,6 +890,9 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.79 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.78 2006/07/08 21:48:46 steve * Handle real valued literals in net contexts. * diff --git a/lexor.lex b/lexor.lex index 51bdf5532..38604c0a6 100644 --- a/lexor.lex +++ b/lexor.lex @@ -21,7 +21,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: lexor.lex,v 1.91 2006/05/17 04:15:12 steve Exp $" +#ident "$Id: lexor.lex,v 1.92 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -134,6 +134,7 @@ W [ \t\b\f\r]+ "<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */} ">>" { return K_RS; } ">>>" { return K_RSS; } +"**" { return K_POW; } "<=" { return K_LE; } ">=" { return K_GE; } "=>" { return K_EG; } diff --git a/net_design.cc b/net_design.cc index eea0fedfb..4c9c8a75a 100644 --- a/net_design.cc +++ b/net_design.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: net_design.cc,v 1.48 2005/11/27 05:56:20 steve Exp $" +#ident "$Id: net_design.cc,v 1.49 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -327,12 +327,20 @@ void NetScope::evaluate_parameters(Design*des) switch (expr->expr_type()) { case IVL_VT_REAL: if (! dynamic_cast(expr)) { - cerr << (*cur).second.expr->get_line() - << ": internal error: " - "unable to evaluate real parameter values: " << - *expr << endl; - des->errors += 1; - continue; + + NetExpr*nexpr = expr->eval_tree(); + if (nexpr == 0) { + cerr << (*cur).second.expr->get_line() + << ": internal error: " + << "unable to evaluate real parameter value: " + << *expr << endl; + des->errors += 1; + continue; + } + + assert(nexpr); + delete expr; + (*cur).second.expr = nexpr; } break; @@ -554,6 +562,9 @@ void Design::delete_process(NetProcTop*top) /* * $Log: net_design.cc,v $ + * Revision 1.49 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.48 2005/11/27 05:56:20 steve * Handle bit select of parameter with ranges. * diff --git a/net_expr.cc b/net_expr.cc index e994ff85e..4129039d6 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: net_expr.cc,v 1.26 2005/11/26 00:35:43 steve Exp $" +#ident "$Id: net_expr.cc,v 1.27 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -248,6 +248,40 @@ ivl_variable_type_t NetEBMult::expr_type() const return IVL_VT_LOGIC; } +NetEBPow::NetEBPow(char op, NetExpr*l, NetExpr*r) +: NetEBinary(op, l, r) +{ + assert(op == 'p'); + expr_width(l->expr_width()); + cast_signed(l->has_sign() || r->has_sign()); +} + +NetEBPow::~NetEBPow() +{ +} + +NetEBPow* NetEBPow::dup_expr() const +{ + NetEBPow*result = new NetEBPow(op_, left_->dup_expr(), + right_->dup_expr()); + result->set_line(*this); + return result; +} + +ivl_variable_type_t NetEBPow::expr_type() const +{ + if (right_->expr_type() == IVL_VT_REAL) + return IVL_VT_REAL; + if (left_->expr_type() == IVL_VT_REAL) + return IVL_VT_REAL; + if (left_->has_sign()) + return IVL_VT_REAL; + if (right_->has_sign()) + return IVL_VT_REAL; + + return IVL_VT_LOGIC; +} + NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r) : NetEBinary(op, l, r) { @@ -526,6 +560,9 @@ ivl_variable_type_t NetESFunc::expr_type() const /* * $Log: net_expr.cc,v $ + * Revision 1.27 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.26 2005/11/26 00:35:43 steve * More precise about r-value width of constants. * diff --git a/netlist.h b/netlist.h index 7380be690..8c82d4463 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.358 2006/06/18 04:15:50 steve Exp $" +#ident "$Id: netlist.h,v 1.359 2006/07/31 03:50:17 steve Exp $" #endif /* @@ -2559,6 +2559,7 @@ class NetProcTop : public LineInfo, public Attrib { * * -- Arithmetic multiply * / -- Arithmetic divide * % -- Arithmetic modulus + * p -- Arithmetic power (**) * & -- Bit-wise AND * | -- Bit-wise OR * < -- Less then @@ -2762,6 +2763,28 @@ class NetEBMult : public NetEBinary { }; +/* + * Support the binary multiplication (*) operator. + */ +class NetEBPow : public NetEBinary { + + public: + NetEBPow(char op, NetExpr*l, NetExpr*r); + ~NetEBPow(); + + virtual ivl_variable_type_t expr_type() const; + + virtual bool set_width(unsigned w, bool last_chance); + virtual NetEBPow* dup_expr() const; + virtual NetExpr* eval_tree(); + virtual NetNet* synthesize(Design*); + + private: + + NetExpr* eval_tree_real_(); + +}; + /* * The binary logical operators are those that return boolean @@ -3486,6 +3509,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.359 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.358 2006/06/18 04:15:50 steve * Add support for system functions in continuous assignments. * diff --git a/parse.y b/parse.y index b434b8501..6b9294951 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: parse.y,v 1.217 2006/05/11 03:26:57 steve Exp $" +#ident "$Id: parse.y,v 1.218 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -148,7 +148,7 @@ static list* list_from_identifier(list*tmp, char*id) %token BASED_NUMBER DEC_NUMBER %token REALTIME %token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_RSS K_SG -%token K_PO_POS K_PO_NEG +%token K_PO_POS K_PO_NEG K_POW %token K_PSTAR K_STARP %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER %token K_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case @@ -249,6 +249,7 @@ static list* list_from_identifier(list*tmp, char*id) %left K_LS K_RS K_RSS %left '+' '-' %left '*' '/' '%' +%left K_POW %left UNARY_PREC /* to resolve dangling else ambiguity. */ @@ -792,6 +793,12 @@ expression tmp->set_lineno(@2.first_line); $$ = tmp; } + | expression K_POW expression + { PEBinary*tmp = new PEBinary('p', $1, $3); + tmp->set_file(@2.text); + tmp->set_lineno(@2.first_line); + $$ = tmp; + } | expression '*' expression { PEBinary*tmp = new PEBinary('*', $1, $3); tmp->set_file(@2.text); diff --git a/set_width.cc b/set_width.cc index 276813cb2..2d1cfa6fa 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: set_width.cc,v 1.38 2006/05/02 04:29:42 steve Exp $" +#ident "$Id: set_width.cc,v 1.39 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -185,6 +185,12 @@ bool NetEBMult::set_width(unsigned w, bool) return w == expr_width(); } +bool NetEBPow::set_width(unsigned w, bool last_chance) +{ + bool flag = left_->set_width(w, last_chance); + return flag; +} + /* * The shift operator allows the shift amount to have its own * natural width. The width of the operator result is the width of the @@ -434,6 +440,9 @@ bool NetEUReduce::set_width(unsigned w, bool) /* * $Log: set_width.cc,v $ + * Revision 1.39 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.38 2006/05/02 04:29:42 steve * Be more stubborn about widths. * diff --git a/verinum.cc b/verinum.cc index 0136e1af2..02bbb2cbc 100644 --- a/verinum.cc +++ b/verinum.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verinum.cc,v 1.46 2006/06/02 04:48:50 steve Exp $" +#ident "$Id: verinum.cc,v 1.47 2006/07/31 03:50:17 steve Exp $" #endif # include "config.h" @@ -749,6 +749,17 @@ verinum operator * (const verinum&left, const verinum&right) return trim_vnum(result); } +verinum pow(const verinum&left, const verinum&right) +{ + verinum result = left; + unsigned pow_count = right.as_ulong(); + + for (unsigned idx = 1 ; idx < pow_count ; idx += 1) + result = result * result; + + return result; +} + verinum operator << (const verinum&that, unsigned shift) { verinum result(verinum::V0, that.len() + shift, that.has_len()); @@ -1007,6 +1018,9 @@ verinum::V operator ^ (verinum::V l, verinum::V r) /* * $Log: verinum.cc,v $ + * Revision 1.47 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.46 2006/06/02 04:48:50 steve * Make elaborate_expr methods aware of the width that the context * requires of it. In the process, fix sizing of the width of unary diff --git a/verinum.h b/verinum.h index 8f4890c1f..53cb2a568 100644 --- a/verinum.h +++ b/verinum.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verinum.h,v 1.30 2006/06/02 04:48:50 steve Exp $" +#ident "$Id: verinum.h,v 1.31 2006/07/31 03:50:17 steve Exp $" #endif # include @@ -147,6 +147,8 @@ extern verinum operator * (const verinum&left, const verinum&right); extern verinum operator / (const verinum&left, const verinum&right); extern verinum operator % (const verinum&left, const verinum&right); +extern verinum pow(const verinum&left, const verinum&right); + extern verinum operator<< (const verinum&left, unsigned shift); extern verinum operator>> (const verinum&left, unsigned shift); @@ -157,6 +159,9 @@ extern verinum v_not(const verinum&left); /* * $Log: verinum.h,v $ + * Revision 1.31 2006/07/31 03:50:17 steve + * Add support for power in constant expressions. + * * Revision 1.30 2006/06/02 04:48:50 steve * Make elaborate_expr methods aware of the width that the context * requires of it. In the process, fix sizing of the width of unary diff --git a/verireal.cc b/verireal.cc index 45e70dcef..300701f31 100644 --- a/verireal.cc +++ b/verireal.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verireal.cc,v 1.15 2004/06/04 23:33:51 steve Exp $" +#ident "$Id: verireal.cc,v 1.16 2006/07/31 03:50:18 steve Exp $" #endif # include "config.h" @@ -117,6 +117,13 @@ verireal operator% (const verireal&l, const verinum&r) return res; } +verireal pow (const verireal&l, const verireal&r) +{ + verireal res; + res.value_ = pow(l.value_, r.value_); + return res; +} + verireal operator- (const verireal&l) { verireal res; @@ -132,6 +139,9 @@ ostream& operator<< (ostream&out, const verireal&v) /* * $Log: verireal.cc,v $ + * Revision 1.16 2006/07/31 03:50:18 steve + * Add support for power in constant expressions. + * * Revision 1.15 2004/06/04 23:33:51 steve * Add unary minus as operator supported by verireal. * diff --git a/verireal.h b/verireal.h index 7d8a2baef..ee967102a 100644 --- a/verireal.h +++ b/verireal.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: verireal.h,v 1.11 2005/06/14 19:13:43 steve Exp $" +#ident "$Id: verireal.h,v 1.12 2006/07/31 03:50:18 steve Exp $" #endif #ifdef HAVE_IOSFWD @@ -47,6 +47,7 @@ class verireal { friend verireal operator/ (const verireal&, const verinum&); friend verireal operator% (const verireal&, const verireal&); friend verireal operator% (const verireal&, const verinum&); + friend verireal pow(const verireal&, const verireal&); // Unary minus. friend verireal operator- (const verireal&); @@ -76,10 +77,14 @@ extern verireal operator/ (const verireal&, const verireal&); extern verireal operator/ (const verireal&, const verinum&); extern verireal operator% (const verireal&, const verireal&); extern verireal operator% (const verireal&, const verinum&); +extern verireal pow(const verireal&, const verireal&); extern verireal operator- (const verireal&); /* * $Log: verireal.h,v $ + * Revision 1.12 2006/07/31 03:50:18 steve + * Add support for power in constant expressions. + * * Revision 1.11 2005/06/14 19:13:43 steve * gcc3/4 compile errors. *