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
*/
#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
/*
@ -1280,7 +1280,7 @@ NetProc* PCondit::elaborate(Design*des, const string&path) const
return 0;
}
if (! expr->set_width(1)) {
if (expr->expr_width() > 1) {
assert(expr->expr_width() > 1);
verinum zero (verinum::V0, expr->expr_width());
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
{
NetExpr*etmp;
NetScope*scope = des->find_scope(path);
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)
connect(lv->pin(idx), sig->pin(idx));
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);
@ -2004,7 +2011,12 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1)
connect(lv->pin(idx), sig->pin(idx));
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);
@ -2355,6 +2367,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $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
* Generalize the evaluation of floating point delays, and
* 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
*/
#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
# include <cassert>
@ -1780,9 +1780,16 @@ bool NetExpr::has_width() const
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)
: NetEBinary(op, l, r)
{
#if 0
if (l->expr_width() > r->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())
l->set_width(r->expr_width());
#endif
if (r->expr_width() > l->expr_width())
expr_width(r->expr_width());
else
@ -1812,9 +1819,17 @@ NetEBAdd* NetEBAdd::dup_expr() const
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)
: NetEBinary(op, l, r)
{
#if 0
/* First try to naturally adjust the size of the
expressions to match. */
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());
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()
@ -2473,6 +2493,9 @@ bool NetUDP::sequ_glob_(string input, char output)
/*
* $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
* NetMux needs a scope. (PR#115)
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
/*
@ -105,18 +105,48 @@ bool NetEBAdd::set_width(unsigned w)
/*
* 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 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;
flag = right_->set_width(w) && flag;
if (flag)
expr_width(w);
/* Now increase me up to the size of the largest operand. This
accounts for operands that can't shrink. */
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 $
* 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
* 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
*/
#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
# include "verinum.h"
@ -144,11 +144,13 @@ verinum& verinum::operator= (const verinum&that)
verinum::V verinum::get(unsigned idx) const
{
assert(idx < nbits_);
return bits_[idx];
}
verinum::V verinum::set(unsigned idx, verinum::V val)
{
assert(idx < nbits_);
return bits_[idx] = val;
}
@ -688,6 +690,9 @@ verinum::V operator & (verinum::V l, verinum::V r)
/*
* $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
* 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
*/
#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
# 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)
{
assert(v.nbits == l.nbits);
assert(v.nbits == r.nbits);
assert(v.nbits <= l.nbits);
assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
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)
{
assert(v.nbits == l.nbits);
assert(v.nbits == r.nbits);
assert(v.nbits <= l.nbits);
assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
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)
{
assert(v.nbits == l.nbits);
assert(v.nbits == r.nbits);
assert(v.nbits <= l.nbits);
assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
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)
{
assert(v.nbits == l.nbits);
assert(v.nbits == r.nbits);
assert(v.nbits <= l.nbits);
assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
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 $
* 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
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.