More precise about r-value width of constants.

This commit is contained in:
steve 2005-11-26 00:35:42 +00:00
parent 7efa6be236
commit 0e044d6684
5 changed files with 100 additions and 69 deletions

View File

@ -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.331 2005/11/10 13:28:11 steve Exp $"
#ident "$Id: elaborate.cc,v 1.332 2005/11/26 00:35:42 steve Exp $"
#endif
# include "config.h"
@ -2479,7 +2479,7 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
unsigned lwid = count_lval_width(lval);
rexp->set_width(lwid);
rexp->set_width(lwid, true);
rexp = pad_to_width(rexp, lwid);
dev = new NetForce(lval, rexp);
@ -3028,6 +3028,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.332 2005/11/26 00:35:42 steve
* More precise about r-value width of constants.
*
* Revision 1.331 2005/11/10 13:28:11 steve
* Reorganize signal part select handling, and add support for
* indexed part selects.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_expr.cc,v 1.25 2005/09/14 02:53:14 steve Exp $"
#ident "$Id: net_expr.cc,v 1.26 2005/11/26 00:35:43 steve Exp $"
#endif
# include "config.h"
@ -468,14 +468,6 @@ bool NetESelect::has_width() const
return true;
}
bool NetESelect::set_width(unsigned w)
{
if (expr_width() == 1)
return true;
else
return false;
}
NetESFunc::NetESFunc(const char*n, ivl_variable_type_t t,
unsigned width, unsigned np)
: name_(0), type_(t)
@ -534,6 +526,9 @@ ivl_variable_type_t NetESFunc::expr_type() const
/*
* $Log: net_expr.cc,v $
* Revision 1.26 2005/11/26 00:35:43 steve
* More precise about r-value width of constants.
*
* Revision 1.25 2005/09/14 02:53:14 steve
* Support bool expressions and compares handle them optimally.
*

View File

@ -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.351 2005/09/19 21:45:36 steve Exp $"
#ident "$Id: netlist.h,v 1.352 2005/11/26 00:35:43 steve Exp $"
#endif
/*
@ -1043,7 +1043,21 @@ class NetExpr : public LineInfo {
// Coerce the expression to have a specific width. If the
// coercion works, then return true. Otherwise, return false.
virtual bool set_width(unsigned);
// A coercion will work or not depending on the implementation
// in the derived class. Normally, the width will be set if
// the expression is:
// - already the requested size, OR
// - otherwise unsized.
// Normally, the resize will not allow a width size that loses
// data. For example, it will not reduce a constant expression
// to the point where significant bits are lost. But if the
// last_chance flag is true, then the method assumes that high
// bits will be lost anyhow, so try harder. Loss will be
// allowed, but it still won't resize fixed size expressions
// such as vector signals. This flag is meant to be used by
// elaboration of procedural assignment to set the expression
// width to the l-value width, if possible.
virtual bool set_width(unsigned wid, bool last_chance =false);
// This method returns true if the expression is
// signed. Unsigned expressions return false.
@ -1106,7 +1120,7 @@ class NetEConst : public NetExpr {
const verinum&value() const;
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance =false);
virtual bool has_width() const;
virtual ivl_variable_type_t expr_type() const;
@ -1132,7 +1146,7 @@ class NetEConstParam : public NetEConst {
perm_string name() const;
const NetScope*scope() const;
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
@ -1156,7 +1170,7 @@ class NetECReal : public NetExpr {
// Reals can be used in vector expressions. Conversions will
// be done at the right time.
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
// This type has no self-determined width. This is false.
virtual bool has_width() const;
@ -2391,7 +2405,7 @@ class NetEUFunc : public NetExpr {
const NetScope* func() const;
virtual bool set_width(unsigned);
virtual bool set_width(unsigned, bool last_chance);
virtual ivl_variable_type_t expr_type() const;
virtual void dump(ostream&) const;
@ -2545,7 +2559,7 @@ class NetEBinary : public NetExpr {
char op() const { return op_; }
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance =false);
// A binary expression node only has a definite
// self-determinable width if the operands both have definite
@ -2581,7 +2595,7 @@ class NetEBAdd : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBAdd* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*);
@ -2600,7 +2614,7 @@ class NetEBDiv : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetNet* synthesize(Design*);
@ -2626,7 +2640,7 @@ class NetEBBits : public NetEBinary {
NetEBBits(char op, NetExpr*l, NetExpr*r);
~NetEBBits();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBBits* dup_expr() const;
virtual NetEConst* eval_tree();
@ -2653,7 +2667,7 @@ class NetEBComp : public NetEBinary {
NetEBComp(char op, NetExpr*l, NetExpr*r);
~NetEBComp();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
/* A compare expression has a definite width. */
virtual bool has_width() const;
@ -2688,7 +2702,7 @@ class NetEBLogic : public NetEBinary {
NetEBLogic(char op, NetExpr*l, NetExpr*r);
~NetEBLogic();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBLogic* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet* synthesize(Design*);
@ -2708,7 +2722,7 @@ class NetEBMult : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree();
virtual NetNet* synthesize(Design*);
@ -2734,7 +2748,7 @@ class NetEBShift : public NetEBinary {
NetEBShift(char op, NetExpr*l, NetExpr*r);
~NetEBShift();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
// A shift expression only needs the left expression to have a
// definite width to give the expression a definite width.
@ -2774,7 +2788,7 @@ class NetEConcat : public NetExpr {
virtual NexusSet* nex_input();
virtual bool has_width() const;
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance =false);
virtual NetEConcat* dup_expr() const;
virtual NetEConst* eval_tree();
virtual NetNet*synthesize(Design*);
@ -2805,7 +2819,7 @@ class NetEParam : public NetExpr {
~NetEParam();
virtual NexusSet* nex_input();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetExpr* eval_tree();
@ -2844,7 +2858,7 @@ class NetESelect : public NetExpr {
const NetExpr*select() const;
virtual NexusSet* nex_input();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance =false);
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEConst* eval_tree();
@ -2922,7 +2936,7 @@ class NetESFunc : public NetExpr {
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input();
virtual bool set_width(unsigned);
virtual bool set_width(unsigned, bool last_chance);
virtual void dump(ostream&) const;
virtual void expr_scan(struct expr_scan_t*) const;
@ -2950,7 +2964,7 @@ class NetETernary : public NetExpr {
NetETernary(NetExpr*c, NetExpr*t, NetExpr*f);
~NetETernary();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
const NetExpr*cond_expr() const;
const NetExpr*true_expr() const;
@ -2994,7 +3008,7 @@ class NetEUnary : public NetExpr {
char op() const { return op_; }
const NetExpr* expr() const { return expr_; }
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetEUnary* dup_expr() const;
virtual NetEConst* eval_tree();
@ -3027,7 +3041,7 @@ class NetEUReduce : public NetEUnary {
NetEUReduce(char op, NetExpr*ex);
~NetEUReduce();
virtual bool set_width(unsigned w);
virtual bool set_width(unsigned w, bool last_chance);
virtual NetNet* synthesize(Design*);
virtual NetEUReduce* dup_expr() const;
virtual NetEConst* eval_tree();
@ -3048,7 +3062,7 @@ class NetEMemory : public NetExpr {
perm_string name () const;
const NetExpr* index() const;
virtual bool set_width(unsigned);
virtual bool set_width(unsigned, bool last_chance);
virtual NetNet* synthesize(Design*des);
NetExpr* eval_tree();
@ -3083,7 +3097,7 @@ class NetESignal : public NetExpr {
~NetESignal();
perm_string name() const;
virtual bool set_width(unsigned);
virtual bool set_width(unsigned, bool last_chance);
virtual NetESignal* dup_expr() const;
NetNet* synthesize(Design*des);
@ -3444,6 +3458,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.352 2005/11/26 00:35:43 steve
* More precise about r-value width of constants.
*
* Revision 1.351 2005/09/19 21:45:36 steve
* Spelling patches from Larry.
*

View File

@ -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.36 2005/05/17 20:56:55 steve Exp $"
#ident "$Id: set_width.cc,v 1.37 2005/11/26 00:35:44 steve Exp $"
#endif
# include "config.h"
@ -36,7 +36,7 @@
# include <typeinfo>
bool NetExpr::set_width(unsigned w)
bool NetExpr::set_width(unsigned w, bool)
{
cerr << get_line() << ": internal warning: "
<<typeid(*this).name() << ": set_width(unsigned) "
@ -45,7 +45,7 @@ bool NetExpr::set_width(unsigned w)
return false;
}
bool NetEBinary::set_width(unsigned w)
bool NetEBinary::set_width(unsigned w, bool)
{
bool flag = true;
switch (op_) {
@ -80,7 +80,7 @@ bool NetEBinary::set_width(unsigned w)
* The bitwise logical operators have operands the same size as the
* result. Anything else is a mess.
*/
bool NetEBAdd::set_width(unsigned w)
bool NetEBAdd::set_width(unsigned w, bool)
{
unsigned wid = w;
@ -113,7 +113,7 @@ bool NetEBAdd::set_width(unsigned w)
* 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)
{
/* First, give the operands a chance to adjust themselves to
the requested width. */
@ -153,7 +153,7 @@ bool NetEBBits::set_width(unsigned w)
* their own natural width, but the comparison operator result has a
* fixed width of 1.
*/
bool NetEBComp::set_width(unsigned w)
bool NetEBComp::set_width(unsigned w, bool)
{
return (w == 1);
}
@ -162,12 +162,12 @@ bool NetEBComp::set_width(unsigned w)
* There is nothing we can do to the operands of a division to make it
* confirm to the requested width. Force the context to pad or truncate.
*/
bool NetEBDiv::set_width(unsigned w)
bool NetEBDiv::set_width(unsigned w, bool)
{
return w == expr_width();
}
bool NetEBLogic::set_width(unsigned w)
bool NetEBLogic::set_width(unsigned w, bool)
{
bool flag;
flag = left_->set_width(right_->expr_width());
@ -180,7 +180,7 @@ bool NetEBLogic::set_width(unsigned w)
* There is nothing we can do to the operands of a multiply to make it
* confirm to the requested width. Force the context to pad or truncate.
*/
bool NetEBMult::set_width(unsigned w)
bool NetEBMult::set_width(unsigned w, bool)
{
return w == expr_width();
}
@ -190,7 +190,7 @@ bool NetEBMult::set_width(unsigned w)
* natural width. The width of the operator result is the width of the
* left operand, the value that is to be shifted.
*/
bool NetEBShift::set_width(unsigned w)
bool NetEBShift::set_width(unsigned w, bool)
{
bool flag = true;
@ -228,7 +228,7 @@ bool NetEBShift::set_width(unsigned w)
* matter because the null expression is indication of an error and
* the compiler will not go beyond elaboration.
*/
bool NetEConcat::set_width(unsigned w)
bool NetEConcat::set_width(unsigned w, bool)
{
unsigned sum = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
@ -241,7 +241,7 @@ bool NetEConcat::set_width(unsigned w)
return true;
}
bool NetEConst::set_width(unsigned w)
bool NetEConst::set_width(unsigned w, bool last_chance)
{
if (w == value_.len()) {
expr_width(w);
@ -289,17 +289,19 @@ bool NetEConst::set_width(unsigned w)
? value_[value_.len() - 1]
: verinum::V0;
// Don't reduce a number too small to hold all the
// significant bits.
for (unsigned idx = w ; idx < value_.len() ; idx += 1)
if (value_[idx] != pad_bit)
use_w = idx+1;
if (! last_chance) {
// Don't reduce a number too small to hold all the
// significant bits.
for (unsigned idx = w ; idx < value_.len() ; idx += 1)
if (value_[idx] != pad_bit)
use_w = idx+1;
// Correct for the special case of signed value. We
// cannot have the result change sign on us.
if (value_.has_sign() && (use_w < value_.len())
&& (value_[use_w-1] != pad_bit))
use_w += 1;
// Correct for the special case of signed value. We
// cannot have the result change sign on us.
if (value_.has_sign() && (use_w < value_.len())
&& (value_[use_w-1] != pad_bit))
use_w += 1;
}
verinum tmp (verinum::V0, use_w, has_width());
for (unsigned idx = 0 ; idx < use_w ; idx += 1)
@ -316,7 +318,7 @@ bool NetEConst::set_width(unsigned w)
* Parameter vectors cannot be resized because they refer to a common
* value.
*/
bool NetEConstParam::set_width(unsigned w)
bool NetEConstParam::set_width(unsigned w, bool)
{
return w == expr_width();
}
@ -326,13 +328,13 @@ bool NetEConstParam::set_width(unsigned w)
* because it isn't really a vector. The environment will convert this
* to a vector at the right time.
*/
bool NetECReal::set_width(unsigned w)
bool NetECReal::set_width(unsigned w, bool)
{
expr_width(w);
return true;
}
bool NetEMemory::set_width(unsigned w)
bool NetEMemory::set_width(unsigned w, bool)
{
if (w != mem_->width())
return false;
@ -341,12 +343,20 @@ bool NetEMemory::set_width(unsigned w)
return true;
}
bool NetEParam::set_width(unsigned)
bool NetEParam::set_width(unsigned, bool)
{
return false;
}
bool NetESFunc::set_width(unsigned w)
bool NetESelect::set_width(unsigned w, bool)
{
if (expr_width() == 1)
return true;
else
return false;
}
bool NetESFunc::set_width(unsigned w, bool)
{
return w == expr_width();
}
@ -355,7 +365,7 @@ bool NetESFunc::set_width(unsigned w)
* The signal should automatically pad with zeros to get to the desired
* width. Do not allow signal bits to be truncated, however.
*/
bool NetESignal::set_width(unsigned w)
bool NetESignal::set_width(unsigned w, bool)
{
if (w != bit_count())
return false;
@ -363,7 +373,7 @@ bool NetESignal::set_width(unsigned w)
return true;
}
bool NetETernary::set_width(unsigned w)
bool NetETernary::set_width(unsigned w, bool)
{
bool flag = true;
flag = flag && true_val_->set_width(w);
@ -377,13 +387,13 @@ bool NetETernary::set_width(unsigned w)
* width. What I really need to do is note the width of the output
* parameter of the function definition and take that into account.
*/
bool NetEUFunc::set_width(unsigned wid)
bool NetEUFunc::set_width(unsigned wid, bool)
{
expr_width(wid);
return true;
}
bool NetEUnary::set_width(unsigned w)
bool NetEUnary::set_width(unsigned w, bool)
{
bool flag = true;
switch (op_) {
@ -406,7 +416,7 @@ bool NetEUnary::set_width(unsigned w)
* Unary reduction operators allow its operand to have any width. The
* result is defined to be 1.
*/
bool NetEUReduce::set_width(unsigned w)
bool NetEUReduce::set_width(unsigned w, bool)
{
return w == 1;
}
@ -414,6 +424,9 @@ bool NetEUReduce::set_width(unsigned w)
/*
* $Log: set_width.cc,v $
* Revision 1.37 2005/11/26 00:35:44 steve
* More precise about r-value width of constants.
*
* Revision 1.36 2005/05/17 20:56:55 steve
* Parameters cannot have their width changed.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_process.c,v 1.119 2005/10/12 17:26:01 steve Exp $"
#ident "$Id: vvp_process.c,v 1.120 2005/11/26 00:35:44 steve Exp $"
#endif
# include "vvp_priv.h"
@ -750,9 +750,9 @@ static void force_vector_to_lval(ivl_statement_t net, struct vector_info rvec)
/* Do not support bit or part selects of l-values yet. */
assert(ivl_lval_mux(lval) == 0);
assert(ivl_lval_part_off(lval) == 0);
assert(ivl_lval_width(lval) == ivl_signal_width(lsig));
//assert(ivl_lval_width(lval) == ivl_signal_width(lsig));
use_wid = ivl_signal_width(lsig);
use_wid = ivl_lval_width(lval);
assert((roff + use_wid) <= rvec.wid);
fprintf(vvp_out, " %s V_%s, %u, %u;\n", command_name,
@ -1468,6 +1468,9 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.120 2005/11/26 00:35:44 steve
* More precise about r-value width of constants.
*
* Revision 1.119 2005/10/12 17:26:01 steve
* force l-values do not support bit/part select.
*