Add support for $timeformat.

This commit is contained in:
steve 2002-05-31 04:26:54 +00:00
parent 12c574d5c9
commit f1ab9e63fa
2 changed files with 182 additions and 1 deletions

View File

@ -359,6 +359,22 @@ language that are defined.
It is said that some commercial compilers do allow macro It is said that some commercial compilers do allow macro
definitions to span library modules. That's just plain weird. definitions to span library modules. That's just plain weird.
Width in %t Time Formats
Standard Verilog does not allow width fields in the %t formats
of display strings. For example, this is illegal:
$display("Time is %0t", %time);
Standard Verilog instead relies on the $timeformat to
completely specify the format.
Icarus Verilog allows the programmer to specify the field
with. The "%t" format in Icarus Verilog works exactly as it
does in standard Verilog. However, if the programmer chooses
to specify a minimum width, i.e. "%5t" Then for that display
Icarus Verilog will override the $timeformat minimum width and
use the explicit minimum width.
6.0 CREDITS 6.0 CREDITS

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_display.c,v 1.37 2002/05/24 19:05:30 steve Exp $" #ident "$Id: sys_display.c,v 1.38 2002/05/31 04:26:54 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -28,6 +28,15 @@
# include <ctype.h> # include <ctype.h>
# include <stdlib.h> # include <stdlib.h>
struct timeformat_info_s {
int units;
unsigned prec;
char*suff;
unsigned width;
};
struct timeformat_info_s timeformat_info = { 0, 0, 0, 20 };
struct strobe_cb_info { struct strobe_cb_info {
char*name; char*name;
int default_format; int default_format;
@ -97,6 +106,81 @@ static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
} }
} }
static void format_time(unsigned mcd, int fsize, const char*value)
{
char buf[256];
const char*cp;
char*bp;
unsigned len;
int cnt;
/* This is the time precision for the simulation. */
int prec = vpi_get(vpiTimePrecision, 0);
if (fsize < 0)
fsize = timeformat_info.width;
bp = buf + sizeof buf;
cp = value + strlen(value);
*--bp = 0;
/* Draw the suffix into the buffer. */
bp -= strlen(timeformat_info.suff);
strcpy(bp, timeformat_info.suff);
/* Draw 0s to pad out the precision to the requested count. */
cnt = timeformat_info.units - prec;
while (cnt < timeformat_info.prec) {
*--bp = '0';
cnt += 1;
}
/* Chop excess precision. */
while (cnt > timeformat_info.prec) {
if (cp > value)
cp -= 1;
cnt -= 1;
prec += 1;
}
/* Draw the digits of the time that are to the right of the
decimal point. Pad to the right with zeros if needed, to
get to the decimal point. */
if (prec < timeformat_info.units) {
while (prec < timeformat_info.units) {
char val;
if (cp == value)
val = '0';
else
val = *--cp;
*--bp = val;
prec += 1;
}
*--bp = '.';
}
/* Put the remaining characters to the left of the decimal
point. */
while (cp > value) {
*--bp = *--cp;
}
if (*bp == '.')
*--bp = '0';
/* Pad the string on the left to the requested minimum
width. Pad with spaces. */
len = strlen(bp);
while (len < fsize) {
*--bp = ' ';
len += 1;
}
vpi_mcd_printf(mcd, "%s", bp);
}
/* /*
* If $display discovers a string as a parameter, this function is * If $display discovers a string as a parameter, this function is
@ -300,6 +384,9 @@ static int format_str(vpiHandle scope, unsigned int mcd,
break; break;
case 't': case 't':
format_time(mcd, fsize, value.value.str);
break;
case 'd': case 'd':
if (fsize==-1){ if (fsize==-1){
// simple %d parameter. // simple %d parameter.
@ -893,8 +980,70 @@ static int sys_fgetc_sizetf(char*x)
return 32; return 32;
} }
static int sys_timeformat_compiletf(char *xx)
{
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle tmp;
assert(argv);
tmp = vpi_scan(argv);
assert(tmp);
assert(vpi_get(vpiType, tmp) == vpiConstant);
tmp = vpi_scan(argv);
assert(tmp);
assert(vpi_get(vpiType, tmp) == vpiConstant);
tmp = vpi_scan(argv);
assert(tmp);
assert(vpi_get(vpiType, tmp) == vpiConstant);
return 0;
}
static int sys_timeformat_calltf(char *xx)
{
s_vpi_value value;
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle units = vpi_scan(argv);
vpiHandle prec = vpi_scan(argv);
vpiHandle suff = vpi_scan(argv);
vpiHandle wid = vpi_scan(argv);
vpi_free_object(argv);
value.format = vpiIntVal;
vpi_get_value(units, &value);
timeformat_info.units = value.value.integer;
value.format = vpiIntVal;
vpi_get_value(prec, &value);
timeformat_info.prec = value.value.integer;
value.format = vpiStringVal;
vpi_get_value(suff, &value);
timeformat_info.suff = strdup(value.value.str);
value.format = vpiIntVal;
vpi_get_value(wid, &value);
timeformat_info.width = value.value.integer;
return 0;
}
static int sys_end_of_compile(p_cb_data cb_data)
{
timeformat_info.suff = strdup("");
timeformat_info.units = vpi_get(vpiTimePrecision, 0);
timeformat_info.width = 20;
return 0;
}
void sys_display_register() void sys_display_register()
{ {
s_cb_data cb_data;
s_vpi_systf_data tf_data; s_vpi_systf_data tf_data;
//============================== display //============================== display
@ -1106,11 +1255,27 @@ void sys_display_register()
tf_data.sizetf = sys_fgetc_sizetf; tf_data.sizetf = sys_fgetc_sizetf;
tf_data.user_data = "$fgetc"; tf_data.user_data = "$fgetc";
vpi_register_systf(&tf_data); vpi_register_systf(&tf_data);
//============================ timeformat
tf_data.type = vpiSysTask;
tf_data.tfname = "$timeformat";
tf_data.calltf = sys_timeformat_calltf;
tf_data.compiletf = sys_timeformat_compiletf;
tf_data.sizetf = 0;
vpi_register_systf(&tf_data);
cb_data.reason = cbEndOfCompile;
cb_data.cb_rtn = sys_end_of_compile;
cb_data.user_data = "system";
vpi_register_cb(&cb_data);
} }
/* /*
* $Log: sys_display.c,v $ * $Log: sys_display.c,v $
* Revision 1.38 2002/05/31 04:26:54 steve
* Add support for $timeformat.
*
* Revision 1.37 2002/05/24 19:05:30 steve * Revision 1.37 2002/05/24 19:05:30 steve
* support GCC __attributes__ for printf formats. * support GCC __attributes__ for printf formats.
* *