Fix for GitHub issue 7 : Undef propagation in power operator.
The vvp_vector2_t constructor that takes a vvp_vector4_t value was documented as creating a NaN value if the supplied vector contained any X or Z bits, but instead used the standard Verilog 4-state to 2-state conversion semantics (X or Z translate to 0). I've added an optional second parameter to the constructor to allow the user to choose which semantics they want, as both are needed.
This commit is contained in:
parent
ac3aee0172
commit
68f8de28af
16
vvp/arith.cc
16
vvp/arith.cc
|
|
@ -156,13 +156,13 @@ vvp_arith_div::~vvp_arith_div()
|
|||
|
||||
void vvp_arith_div::wide4_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
vvp_vector2_t a2 (op_a_);
|
||||
vvp_vector2_t a2 (op_a_, true);
|
||||
if (a2.is_NaN()) {
|
||||
ptr.ptr()->send_vec4(x_val_, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
vvp_vector2_t b2 (op_b_);
|
||||
vvp_vector2_t b2 (op_b_, true);
|
||||
if (b2.is_NaN() || b2.is_zero()) {
|
||||
ptr.ptr()->send_vec4(x_val_, 0);
|
||||
return;
|
||||
|
|
@ -270,13 +270,13 @@ vvp_arith_mod::~vvp_arith_mod()
|
|||
|
||||
void vvp_arith_mod::wide_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
vvp_vector2_t a2 (op_a_);
|
||||
vvp_vector2_t a2 (op_a_, true);
|
||||
if (a2.is_NaN()) {
|
||||
ptr.ptr()->send_vec4(x_val_, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
vvp_vector2_t b2 (op_b_);
|
||||
vvp_vector2_t b2 (op_b_, true);
|
||||
if (b2.is_NaN() || b2.is_zero()) {
|
||||
ptr.ptr()->send_vec4(x_val_, 0);
|
||||
return;
|
||||
|
|
@ -384,8 +384,8 @@ vvp_arith_mult::~vvp_arith_mult()
|
|||
|
||||
void vvp_arith_mult::wide_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
vvp_vector2_t a2 (op_a_);
|
||||
vvp_vector2_t b2 (op_b_);
|
||||
vvp_vector2_t a2 (op_a_, true);
|
||||
vvp_vector2_t b2 (op_b_, true);
|
||||
|
||||
if (a2.is_NaN() || b2.is_NaN()) {
|
||||
ptr.ptr()->send_vec4(x_val_, 0);
|
||||
|
|
@ -469,8 +469,8 @@ void vvp_arith_pow::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
|
||||
res4 = vvp_vector4_t(wid_, resd);
|
||||
} else {
|
||||
vvp_vector2_t a2 (op_a_);
|
||||
vvp_vector2_t b2 (op_b_);
|
||||
vvp_vector2_t a2 (op_a_, true);
|
||||
vvp_vector2_t b2 (op_b_, true);
|
||||
|
||||
if (a2.is_NaN() || b2.is_NaN()) {
|
||||
ptr.ptr()->send_vec4(x_val_, 0);
|
||||
|
|
|
|||
|
|
@ -4547,8 +4547,8 @@ bool of_POW(vthread_t thr, vvp_code_t cp)
|
|||
unsigned idx = cp->bit_idx[0];
|
||||
unsigned idy = cp->bit_idx[1];
|
||||
unsigned wid = cp->number;
|
||||
vvp_vector2_t xv2 = vvp_vector2_t(vthread_bits_to_vector(thr, idx, wid));
|
||||
vvp_vector2_t yv2 = vvp_vector2_t(vthread_bits_to_vector(thr, idy, wid));
|
||||
vvp_vector2_t xv2 = vvp_vector2_t(vthread_bits_to_vector(thr, idx, wid), true);
|
||||
vvp_vector2_t yv2 = vvp_vector2_t(vthread_bits_to_vector(thr, idy, wid), true);
|
||||
|
||||
/* If we have an X or Z in the arguments return X. */
|
||||
if (xv2.is_NaN() || yv2.is_NaN()) {
|
||||
|
|
|
|||
|
|
@ -619,9 +619,11 @@ class vvp_vector2_t {
|
|||
vvp_vector2_t(const vvp_vector2_t&);
|
||||
vvp_vector2_t(const vvp_vector2_t&, unsigned newsize);
|
||||
vvp_vector2_t(const vvp_vector2_t&, unsigned base, unsigned wid);
|
||||
// Make a vvp_vector2_t from a vvp_vector4_t. If there are X
|
||||
// or Z bits, then the result becomes a NaN value.
|
||||
vvp_vector2_t(const vvp_vector4_t&that);
|
||||
// Make a vvp_vector2_t from a vvp_vector4_t. If enable_NaN
|
||||
// is true and there are X or Z bits, then the result becomes
|
||||
// a NaN value. If enable_NaN is false then X or Z bits are
|
||||
// converted to 0 as per the standard Verilog rules.
|
||||
vvp_vector2_t(const vvp_vector4_t&that, bool allow_NaN = false);
|
||||
// Make from a native long and a specified width.
|
||||
vvp_vector2_t(unsigned long val, unsigned wid);
|
||||
// Make with the width, and filled with 1 or 0 bits.
|
||||
|
|
@ -693,8 +695,13 @@ inline vvp_vector2_t::vvp_vector2_t(const vvp_vector2_t&that)
|
|||
copy_from_that_(that);
|
||||
}
|
||||
|
||||
inline vvp_vector2_t::vvp_vector2_t(const vvp_vector4_t&that)
|
||||
inline vvp_vector2_t::vvp_vector2_t(const vvp_vector4_t&that, bool enable_NaN)
|
||||
{
|
||||
if (enable_NaN && that.has_xz()) {
|
||||
vec_ = 0;
|
||||
wid_ = 0;
|
||||
return;
|
||||
}
|
||||
copy_from_that_(that);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue