diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 4ade4186a..068bddb60 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -50,7 +50,7 @@ static PLI_INT32 my_mcd_printf(PLI_UINT32 mcd, const char *fmt, ...) struct timeformat_info_s timeformat_info = { 0, 0, 0, 20 }; struct strobe_cb_info { - char*name; + const char*name; char*filename; int lineno; int default_format; @@ -129,7 +129,7 @@ static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv) } } -static int get_default_format(char *name) +static int get_default_format(const char *name) { int default_format; @@ -247,16 +247,18 @@ static void get_time(char *rtn, const char *value, int prec, static void get_time_real(char *rtn, double value, int prec, PLI_INT32 time_units) { - /* Scale the value if its time units differ from the format units. */ - if (time_units != timeformat_info.units) { + /* Scale the value from its time units to the format time units. */ + if (time_units >= timeformat_info.units) { value *= pow(10.0, time_units - timeformat_info.units); + } else { + value /= pow(10.0, timeformat_info.units - time_units); } sprintf(rtn, "%0.*f%s", prec, value, timeformat_info.suff); } static unsigned int get_format_char(char **rtn, int ljust, int plus, int ld_zero, int width, int prec, - char fmt, struct strobe_cb_info *info, + char fmt, const struct strobe_cb_info *info, unsigned int *idx) { s_vpi_value value; @@ -609,7 +611,7 @@ static unsigned int get_format_char(char **rtn, int ljust, int plus, /* The 512 (513-1 for EOL) is more than enough for any double * value (309 digits plus a decimal point maximum). Because of * scaling this could be larger. For decimal values you can - * have an arbitraty value so you can overflow the buffer, but + * have an arbitrary value so you can overflow the buffer, but * for now we will assume the user will use this as intended * (pass a time variable or the result of a time function). */ tbuf = malloc((513+suff_len)*sizeof(char)); @@ -807,7 +809,7 @@ static unsigned int get_format_char(char **rtn, int ljust, int plus, /* We can't use the normal str functions on the return value since * %u and %z can insert NULL characters into the stream. */ static unsigned int get_format(char **rtn, char *fmt, - struct strobe_cb_info *info, unsigned int *idx) + const struct strobe_cb_info *info, unsigned int *idx) { char *cp = fmt; unsigned int size; @@ -854,7 +856,7 @@ static unsigned int get_format(char **rtn, char *fmt, return size - 1; } -static unsigned int get_numeric(char **rtn, struct strobe_cb_info *info, +static unsigned int get_numeric(char **rtn, const struct strobe_cb_info *info, vpiHandle item) { int size, min; @@ -883,7 +885,7 @@ static unsigned int get_numeric(char **rtn, struct strobe_cb_info *info, /* In many places we can't use the normal str functions since %u and %z * can insert NULL characters into the stream. */ -static char *get_display(unsigned int *rtnsz, struct strobe_cb_info *info) +static char *get_display(unsigned int *rtnsz, const struct strobe_cb_info *info) { char *result, *fmt, *rtn, *func_name; const char *cresult; @@ -1020,7 +1022,7 @@ static char *get_display(unsigned int *rtnsz, struct strobe_cb_info *info) return rtn; } -static int sys_check_args(vpiHandle callh, vpiHandle argv, PLI_BYTE8*name, +static int sys_check_args(vpiHandle callh, vpiHandle argv, const PLI_BYTE8*name, int no_auto, int is_monitor) { vpiHandle arg; @@ -1197,8 +1199,6 @@ static PLI_INT32 sys_display_calltf(PLI_BYTE8 *name) */ static PLI_INT32 strobe_cb(p_cb_data cb) { - char* result = NULL; - unsigned int size, location=0; struct strobe_cb_info*info = (struct strobe_cb_info*)cb->user_data; /* We really need to cancel any $fstrobe() calls for a file when it @@ -1206,6 +1206,8 @@ static PLI_INT32 strobe_cb(p_cb_data cb) * Which has the same basic effect. */ if ((! IS_MCD(info->fd_mcd) && vpi_get_file(info->fd_mcd) != NULL) || ( IS_MCD(info->fd_mcd) && my_mcd_printf(info->fd_mcd, "") != EOF)) { + char* result = NULL; + unsigned int size, location=0; /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, info); @@ -1219,12 +1221,12 @@ static PLI_INT32 strobe_cb(p_cb_data cb) } } my_mcd_printf(info->fd_mcd, "\n"); + free(result); } free(info->filename); free(info->items); free(info); - free(result); return 0; } diff --git a/vpi/sys_time.c b/vpi/sys_time.c index c14812d9f..30e3f179f 100644 --- a/vpi/sys_time.c +++ b/vpi/sys_time.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -95,7 +95,9 @@ static PLI_INT32 sys_realtime_calltf(PLI_BYTE8*name) /* For $abstime() we return the time in second. */ if (strcmp(name, "$abstime") == 0) { - now.real *= pow(10.0, vpi_get(vpiTimeUnit, mod)); + PLI_INT32 scale = vpi_get(vpiTimeUnit, mod); + if (scale >= 0) now.real *= pow(10.0, scale); + else now.real /= pow(10.0, -scale); } val.format = vpiRealVal; diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index ec13fddd8..9996abf39 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008-2011 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -407,7 +407,7 @@ int vpip_time_precision_from_handle(vpiHandle obj) void vpi_get_time(vpiHandle obj, s_vpi_time*vp) { - int units; + int scale; vvp_time64_t time; assert(vp); @@ -421,9 +421,10 @@ void vpi_get_time(vpiHandle obj, s_vpi_time*vp) break; case vpiScaledRealTime: - units = vpip_time_units_from_handle(obj); - vp->real = pow(10.0L, vpip_get_time_precision() - units); - vp->real *= time; + scale = vpip_get_time_precision() - + vpip_time_units_from_handle(obj); + if (scale >= 0) vp->real = (double)time * pow(10.0, scale); + else vp->real = (double)time / pow(10.0, -scale); break; default: @@ -840,6 +841,7 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp, if (flags!=vpiNoDelay && flags!=vpiForceFlag && flags!=vpiReleaseFlag) { vvp_time64_t dly; + int scale; if (vpi_get(vpiAutomatic, obj)) { fprintf(stderr, "vpi error: cannot put a value with " @@ -853,10 +855,13 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp, switch (when->type) { case vpiScaledRealTime: - dly = (vvp_time64_t)(when->real * - (pow(10.0L, - vpip_time_units_from_handle(obj) - - vpip_get_time_precision()))); + scale = vpip_time_units_from_handle(obj) - + vpip_get_time_precision(); + if (scale >= 0) { + dly = (vvp_time64_t)(when->real * pow(10.0, scale)); + } else { + dly = (vvp_time64_t)(when->real / pow(10.0, -scale)); + } break; case vpiSimTime: dly = vpip_timestruct_to_time(when); diff --git a/vvp/vpi_time.cc b/vvp/vpi_time.cc index 43a4e6e00..015104806 100644 --- a/vvp/vpi_time.cc +++ b/vvp/vpi_time.cc @@ -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 * and/or modify it in source code form under the terms of the GNU @@ -55,14 +55,12 @@ vvp_time64_t vpip_timestruct_to_time(const struct t_vpi_time*ts) 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; + int scale = 0; + if (scope) scale = vpi_time_precision - scope->time_units; - double val = pow(10.0L, vpi_time_precision - units); - val *= ti; + if (scale >= 0) val = (double)ti * pow(10.0, scale); + else val = (double) ti / pow(10.0, -scale); return val; }