diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index e0d2e2c43..4fc8bcc48 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -26,6 +26,7 @@ # include "vpi_user.h" # include "vpi_priv.h" +# include "vpi_utils.h" # include "vvp_net.h" # include "schedule.h" # include "event.h" @@ -949,23 +950,6 @@ void vvp_signal_value::get_signal_value(struct t_vpi_value*vp) } } -static double vlg_round(double rval) -{ - if (rval >= 0.0) { - return floor(rval + 0.5); - } else { - return ceil(rval - 0.5); - } -} - -static uint64_t vlg_round_to_u64(double rval) -{ - // Directly casting a negative double to an unsigned integer types is - // undefined behavior and behaves differently on different architectures. - // Cast to signed integer first to get the behavior we want. - return static_cast(static_cast(vlg_round(rval))); -} - static void real_signal_value(struct t_vpi_value*vp, double rval) { static const size_t RBUF_SIZE = 64 + 1; @@ -984,7 +968,7 @@ static void real_signal_value(struct t_vpi_value*vp, double rval) if (rval != rval || (rval && (rval == 0.5*rval))) { rval = 0.0; } else { - rval = vlg_round(rval); + rval = std::round(rval); } vp->value.integer = (PLI_INT32)rval; break; @@ -993,7 +977,7 @@ static void real_signal_value(struct t_vpi_value*vp, double rval) if (std::isnan(rval)) snprintf(rbuf, RBUF_SIZE, "%s", "nan"); else - snprintf(rbuf, RBUF_SIZE, "%0.0f", vlg_round(rval)); + snprintf(rbuf, RBUF_SIZE, "%0.0f", std::round(rval)); vp->value.str = rbuf; break; diff --git a/vvp/vpi_utils.h b/vvp/vpi_utils.h new file mode 100644 index 000000000..244aff3f9 --- /dev/null +++ b/vvp/vpi_utils.h @@ -0,0 +1,15 @@ +#ifndef IVL_vpi_utils_H +#define IVL_vpi_utils_H + +#include +#include + +static inline uint64_t vlg_round_to_u64(double rval) +{ + // Directly casting a negative double to an unsigned integer types is + // undefined behavior and behaves differently on different architectures. + // Cast to signed integer first to get the behavior we want. + return static_cast(static_cast(std::llround(rval))); +} + +#endif diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc index 91e7b3e1a..87ea1bc34 100644 --- a/vvp/vpi_vthr_vector.cc +++ b/vvp/vpi_vthr_vector.cc @@ -24,6 +24,7 @@ */ # include "vpi_priv.h" +# include "vpi_utils.h" # include "vthread.h" # include "config.h" #ifdef CHECK_WITH_VALGRIND @@ -87,23 +88,6 @@ static int vthr_word_get(int code, vpiHandle ref) } } -static double vlg_round(double rval) -{ - if (rval >= 0.0) { - return floor(rval + 0.5); - } else { - return ceil(rval - 0.5); - } -} - -static uint64_t vlg_round_to_u64(double rval) -{ - // Directly casting a negative double to an unsigned integer types is - // undefined behavior and behaves differently on different architectures. - // Cast to signed integer first to get the behavior we want. - return static_cast(static_cast(vlg_round(rval))); -} - static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp) { __vpiVThrWord*obj = dynamic_cast<__vpiVThrWord*>(ref); @@ -135,7 +119,7 @@ static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp) if (val != val || (val && (val == 0.5*val))) { val = 0.0; } else { - val = vlg_round(val); + val = std::round(val); } vp->value.integer = (PLI_INT32)val; break; @@ -144,7 +128,7 @@ static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp) if (std::isnan(val)) snprintf(rbuf, RBUF_USE_SIZE, "%s", "nan"); else - snprintf(rbuf, RBUF_USE_SIZE, "%0.0f", vlg_round(val)); + snprintf(rbuf, RBUF_USE_SIZE, "%0.0f", std::round(val)); vp->value.str = rbuf; break; diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 505e5f11c..ba77178ee 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -24,6 +24,7 @@ # include "ufunc.h" # include "event.h" # include "vpi_priv.h" +# include "vpi_utils.h" # include "vvp_net_sig.h" # include "vvp_cobject.h" # include "vvp_darray.h" @@ -2374,23 +2375,6 @@ bool of_CVT_SR(vthread_t thr, vvp_code_t cp) return true; } -static double vlg_round(double rval) -{ - if (rval >= 0.0) { - return floor(rval + 0.5); - } else { - return ceil(rval - 0.5); - } -} - -static uint64_t vlg_round_to_u64(double rval) -{ - // Directly casting a negative double to an unsigned integer types is - // undefined behavior and behaves differently on different architectures. - // Cast to signed integer first to get the behavior we want. - return static_cast(static_cast(vlg_round(rval))); -} - /* * %cvt/ur */