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;
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,
unsigned width,
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
* 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
@ -405,6 +405,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, -1, true);
sub->cast_signed(false);
if (expr_wid > 0 && (unsigned)expr_wid > sub->expr_width())
sub = pad_to_width(sub, expr_wid);
return sub;
}
@ -536,7 +540,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool) const
{
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_);
if (def == 0) {
@ -570,7 +574,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
PExpr*tmp = parms_[idx];
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 {
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.
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));
NetEConst*tmp = new NetEConst(val);
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)
{
/* 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()) {
expr_width(w);
return true;
@ -438,153 +443,3 @@ bool NetEUReduce::set_width(unsigned w, bool)
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;
}
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
* 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 {
/* 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
large for the native integer. */
assert(use_len <= 8*sizeof(unsigned long));
unsigned long l = left.as_ulong();
unsigned long r = right.as_ulong();
unsigned long v = l % r;
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
v >>= 1;
large for the native integer, so resort to a modulus
function in that case. */
if (use_len <= 8*sizeof(unsigned long)) {
assert(use_len <= 8*sizeof(unsigned long));
unsigned long l = left.as_ulong();
unsigned long r = right.as_ulong();
unsigned long v = l % r;
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)