V0.8: fix signed parameter multiply
This patch mirrors what was done in development to fix the multiplication of signed values.
This commit is contained in:
parent
abc2aa17d2
commit
7dc473db8d
|
|
@ -424,10 +424,6 @@ void NetScope::evaluate_parameters(Design*des)
|
|||
assert(nexpr);
|
||||
delete expr;
|
||||
(*cur).second.expr = nexpr;
|
||||
|
||||
// Set the signedness flag.
|
||||
(*cur).second.expr
|
||||
->cast_signed( (*cur).second.signed_flag );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -440,7 +436,9 @@ void NetScope::evaluate_parameters(Design*des)
|
|||
}
|
||||
|
||||
/* If the parameter has range information, then make
|
||||
sure the value is set right. */
|
||||
sure the value is set right. Note that if the
|
||||
parameter doesn't have an explicit range, then it
|
||||
will get the signedness from the expression itself. */
|
||||
if (range_flag) {
|
||||
unsigned long wid = (msb >= lsb)? msb - lsb : lsb - msb;
|
||||
wid += 1;
|
||||
|
|
|
|||
12
verinum.cc
12
verinum.cc
|
|
@ -734,14 +734,18 @@ verinum operator * (const verinum&left, const verinum&right)
|
|||
verinum result(verinum::V0, left.len() + right.len(), has_len_flag);
|
||||
result.has_sign(left.has_sign() || right.has_sign());
|
||||
|
||||
for (unsigned rdx = 0 ; rdx < right.len() ; rdx += 1) {
|
||||
verinum::V r_sign = sign_bit(right);
|
||||
for (unsigned rdx = 0 ; rdx < result.len() ; rdx += 1) {
|
||||
|
||||
if (right.get(rdx) == verinum::V0)
|
||||
verinum::V r_bit = rdx < right.len()? right.get(rdx) : r_sign;
|
||||
if (r_bit == verinum::V0)
|
||||
continue;
|
||||
|
||||
verinum::V l_sign = sign_bit(left);
|
||||
verinum::V carry = verinum::V0;
|
||||
for (unsigned ldx = 0 ; ldx < left.len() ; ldx += 1) {
|
||||
result.set(ldx+rdx, add_with_carry(left[ldx],
|
||||
for (unsigned ldx = 0 ; ldx < result.len()-rdx ; ldx += 1) {
|
||||
verinum::V l_bit = ldx < left.len()? left[ldx] : l_sign;
|
||||
result.set(ldx+rdx, add_with_carry(l_bit,
|
||||
result[rdx+ldx],
|
||||
carry));
|
||||
}
|
||||
|
|
|
|||
13
verinum.h
13
verinum.h
|
|
@ -106,6 +106,19 @@ class verinum {
|
|||
bool string_flag_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This returns the sign bit of the verinum value. If the value is
|
||||
* unsigned, then return an implicit sign bit of 0. Otherwise, return
|
||||
* the high bit.
|
||||
*/
|
||||
inline verinum::V sign_bit(const verinum&val)
|
||||
{
|
||||
if (val.has_sign())
|
||||
return val.get(val.len()-1);
|
||||
else
|
||||
return verinum::V0;
|
||||
}
|
||||
|
||||
/* Return a verinum that is minimal. That is, it has only the length
|
||||
needed to accurately represent the contained value, signed or not. */
|
||||
extern verinum trim_vnum(const verinum&);
|
||||
|
|
|
|||
Loading…
Reference in New Issue