Merge branch 'master' of ssh://steve-icarus@icarus.com/home/u/icarus/steve/git/verilog

This commit is contained in:
Stephen Williams 2007-10-11 14:50:00 -07:00
commit e1dbe7eede
4 changed files with 66 additions and 165 deletions

View File

@ -666,7 +666,7 @@ class PECallFunction : public PExpr {
bool check_call_matches_definition_(Design*des, NetScope*dscope) const; bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope, NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width, unsigned width,
const NetExpr* rise, const NetExpr* rise,

View File

@ -372,7 +372,7 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
* size_tf functions, make assumptions about widths based on some * size_tf functions, make assumptions about widths based on some
* known function names. * known function names.
*/ */
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const
{ {
/* Catch the special case that the system function is the /* Catch the special case that the system function is the
@ -405,6 +405,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
PExpr*expr = parms_[0]; PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, -1, true); NetExpr*sub = expr->elaborate_expr(des, scope, -1, true);
sub->cast_signed(false); sub->cast_signed(false);
if (expr_wid > 0 && (unsigned)expr_wid > sub->expr_width())
sub = pad_to_width(sub, expr_wid);
return sub; return sub;
} }
@ -536,7 +540,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool) const int expr_wid, bool) const
{ {
if (peek_tail_name(path_)[0] == '$') if (peek_tail_name(path_)[0] == '$')
return elaborate_sfunc_(des, scope); return elaborate_sfunc_(des, scope, expr_wid);
NetFuncDef*def = des->find_function(scope, path_); NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) { if (def == 0) {
@ -570,7 +574,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
PExpr*tmp = parms_[idx]; PExpr*tmp = parms_[idx];
if (tmp) { if (tmp) {
parms[idx] = elab_and_eval(des, scope, tmp, -1); int argwid = def->port(idx)->vector_width();
parms[idx] = elab_and_eval(des, scope, tmp, argwid);
if (debug_elaborate)
cerr << get_line() << ": debug:"
<< " function " << path_
<< " arg " << (idx+1)
<< " argwid=" << argwid
<< ": " << *parms[idx] << endl;
} else { } else {
missing_parms += 1; missing_parms += 1;
@ -1253,7 +1264,7 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
// Recalculate the constant address with the adjusted base. // Recalculate the constant address with the adjusted base.
unsigned use_addr = net->array_index_to_address(addr); unsigned use_addr = net->array_index_to_address(addr);
if (use_addr != addr) { if (addr < 0 || use_addr != (unsigned long)addr) {
verinum val (use_addr, 8*sizeof(use_addr)); verinum val (use_addr, 8*sizeof(use_addr));
NetEConst*tmp = new NetEConst(val); NetEConst*tmp = new NetEConst(val);
tmp->set_line(*this); tmp->set_line(*this);

View File

@ -250,6 +250,11 @@ bool NetEConcat::set_width(unsigned w, bool)
bool NetEConst::set_width(unsigned w, bool last_chance) bool NetEConst::set_width(unsigned w, bool last_chance)
{ {
/* Make the value signed if the NetEConst is signed.
* This happens when $signed() is called, so this
* sign information needs to be propagated. */
value_.has_sign(has_sign());
if (w == value_.len()) { if (w == value_.len()) {
expr_width(w); expr_width(w);
return true; return true;
@ -438,153 +443,3 @@ bool NetEUReduce::set_width(unsigned w, bool)
return w == 1; return w == 1;
} }
/*
* $Log: set_width.cc,v $
* Revision 1.42 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.41 2006/11/04 06:19:25 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may
* contain unsized numbers.
*
* 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.
*
* Revision 1.38 2006/05/02 04:29:42 steve
* Be more stubborn about widths.
*
* 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.
*
* Revision 1.35 2005/01/24 05:28:31 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*
* Revision 1.34 2003/08/28 04:11:19 steve
* Spelling patch.
*
* Revision 1.33 2003/07/26 03:34:42 steve
* Start handling pad of expressions in code generators.
*
* Revision 1.32 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.31 2003/06/18 03:55:19 steve
* Add arithmetic shift operators.
*
* Revision 1.30 2003/05/20 15:05:33 steve
* Do not try to set constants to width 0.
*
* Revision 1.29 2003/05/04 20:04:09 steve
* Fix truncation of signed constant in constant addition.
*
* Revision 1.28 2003/04/02 04:25:26 steve
* Fix xz extension of constants.
*
* Revision 1.27 2003/02/06 17:50:23 steve
* Real constants have no defined vector width
*
* Revision 1.26 2003/01/26 21:02:21 steve
* Remember to save signedness of number.
*
* Revision 1.25 2002/11/13 03:03:08 steve
* Do not truncate high bits of right shift.
*
* Revision 1.24 2002/11/06 02:25:13 steve
* No need to keep excess width from an
* unsigned constant value, if it can
* be trimmed safely.
*
* Revision 1.23 2002/08/12 01:35:00 steve
* conditional ident string using autoconfig.
*
* Revision 1.22 2002/05/05 21:11:50 steve
* Put off evaluation of concatenation repeat expresions
* until after parameters are defined. This allows parms
* to be used in repeat expresions.
*
* Add the builtin $signed system function.
*
* Revision 1.21 2002/04/27 04:49:27 steve
* If the verinum is already right, no need to reset it.
*
* Revision 1.20 2001/11/19 04:26:46 steve
* Unary reduction operators are all 1-bit results.
*
* Revision 1.19 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of
* creating new and useless temporary signals.
*
* Revision 1.18 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.17 2001/02/08 01:10:30 steve
* Remove dead code.
*
* 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)
*
* Revision 1.14 2000/06/18 03:29:52 steve
* Handle width expansion of shift operators.
*
* Revision 1.13 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.12 2000/04/28 18:43:23 steve
* integer division in expressions properly get width.
*
* Revision 1.11 2000/04/26 03:33:32 steve
* Do not set width too small to hold significant bits.
*
* Revision 1.10 2000/04/21 02:46:42 steve
* Many Unary operators have known widths.
*
* Revision 1.9 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident.
*
* Revision 1.8 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.7 2000/01/01 19:56:51 steve
* Properly expand/shrink constants in expressions.
*
* Revision 1.6 1999/10/05 06:19:46 steve
* Add support for reduction NOR.
*
* Revision 1.5 1999/10/05 04:02:10 steve
* Relaxed width handling for <= assignment.
*
* Revision 1.4 1999/09/29 00:42:51 steve
* Allow expanding of additive operators.
*
* Revision 1.3 1999/09/23 03:56:57 steve
* Support shift operators.
*
* Revision 1.2 1999/09/23 02:27:50 steve
* comparison parameter width is self determined.
*
* Revision 1.1 1999/09/23 00:21:55 steve
* Move set_width methods into a single file,
* Add the NetEBLogic class for logic expressions,
* Fix error setting with of && in if statements.
*
*/

View File

@ -912,6 +912,36 @@ static verinum unsigned_divide(verinum num, verinum den)
return result; return result;
} }
static verinum unsigned_modulus(verinum num, verinum den)
{
unsigned nwid = num.len();
while (nwid > 0 && (num.get(nwid-1) == verinum::V0))
nwid -= 1;
unsigned dwid = den.len();
while (dwid > 0 && (den.get(dwid-1) == verinum::V0))
dwid -= 1;
if (dwid > nwid)
return num;
den = den << (nwid-dwid);
unsigned idx = nwid - dwid + 1;
verinum result (verinum::V0, idx);
while (idx > 0) {
if (den <= num) {
verinum dif = num - den;
num = dif;
result.set(idx-1, verinum::V1);
}
den = den >> 1;
idx -= 1;
}
return num;
}
/* /*
* This operator divides the left number by the right number. If * This operator divides the left number by the right number. If
* either value is signed, the result is signed. If both values have a * either value is signed, the result is signed. If both values have a
@ -1039,20 +1069,25 @@ verinum operator % (const verinum&left, const verinum&right)
} else { } else {
/* XXXX FIXME XXXX Use native unsigned division to do /* Use native unsigned division, if possible, to do
the work. This does not work if the result is too the work. This does not work if the result is too
large for the native integer. */ large for the native integer, so resort to a modulus
assert(use_len <= 8*sizeof(unsigned long)); function in that case. */
unsigned long l = left.as_ulong(); if (use_len <= 8*sizeof(unsigned long)) {
unsigned long r = right.as_ulong(); assert(use_len <= 8*sizeof(unsigned long));
unsigned long v = l % r; unsigned long l = left.as_ulong();
for (unsigned idx = 0 ; idx < use_len ; idx += 1) { unsigned long r = right.as_ulong();
result.set(idx, (v & 1)? verinum::V1 : verinum::V0); unsigned long v = l % r;
v >>= 1; for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
v >>= 1;
}
} else {
result = unsigned_modulus(left, right);
} }
} }
return result; return trim_vnum(result);
} }
verinum concat(const verinum&left, const verinum&right) verinum concat(const verinum&left, const verinum&right)