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();
|
long pow_count = right.as_long();
|
||||||
|
|
||||||
// We need positive and negative one in a few places.
|
// 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.has_sign(left.has_sign());
|
||||||
one.set(0, verinum::V1);
|
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);
|
m_one.has_sign(true);
|
||||||
|
|
||||||
// If either the right or left values are undefined we return 'bx.
|
// If either the right or left values are undefined we return 'bx.
|
||||||
if (!right.is_defined() || !left.is_defined()) {
|
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());
|
result.has_sign(left.has_sign());
|
||||||
// If the right value is zero we need to set the result to 1.
|
// If the right value is zero we need to set the result to 1.
|
||||||
} else if (pow_count == 0) {
|
} else if (pow_count == 0) {
|
||||||
|
|
@ -1069,7 +1071,7 @@ verinum pow(const verinum&left, const verinum&right)
|
||||||
} else if (pow_count < 0) {
|
} else if (pow_count < 0) {
|
||||||
// 0 ** <negative> is 'bx.
|
// 0 ** <negative> is 'bx.
|
||||||
if (left.is_zero()) {
|
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());
|
result.has_sign(left.has_sign());
|
||||||
// 1 ** <negative> is 1.
|
// 1 ** <negative> is 1.
|
||||||
} else if (left == one) {
|
} else if (left == one) {
|
||||||
|
|
@ -1083,7 +1085,7 @@ verinum pow(const verinum&left, const verinum&right)
|
||||||
}
|
}
|
||||||
// Everything else is 0.
|
// Everything else is 0.
|
||||||
} else {
|
} else {
|
||||||
result = verinum(verinum::V0, left.len(), left.has_len());
|
result = verinum(verinum::V0, len, left.has_len());
|
||||||
result.has_sign(left.has_sign());
|
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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ad, bd;
|
double ad, bd, resd;
|
||||||
vector4_to_value(op_a_, ad, true);
|
vector4_to_value(op_a_, ad, true);
|
||||||
vector4_to_value(op_b_, bd, 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 {
|
} else {
|
||||||
vvp_vector2_t a2 (op_a_);
|
vvp_vector2_t a2 (op_a_);
|
||||||
vvp_vector2_t b2 (op_b_);
|
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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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. */
|
/* Calculate the result using the double pow() function. */
|
||||||
double xd, yd;
|
double xd, yd, resd;
|
||||||
vector4_to_value(xv, xd, true);
|
vector4_to_value(xv, xd, true);
|
||||||
vector4_to_value(yv, yd, 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. */
|
/* Copy the result. */
|
||||||
for (unsigned jdx = 0; jdx < wid; jdx += 1)
|
for (unsigned jdx = 0; jdx < wid; jdx += 1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue