Implement $ftell, $fseek and $rewind system functions.
This patch implements the $ftell, $fseek and $rewind system function.
This commit is contained in:
parent
965374acf9
commit
63ca4e6d41
224
vpi/sys_fileio.c
224
vpi/sys_fileio.c
|
|
@ -126,13 +126,8 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_fopen_sizetf(PLI_BYTE8*x)
|
|
||||||
{
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implement the $fopenr(), $fopenw() and $fopena() systen functions
|
* Implement the $fopenr(), $fopenw() and $fopena() system functions
|
||||||
* from Chris Spear's File I/O for Verilog.
|
* from Chris Spear's File I/O for Verilog.
|
||||||
*/
|
*/
|
||||||
static PLI_INT32 sys_fopenrwa_compiletf(PLI_BYTE8*name)
|
static PLI_INT32 sys_fopenrwa_compiletf(PLI_BYTE8*name)
|
||||||
|
|
@ -329,11 +324,6 @@ static PLI_INT32 sys_fgetc_calltf(PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_fgetc_sizetf(PLI_BYTE8*x)
|
|
||||||
{
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||||
{
|
{
|
||||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
|
@ -489,13 +479,7 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_ungetc_sizetf(PLI_BYTE8*x)
|
static PLI_INT32 sys_check_fd_compiletf(PLI_BYTE8 *ud)
|
||||||
{
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* $feof() is from 1364-2005. */
|
|
||||||
static PLI_INT32 sys_feof_compiletf(PLI_BYTE8 *ud)
|
|
||||||
{
|
{
|
||||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
|
@ -535,11 +519,45 @@ static PLI_INT32 sys_feof_compiletf(PLI_BYTE8 *ud)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_feof_calltf(PLI_BYTE8 *ud)
|
static PLI_INT32 sys_rewind_calltf(PLI_BYTE8 *ud)
|
||||||
{
|
{
|
||||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
vpiHandle item = vpi_scan(argv);;
|
vpiHandle item = vpi_scan(argv);
|
||||||
|
s_vpi_value val;
|
||||||
|
PLI_INT32 fd;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
/* Get the file pointer. */
|
||||||
|
vpi_free_object(argv);
|
||||||
|
val.format = vpiIntVal;
|
||||||
|
vpi_get_value(item, &val);
|
||||||
|
fd = val.value.integer;
|
||||||
|
if (IS_MCD(fd)) {
|
||||||
|
vpi_printf("ERROR: %s cannot be used with a MCD.\n", ud);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fp = vpi_get_file(fd);
|
||||||
|
|
||||||
|
/* If we have a valid file descriptor rewind the file. */
|
||||||
|
if (!fp) {
|
||||||
|
val.value.integer = EOF;
|
||||||
|
} else {
|
||||||
|
rewind(fp);
|
||||||
|
val.value.integer = 0;
|
||||||
|
}
|
||||||
|
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* $feof() is from 1364-2005. */
|
||||||
|
static PLI_INT32 sys_ftell_feof_calltf(PLI_BYTE8 *ud)
|
||||||
|
{
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
vpiHandle item = vpi_scan(argv);
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
PLI_INT32 fd;
|
PLI_INT32 fd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
@ -557,18 +575,134 @@ static PLI_INT32 sys_feof_calltf(PLI_BYTE8 *ud)
|
||||||
fp = vpi_get_file(fd);
|
fp = vpi_get_file(fd);
|
||||||
|
|
||||||
/* If we do not have a valid file descriptor return EOF, otherwise
|
/* If we do not have a valid file descriptor return EOF, otherwise
|
||||||
* check for EOF and return that value. */
|
* return that value. */
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
val.value.integer = EOF;
|
val.value.integer = EOF;
|
||||||
} else {
|
} else {
|
||||||
val.value.integer = feof(fp);
|
if (ud[2] == 'e') {
|
||||||
|
val.value.integer = feof(fp);
|
||||||
|
} else {
|
||||||
|
val.value.integer = ftell(fp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_feof_sizetf(PLI_BYTE8 *ud)
|
static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8 *ud)
|
||||||
|
{
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
vpiHandle item;
|
||||||
|
PLI_INT32 type;
|
||||||
|
|
||||||
|
/* Check that there is an argument. */
|
||||||
|
if (argv == 0) {
|
||||||
|
vpi_printf("ERROR: %s requires three arguments.\n", ud);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Check that the file descriptor is the right type. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
type = vpi_get(vpiType, item);
|
||||||
|
switch (type) {
|
||||||
|
case vpiReg:
|
||||||
|
case vpiRealVal:
|
||||||
|
case vpiIntegerVar:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vpi_printf("ERROR: %s fd parameter must be integral", ud);
|
||||||
|
vpi_printf(", got vpiType=%d\n", type);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that there is an offset argument. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
if (item == 0) {
|
||||||
|
vpi_printf("ERROR: %s is missing an offset and operation "
|
||||||
|
"argument.\n", ud);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that there is an operation argument. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
if (item == 0) {
|
||||||
|
vpi_printf("ERROR: %s is missing an operation argument.\n", ud);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that there is at most one argument. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
if (item != 0) {
|
||||||
|
vpi_printf("ERROR: %s takes at most three argument.\n", ud);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vpi_scan returning 0 (NULL) has already freed argv. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 sys_fseek_calltf(PLI_BYTE8 *ud)
|
||||||
|
{
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
vpiHandle item;
|
||||||
|
s_vpi_value val;
|
||||||
|
PLI_INT32 fd, offset, oper;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
val.format = vpiIntVal;
|
||||||
|
|
||||||
|
/* Get the file pointer. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
vpi_get_value(item, &val);
|
||||||
|
fd = val.value.integer;
|
||||||
|
if (IS_MCD(fd)) {
|
||||||
|
vpi_printf("ERROR: %s cannot be used with a MCD.\n", ud);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fp = vpi_get_file(fd);
|
||||||
|
|
||||||
|
/* Get the offset. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
vpi_get_value(item, &val);
|
||||||
|
offset = val.value.integer;
|
||||||
|
|
||||||
|
/* Get the operation. */
|
||||||
|
item = vpi_scan(argv);
|
||||||
|
vpi_get_value(item, &val);
|
||||||
|
oper = val.value.integer;
|
||||||
|
/* Should this translate to the SEEK_??? codes? */
|
||||||
|
/* What about verifying offset value vs operation ($fseek(fd, -1, 0))? */
|
||||||
|
if ((oper < 0) || (oper > 2)) {
|
||||||
|
vpi_printf("ERROR: %s's operation must be 0, 1 or 2 given %d.\n",
|
||||||
|
ud, oper);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we do not have a valid file descriptor return EOF, otherwise
|
||||||
|
* return that value. */
|
||||||
|
if (!fp) {
|
||||||
|
val.value.integer = EOF;
|
||||||
|
} else {
|
||||||
|
fseek(fp, offset, oper);
|
||||||
|
val.value.integer = 0;
|
||||||
|
}
|
||||||
|
vpi_put_value(callh, &val, 0 , vpiNoDelay);
|
||||||
|
|
||||||
|
vpi_free_object(argv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 sys_integer_sizetf(PLI_BYTE8 *ud)
|
||||||
{
|
{
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
@ -582,7 +716,7 @@ void sys_fileio_register()
|
||||||
tf_data.tfname = "$fopen";
|
tf_data.tfname = "$fopen";
|
||||||
tf_data.calltf = sys_fopen_calltf;
|
tf_data.calltf = sys_fopen_calltf;
|
||||||
tf_data.compiletf = sys_fopen_compiletf;
|
tf_data.compiletf = sys_fopen_compiletf;
|
||||||
tf_data.sizetf = sys_fopen_sizetf;
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
tf_data.user_data = "$fopen";
|
tf_data.user_data = "$fopen";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
|
@ -591,7 +725,7 @@ void sys_fileio_register()
|
||||||
tf_data.tfname = "$fopenr";
|
tf_data.tfname = "$fopenr";
|
||||||
tf_data.calltf = sys_fopenrwa_calltf;
|
tf_data.calltf = sys_fopenrwa_calltf;
|
||||||
tf_data.compiletf = sys_fopenrwa_compiletf;
|
tf_data.compiletf = sys_fopenrwa_compiletf;
|
||||||
tf_data.sizetf = sys_fopen_sizetf;
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
tf_data.user_data = "$fopenr";
|
tf_data.user_data = "$fopenr";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
|
@ -638,7 +772,7 @@ void sys_fileio_register()
|
||||||
tf_data.tfname = "$fgetc";
|
tf_data.tfname = "$fgetc";
|
||||||
tf_data.calltf = sys_fgetc_calltf;
|
tf_data.calltf = sys_fgetc_calltf;
|
||||||
tf_data.compiletf = 0;
|
tf_data.compiletf = 0;
|
||||||
tf_data.sizetf = sys_fgetc_sizetf;
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
tf_data.user_data = "$fgetc";
|
tf_data.user_data = "$fgetc";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
|
@ -658,18 +792,48 @@ void sys_fileio_register()
|
||||||
tf_data.tfname = "$ungetc";
|
tf_data.tfname = "$ungetc";
|
||||||
tf_data.calltf = sys_ungetc_calltf;
|
tf_data.calltf = sys_ungetc_calltf;
|
||||||
tf_data.compiletf = sys_ungetc_compiletf;
|
tf_data.compiletf = sys_ungetc_compiletf;
|
||||||
tf_data.sizetf = sys_ungetc_sizetf;
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
tf_data.user_data = "$ungetc";
|
tf_data.user_data = "$ungetc";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
//============================== ftell
|
||||||
|
tf_data.type = vpiSysFunc;
|
||||||
|
tf_data.sysfunctype = vpiSysFuncInt;
|
||||||
|
tf_data.tfname = "$ftell";
|
||||||
|
tf_data.calltf = sys_ftell_feof_calltf;
|
||||||
|
tf_data.compiletf = sys_check_fd_compiletf;
|
||||||
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
|
tf_data.user_data = "$ftell";
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
//============================== fseek
|
||||||
|
tf_data.type = vpiSysFunc;
|
||||||
|
tf_data.sysfunctype = vpiSysFuncInt;
|
||||||
|
tf_data.tfname = "$fseek";
|
||||||
|
tf_data.calltf = sys_fseek_calltf;
|
||||||
|
tf_data.compiletf = sys_fseek_compiletf;
|
||||||
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
|
tf_data.user_data = "$fseek";
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
//============================== rewind
|
||||||
|
tf_data.type = vpiSysFunc;
|
||||||
|
tf_data.sysfunctype = vpiSysFuncInt;
|
||||||
|
tf_data.tfname = "$rewind";
|
||||||
|
tf_data.calltf = sys_rewind_calltf;
|
||||||
|
tf_data.compiletf = sys_check_fd_compiletf;
|
||||||
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
|
tf_data.user_data = "$rewind";
|
||||||
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
/* $feof() is from 1364-2005. */
|
/* $feof() is from 1364-2005. */
|
||||||
//============================== feof
|
//============================== feof
|
||||||
tf_data.type = vpiSysFunc;
|
tf_data.type = vpiSysFunc;
|
||||||
tf_data.sysfunctype = vpiSysFuncInt;
|
tf_data.sysfunctype = vpiSysFuncInt;
|
||||||
tf_data.tfname = "$feof";
|
tf_data.tfname = "$feof";
|
||||||
tf_data.calltf = sys_feof_calltf;
|
tf_data.calltf = sys_ftell_feof_calltf;
|
||||||
tf_data.compiletf = sys_feof_compiletf;
|
tf_data.compiletf = sys_check_fd_compiletf;
|
||||||
tf_data.sizetf = sys_feof_sizetf;
|
tf_data.sizetf = sys_integer_sizetf;
|
||||||
tf_data.user_data = "$feof";
|
tf_data.user_data = "$feof";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue