Merge branch 'master' of ssh://steve-icarus@icarus.com/home/u/icarus/steve/git/verilog
This commit is contained in:
commit
e1dbe7eede
2
PExpr.h
2
PExpr.h
|
|
@ -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,
|
||||
|
|
|
|||
19
elab_expr.cc
19
elab_expr.cc
|
|
@ -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);
|
||||
|
|
|
|||
155
set_width.cc
155
set_width.cc
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
41
verinum.cc
41
verinum.cc
|
|
@ -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,9 +1069,11 @@ 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. */
|
||||
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();
|
||||
|
|
@ -1050,9 +1082,12 @@ verinum operator % (const verinum&left, const verinum&right)
|
|||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue