fread() support integral variables not just registers

This commit is contained in:
Cary R 2023-12-09 14:29:07 -08:00
parent 5d561f3ef1
commit 987b7d1dc0
6 changed files with 40 additions and 17 deletions

View File

@ -1,4 +1,4 @@
ERROR: vlog95.v:17: $fread's first argument must be a reg or memory.
ERROR: vlog95.v:17: $fread's first argument must be an integral variable or memory.
ERROR: vlog95.v:18: $fread requires a second (file descriptor) argument.
ERROR: vlog95.v:19: $fread's second argument must be numeric.
ERROR: vlog95.v:20: $fread's third argument must be numeric.

View File

@ -1,7 +1,7 @@
ERROR: ./ivltests/fread-error.v:7: $fread's first argument must be a reg or memory.
ERROR: ./ivltests/fread-error.v:8: $fread requires a second (file descriptor) argument.
ERROR: ./ivltests/fread-error.v:9: $fread's second argument must be numeric.
ERROR: ./ivltests/fread-error.v:10: $fread's third argument must be numeric.
ERROR: ./ivltests/fread-error.v:11: $fread's fourth argument must be numeric.
ERROR: ./ivltests/fread-error.v:12: $fread takes at most four arguments.
ERROR: ./ivltests/fread-error.v:8: $fread's first argument must be an integral variable or memory.
ERROR: ./ivltests/fread-error.v:9: $fread requires a second (file descriptor) argument.
ERROR: ./ivltests/fread-error.v:10: $fread's second argument must be numeric.
ERROR: ./ivltests/fread-error.v:11: $fread's third argument must be numeric.
ERROR: ./ivltests/fread-error.v:12: $fread's fourth argument must be numeric.
ERROR: ./ivltests/fread-error.v:13: $fread takes at most four arguments.
Found 1 extra argument.

View File

@ -1,10 +1,11 @@
module top;
integer res, ival;
real rval;
integer res;
reg [7:0] rg;
reg [7:0] mem [3:0];
initial begin
res = $fread(ival, 1); // 1st arg. must be a reg. or memory.
res = $fread(rval, 1); // 1st arg. must be a reg. or memory.
res = $fread(rg); // Too few argument.
res = $fread(mem, "a"); // Not a valid fd.
res = $fread(mem, 1, "a"); // Not a valid start.

View File

@ -472,7 +472,6 @@ static PLI_INT32 sys_fread_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh);
vpiHandle arg;
PLI_INT32 type;
/* We must have at least two arguments. */
if (argv == 0) {
@ -484,12 +483,11 @@ static PLI_INT32 sys_fread_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
return 0;
}
/* Check that the first required argument is a register or memory. */
type = vpi_get(vpiType, vpi_scan(argv));
if (type != vpiReg && type != vpiMemory) {
/* Check that the first required argument is an integral variable or memory. */
if (! is_int_var_or_mem(vpi_scan(argv))) {
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s's first argument must be a reg or memory.\n", name);
vpi_printf("%s's first argument must be an integral variable or memory.\n", name);
vpip_set_return_value(1);
vpi_control(vpiFinish, 1);
}
@ -612,7 +610,6 @@ static PLI_INT32 sys_fread_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* Get the register/memory. */
mem_reg = vpi_scan(argv);
/* Get the file descriptor. */
arg = vpi_scan(argv);
val.format = vpiIntVal;
@ -635,8 +632,8 @@ static PLI_INT32 sys_fread_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
}
/* Are we reading into a memory? */
if (vpi_get(vpiType, mem_reg) == vpiReg) is_mem = 0;
else is_mem = 1;
if (vpi_get(vpiType, mem_reg) == vpiMemory) is_mem = 1;
else is_mem = 0;
/* We only need to get these for memories. */
if (is_mem) {

View File

@ -256,6 +256,30 @@ unsigned is_string_obj(vpiHandle obj)
return rtn;
}
/*
* This routine returns 1 if the argument is an integral value or is a memory,
* otherwise it returns 0.
*/
unsigned is_int_var_or_mem(vpiHandle obj)
{
unsigned rtn = 0;
assert(obj);
switch(vpi_get(vpiType, obj)) {
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiReg:
case vpiTimeVar:
case vpiMemory:
rtn = 1;
break;
}
return rtn;
}
/*
* This routine returns 1 if the argument supports a valid string value,

View File

@ -58,6 +58,7 @@ extern struct timeformat_info_s timeformat_info;
extern unsigned is_constant_obj(vpiHandle obj);
extern unsigned is_numeric_obj(vpiHandle obj);
extern unsigned is_string_obj(vpiHandle obj);
extern unsigned is_int_var_or_mem(vpiHandle obj);
extern unsigned is_variable(vpiHandle obj);
extern unsigned is_valid_fd_mcd(PLI_UINT32 fd_mcd);