Support evaluating + operator at compile time.

This commit is contained in:
steve 1999-10-10 23:29:37 +00:00
parent 564f972aef
commit 19b8615363
5 changed files with 244 additions and 34 deletions

View File

@ -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.4 1999/09/23 03:56:57 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.5 1999/10/10 23:29:37 steve Exp $"
#endif
# include "netlist.h"
@ -26,8 +26,8 @@ NetExpr* NetExpr::eval_tree()
{
return 0;
}
/*
/*
* Some of the derived classes can be evaluated by the compiler, this
* method provides the common aid of evaluating the parameter
* expressions.
@ -46,8 +46,33 @@ void NetEBinary::eval_sub_tree_()
}
}
NetEConst* NetEBAdd::eval_tree()
{
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
NetExpr* NetEBComp::eval_eqeq_()
verinum lval = lc->value();
verinum rval = rc->value();
verinum val;
switch (op_) {
case '+':
val = lval + rval;
break;
case '-':
val = lval - rval;
break;
default:
return 0;
}
return new NetEConst(val);
}
NetEConst* NetEBComp::eval_eqeq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
@ -70,7 +95,7 @@ NetExpr* NetEBComp::eval_eqeq_()
}
NetExpr* NetEBComp::eval_leeq_()
NetEConst* NetEBComp::eval_leeq_()
{
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
@ -90,7 +115,7 @@ NetExpr* NetEBComp::eval_leeq_()
}
NetExpr* NetEBComp::eval_tree()
NetEConst* NetEBComp::eval_tree()
{
eval_sub_tree_();
@ -106,7 +131,7 @@ NetExpr* NetEBComp::eval_tree()
}
}
NetExpr* NetEBLogic::eval_tree()
NetEConst* NetEBLogic::eval_tree()
{
eval_sub_tree_();
return 0;
@ -116,7 +141,7 @@ NetExpr* NetEBLogic::eval_tree()
* Evaluate the shift operator if possible. For this to work, both
* operands must be constant.
*/
NetExpr* NetEBShift::eval_tree()
NetEConst* NetEBShift::eval_tree()
{
eval_sub_tree_();
NetEConst*re = dynamic_cast<NetEConst*>(right_);
@ -236,6 +261,9 @@ NetExpr* NetEParam::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.5 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time.
*
* Revision 1.4 1999/09/23 03:56:57 steve
* Support shift operators.
*

View File

@ -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.76 1999/10/10 01:59:55 steve Exp $"
#ident "$Id: netlist.cc,v 1.77 1999/10/10 23:29:37 steve Exp $"
#endif
# include <cassert>
@ -833,6 +833,13 @@ NetEBAdd::~NetEBAdd()
{
}
NetEBAdd* NetEBAdd::dup_expr() const
{
NetEBAdd*result = new NetEBAdd(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
@ -865,6 +872,13 @@ NetEBBits::~NetEBBits()
{
}
NetEBBits* NetEBBits::dup_expr() const
{
NetEBBits*result = new NetEBBits(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
@ -875,6 +889,13 @@ NetEBComp::~NetEBComp()
{
}
NetEBComp* NetEBComp::dup_expr() const
{
NetEBComp*result = new NetEBComp(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
: op_(op), left_(l), right_(r)
{
@ -901,6 +922,13 @@ NetEBLogic::~NetEBLogic()
{
}
NetEBLogic* NetEBLogic::dup_expr() const
{
NetEBLogic*result = new NetEBLogic(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
@ -911,6 +939,13 @@ NetEBShift::~NetEBShift()
{
}
NetEBShift* NetEBShift::dup_expr() const
{
NetEBShift*result = new NetEBShift(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEConcat::NetEConcat(unsigned cnt, unsigned r)
: parms_(cnt), repeat_(r)
{
@ -1754,6 +1789,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.77 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time.
*
* Revision 1.76 1999/10/10 01:59:55 steve
* Structural case equals device.
*

View File

@ -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.79 1999/10/10 01:59:55 steve Exp $"
#ident "$Id: netlist.h,v 1.80 1999/10/10 23:29:37 steve Exp $"
#endif
/*
@ -398,6 +398,29 @@ class NetExpr : public LineInfo {
NetExpr& operator=(const NetExpr&);
};
/*
* The expression constant is slightly special, and is sometimes
* retured from other classes that can be evaluated at compile
* time. This class represents constant values in expressions.
*/
class NetEConst : public NetExpr {
public:
explicit NetEConst(const verinum&val);
~NetEConst();
const verinum&value() const { return value_; }
virtual bool set_width(unsigned w);
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
virtual NetEConst* dup_expr() const;
private:
verinum value_;
};
/*
* The NetTmp object is a network that is only used momentarily by
* elaboration to carry links around. A completed netlist cannot have
@ -1219,6 +1242,8 @@ class NetEBAdd : public NetEBinary {
~NetEBAdd();
virtual bool set_width(unsigned w);
virtual NetEBAdd* dup_expr() const;
virtual NetEConst* eval_tree();
};
/*
@ -1242,6 +1267,7 @@ class NetEBBits : public NetEBinary {
~NetEBBits();
virtual bool set_width(unsigned w);
virtual NetEBBits* dup_expr() const;
};
/*
@ -1265,11 +1291,12 @@ class NetEBComp : public NetEBinary {
~NetEBComp();
virtual bool set_width(unsigned w);
virtual NetExpr* eval_tree();
virtual NetEBComp* dup_expr() const;
virtual NetEConst* eval_tree();
private:
NetExpr*eval_eqeq_();
NetExpr*eval_leeq_();
NetEConst*eval_eqeq_();
NetEConst*eval_leeq_();
};
@ -1286,7 +1313,8 @@ class NetEBLogic : public NetEBinary {
~NetEBLogic();
virtual bool set_width(unsigned w);
virtual NetExpr* eval_tree();
virtual NetEBLogic* dup_expr() const;
virtual NetEConst* eval_tree();
private:
};
@ -1306,7 +1334,8 @@ class NetEBShift : public NetEBinary {
~NetEBShift();
virtual bool set_width(unsigned w);
virtual NetExpr* eval_tree();
virtual NetEBShift* dup_expr() const;
virtual NetEConst* eval_tree();
private:
};
@ -1345,24 +1374,6 @@ class NetEConcat : public NetExpr {
unsigned repeat_;
};
class NetEConst : public NetExpr {
public:
explicit NetEConst(const verinum&val);
~NetEConst();
const verinum&value() const { return value_; }
virtual bool set_width(unsigned w);
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
virtual NetEConst* dup_expr() const;
private:
verinum value_;
};
/*
* This clas is a placeholder for a parameter expression. When
* parameters are first created, an instance of this object is used to
@ -1733,6 +1744,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.80 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time.
*
* Revision 1.79 1999/10/10 01:59:55 steve
* Structural case equals device.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: verinum.cc,v 1.9 1999/07/20 05:12:22 steve Exp $"
#ident "$Id: verinum.cc,v 1.10 1999/10/10 23:29:37 steve Exp $"
#endif
# include "verinum.h"
@ -308,8 +308,133 @@ bool operator == (const verinum&left, const verinum&right)
return true;
}
static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c)
{
unsigned sum = 0;
switch (c) {
case verinum::Vx:
case verinum::Vz:
c = verinum::Vx;
return verinum::Vx;
case verinum::V0:
break;
case verinum::V1:
sum += 1;
}
switch (l) {
case verinum::Vx:
case verinum::Vz:
c = verinum::Vx;
return verinum::Vx;
case verinum::V0:
break;
case verinum::V1:
sum += 1;
break;
}
switch (r) {
case verinum::Vx:
case verinum::Vz:
c = verinum::Vx;
return verinum::Vx;
case verinum::V0:
break;
case verinum::V1:
sum += 1;
break;
}
if (sum & 2)
c = verinum::V1;
else
c = verinum::V0;
if (sum & 1)
return verinum::V1;
else
return verinum::V0;
}
verinum not(const verinum&left)
{
verinum val = left;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
switch (val[idx]) {
case verinum::V0:
val.set(idx, verinum::V1);
break;
case verinum::V1:
val.set(idx, verinum::V0);
break;
default:
val.set(idx, verinum::Vx);
break;
}
return val;
}
/*
* Addition works a bit at a time, from the least significant up to
* the most significant.
*/
verinum operator + (const verinum&left, const verinum&right)
{
unsigned min = left.len();
if (right.len() < min) min = right.len();
unsigned max = left.len();
if (right.len() > max) max = right.len();
verinum val (verinum::V0, max);
verinum::V carry = verinum::V0;
for (unsigned idx = 0 ; idx < min ; idx += 1)
val.set(idx, add_with_carry(left[idx], right[idx], carry));
if (left.len() > right.len()) {
for (unsigned idx = min ; idx < max ; idx += 1)
val.set(idx,add_with_carry(left[idx], verinum::V0, carry));
} else {
for (unsigned idx = min ; idx < max ; idx += 1)
val.set(idx, add_with_carry(verinum::V0, right[idx], carry));
}
return val;
}
verinum operator - (const verinum&left, const verinum&r)
{
verinum right = not(r);
unsigned min = left.len();
if (right.len() < min) min = right.len();
unsigned max = left.len();
if (right.len() > max) max = right.len();
verinum val (verinum::V0, max);
verinum::V carry = verinum::V1;
for (unsigned idx = 0 ; idx < min ; idx += 1)
val.set(idx, add_with_carry(left[idx], right[idx], carry));
if (left.len() > right.len()) {
for (unsigned idx = min ; idx < max ; idx += 1)
val.set(idx,add_with_carry(left[idx], verinum::V0, carry));
} else {
for (unsigned idx = min ; idx < max ; idx += 1)
val.set(idx, add_with_carry(verinum::V0, right[idx], carry));
}
return val;
}
/*
* $Log: verinum.cc,v $
* Revision 1.10 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time.
*
* Revision 1.9 1999/07/20 05:12:22 steve
* Implement the set method.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: verinum.h,v 1.5 1999/05/13 04:02:09 steve Exp $"
#ident "$Id: verinum.h,v 1.6 1999/10/10 23:29:37 steve Exp $"
#endif
# include <string>
@ -91,9 +91,14 @@ extern ostream& operator<< (ostream&, const verinum&);
extern ostream& operator<< (ostream&, verinum::V);
extern bool 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);
/*
* $Log: verinum.h,v $
* Revision 1.6 1999/10/10 23:29:37 steve
* Support evaluating + operator at compile time.
*
* Revision 1.5 1999/05/13 04:02:09 steve
* More precise handling of verinum bit lengths.
*