vpi: $sformatf() function.

This commit is contained in:
Maciej Suminski 2015-12-11 12:58:25 +01:00
parent 9276515e19
commit 1d2aef7142
2 changed files with 75 additions and 9 deletions

View File

@ -169,10 +169,11 @@ static int get_default_format(const char *name)
int default_format;
switch(name[ strlen(name)-1 ]){
/* writE/strobE or monitoR or displaY/fdisplaY or sformaT */
/* writE/strobE or monitoR or displaY/fdisplaY or sformaT/sformatF */
case 'e':
case 'r':
case 't':
case 'f':
case 'y': default_format = vpiDecStrVal; break;
case 'h': default_format = vpiHexStrVal; break;
case 'o': default_format = vpiOctStrVal; break;
@ -1238,7 +1239,8 @@ static PLI_INT32 sys_display_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
return sys_common_compiletf(name, 0, 0);
}
/* This implements the $display/$fdisplay and the $write/$fwrite based tasks. */
/* This implements the $sformatf, $display/$fdisplay
* and the $write/$fwrite based tasks. */
static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
vpiHandle callh, argv, scope;
@ -1246,6 +1248,7 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
char* result;
unsigned int size;
PLI_UINT32 fd_mcd;
s_vpi_value val;
callh = vpi_handle(vpiSysTfCall, 0);
argv = vpi_iterate(vpiArgument, callh);
@ -1254,7 +1257,6 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
if(name[1] == 'f') {
errno = 0;
vpiHandle arg = vpi_scan(argv);
s_vpi_value val;
val.format = vpiIntVal;
vpi_get_value(arg, &val);
fd_mcd = val.value.integer;
@ -1275,7 +1277,11 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
vpi_free_object(argv);
return 0;
}
} else if(strncmp(name,"$sformatf",9) == 0) {
/* return as a string */
fd_mcd = 0;
} else {
/* stdout */
fd_mcd = 1;
}
@ -1293,13 +1299,21 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
/* 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);
my_mcd_rawwrite(fd_mcd, result, size);
if ((strncmp(name,"$display",8) == 0) ||
(strncmp(name,"$fdisplay",9) == 0)) my_mcd_rawwrite(fd_mcd, "\n", 1);
if(fd_mcd > 0) {
my_mcd_rawwrite(fd_mcd, result, size);
if ((strncmp(name,"$display",8) == 0) ||
(strncmp(name,"$fdisplay",9) == 0)) my_mcd_rawwrite(fd_mcd, "\n", 1);
} else {
/* Return as a string ($sformatf) */
val.format = vpiStringVal;
val.value.str = result;
vpi_put_value(callh, &val, 0, vpiNoDelay);
}
free(result);
free(info.filename);
free(info.items);
free(result);
return 0;
}
@ -1665,7 +1679,7 @@ static PLI_INT32 sys_sformat_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
if (argv == 0) {
vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s requires at least two argument.\n", name);
vpi_printf("%s requires at least two arguments.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
@ -1686,7 +1700,7 @@ static PLI_INT32 sys_sformat_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
if (arg == 0) {
vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s requires at least two argument.\n", name);
vpi_printf("%s requires at least two arguments.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
@ -1754,6 +1768,46 @@ static PLI_INT32 sys_sformat_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
return 0;
}
static PLI_INT32 sys_sformatf_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh);
vpiHandle arg;
PLI_INT32 type;
/* Check that there are arguments. */
if (argv == 0) {
vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s requires at least one argument.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
/* The first argument must be a string, a register or a SV string. */
arg = vpi_scan(argv);
if (arg == 0) {
vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s requires at least one argument.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
type = vpi_get(vpiType, arg);
if (((type != vpiConstant && type != vpiParameter) ||
vpi_get(vpiConstType, arg) != vpiStringConst) &&
type != vpiReg && type != vpiStringVar) {
vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s's first argument must be a string or a register.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
if (sys_check_args(callh, argv, name, 0, 0)) vpi_control(vpiFinish, 1);
return 0;
}
static PLI_INT32 sys_end_of_compile(p_cb_data cb_data)
{
(void)cb_data; /* Parameter is not used. */
@ -2434,6 +2488,16 @@ void sys_display_register(void)
res = vpi_register_systf(&tf_data);
vpip_make_systf_system_defined(res);
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiStringFunc;
tf_data.tfname = "$sformatf";
tf_data.calltf = sys_display_calltf;
tf_data.compiletf = sys_sformatf_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = "$sformatf";
res = vpi_register_systf(&tf_data);
vpip_make_systf_system_defined(res);
/*============================ timeformat */
tf_data.type = vpiSysTask;
tf_data.tfname = "$timeformat";

View File

@ -24,3 +24,5 @@ $table_model vpiSysFuncReal
$ivl_string_method$len vpiSysFuncInt
$ivl_string_method$to_vec vpiSysFuncVoid
$sformatf vpiSysFuncString