Fix expression widths for rvalues and parameters (PR#131,132)

This commit is contained in:
steve 2001-02-07 21:47:13 +00:00
parent 94a1d59817
commit 2fbc0af1ea
5 changed files with 103 additions and 24 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elaborate.cc,v 1.205 2001/01/14 23:04:56 steve Exp $" #ident "$Id: elaborate.cc,v 1.206 2001/02/07 21:47:13 steve Exp $"
#endif #endif
/* /*
@ -1280,7 +1280,7 @@ NetProc* PCondit::elaborate(Design*des, const string&path) const
return 0; return 0;
} }
if (! expr->set_width(1)) { if (expr->expr_width() > 1) {
assert(expr->expr_width() > 1); assert(expr->expr_width() > 1);
verinum zero (verinum::V0, expr->expr_width()); verinum zero (verinum::V0, expr->expr_width());
NetEConst*ezero = new NetEConst(zero); NetEConst*ezero = new NetEConst(zero);
@ -1955,6 +1955,7 @@ NetProc* PForce::elaborate(Design*des, const string&path) const
*/ */
NetProc* PForStatement::elaborate(Design*des, const string&path) const NetProc* PForStatement::elaborate(Design*des, const string&path) const
{ {
NetExpr*etmp;
NetScope*scope = des->find_scope(path); NetScope*scope = des->find_scope(path);
assert(scope); assert(scope);
@ -1980,7 +1981,13 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1)
connect(lv->pin(idx), sig->pin(idx)); connect(lv->pin(idx), sig->pin(idx));
des->add_node(lv); des->add_node(lv);
NetAssign*init = new NetAssign(lv, expr1_->elaborate_expr(des, scope));
/* Make the r-value of the initial assignment, and size it
properly. Then use it to build the assignment statement. */
etmp = expr1_->elaborate_expr(des, scope);
etmp->set_width(lv->lwidth());
NetAssign*init = new NetAssign(lv, etmp);
top->append(init); top->append(init);
@ -2004,7 +2011,12 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1)
connect(lv->pin(idx), sig->pin(idx)); connect(lv->pin(idx), sig->pin(idx));
des->add_node(lv); des->add_node(lv);
NetAssign*step = new NetAssign(lv, expr2_->elaborate_expr(des, scope));
/* Make the rvalue of the increment expression, and size it
for the lvalue. */
etmp = expr2_->elaborate_expr(des, scope);
etmp->set_width(lv->lwidth());
NetAssign*step = new NetAssign(lv, etmp);
body->append(step); body->append(step);
@ -2355,6 +2367,9 @@ Design* elaborate(const map<string,Module*>&modules,
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.206 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.205 2001/01/14 23:04:56 steve * Revision 1.205 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and * Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements. * get it working with delay assignment statements.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.cc,v 1.154 2001/01/18 03:16:35 steve Exp $" #ident "$Id: netlist.cc,v 1.155 2001/02/07 21:47:13 steve Exp $"
#endif #endif
# include <cassert> # include <cassert>
@ -1780,9 +1780,16 @@ bool NetExpr::has_width() const
return true; return true;
} }
/*
* Create a bitwise operator node from the opcode and the left and
* right expressions. Don't worry about the width of the expression
* yet, we'll get that from the l-value, whatever that turns out to
* be.
*/
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r) NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r) : NetEBinary(op, l, r)
{ {
#if 0
if (l->expr_width() > r->expr_width()) if (l->expr_width() > r->expr_width())
r->set_width(l->expr_width()); r->set_width(l->expr_width());
@ -1794,7 +1801,7 @@ NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
if (r->expr_width() < l->expr_width()) if (r->expr_width() < l->expr_width())
l->set_width(r->expr_width()); l->set_width(r->expr_width());
#endif
if (r->expr_width() > l->expr_width()) if (r->expr_width() > l->expr_width())
expr_width(r->expr_width()); expr_width(r->expr_width());
else else
@ -1812,9 +1819,17 @@ NetEBAdd* NetEBAdd::dup_expr() const
return result; return result;
} }
/*
* Create a bitwise operator node from the opcode and the left and
* right expressions. Don't worry about the width of the expression
* yet, we'll get that from the l-value, whatever that turns out to
* be. However, if we don't, our default will be the width of the
* largest operand.
*/
NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r) NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r) : NetEBinary(op, l, r)
{ {
#if 0
/* First try to naturally adjust the size of the /* First try to naturally adjust the size of the
expressions to match. */ expressions to match. */
if (l->expr_width() > r->expr_width()) if (l->expr_width() > r->expr_width())
@ -1838,6 +1853,11 @@ NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
assert(left_->expr_width() == right_->expr_width()); assert(left_->expr_width() == right_->expr_width());
expr_width(left_->expr_width()); expr_width(left_->expr_width());
#endif
if (r->expr_width() > l->expr_width())
expr_width(r->expr_width());
else
expr_width(l->expr_width());
} }
NetEBBits::~NetEBBits() NetEBBits::~NetEBBits()
@ -2473,6 +2493,9 @@ bool NetUDP::sequ_glob_(string input, char output)
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.155 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.154 2001/01/18 03:16:35 steve * Revision 1.154 2001/01/18 03:16:35 steve
* NetMux needs a scope. (PR#115) * NetMux needs a scope. (PR#115)
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: set_width.cc,v 1.15 2001/01/27 05:41:48 steve Exp $" #ident "$Id: set_width.cc,v 1.16 2001/02/07 21:47:13 steve Exp $"
#endif #endif
/* /*
@ -105,18 +105,48 @@ bool NetEBAdd::set_width(unsigned w)
/* /*
* The bitwise logical operators have operands the same size as the * The bitwise logical operators have operands the same size as the
* result. Anything else is a mess. * result. Anything else is a mess. I first try to get the operands to
* shrink to the desired size. I then expand operands that are too small.
*/ */
bool NetEBBits::set_width(unsigned w) bool NetEBBits::set_width(unsigned w)
{ {
bool flag = true; /* First, give the operands a chance to adjust themselves to
the requested width. */
left_->set_width(w);
right_->set_width(w);
flag = left_->set_width(w) && flag; /* Now increase me up to the size of the largest operand. This
flag = right_->set_width(w) && flag; accounts for operands that can't shrink. */
if (flag)
expr_width(w);
return flag; unsigned use_width = w;
#if 0
if (use_width < left_->expr_width())
use_width = left_->expr_width();
if (use_width < right_->expr_width())
use_width = right_->expr_width();
#endif
/* If the operands end up too small, then pad them to suit. */
if (left_->expr_width() < use_width) {
NetExpr*tmp = pad_to_width(left_, use_width);
assert(tmp);
left_ = tmp;
}
if (right_->expr_width() < w) {
NetExpr*tmp = pad_to_width(right_, use_width);
assert(tmp);
right_ = tmp;
}
/* And here is the final width. If this is not the size the
caller requested, then return false. Otherwise, return
true. */
expr_width(use_width);
return w == use_width;
} }
/* /*
@ -313,6 +343,9 @@ bool NetEUnary::set_width(unsigned w)
/* /*
* $Log: set_width.cc,v $ * $Log: set_width.cc,v $
* Revision 1.16 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.15 2001/01/27 05:41:48 steve * Revision 1.15 2001/01/27 05:41:48 steve
* Fix sign extension of evaluated constants. (PR#91) * Fix sign extension of evaluated constants. (PR#91)
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: verinum.cc,v 1.23 2001/02/07 02:46:31 steve Exp $" #ident "$Id: verinum.cc,v 1.24 2001/02/07 21:47:13 steve Exp $"
#endif #endif
# include "verinum.h" # include "verinum.h"
@ -144,11 +144,13 @@ verinum& verinum::operator= (const verinum&that)
verinum::V verinum::get(unsigned idx) const verinum::V verinum::get(unsigned idx) const
{ {
assert(idx < nbits_);
return bits_[idx]; return bits_[idx];
} }
verinum::V verinum::set(unsigned idx, verinum::V val) verinum::V verinum::set(unsigned idx, verinum::V val)
{ {
assert(idx < nbits_);
return bits_[idx] = val; return bits_[idx] = val;
} }
@ -688,6 +690,9 @@ verinum::V operator & (verinum::V l, verinum::V r)
/* /*
* $Log: verinum.cc,v $ * $Log: verinum.cc,v $
* Revision 1.24 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.23 2001/02/07 02:46:31 steve * Revision 1.23 2001/02/07 02:46:31 steve
* Support constant evaluation of / and % (PR#124) * Support constant evaluation of / and % (PR#124)
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: vvm_func.cc,v 1.13 2000/12/11 00:31:44 steve Exp $" #ident "$Id: vvm_func.cc,v 1.14 2001/02/07 21:47:13 steve Exp $"
#endif #endif
# include "vvm_func.h" # include "vvm_func.h"
@ -122,16 +122,16 @@ void vvm_binop_minus(vvm_bitset_t&v, const vvm_bitset_t&l,
void vvm_binop_nor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) void vvm_binop_nor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{ {
assert(v.nbits == l.nbits); assert(v.nbits <= l.nbits);
assert(v.nbits == r.nbits); assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_NOT(B_OR(l[idx], r[idx])); v[idx] = B_NOT(B_OR(l[idx], r[idx]));
} }
void vvm_binop_or(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) void vvm_binop_or(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{ {
assert(v.nbits == l.nbits); assert(v.nbits <= l.nbits);
assert(v.nbits == r.nbits); assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_OR(l[idx], r[idx]); v[idx] = B_OR(l[idx], r[idx]);
} }
@ -167,16 +167,16 @@ void vvm_binop_shiftr(vvm_bitset_t&v,
void vvm_binop_xnor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) void vvm_binop_xnor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{ {
assert(v.nbits == l.nbits); assert(v.nbits <= l.nbits);
assert(v.nbits == r.nbits); assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_NOT(B_XOR(l[idx], r[idx])); v[idx] = B_NOT(B_XOR(l[idx], r[idx]));
} }
void vvm_binop_xor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r) void vvm_binop_xor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{ {
assert(v.nbits == l.nbits); assert(v.nbits <= l.nbits);
assert(v.nbits == r.nbits); assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_XOR(l[idx], r[idx]); v[idx] = B_XOR(l[idx], r[idx]);
} }
@ -607,6 +607,9 @@ void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c,
/* /*
* $Log: vvm_func.cc,v $ * $Log: vvm_func.cc,v $
* Revision 1.14 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.13 2000/12/11 00:31:44 steve * Revision 1.13 2000/12/11 00:31:44 steve
* Add support for signed reg variables, * Add support for signed reg variables,
* simulate in t-vvm signed comparisons. * simulate in t-vvm signed comparisons.