diff --git a/vvp/delay.cc b/vvp/delay.cc index 71912d4b7..446795e37 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -577,10 +577,16 @@ static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays ) vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); assert( fun ); assert(delays->no_of_delays == 12); - assert(delays->time_type == vpiSimTime); - for (idx = 0 ; idx < delays->no_of_delays ; idx += 1) { - tmp[idx] = vpip_timestruct_to_time(delays->da+idx); + if (delays->time_type == vpiSimTime) { + for (idx = 0 ; idx < delays->no_of_delays ; idx += 1) { + tmp[idx] = vpip_timestruct_to_time(delays->da+idx); + } + } else { + for (idx = 0 ; idx < delays->no_of_delays ; idx += 1) { + tmp[idx] = vpip_scaled_real_to_time64(delays->da[idx].real, + src->dest->scope); + } } fun->put_delay12(tmp); @@ -601,18 +607,28 @@ static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays ) vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); assert(fun); + + int idx; + vvp_time64_t tmp[12]; + fun->get_delay12(tmp); + switch (delays->no_of_delays) { case 12: - { int idx; - vvp_time64_t tmp[12]; - fun->get_delay12(tmp); - for (idx = 0; idx < 12; idx += 1) { - vpip_time_to_timestruct(delays->da+idx, tmp[idx]); - } - } - break; + if (delays->time_type == vpiSimTime) { + for (idx = 0; idx < 12; idx += 1) { + vpip_time_to_timestruct(delays->da+idx, tmp[idx]); + } + } else { + int units = src->dest->scope->time_units; + for (idx = 0; idx < 12; idx += 1) { + delays->da[idx].real = vpip_time_to_scaled_real(tmp[idx], src->dest->scope); + } + } + break; + default: assert(0); + break; } } diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index beee203dd..8cecc64da 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -480,6 +480,9 @@ extern int vpip_time_precision_from_handle(vpiHandle obj); extern void vpip_time_to_timestruct(struct t_vpi_time*ts, vvp_time64_t ti); extern vvp_time64_t vpip_timestruct_to_time(const struct t_vpi_time*ts); +extern double vpip_time_to_scaled_real(vvp_time64_t ti, struct __vpiScope*sc); +extern vvp_time64_t vpip_scaled_real_to_time64(double val, struct __vpiScope*sc); + /* * These functions are used mostly as compile time to strings into * permallocated memory. The vpip_string function is the most general, diff --git a/vvp/vpi_time.cc b/vvp/vpi_time.cc index f30bde56a..9da7bb8e4 100644 --- a/vvp/vpi_time.cc +++ b/vvp/vpi_time.cc @@ -56,6 +56,33 @@ vvp_time64_t vpip_timestruct_to_time(const struct t_vpi_time*ts) return ti; } +double vpip_time_to_scaled_real(vvp_time64_t ti, struct __vpiScope*scope) +{ + int units; + if (scope) + units = scope->time_units; + else + units = vpi_time_precision; + + double val = pow(10.0L, vpi_time_precision - units); + val *= ti; + + return val; +} + +vvp_time64_t vpip_scaled_real_to_time64(double val, struct __vpiScope*scope) +{ + int units; + if (scope) + units = scope->time_units; + else + units = vpi_time_precision; + + double scale = pow(10.0L, units - vpi_time_precision); + val *= scale; + + return val; +} static int timevar_time_get(int code, vpiHandle ref) { @@ -189,9 +216,8 @@ static void timevar_get_value(vpiHandle ref, s_vpi_value*vp) /* Oops, in this case I want a double power of 10 to do the scaling, instead of the integer scaling done everywhere else. */ - units = rfp->scope? rfp->scope->time_units : vpi_time_precision; - vp->value.real = pow(10.0L, vpi_time_precision - units); - vp->value.real *= schedule_simtime(); + vp->value.real = vpip_time_to_scaled_real(schedule_simtime(), + rfp->scope); break; case vpiBinStrVal: