V0.9: Fix a few problems with the power operator.
The power operator defines 2**-1 and -2**-1 to be zero. This patch fixes both the procedural and continuous assignments to work correctly. It also fixes a problem in the compiler power code so that the one constant value always has at least two bits.
This commit is contained in:
parent
4c9853551c
commit
6f2fd4e169
12
verinum.cc
12
verinum.cc
|
|
@ -1053,15 +1053,17 @@ verinum pow(const verinum&left, const verinum&right)
|
|||
long pow_count = right.as_long();
|
||||
|
||||
// We need positive and negative one in a few places.
|
||||
verinum one (verinum::V0, left.len(), left.has_len());
|
||||
unsigned len = left.len();
|
||||
// Positive one must be at least two bits wide!
|
||||
verinum one (verinum::V0, (len<2) ? 2 : len, left.has_len());
|
||||
one.has_sign(left.has_sign());
|
||||
one.set(0, verinum::V1);
|
||||
verinum m_one (verinum::V1, left.len(), left.has_len());
|
||||
verinum m_one (verinum::V1, len, left.has_len());
|
||||
m_one.has_sign(true);
|
||||
|
||||
// If either the right or left values are undefined we return 'bx.
|
||||
if (!right.is_defined() || !left.is_defined()) {
|
||||
result = verinum(verinum::Vx, left.len(), left.has_len());
|
||||
result = verinum(verinum::Vx, len, left.has_len());
|
||||
result.has_sign(left.has_sign());
|
||||
// If the right value is zero we need to set the result to 1.
|
||||
} else if (pow_count == 0) {
|
||||
|
|
@ -1069,7 +1071,7 @@ verinum pow(const verinum&left, const verinum&right)
|
|||
} else if (pow_count < 0) {
|
||||
// 0 ** <negative> is 'bx.
|
||||
if (left.is_zero()) {
|
||||
result = verinum(verinum::Vx, left.len(), left.has_len());
|
||||
result = verinum(verinum::Vx, len, left.has_len());
|
||||
result.has_sign(left.has_sign());
|
||||
// 1 ** <negative> is 1.
|
||||
} else if (left == one) {
|
||||
|
|
@ -1083,7 +1085,7 @@ verinum pow(const verinum&left, const verinum&right)
|
|||
}
|
||||
// Everything else is 0.
|
||||
} else {
|
||||
result = verinum(verinum::V0, left.len(), left.has_len());
|
||||
result = verinum(verinum::V0, len, left.has_len());
|
||||
result.has_sign(left.has_sign());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -438,11 +438,14 @@ void vvp_arith_pow::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
return;
|
||||
}
|
||||
|
||||
double ad, bd;
|
||||
double ad, bd, resd;
|
||||
vector4_to_value(op_a_, ad, true);
|
||||
vector4_to_value(op_b_, bd, true);
|
||||
/* 2**-1 and -2**-1 are defined to be zero. */
|
||||
if ((bd == -1) && (fabs(ad) == 2.0)) resd = 0.0;
|
||||
else resd = pow(ad, bd);
|
||||
|
||||
res4 = vvp_vector4_t(wid_, pow(ad, bd));
|
||||
res4 = vvp_vector4_t(wid_, resd);
|
||||
} else {
|
||||
vvp_vector2_t a2 (op_a_);
|
||||
vvp_vector2_t b2 (op_b_);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -3989,10 +3989,13 @@ bool of_POW_S(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
|
||||
/* Calculate the result using the double pow() function. */
|
||||
double xd, yd;
|
||||
double xd, yd, resd;
|
||||
vector4_to_value(xv, xd, true);
|
||||
vector4_to_value(yv, yd, true);
|
||||
vvp_vector4_t res = vvp_vector4_t(wid, pow(xd, yd));
|
||||
/* 2**-1 and -2**-1 are defined to be zero. */
|
||||
if ((yd == -1.0) && (fabs(xd) == 2.0)) resd = 0.0;
|
||||
else resd = pow(xd, yd);
|
||||
vvp_vector4_t res = vvp_vector4_t(wid, resd);
|
||||
|
||||
/* Copy the result. */
|
||||
for (unsigned jdx = 0; jdx < wid; jdx += 1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue