Expression widths with unsized literals are pseudo-infinite width.
This commit is contained in:
parent
2a8b960b06
commit
2302693201
23
PExpr.cc
23
PExpr.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.cc,v 1.37 2005/10/04 04:09:25 steve Exp $"
|
||||
#ident "$Id: PExpr.cc,v 1.38 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -75,6 +75,24 @@ bool PEBinary::is_constant(Module*mod) const
|
|||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBComp::~PEBComp()
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::~PEBShift()
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
|
|
@ -270,6 +288,9 @@ bool PEUnary::is_constant(Module*m) const
|
|||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.38 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.37 2005/10/04 04:09:25 steve
|
||||
* Add support for indexed select attached to parameters.
|
||||
*
|
||||
|
|
|
|||
79
PExpr.h
79
PExpr.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.h,v 1.83 2006/06/18 04:15:50 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.84 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
|
@ -51,6 +51,29 @@ class PExpr : public LineInfo {
|
|||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
// This method tests the width that the expression wants to
|
||||
// be. It is used by elaboration of assignments to figure out
|
||||
// the width of the expression.
|
||||
//
|
||||
// The "min" is the width of the local context, so it the
|
||||
// minimum width that this function should return. Initially
|
||||
// this is the same as the lval width.
|
||||
//
|
||||
// The "lval" is the width of the destination where this
|
||||
// result is going to go. This can be used to constrain the
|
||||
// amount that an expression can reasonably expand. For
|
||||
// example, there is no point expanding an addition to beyond
|
||||
// the lval. This extra bit of information allows the
|
||||
// expression to optimize itself a bit. If the lval==0, then
|
||||
// the subexpression should not make l-value related
|
||||
// optimizations.
|
||||
//
|
||||
// The unsigned_flag is set to true if the expression is
|
||||
// unsized and therefore expandable. This happens if a
|
||||
// sub-expression is an unsized literal. Some expressions make
|
||||
// special use of that.
|
||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
||||
|
||||
// Procedural elaboration of the expression. The expr_width is
|
||||
// the width of the context of the expression (i.e. the
|
||||
// l-value width of an assignment) or -1 if the expression is
|
||||
|
|
@ -128,6 +151,8 @@ class PEConcat : public PExpr {
|
|||
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
|
|
@ -177,6 +202,8 @@ class PEEvent : public PExpr {
|
|||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
private:
|
||||
edge_t type_;
|
||||
PExpr *expr_;
|
||||
|
|
@ -193,6 +220,8 @@ class PEFNumber : public PExpr {
|
|||
|
||||
const verireal& value() const;
|
||||
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
/* The eval_const method as applied to a floating point number
|
||||
gets the *integer* value of the number. This accounts for
|
||||
any rounding that is needed to get the value. */
|
||||
|
|
@ -226,6 +255,9 @@ class PEIdent : public PExpr {
|
|||
~PEIdent();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
||||
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
// Identifiers are allowed (with restrictions) is assign l-values.
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
|
|
@ -344,6 +376,8 @@ class PENumber : public PExpr {
|
|||
const verinum& value() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -382,6 +416,8 @@ class PEString : public PExpr {
|
|||
|
||||
string value() const;
|
||||
virtual void dump(ostream&) const;
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -407,6 +443,8 @@ class PEUnary : public PExpr {
|
|||
~PEUnary();
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -433,8 +471,12 @@ class PEBinary : public PExpr {
|
|||
~PEBinary();
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
|
||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&unsized_flag) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -447,13 +489,15 @@ class PEBinary : public PExpr {
|
|||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, NetScope*sc) const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
char op_;
|
||||
PExpr*left_;
|
||||
PExpr*right_;
|
||||
|
||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
||||
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
||||
|
||||
private:
|
||||
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -496,6 +540,31 @@ class PEBinary : public PExpr {
|
|||
const NetExpr* decay) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* Here are a few specilized classes for handling specific binary
|
||||
* operators.
|
||||
*/
|
||||
class PEBComp : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
||||
~PEBComp();
|
||||
|
||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&flag) const;
|
||||
|
||||
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
};
|
||||
|
||||
class PEBShift : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
||||
~PEBShift();
|
||||
|
||||
virtual unsigned test_width(unsigned min, unsigned lval, bool&flag) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class supports the ternary (?:) operator. The operator takes
|
||||
* three expressions, the test, the true result and the false result.
|
||||
|
|
@ -507,6 +576,7 @@ class PETernary : public PExpr {
|
|||
~PETernary();
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
|
|
@ -539,6 +609,8 @@ class PECallFunction : public PExpr {
|
|||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
//virtual int test_width(bool) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
const NetExpr* rise,
|
||||
|
|
@ -567,6 +639,9 @@ class PECallFunction : public PExpr {
|
|||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.84 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.83 2006/06/18 04:15:50 steve
|
||||
* Add support for system functions in continuous assignments.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.170 2006/10/03 05:06:00 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.171 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1162,8 +1162,10 @@ void NetEParam::dump(ostream&o) const
|
|||
{
|
||||
if (scope_ != 0)
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
else
|
||||
else if (name_)
|
||||
o << "<" << name_ << ">";
|
||||
else
|
||||
o << "<???>";
|
||||
}
|
||||
|
||||
void NetETernary::dump(ostream&o) const
|
||||
|
|
@ -1229,6 +1231,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.171 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.170 2006/10/03 05:06:00 steve
|
||||
* Support real valued specify delays, properly scaled.
|
||||
*
|
||||
|
|
|
|||
127
elab_expr.cc
127
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.113 2006/10/15 03:25:57 steve Exp $"
|
||||
#ident "$Id: elab_expr.cc,v 1.114 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -28,6 +28,19 @@
|
|||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
||||
/*
|
||||
* The default behavor for the test_width method is to just return the
|
||||
* minimum width that is passed in.
|
||||
*/
|
||||
unsigned PExpr::test_width(unsigned min, unsigned lval, bool&) const
|
||||
{
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: test_width defaults to "
|
||||
<< min << ", ignoring unsized_flag" << endl;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, int, bool) const
|
||||
{
|
||||
cerr << get_line() << ": internal error: I do not know how to elaborate"
|
||||
|
|
@ -38,6 +51,42 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, int, bool) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned PEBinary::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
||||
{
|
||||
bool flag_left = false;
|
||||
bool flag_right = false;
|
||||
unsigned wid_left = left_->test_width(min, lval, flag_left);
|
||||
unsigned wid_right = right_->test_width(min, lval, flag_right);
|
||||
|
||||
if (flag_left || flag_right)
|
||||
unsized_flag = true;
|
||||
|
||||
switch (op_) {
|
||||
case '+':
|
||||
case '-':
|
||||
if (unsized_flag) {
|
||||
wid_left += 1;
|
||||
wid_right += 1;
|
||||
}
|
||||
if (wid_left > min)
|
||||
min = wid_left;
|
||||
if (wid_right > min)
|
||||
min = wid_right;
|
||||
if (lval > 0 && min > lval)
|
||||
min = lval;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (wid_left > min)
|
||||
min = wid_left;
|
||||
if (wid_right > min)
|
||||
min = wid_right;
|
||||
break;
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate binary expressions. This involves elaborating the left
|
||||
* and right sides, and creating one of a variety of different NetExpr
|
||||
|
|
@ -57,7 +106,14 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetEBinary*tmp = elaborate_eval_expr_base_(des, lp, rp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des,
|
||||
NetExpr*lp,
|
||||
NetExpr*rp) const
|
||||
{
|
||||
/* If either expression can be evaluated ahead of time, then
|
||||
do so. This can prove helpful later. */
|
||||
{ NetExpr*tmp;
|
||||
|
|
@ -74,8 +130,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
|
||||
return tmp;
|
||||
return elaborate_expr_base_(des, lp, rp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -87,6 +142,7 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
|||
NetExpr*lp, NetExpr*rp) const
|
||||
{
|
||||
bool flag;
|
||||
|
||||
NetEBinary*tmp;
|
||||
|
||||
switch (op_) {
|
||||
|
|
@ -189,6 +245,50 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
unsigned PEBComp::test_width(unsigned, unsigned, bool&) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
NetEBinary* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_width, bool sys_task_arg) const
|
||||
{
|
||||
assert(left_);
|
||||
assert(right_);
|
||||
|
||||
/* Width of operands is self-determined. */
|
||||
int use_wid = -1;
|
||||
|
||||
NetExpr*lp = left_->elaborate_expr(des, scope, use_wid, false);
|
||||
NetExpr*rp = right_->elaborate_expr(des, scope, use_wid, false);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
delete lp;
|
||||
delete rp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we find that one of the operands are indefinitely wide,
|
||||
then go ahead and relax the width of the operand to
|
||||
eliminate loss. */
|
||||
if (! lp->has_width())
|
||||
rp->relax_width();
|
||||
if (! rp->has_width())
|
||||
lp->relax_width();
|
||||
|
||||
return elaborate_eval_expr_base_(des, lp, rp);
|
||||
}
|
||||
|
||||
unsigned PEBShift::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
||||
{
|
||||
unsigned wid_left = left_->test_width(min, 0, unsized_flag);
|
||||
|
||||
// The right expression is self-determined and has no impact
|
||||
// on the expression size that is generated.
|
||||
|
||||
return wid_left;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a call to a system function, generate the proper expression
|
||||
* nodes to represent the call in the netlist. Since we don't support
|
||||
|
|
@ -491,6 +591,12 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, int, bool) const
|
|||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
unsigned PEIdent::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate an identifier in an expression. The identifier can be a
|
||||
* parameter name, a signal name or a memory name. It can also be a
|
||||
|
|
@ -1229,6 +1335,18 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
|||
return node;
|
||||
}
|
||||
|
||||
unsigned PENumber::test_width(unsigned min, unsigned lval, bool&unsized_flag) const
|
||||
{
|
||||
unsigned use_wid = value_->len();
|
||||
if (min > use_wid)
|
||||
use_wid = min;
|
||||
|
||||
if (! value_->has_len())
|
||||
unsized_flag = true;
|
||||
|
||||
return use_wid;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*,
|
||||
int expr_width, bool) const
|
||||
{
|
||||
|
|
@ -1427,6 +1545,9 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.114 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.113 2006/10/15 03:25:57 steve
|
||||
* More detailed internal error message.
|
||||
*
|
||||
|
|
|
|||
18
elaborate.cc
18
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elaborate.cc,v 1.347 2006/10/03 15:33:49 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.348 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1419,10 +1419,19 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
delay = elaborate_delay_expr(delay_, des, scope);
|
||||
|
||||
|
||||
assert(rval());
|
||||
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
|
||||
assert(rval());
|
||||
NetExpr*rv = elab_and_eval(des, scope, rval(), lv->lwidth());
|
||||
/* Find out what the r-value width is going to be. We guess it
|
||||
will be the l-value width, but it may turn out to be
|
||||
something else based on self-determined widths inside. */
|
||||
unsigned use_width = lv->lwidth();
|
||||
bool unsized_flag = false;
|
||||
use_width = rval()->test_width(use_width, use_width, unsized_flag);
|
||||
|
||||
/* Now elaborate to the expected width. */
|
||||
NetExpr*rv = elab_and_eval(des, scope, rval(), use_width);
|
||||
if (rv == 0) return 0;
|
||||
assert(rv);
|
||||
|
||||
|
|
@ -3311,6 +3320,9 @@ Design* elaborate(list<perm_string>roots)
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.348 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.347 2006/10/03 15:33:49 steve
|
||||
* no-specify turns of specparam elaboration.
|
||||
*
|
||||
|
|
|
|||
14
eval_tree.cc
14
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.70 2006/09/19 23:00:15 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.71 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1236,8 +1236,15 @@ NetExpr* NetEMemory::eval_tree()
|
|||
|
||||
NetExpr* NetEParam::eval_tree()
|
||||
{
|
||||
if (des_ == 0)
|
||||
if (des_ == 0) {
|
||||
assert(scope_ == 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: evaluating expression: "
|
||||
<< *this << endl;
|
||||
}
|
||||
|
||||
assert(scope_);
|
||||
const NetExpr*expr_msb;
|
||||
|
|
@ -1670,6 +1677,9 @@ NetEConst* NetEUReduce::eval_tree()
|
|||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.71 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.70 2006/09/19 23:00:15 steve
|
||||
* Use elab_and_eval for bit select expressions.
|
||||
*
|
||||
|
|
|
|||
12
netlist.h
12
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.363 2006/10/03 05:06:00 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.364 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1134,6 +1134,12 @@ class NetExpr : public LineInfo {
|
|||
// width to the l-value width, if possible.
|
||||
virtual bool set_width(unsigned wid, bool last_chance =false);
|
||||
|
||||
// This is similar to set_width, but allows the expression to
|
||||
// set the width for itself, it a way that eliminates
|
||||
// loss. This is used by elaboration in expressions where the
|
||||
// expression width is determined to be "indefinitely large".
|
||||
virtual void relax_width(void);
|
||||
|
||||
// This method returns true if the expression is
|
||||
// signed. Unsigned expressions return false.
|
||||
bool has_sign() const;
|
||||
|
|
@ -2676,6 +2682,7 @@ class NetEBAdd : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void relax_width(void);
|
||||
virtual NetEBAdd* dup_expr() const;
|
||||
virtual NetEConst* eval_tree();
|
||||
virtual NetNet* synthesize(Design*);
|
||||
|
|
@ -3567,6 +3574,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.364 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.363 2006/10/03 05:06:00 steve
|
||||
* Support real valued specify delays, properly scaled.
|
||||
*
|
||||
|
|
|
|||
24
parse.y
24
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.220 2006/09/23 04:57:19 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.221 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -879,67 +879,67 @@ expression
|
|||
$$ = tmp;
|
||||
}
|
||||
| expression '<' expression
|
||||
{ PEBinary*tmp = new PEBinary('<', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('<', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression '>' expression
|
||||
{ PEBinary*tmp = new PEBinary('>', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('>', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_LS expression
|
||||
{ PEBinary*tmp = new PEBinary('l', $1, $3);
|
||||
{ PEBinary*tmp = new PEBShift('l', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_RS expression
|
||||
{ PEBinary*tmp = new PEBinary('r', $1, $3);
|
||||
{ PEBinary*tmp = new PEBShift('r', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_RSS expression
|
||||
{ PEBinary*tmp = new PEBinary('R', $1, $3);
|
||||
{ PEBinary*tmp = new PEBShift('R', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_EQ expression
|
||||
{ PEBinary*tmp = new PEBinary('e', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('e', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_CEQ expression
|
||||
{ PEBinary*tmp = new PEBinary('E', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('E', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_LE expression
|
||||
{ PEBinary*tmp = new PEBinary('L', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('L', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_GE expression
|
||||
{ PEBinary*tmp = new PEBinary('G', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('G', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_NE expression
|
||||
{ PEBinary*tmp = new PEBinary('n', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('n', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_CNE expression
|
||||
{ PEBinary*tmp = new PEBinary('N', $1, $3);
|
||||
{ PEBinary*tmp = new PEBComp('N', $1, $3);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
|
|
|
|||
34
set_width.cc
34
set_width.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2006 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -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.39 2006/07/31 03:50:17 steve Exp $"
|
||||
#ident "$Id: set_width.cc,v 1.40 2006/10/30 05:44:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
*/
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
# include <typeinfo>
|
||||
|
||||
|
||||
|
|
@ -45,6 +46,14 @@ bool NetExpr::set_width(unsigned w, bool)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The default relax_width method does nothing, and leaves the
|
||||
* previously elaborated width.
|
||||
*/
|
||||
void NetExpr::relax_width(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool NetEBinary::set_width(unsigned w, bool)
|
||||
{
|
||||
bool flag = true;
|
||||
|
|
@ -108,6 +117,24 @@ bool NetEBAdd::set_width(unsigned w, bool)
|
|||
return wid == w;
|
||||
}
|
||||
|
||||
void NetEBAdd::relax_width(void)
|
||||
{
|
||||
unsigned wid = left_->expr_width();
|
||||
if (right_->expr_width() > wid)
|
||||
wid = right_->expr_width();
|
||||
|
||||
// Allow space for the carry.
|
||||
wid += 1;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Relax addition width to " << wid << endl;
|
||||
|
||||
left_->set_width(wid);
|
||||
right_->set_width(wid);
|
||||
expr_width(wid);
|
||||
}
|
||||
|
||||
/*
|
||||
* The bitwise logical operators have operands the same size as the
|
||||
* result. Anything else is a mess. I first try to get the operands to
|
||||
|
|
@ -440,6 +467,9 @@ bool NetEUReduce::set_width(unsigned w, bool)
|
|||
|
||||
/*
|
||||
* $Log: set_width.cc,v $
|
||||
* Revision 1.40 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.39 2006/07/31 03:50:17 steve
|
||||
* Add support for power in constant expressions.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue