Support evaluating + operator at compile time.
This commit is contained in:
parent
564f972aef
commit
19b8615363
42
eval_tree.cc
42
eval_tree.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
40
netlist.cc
40
netlist.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
62
netlist.h
62
netlist.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
127
verinum.cc
127
verinum.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue