Add support for power in constant expressions.

This commit is contained in:
steve 2006-07-31 03:50:17 +00:00
parent 06d6ac4b33
commit 49b65e86fe
14 changed files with 248 additions and 21 deletions

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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<NetECReal*> (left_);
if (lc == 0) return 0;
lval = lc->value();
break;
}
case IVL_VT_BOOL:
case IVL_VT_LOGIC: {
NetEConst*lc = dynamic_cast<NetEConst*>(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<NetECReal*> (right_);
if (rc == 0) return 0;
rval = rc->value();
break;
}
case IVL_VT_BOOL:
case IVL_VT_LOGIC: {
NetEConst*rc = dynamic_cast<NetEConst*>(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<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(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.
*

View File

@ -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.
*

View File

@ -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; }

View File

@ -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<const NetECReal*>(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.
*

View File

@ -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.
*

View File

@ -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.
*

11
parse.y
View File

@ -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<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
%token <number> BASED_NUMBER DEC_NUMBER
%token <realtime> 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<perm_string>* list_from_identifier(list<perm_string>*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);

View File

@ -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.
*

View File

@ -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

View File

@ -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 <string>
@ -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

View File

@ -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.
*

View File

@ -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.
*