Use rounding functions from <cmath> and put `vlg_round_to_u64` into a
common utility header.
This commit is contained in:
parent
7a912c55fb
commit
aa6ae73740
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
# include "vpi_user.h"
|
# include "vpi_user.h"
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
|
# include "vpi_utils.h"
|
||||||
# include "vvp_net.h"
|
# include "vvp_net.h"
|
||||||
# include "schedule.h"
|
# include "schedule.h"
|
||||||
# include "event.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<uint64_t>(static_cast<int64_t>(vlg_round(rval)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void real_signal_value(struct t_vpi_value*vp, double rval)
|
static void real_signal_value(struct t_vpi_value*vp, double rval)
|
||||||
{
|
{
|
||||||
static const size_t RBUF_SIZE = 64 + 1;
|
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))) {
|
if (rval != rval || (rval && (rval == 0.5*rval))) {
|
||||||
rval = 0.0;
|
rval = 0.0;
|
||||||
} else {
|
} else {
|
||||||
rval = vlg_round(rval);
|
rval = std::round(rval);
|
||||||
}
|
}
|
||||||
vp->value.integer = (PLI_INT32)rval;
|
vp->value.integer = (PLI_INT32)rval;
|
||||||
break;
|
break;
|
||||||
|
|
@ -993,7 +977,7 @@ static void real_signal_value(struct t_vpi_value*vp, double rval)
|
||||||
if (std::isnan(rval))
|
if (std::isnan(rval))
|
||||||
snprintf(rbuf, RBUF_SIZE, "%s", "nan");
|
snprintf(rbuf, RBUF_SIZE, "%s", "nan");
|
||||||
else
|
else
|
||||||
snprintf(rbuf, RBUF_SIZE, "%0.0f", vlg_round(rval));
|
snprintf(rbuf, RBUF_SIZE, "%0.0f", std::round(rval));
|
||||||
vp->value.str = rbuf;
|
vp->value.str = rbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef IVL_vpi_utils_H
|
||||||
|
#define IVL_vpi_utils_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
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<uint64_t>(static_cast<int64_t>(std::llround(rval)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
|
# include "vpi_utils.h"
|
||||||
# include "vthread.h"
|
# include "vthread.h"
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#ifdef CHECK_WITH_VALGRIND
|
#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<uint64_t>(static_cast<int64_t>(vlg_round(rval)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||||
{
|
{
|
||||||
__vpiVThrWord*obj = dynamic_cast<__vpiVThrWord*>(ref);
|
__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))) {
|
if (val != val || (val && (val == 0.5*val))) {
|
||||||
val = 0.0;
|
val = 0.0;
|
||||||
} else {
|
} else {
|
||||||
val = vlg_round(val);
|
val = std::round(val);
|
||||||
}
|
}
|
||||||
vp->value.integer = (PLI_INT32)val;
|
vp->value.integer = (PLI_INT32)val;
|
||||||
break;
|
break;
|
||||||
|
|
@ -144,7 +128,7 @@ static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||||
if (std::isnan(val))
|
if (std::isnan(val))
|
||||||
snprintf(rbuf, RBUF_USE_SIZE, "%s", "nan");
|
snprintf(rbuf, RBUF_USE_SIZE, "%s", "nan");
|
||||||
else
|
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;
|
vp->value.str = rbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
# include "ufunc.h"
|
# include "ufunc.h"
|
||||||
# include "event.h"
|
# include "event.h"
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
|
# include "vpi_utils.h"
|
||||||
# include "vvp_net_sig.h"
|
# include "vvp_net_sig.h"
|
||||||
# include "vvp_cobject.h"
|
# include "vvp_cobject.h"
|
||||||
# include "vvp_darray.h"
|
# include "vvp_darray.h"
|
||||||
|
|
@ -2374,23 +2375,6 @@ bool of_CVT_SR(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
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<uint64_t>(static_cast<int64_t>(vlg_round(rval)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* %cvt/ur <idx>
|
* %cvt/ur <idx>
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue