Rework $plusarg routines.
This patch addresses a number of issues:
Rewrote the $test$plusargs and $value$plusargs routines to have
better error/warning messages, to support runtime strings, to
correctly load bit based values (truncating, padding, negative
value), added support for the real formats using strtod() and
added "x/X" as an alias for "h/H" to match the other part of
Icarus.
Rewrite the vpip_{bin,oct,hex}_str_to_vec4 routines to ignore
embedded "_" characters. Add support for a negative value and
set the entire value to 'bx if an invalid digit is found. A
warning is printed for this case.
Rewrite vpip_dec_str_to_vec4 to ignore embedded "_" characters,
to support a single "x" or "z" constant and to return 'bx if an
invalid digit is found. A warning is printed for this case.
It simplifies the system task/functions error/warning messages.
It removes the signed flag for the bin and dec string conversions.
This was not being used (was always false) and the new negative
value support makes this obsolete.
Add support for a real variable to handle Bin, Oct, Dec and Hex
strings. They are converted into a vvp_vector4_t which is then
converted to a real value.
Add support for setting a bit based value using a real value.
Removed an unneeded rfp signal in vpip_make_reg()
This commit is contained in:
parent
69428bb050
commit
221b83b932
|
|
@ -69,7 +69,7 @@ static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* We must have an argument. */
|
/* We must have an argument. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("$clog2 requires one numeric argument.\n");
|
vpi_printf("$clog2 requires one numeric argument.\n");
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -79,7 +79,7 @@ static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
|
||||||
/* The argument must be numeric. */
|
/* The argument must be numeric. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (! is_numeric_obj(arg)) {
|
if (! is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("The first argument to $clog2 must be numeric.\n");
|
vpi_printf("The first argument to $clog2 must be numeric.\n");
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -90,7 +90,7 @@ static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ static void double2bits(double real, PLI_UINT32 bits[2])
|
||||||
|
|
||||||
static void error_message(vpiHandle callh, const char* msg)
|
static void error_message(vpiHandle callh, const char* msg)
|
||||||
{
|
{
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf(msg, vpi_get_str(vpiName, callh));
|
vpi_printf(msg, vpi_get_str(vpiName, callh));
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* Check that there is a file name argument and that it is a string. */
|
/* Check that there is a file name argument and that it is a string. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a string file name argument.\n", name);
|
vpi_printf("%s requires a string file name argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! is_string_obj(vpi_scan(argv))) {
|
if (! is_string_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's file name argument must be a string.\n", name);
|
vpi_printf("%s's file name argument must be a string.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -60,7 +60,7 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* When provided, the type argument must be a string. */
|
/* When provided, the type argument must be a string. */
|
||||||
if (! is_string_obj(arg)) {
|
if (! is_string_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's type argument must be a string.\n", name);
|
vpi_printf("%s's type argument must be a string.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -71,7 +71,7 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -106,7 +106,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
vpi_get_value(mode, &val);
|
vpi_get_value(mode, &val);
|
||||||
/* Verify that we have a string and that it is not NULL. */
|
/* Verify that we have a string and that it is not NULL. */
|
||||||
if (val.format != vpiStringVal || !*(val.value.str)) {
|
if (val.format != vpiStringVal || !*(val.value.str)) {
|
||||||
vpi_printf("WARNING: %s line %d: ",
|
vpi_printf("WARNING: %s:%d: ",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's mode argument is not a valid string.\n",
|
vpi_printf("%s's mode argument is not a valid string.\n",
|
||||||
|
|
@ -116,7 +116,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
|
|
||||||
/* Make sure the mode string is correct. */
|
/* Make sure the mode string is correct. */
|
||||||
if (strlen(val.value.str) > 3) {
|
if (strlen(val.value.str) > 3) {
|
||||||
vpi_printf("WARNING: %s line %d: ",
|
vpi_printf("WARNING: %s:%d: ",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's mode argument (%s) is too long.\n",
|
vpi_printf("%s's mode argument (%s) is too long.\n",
|
||||||
|
|
@ -147,7 +147,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
if (! fail) break;
|
if (! fail) break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vpi_printf("WARNING: %s line %d: ",
|
vpi_printf("WARNING: %s:%d: ",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's mode argument (%s) is invalid.\n",
|
vpi_printf("%s's mode argument (%s) is invalid.\n",
|
||||||
|
|
@ -169,7 +169,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
|
|
||||||
/* Verify that we have a string and that it is not NULL. */
|
/* Verify that we have a string and that it is not NULL. */
|
||||||
if (val.format != vpiStringVal || !*(val.value.str)) {
|
if (val.format != vpiStringVal || !*(val.value.str)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's file name argument is not a valid string.\n",
|
vpi_printf("%s's file name argument is not a valid string.\n",
|
||||||
name);
|
name);
|
||||||
|
|
@ -185,7 +185,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
|
||||||
for (idx = 0; idx < len; idx++) {
|
for (idx = 0; idx < len; idx++) {
|
||||||
if (! isprint(val.value.str[idx])) {
|
if (! isprint(val.value.str[idx])) {
|
||||||
char msg [64];
|
char msg [64];
|
||||||
snprintf(msg, 64, "WARNING: %s line %d:",
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s %s's file name argument contains non-"
|
vpi_printf("%s %s's file name argument contains non-"
|
||||||
|
|
@ -236,7 +236,7 @@ static PLI_INT32 sys_fopenrwa_calltf(PLI_BYTE8*name)
|
||||||
|
|
||||||
/* Verify that we have a string and that it is not NULL. */
|
/* Verify that we have a string and that it is not NULL. */
|
||||||
if (val.format != vpiStringVal || !*(val.value.str)) {
|
if (val.format != vpiStringVal || !*(val.value.str)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's file name argument is not a valid string.\n",
|
vpi_printf("%s's file name argument is not a valid string.\n",
|
||||||
name);
|
name);
|
||||||
|
|
@ -251,7 +251,7 @@ static PLI_INT32 sys_fopenrwa_calltf(PLI_BYTE8*name)
|
||||||
for (idx = 0; idx < len; idx++) {
|
for (idx = 0; idx < len; idx++) {
|
||||||
if (! isprint(val.value.str[idx])) {
|
if (! isprint(val.value.str[idx])) {
|
||||||
char msg [64];
|
char msg [64];
|
||||||
snprintf(msg, 64, "WARNING: %s line %d:",
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s %s's file name argument contains non-"
|
vpi_printf("%s %s's file name argument contains non-"
|
||||||
|
|
@ -355,7 +355,7 @@ static PLI_INT32 sys_fputc_calltf(PLI_BYTE8*name)
|
||||||
fp = vpi_get_file(fd_mcd);
|
fp = vpi_get_file(fd_mcd);
|
||||||
val.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
if (!fp || IS_MCD(fd_mcd)) {
|
if (!fp || IS_MCD(fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
|
@ -378,7 +378,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||||
* register and that the second is numeric.
|
* register and that the second is numeric.
|
||||||
*/
|
*/
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires two arguments.\n", name);
|
vpi_printf("%s requires two arguments.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -386,7 +386,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vpi_get(vpiType, vpi_scan(argv)) != vpiReg) {
|
if (vpi_get(vpiType, vpi_scan(argv)) != vpiReg) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's first argument must be a reg.\n", name);
|
vpi_printf("%s's first argument must be a reg.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -394,7 +394,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||||
|
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (! arg) {
|
if (! arg) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a second (numeric) argument.\n", name);
|
vpi_printf("%s requires a second (numeric) argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -402,7 +402,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_numeric_obj(arg)) {
|
if (! is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's second argument must be numeric.\n", name);
|
vpi_printf("%s's second argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -413,7 +413,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -455,7 +455,7 @@ static PLI_INT32 sys_fgets_calltf(PLI_BYTE8*name)
|
||||||
/* Return zero if this is not a valid fd. */
|
/* Return zero if this is not a valid fd. */
|
||||||
fp = vpi_get_file(fd_mcd);
|
fp = vpi_get_file(fd_mcd);
|
||||||
if (!fp || IS_MCD(fd_mcd)) {
|
if (!fp || IS_MCD(fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
|
@ -519,7 +519,7 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
|
||||||
/* Return EOF if this is not a valid fd. */
|
/* Return EOF if this is not a valid fd. */
|
||||||
fp = vpi_get_file(fd_mcd);
|
fp = vpi_get_file(fd_mcd);
|
||||||
if (!fp || IS_MCD(fd_mcd)) {
|
if (!fp || IS_MCD(fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
|
@ -545,7 +545,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
|
|
||||||
/* Check that there are three numeric arguments. */
|
/* Check that there are three numeric arguments. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires three arguments.\n", name);
|
vpi_printf("%s requires three arguments.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -554,7 +554,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
|
|
||||||
/* Check that the first argument is numeric. */
|
/* Check that the first argument is numeric. */
|
||||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's first argument must be numeric.\n", name);
|
vpi_printf("%s's first argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -563,7 +563,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
/* Check that the second argument exists and is numeric. */
|
/* Check that the second argument exists and is numeric. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (! arg) {
|
if (! arg) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a second (numeric) argument.\n", name);
|
vpi_printf("%s requires a second (numeric) argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -571,7 +571,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg || !is_numeric_obj(arg)) {
|
if (!arg || !is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's second argument must be numeric.\n", name);
|
vpi_printf("%s's second argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -580,7 +580,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
/* Check that the third argument exists and is numeric. */
|
/* Check that the third argument exists and is numeric. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (! arg) {
|
if (! arg) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a third (numeric) argument.\n", name);
|
vpi_printf("%s requires a third (numeric) argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -588,7 +588,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg || !is_numeric_obj(arg)) {
|
if (!arg || !is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's third argument must be numeric.\n", name);
|
vpi_printf("%s's third argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -599,7 +599,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -647,7 +647,7 @@ static PLI_INT32 sys_fseek_calltf(PLI_BYTE8*name)
|
||||||
|
|
||||||
/* Check that the operation is in the valid range. */
|
/* Check that the operation is in the valid range. */
|
||||||
if ((oper < 0) || (oper > 2)) {
|
if ((oper < 0) || (oper > 2)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's operation must be 0, 1 or 2 given %d.\n",
|
vpi_printf("%s's operation must be 0, 1 or 2 given %d.\n",
|
||||||
name, oper);
|
name, oper);
|
||||||
|
|
@ -660,7 +660,7 @@ static PLI_INT32 sys_fseek_calltf(PLI_BYTE8*name)
|
||||||
/* Return EOF if this is not a valid fd. */
|
/* Return EOF if this is not a valid fd. */
|
||||||
fp = vpi_get_file(fd_mcd);
|
fp = vpi_get_file(fd_mcd);
|
||||||
if (!fp || IS_MCD(fd_mcd)) {
|
if (!fp || IS_MCD(fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
|
@ -696,7 +696,7 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
|
||||||
/* Return EOF if this is not a valid fd. */
|
/* Return EOF if this is not a valid fd. */
|
||||||
fp = vpi_get_file(fd_mcd);
|
fp = vpi_get_file(fd_mcd);
|
||||||
if (!fp || IS_MCD(fd_mcd)) {
|
if (!fp || IS_MCD(fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
|
||||||
name);
|
name);
|
||||||
|
|
@ -721,7 +721,7 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
|
||||||
val.value.integer = fgetc(fp);
|
val.value.integer = fgetc(fp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s cannot be processed with this routine.\n", name);
|
vpi_printf("%s cannot be processed with this routine.\n", name);
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
||||||
|
|
@ -435,7 +435,7 @@ static void open_dumpfile(vpiHandle callh)
|
||||||
dump_file = lt_init(dump_path);
|
dump_file = lt_init(dump_path);
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
vpi_printf("LXT Error: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("LXT Error: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
|
||||||
|
|
@ -433,7 +433,7 @@ static void open_dumpfile(vpiHandle callh)
|
||||||
dump_file = lxt2_wr_init(dump_path);
|
dump_file = lxt2_wr_init(dump_path);
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
vpi_printf("LXT2 Error: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("LXT2 Error: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -16,87 +16,32 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
|
||||||
#ident "$Id: sys_plusargs.c,v 1.7 2007/03/14 04:05:51 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
# include "sys_priv.h"
|
||||||
# include <vpi_user.h>
|
# include <vpi_user.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
static PLI_INT32 sys_plusargs_sizetf(PLI_BYTE8*x)
|
|
||||||
{
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The compiletf for $test$plusargs checks that there is one argument
|
|
||||||
* to the function call, and that argument is a constant string.
|
|
||||||
*/
|
|
||||||
static PLI_INT32 sys_test_plusargs_compiletf(PLI_BYTE8*xx)
|
|
||||||
{
|
|
||||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
|
||||||
vpiHandle arg;
|
|
||||||
|
|
||||||
if (argv == 0) {
|
|
||||||
vpi_printf("ERROR: $test$plusargs requires one argument\n");
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arg = vpi_scan(argv);
|
|
||||||
assert(arg != 0);
|
|
||||||
|
|
||||||
switch (vpi_get(vpiType, arg)) {
|
|
||||||
case vpiConstant:
|
|
||||||
if (vpi_get(vpiConstType, arg) != vpiStringConst) {
|
|
||||||
vpi_printf("ERROR: Argument of $test$plusargs "
|
|
||||||
" must be a constant string.\n");
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
vpi_printf("ERROR: Argument of $test$plusargs "
|
|
||||||
" must be a constant string.\n");
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
arg = vpi_scan(argv);
|
|
||||||
if (arg != 0) {
|
|
||||||
vpi_printf("ERROR: too many arguments to $test$plusargs\n");
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare the +arguments passed to the simulator with the argument
|
* Compare the +arguments passed to the simulator with the argument
|
||||||
* passed to the $test$plusargs. If there is a simulator argument that
|
* passed to the $test$plusargs. If there is a simulator argument that
|
||||||
* is like this argument, then return true. Otherwise return false.
|
* is like this argument, then return true. Otherwise return false.
|
||||||
*/
|
*/
|
||||||
static PLI_INT32 sys_test_plusargs_calltf(PLI_BYTE8*xx)
|
static PLI_INT32 sys_test_plusargs_calltf(PLI_BYTE8*name)
|
||||||
{
|
{
|
||||||
|
s_vpi_value val;
|
||||||
|
s_vpi_vlog_info info;
|
||||||
int idx;
|
int idx;
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
size_t slen, len;
|
size_t slen, len;
|
||||||
s_vpi_vlog_info info;
|
|
||||||
s_vpi_value value;
|
|
||||||
s_vpi_value result;
|
|
||||||
|
|
||||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
vpiHandle arg = vpi_scan(argv);
|
|
||||||
|
|
||||||
value.format = vpiStringVal;
|
val.format = vpiStringVal;
|
||||||
vpi_get_value(arg, &value);
|
vpi_get_value(vpi_scan(argv), &val);
|
||||||
slen = strlen(value.value.str);
|
slen = strlen(val.value.str);
|
||||||
|
|
||||||
vpi_get_vlog_info(&info);
|
vpi_get_vlog_info(&info);
|
||||||
|
|
||||||
|
|
@ -111,97 +56,52 @@ static PLI_INT32 sys_test_plusargs_calltf(PLI_BYTE8*xx)
|
||||||
if (len < slen)
|
if (len < slen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strncmp(value.value.str, info.argv[idx]+1, slen) != 0)
|
if (strncmp(val.value.str, info.argv[idx]+1, slen) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
flag = 1;
|
flag = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.format = vpiIntVal;
|
val.format = vpiIntVal;
|
||||||
result.value.integer = flag;
|
val.value.integer = flag;
|
||||||
vpi_put_value(sys, &result, 0, vpiNoDelay);
|
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||||
|
|
||||||
|
vpi_free_object(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_value_plusargs_compiletf(PLI_BYTE8*xx)
|
static PLI_INT32 sys_value_plusargs_compiletf(PLI_BYTE8*name)
|
||||||
{
|
{
|
||||||
s_vpi_value value;
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
|
||||||
vpiHandle arg;
|
vpiHandle arg;
|
||||||
|
|
||||||
|
/* Check that there are arguments. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: $value$plusargs requires two arguments\n");
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s requires two arguments.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that the first argument is a string. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
assert(arg != 0);
|
assert(arg != 0);
|
||||||
|
if ( ! is_string_obj(arg)) {
|
||||||
switch (vpi_get(vpiType, arg)) {
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
case vpiConstant:
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
if (vpi_get(vpiConstType, arg) != vpiStringConst) {
|
vpi_printf("%s's first argument must be a string.\n", name);
|
||||||
vpi_printf("ERROR: First argument of $value$plusargs "
|
|
||||||
" must be a constant string.\n");
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
vpi_printf("ERROR: First argument of $value$plusargs "
|
|
||||||
" must be a constant string.\n");
|
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that the format string has a reasonable format. */
|
|
||||||
value.format = vpiStringVal;
|
|
||||||
vpi_get_value(arg, &value);
|
|
||||||
{ char*fmt = value.value.str;
|
|
||||||
char*cp = strchr(fmt, '%');
|
|
||||||
|
|
||||||
if (cp == 0) {
|
|
||||||
vpi_printf("ERROR: Invalid argument format string"
|
|
||||||
": %s\n", fmt);
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cp += 1;
|
|
||||||
if (*cp == '0')
|
|
||||||
cp += 1;
|
|
||||||
|
|
||||||
switch (*cp) {
|
|
||||||
case 'd':
|
|
||||||
case 'o':
|
|
||||||
case 'b':
|
|
||||||
case 'h':
|
|
||||||
case 's':
|
|
||||||
cp += 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vpi_printf("ERROR: Invalid argument format string"
|
|
||||||
": %s\n", fmt);
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*cp != 0) {
|
|
||||||
vpi_printf("ERROR: Trailing junk after value format"
|
|
||||||
": %s\n", fmt);
|
|
||||||
vpi_control(vpiFinish, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (argv == 0) {
|
if (! arg) {
|
||||||
vpi_printf("ERROR: $value$plusargs requires two arguments\n");
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s's requires a second variable argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -210,55 +110,129 @@ static PLI_INT32 sys_value_plusargs_compiletf(PLI_BYTE8*xx)
|
||||||
|
|
||||||
case vpiReg:
|
case vpiReg:
|
||||||
case vpiIntegerVar:
|
case vpiIntegerVar:
|
||||||
|
case vpiRealVar:
|
||||||
|
case vpiTimeVar:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vpi_printf("ERROR: value field doesn\'t match format: %s\n",
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
value.value.str);
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s's second argument must be a variable, found a %s.\n",
|
||||||
|
name, vpi_get_str(vpiType, arg));
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = vpi_scan(argv);
|
/* Make sure there are no extra arguments. */
|
||||||
if (arg != 0) {
|
if (vpi_scan(argv) != 0) {
|
||||||
vpi_printf("ERROR: too many arguments to $value$plusargs\n");
|
char msg [64];
|
||||||
|
unsigned argc;
|
||||||
|
|
||||||
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
argc = 1;
|
||||||
|
while (vpi_scan(argv)) argc += 1;
|
||||||
|
|
||||||
|
vpi_printf("%s %s takes two arguments.\n", msg, name);
|
||||||
|
vpi_printf("%*s Found %u extra argument%s.\n",
|
||||||
|
(int)strlen(msg), " ", argc, argc == 1 ? "" : "s");
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLI_INT32 sys_value_plusargs_calltf(PLI_BYTE8*xx)
|
static PLI_INT32 sys_value_plusargs_calltf(PLI_BYTE8*name)
|
||||||
{
|
{
|
||||||
|
s_vpi_vlog_info info;
|
||||||
|
s_vpi_value fmt;
|
||||||
|
s_vpi_value res;
|
||||||
|
char msg [64];
|
||||||
char*cp;
|
char*cp;
|
||||||
int idx;
|
int idx;
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
size_t slen, len;
|
size_t slen, len;
|
||||||
s_vpi_vlog_info info;
|
|
||||||
s_vpi_value format;
|
|
||||||
s_vpi_value result;
|
|
||||||
|
|
||||||
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||||
vpiHandle arg1 = vpi_scan(argv);
|
|
||||||
vpiHandle arg2 = vpi_scan(argv);
|
|
||||||
|
|
||||||
format.format = vpiStringVal;
|
fmt.format = vpiStringVal;
|
||||||
vpi_get_value(arg1, &format);
|
vpi_get_value(vpi_scan(argv), &fmt);
|
||||||
|
|
||||||
|
/* Check for the start of a format string. */
|
||||||
|
cp = strchr(fmt.value.str, '%');
|
||||||
|
if (cp == 0) {
|
||||||
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
vpi_printf("%s %s is missing a format code.\n", msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the length of string we will look for. */
|
||||||
|
slen = cp - fmt.value.str;
|
||||||
|
|
||||||
|
/* Skip a zero. */
|
||||||
|
cp += 1;
|
||||||
|
if (*cp == '0') cp += 1;
|
||||||
|
|
||||||
|
/* Check the format code. */
|
||||||
|
switch (*cp) {
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
vpi_printf("%s %s has an invalid format string:\n", msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Warn if there is any trailing garbage. */
|
||||||
|
if (*(cp+1) != '\0') {
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
vpi_printf("%s Skipping trailing garbage in %s's format string:\n",
|
||||||
|
msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str);
|
||||||
|
*(cp+1) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
vpi_get_vlog_info(&info);
|
vpi_get_vlog_info(&info);
|
||||||
|
|
||||||
cp = strchr(format.value.str, '%');
|
/* Look for a +arg that matches the prefix supplied. */
|
||||||
assert(cp);
|
|
||||||
slen = cp - format.value.str;
|
|
||||||
|
|
||||||
cp += 1;
|
|
||||||
if (*cp == '0')
|
|
||||||
cp += 1;
|
|
||||||
|
|
||||||
for (idx = 0 ; idx < info.argc ; idx += 1) {
|
for (idx = 0 ; idx < info.argc ; idx += 1) {
|
||||||
|
char*sp, *tp, *end;
|
||||||
|
size_t sp_len;
|
||||||
|
|
||||||
|
/* Skip arguments that are not +args. */
|
||||||
if (info.argv[idx][0] != '+')
|
if (info.argv[idx][0] != '+')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -266,43 +240,146 @@ static PLI_INT32 sys_value_plusargs_calltf(PLI_BYTE8*xx)
|
||||||
if (len < slen)
|
if (len < slen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strncmp(format.value.str, info.argv[idx]+1, slen) != 0)
|
if (strncmp(fmt.value.str, info.argv[idx]+1, slen) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
sp = info.argv[idx]+1+slen;
|
||||||
|
sp_len = strlen(sp);
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case 'd':
|
case 'd':
|
||||||
result.format = vpiIntVal;
|
case 'D':
|
||||||
result.value.integer = strtoul(info.argv[idx]+1+slen,0,10);
|
res.format = vpiDecStrVal;
|
||||||
|
/* A decimal string can set the value to "x" or "z". */
|
||||||
|
if (sp_len == strspn(sp, "xX_") ||
|
||||||
|
sp_len == strspn(sp, "zZ_")) {
|
||||||
|
res.value.str = sp;
|
||||||
|
/* A decimal string must contain only these characters.
|
||||||
|
* A decimal string can not start with an "_" character.
|
||||||
|
* A "-" can only be at the start of the string. */
|
||||||
|
} else if (sp_len != strspn(sp, "-0123456789_") ||
|
||||||
|
*sp == '_' ||
|
||||||
|
((tp = strrchr(sp, '-')) && tp != sp)) {
|
||||||
|
res.value.str = "x";
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s Invalid decimal value passed to %s:\n",
|
||||||
|
msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
|
||||||
|
} else {
|
||||||
|
res.value.str = sp;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
result.format = vpiIntVal;
|
case 'O':
|
||||||
result.value.integer = strtoul(info.argv[idx]+1+slen,0,8);
|
res.format = vpiOctStrVal;
|
||||||
|
/* An octal string must contain only these characters.
|
||||||
|
* An octal string can not start with an "_" character.
|
||||||
|
* A "-" can only be at the start of the string. */
|
||||||
|
if (sp_len != strspn(sp, "-01234567_xXzZ") ||
|
||||||
|
*sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) {
|
||||||
|
res.value.str = "x";
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s Invalid octal value passed to %s:\n",
|
||||||
|
msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
|
||||||
|
} else {
|
||||||
|
res.value.str = sp;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
result.format = vpiIntVal;
|
case 'H':
|
||||||
result.value.integer = strtoul(info.argv[idx]+1+slen,0,16);
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
res.format = vpiHexStrVal;
|
||||||
|
/* A hex. string must contain only these characters.
|
||||||
|
* A hex. string can not start with an "_" character.
|
||||||
|
* A "-" can only be at the start of the string. */
|
||||||
|
if (sp_len != strspn(sp, "-0123456789aAbBcCdDeEfF_xXzZ") ||
|
||||||
|
*sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) {
|
||||||
|
res.value.str = "x";
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s Invalid hex value passed to %s:\n",
|
||||||
|
msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
|
||||||
|
} else {
|
||||||
|
res.value.str = sp;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
result.format = vpiIntVal;
|
case 'B':
|
||||||
result.value.integer = strtoul(info.argv[idx]+1+slen,0,12);
|
res.format = vpiBinStrVal;
|
||||||
|
/* A binary string must contain only these characters.
|
||||||
|
* A binary string can not start with an "_" character.
|
||||||
|
* A "-" can only be at the start of the string. */
|
||||||
|
if (sp_len != strspn(sp, "-01_xXzZ") ||
|
||||||
|
*sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) {
|
||||||
|
res.value.str = "x";
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s Invalid binary value passed to %s:\n",
|
||||||
|
msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
|
||||||
|
} else {
|
||||||
|
res.value.str = sp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
res.format = vpiRealVal;
|
||||||
|
res.value.real = strtod(sp, &end);
|
||||||
|
/* If we didn't get a full conversion print a warning. */
|
||||||
|
if (*end) {
|
||||||
|
/* We had an invalid value passed. */
|
||||||
|
if (end == sp) {
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s Invalid real value passed to "
|
||||||
|
"%s:\n", msg, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ",
|
||||||
|
sp);
|
||||||
|
/* We have extra garbage at the end. */
|
||||||
|
} else {
|
||||||
|
snprintf(msg, 64, "WARNING: %s:%d:",
|
||||||
|
vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s Extra character(s) \"%s\" found "
|
||||||
|
"in %s's real string:\n",
|
||||||
|
msg, end, name);
|
||||||
|
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ",
|
||||||
|
sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
result.format = vpiStringVal;
|
case 'S':
|
||||||
result.value.str = info.argv[idx]+1+slen;
|
res.format = vpiStringVal;
|
||||||
|
res.value.str = sp;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vpi_put_value(arg2, &result, 0, vpiNoDelay);
|
vpi_put_value(vpi_scan(argv), &res, 0, vpiNoDelay);
|
||||||
flag = 1;
|
flag = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.format = vpiIntVal;
|
res.format = vpiIntVal;
|
||||||
result.value.integer = flag;
|
res.value.integer = flag;
|
||||||
vpi_put_value(sys, &result, 0, vpiNoDelay);
|
vpi_put_value(callh, &res, 0, vpiNoDelay);
|
||||||
|
|
||||||
|
vpi_free_object(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,44 +388,22 @@ void sys_plusargs_register()
|
||||||
s_vpi_systf_data tf_data;
|
s_vpi_systf_data tf_data;
|
||||||
|
|
||||||
|
|
||||||
tf_data.type = vpiSysFunc;
|
tf_data.type = vpiSysFunc;
|
||||||
tf_data.tfname = "$test$plusargs";
|
tf_data.sysfunctype = vpiIntFunc;
|
||||||
tf_data.calltf = sys_test_plusargs_calltf;
|
tf_data.tfname = "$test$plusargs";
|
||||||
tf_data.compiletf = sys_test_plusargs_compiletf;
|
tf_data.calltf = sys_test_plusargs_calltf;
|
||||||
tf_data.sizetf = sys_plusargs_sizetf;
|
tf_data.compiletf = sys_one_string_arg_compiletf;
|
||||||
|
tf_data.sizetf = 0;
|
||||||
|
tf_data.user_data = "$test$plusargs";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
tf_data.type = vpiSysFunc;
|
tf_data.type = vpiSysFunc;
|
||||||
tf_data.tfname = "$value$plusargs";
|
tf_data.sysfunctype = vpiIntFunc;
|
||||||
tf_data.calltf = sys_value_plusargs_calltf;
|
tf_data.tfname = "$value$plusargs";
|
||||||
tf_data.compiletf = sys_value_plusargs_compiletf;
|
tf_data.calltf = sys_value_plusargs_calltf;
|
||||||
tf_data.sizetf = sys_plusargs_sizetf;
|
tf_data.compiletf = sys_value_plusargs_compiletf;
|
||||||
|
tf_data.sizetf = 0;
|
||||||
|
tf_data.user_data = "$value$plusargs";
|
||||||
vpi_register_systf(&tf_data);
|
vpi_register_systf(&tf_data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: sys_plusargs.c,v $
|
|
||||||
* Revision 1.7 2007/03/14 04:05:51 steve
|
|
||||||
* VPI tasks take PLI_BYTE* by the standard.
|
|
||||||
*
|
|
||||||
* Revision 1.6 2006/10/30 22:45:37 steve
|
|
||||||
* Updates for Cygwin portability (pr1585922)
|
|
||||||
*
|
|
||||||
* Revision 1.5 2004/10/04 01:10:58 steve
|
|
||||||
* Clean up spurious trailing white space.
|
|
||||||
*
|
|
||||||
* Revision 1.4 2002/08/12 01:35:05 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.3 2002/08/11 23:47:04 steve
|
|
||||||
* Add missing Log and Ident strings.
|
|
||||||
*
|
|
||||||
* Revision 1.2 2002/08/10 17:00:31 steve
|
|
||||||
* Allow vpiIntegerVar as parameter to $value$plusarg
|
|
||||||
*
|
|
||||||
* Revision 1.1 2002/04/07 04:37:53 steve
|
|
||||||
* Add $plusargs system functions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ unsigned is_numeric_obj(vpiHandle obj)
|
||||||
case vpiRealVar:
|
case vpiRealVar:
|
||||||
case vpiReg:
|
case vpiReg:
|
||||||
case vpiTimeVar:
|
case vpiTimeVar:
|
||||||
rtn = 1;;
|
rtn = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ unsigned is_string_obj(vpiHandle obj)
|
||||||
case vpiPartSelect:
|
case vpiPartSelect:
|
||||||
case vpiReg:
|
case vpiReg:
|
||||||
case vpiTimeVar:
|
case vpiTimeVar:
|
||||||
rtn = 1;;
|
rtn = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ PLI_INT32 sys_no_arg_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -176,7 +176,7 @@ PLI_INT32 sys_one_numeric_arg_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* Check that there is an argument and that it is numeric. */
|
/* Check that there is an argument and that it is numeric. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a single numeric argument.\n", name);
|
vpi_printf("%s requires a single numeric argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -184,7 +184,7 @@ PLI_INT32 sys_one_numeric_arg_compiletf(PLI_BYTE8 *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's argument must be numeric.\n", name);
|
vpi_printf("%s's argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -195,7 +195,7 @@ PLI_INT32 sys_one_numeric_arg_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ PLI_INT32 sys_one_opt_numeric_arg_compiletf(PLI_BYTE8 *name)
|
||||||
if (argv == 0) return 0;
|
if (argv == 0) return 0;
|
||||||
|
|
||||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's argument must be numeric.\n", name);
|
vpi_printf("%s's argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -232,7 +232,7 @@ PLI_INT32 sys_one_opt_numeric_arg_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -258,7 +258,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* Check that there are two argument and that they are numeric. */
|
/* Check that there are two argument and that they are numeric. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires two numeric arguments.\n", name);
|
vpi_printf("%s requires two numeric arguments.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -266,7 +266,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's first argument must be numeric.\n", name);
|
vpi_printf("%s's first argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -274,7 +274,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (! arg) {
|
if (! arg) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a second (numeric) argument.\n", name);
|
vpi_printf("%s requires a second (numeric) argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -282,7 +282,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_numeric_obj(arg)) {
|
if (! is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's second argument must be numeric.\n", name);
|
vpi_printf("%s's second argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -293,7 +293,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -317,14 +317,14 @@ PLI_INT32 sys_one_string_arg_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* Check that there is an argument and that it is a string. */
|
/* Check that there is an argument and that it is a string. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s requires a single string argument.\n", name);
|
vpi_printf("%s requires a single string argument.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! is_string_obj(vpi_scan(argv))) {
|
if (! is_string_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's argument must be a string.\n", name);
|
vpi_printf("%s's argument must be a string.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -335,7 +335,7 @@ PLI_INT32 sys_one_string_arg_compiletf(PLI_BYTE8 *name)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ static void open_dumpfile(vpiHandle callh)
|
||||||
dump_file = fopen(dump_path, "w");
|
dump_file = fopen(dump_path, "w");
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
vpi_printf("VCD Error: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("VCD Error: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -677,7 +677,7 @@ static int draw_scope(vpiHandle item, vpiHandle callh)
|
||||||
case vpiNamedFork: type = "fork"; break;
|
case vpiNamedFork: type = "fork"; break;
|
||||||
case vpiModule: type = "module"; break;
|
case vpiModule: type = "module"; break;
|
||||||
default:
|
default:
|
||||||
vpi_printf("VCD Error: %s line %d: $dumpvars: Unsupported scope "
|
vpi_printf("VCD Error: %s:%d: $dumpvars: Unsupported scope "
|
||||||
"type (%d)\n", vpi_get_str(vpiFile, callh),
|
"type (%d)\n", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh), vpi_get(vpiType, item));
|
(int)vpi_get(vpiLineNo, callh), vpi_get(vpiType, item));
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
|
||||||
|
|
||||||
/* We must have at least one argument. */
|
/* We must have at least one argument. */
|
||||||
if (argv == 0) {
|
if (argv == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("$simparam%s requires a string argument.\n", name_ext);
|
vpi_printf("$simparam%s requires a string argument.\n", name_ext);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -54,7 +54,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
|
||||||
/* The first argument must be a string. */
|
/* The first argument must be a string. */
|
||||||
arg = vpi_scan(argv);
|
arg = vpi_scan(argv);
|
||||||
if (! is_string_obj(arg)) {
|
if (! is_string_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("The first argument to $simparam%s must be a string.\n",
|
vpi_printf("The first argument to $simparam%s must be a string.\n",
|
||||||
name_ext);
|
name_ext);
|
||||||
|
|
@ -68,7 +68,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
|
||||||
/* For the string version the default must also be a string. */
|
/* For the string version the default must also be a string. */
|
||||||
if (strcmp(name_ext, "$str") == 0) {
|
if (strcmp(name_ext, "$str") == 0) {
|
||||||
if (! is_string_obj(arg)) {
|
if (! is_string_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("When provided, the second argument to $simparam%s"
|
vpi_printf("When provided, the second argument to $simparam%s"
|
||||||
"must be a string.\n", name_ext);
|
"must be a string.\n", name_ext);
|
||||||
|
|
@ -77,7 +77,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
|
||||||
/* For the rest the default must be numeric. */
|
/* For the rest the default must be numeric. */
|
||||||
} else {
|
} else {
|
||||||
if (! is_numeric_obj(arg)) {
|
if (! is_numeric_obj(arg)) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("When provided, the second argument to $simparam%s"
|
vpi_printf("When provided, the second argument to $simparam%s"
|
||||||
"must be numeric.\n", name_ext);
|
"must be numeric.\n", name_ext);
|
||||||
|
|
@ -90,7 +90,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
|
||||||
char msg [64];
|
char msg [64];
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
|
||||||
snprintf(msg, 64, "ERROR: %s line %d:",
|
snprintf(msg, 64, "ERROR: %s:%d:",
|
||||||
vpi_get_str(vpiFile, callh),
|
vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ static PLI_INT32 simparam_calltf(PLI_BYTE8 *name_ext)
|
||||||
retval = 8.0*sizeof(long);
|
retval = 8.0*sizeof(long);
|
||||||
} else {
|
} else {
|
||||||
if (! have_def_val) {
|
if (! have_def_val) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("$simparam%s unknown parameter name \"%s\".\n",
|
vpi_printf("$simparam%s unknown parameter name \"%s\".\n",
|
||||||
name_ext, param);
|
name_ext, param);
|
||||||
|
|
@ -229,7 +229,7 @@ static PLI_INT32 simparam_str_calltf(PLI_BYTE8 *name_ext)
|
||||||
vpi_handle(vpiScope,callh)));
|
vpi_handle(vpiScope,callh)));
|
||||||
} else {
|
} else {
|
||||||
if (defval == 0) {
|
if (defval == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("$simparam%s unknown parameter name \"%s\".\n",
|
vpi_printf("$simparam%s unknown parameter name \"%s\".\n",
|
||||||
name_ext, param);
|
name_ext, param);
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
|
||||||
|
|
||||||
/* The first argument is the numeric level. */
|
/* The first argument is the numeric level. */
|
||||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s's argument must be numeric.\n", name);
|
vpi_printf("%s's argument must be numeric.\n", name);
|
||||||
vpi_control(vpiFinish, 1);
|
vpi_control(vpiFinish, 1);
|
||||||
|
|
@ -215,7 +215,7 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
|
||||||
switch(vpi_get(vpiType, arg)) {
|
switch(vpi_get(vpiType, arg)) {
|
||||||
case vpiMemoryWord:
|
case vpiMemoryWord:
|
||||||
if (vpi_get(vpiConstantSelect, arg) == 0) {
|
if (vpi_get(vpiConstantSelect, arg) == 0) {
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s cannot dump a non-constant select %s.\n", name,
|
vpi_printf("%s cannot dump a non-constant select %s.\n", name,
|
||||||
vpi_get_str(vpiType, arg));
|
vpi_get_str(vpiType, arg));
|
||||||
|
|
@ -235,7 +235,7 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
|
||||||
case vpiRealVar:
|
case vpiRealVar:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
vpi_printf("%s cannot dump a %s.\n", name,
|
vpi_printf("%s cannot dump a %s.\n", name,
|
||||||
vpi_get_str(vpiType, arg));
|
vpi_get_str(vpiType, arg));
|
||||||
|
|
|
||||||
|
|
@ -562,8 +562,6 @@ extern unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4,
|
||||||
char *buf, unsigned int nbuf,
|
char *buf, unsigned int nbuf,
|
||||||
int signed_flag);
|
int signed_flag);
|
||||||
|
|
||||||
extern void vpip_bin_str_to_vec4(vvp_vector4_t&val,
|
|
||||||
const char*buf, bool signed_flag);
|
|
||||||
|
|
||||||
extern void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf,
|
extern void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf,
|
||||||
unsigned nbuf, bool signed_flag);
|
unsigned nbuf, bool signed_flag);
|
||||||
|
|
@ -571,8 +569,9 @@ extern void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf,
|
||||||
extern void vpip_vec4_to_oct_str(const vvp_vector4_t&bits, char*buf,
|
extern void vpip_vec4_to_oct_str(const vvp_vector4_t&bits, char*buf,
|
||||||
unsigned nbuf, bool signed_flag);
|
unsigned nbuf, bool signed_flag);
|
||||||
|
|
||||||
|
extern void vpip_bin_str_to_vec4(vvp_vector4_t&val, const char*buf);
|
||||||
extern void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str);
|
extern void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str);
|
||||||
extern void vpip_dec_str_to_vec4(vvp_vector4_t&val, const char*str, bool sign);
|
extern void vpip_dec_str_to_vec4(vvp_vector4_t&val, const char*str);
|
||||||
extern void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str);
|
extern void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str);
|
||||||
|
|
||||||
extern vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid);
|
extern vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid);
|
||||||
|
|
|
||||||
|
|
@ -136,23 +136,37 @@ static void real_var_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||||
|
|
||||||
static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int)
|
static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||||
{
|
{
|
||||||
|
vvp_vector4_t vec4(1024);
|
||||||
|
double result;
|
||||||
|
bool is_signed = false;
|
||||||
assert(ref->vpi_type->type_code == vpiRealVar);
|
assert(ref->vpi_type->type_code == vpiRealVar);
|
||||||
|
|
||||||
struct __vpiRealVar*rfp
|
|
||||||
= (struct __vpiRealVar*)ref;
|
|
||||||
|
|
||||||
vvp_net_ptr_t destination (rfp->net, 0);
|
|
||||||
|
|
||||||
switch (vp->format) {
|
switch (vp->format) {
|
||||||
|
|
||||||
case vpiRealVal:
|
case vpiRealVal:
|
||||||
vvp_send_real(destination, vp->value.real,
|
result = vp->value.real;
|
||||||
vthread_get_wt_context());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vpiIntVal:
|
case vpiIntVal:
|
||||||
vvp_send_real(destination, (double)vp->value.integer,
|
result = (double)vp->value.integer;
|
||||||
vthread_get_wt_context());
|
break;
|
||||||
|
case vpiBinStrVal:
|
||||||
|
vpip_bin_str_to_vec4(vec4, vp->value.str);
|
||||||
|
if (vp->value.str[0] == '-') is_signed = true;
|
||||||
|
vector4_to_value(vec4, result, is_signed);
|
||||||
|
break;
|
||||||
|
case vpiOctStrVal:
|
||||||
|
vpip_oct_str_to_vec4(vec4, vp->value.str);
|
||||||
|
if (vp->value.str[0] == '-') is_signed = true;
|
||||||
|
vector4_to_value(vec4, result, is_signed);
|
||||||
|
break;
|
||||||
|
case vpiDecStrVal:
|
||||||
|
vpip_dec_str_to_vec4(vec4, vp->value.str);
|
||||||
|
if (vp->value.str[0] == '-') is_signed = true;
|
||||||
|
vector4_to_value(vec4, result, is_signed);
|
||||||
|
break;
|
||||||
|
case vpiHexStrVal:
|
||||||
|
vpip_hex_str_to_vec4(vec4, vp->value.str);
|
||||||
|
if (vp->value.str[0] == '-') is_signed = true;
|
||||||
|
vector4_to_value(vec4, result, is_signed);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -160,8 +174,12 @@ static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||||
vp->format);
|
vp->format);
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
|
||||||
|
assert(rfp);
|
||||||
|
vvp_net_ptr_t destination (rfp->net, 0);
|
||||||
|
vvp_send_real(destination, result, vthread_get_wt_context());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -804,13 +804,13 @@ vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case vpiBinStrVal:
|
case vpiBinStrVal:
|
||||||
vpip_bin_str_to_vec4(val, vp->value.str, false);
|
vpip_bin_str_to_vec4(val, vp->value.str);
|
||||||
break;
|
break;
|
||||||
case vpiOctStrVal:
|
case vpiOctStrVal:
|
||||||
vpip_oct_str_to_vec4(val, vp->value.str);
|
vpip_oct_str_to_vec4(val, vp->value.str);
|
||||||
break;
|
break;
|
||||||
case vpiDecStrVal:
|
case vpiDecStrVal:
|
||||||
vpip_dec_str_to_vec4(val, vp->value.str, false);
|
vpip_dec_str_to_vec4(val, vp->value.str);
|
||||||
break;
|
break;
|
||||||
case vpiHexStrVal:
|
case vpiHexStrVal:
|
||||||
vpip_hex_str_to_vec4(val, vp->value.str);
|
vpip_hex_str_to_vec4(val, vp->value.str);
|
||||||
|
|
@ -821,6 +821,9 @@ vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid)
|
||||||
case vpiStringVal:
|
case vpiStringVal:
|
||||||
val = from_stringval(vp->value.str, wid);
|
val = from_stringval(vp->value.str, wid);
|
||||||
break;
|
break;
|
||||||
|
case vpiRealVal:
|
||||||
|
val = vvp_vector4_t(wid, vp->value.real);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "vvp internal error: put_value: "
|
fprintf(stderr, "vvp internal error: put_value: "
|
||||||
|
|
@ -877,7 +880,6 @@ vpiHandle vpip_make_reg(const char*name, int msb, int lsb,
|
||||||
bool signed_flag, vvp_net_t*vec)
|
bool signed_flag, vvp_net_t*vec)
|
||||||
{
|
{
|
||||||
vpiHandle obj = vpip_make_net(name, msb,lsb, signed_flag, vec);
|
vpiHandle obj = vpip_make_net(name, msb,lsb, signed_flag, vec);
|
||||||
struct __vpiSignal*rfp = (struct __vpiSignal*)obj;
|
|
||||||
obj->vpi_type = &vpip_reg_rt;
|
obj->vpi_type = &vpip_reg_rt;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
125
vvp/vpip_bin.cc
125
vvp/vpip_bin.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002-2006 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
|
||||||
#ident "$Id: vpip_bin.cc,v 1.4 2006/08/03 05:05:06 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
|
|
@ -31,69 +28,89 @@
|
||||||
#endif
|
#endif
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
void vpip_bin_str_to_vec4(vvp_vector4_t&vec4,
|
void vpip_bin_str_to_vec4(vvp_vector4_t&vec4, const char*buf)
|
||||||
const char*buf, bool signed_flag)
|
|
||||||
{
|
{
|
||||||
const char*ebuf = buf + strlen(buf);
|
const char*ebuf = buf + strlen(buf);
|
||||||
vvp_bit4_t last = BIT4_0;
|
|
||||||
|
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
|
unsigned skip_chars = 0;
|
||||||
|
const char*tbuf = buf;
|
||||||
|
/* Find the number of non-numeric characters. */
|
||||||
|
while (tbuf = strpbrk(tbuf, "-_")) {
|
||||||
|
skip_chars += 1;
|
||||||
|
tbuf += 1;
|
||||||
|
}
|
||||||
|
vvp_vector4_t tval(strlen(buf)-skip_chars);
|
||||||
while (ebuf > buf) {
|
while (ebuf > buf) {
|
||||||
vvp_bit4_t val;
|
|
||||||
|
|
||||||
if (idx == vec4.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
ebuf -= 1;
|
ebuf -= 1;
|
||||||
switch (*ebuf) {
|
/* Skip any "_" characters in the string. */
|
||||||
case '0': val = BIT4_0; break;
|
while (*ebuf == '_') {
|
||||||
case '1': val = BIT4_1; break;
|
ebuf -= 1;
|
||||||
case 'x':
|
assert(ebuf > buf);
|
||||||
case 'X': val = BIT4_X; break;
|
}
|
||||||
case 'z':
|
|
||||||
case 'Z': val = BIT4_Z; break;
|
/* If we find a "-" it must be at the head of the string. */
|
||||||
default: val = BIT4_0; break;
|
if (*ebuf == '-') {
|
||||||
|
if (ebuf != buf) assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(idx < tval.size());
|
||||||
|
switch (*ebuf) {
|
||||||
|
case '0':
|
||||||
|
tval.set_bit(idx, BIT4_0);
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
tval.set_bit(idx, BIT4_1);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
tval.set_bit(idx, BIT4_X);
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
case 'Z':
|
||||||
|
tval.set_bit(idx, BIT4_Z);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Return "x" if there are invalid digits in the string. */
|
||||||
|
fprintf(stderr, "Warning: Invalid binary digit %c(%d) in "
|
||||||
|
"\"%s\".\n", *ebuf, *ebuf, buf);
|
||||||
|
for (unsigned idx = 0 ; idx < vec4.size() ; idx += 1) {
|
||||||
|
vec4.set_bit(idx, BIT4_X);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
last = val;
|
|
||||||
vec4.set_bit(idx, val);
|
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the pad value based on the top bit and the signed
|
/* Make a negative value when needed. */
|
||||||
flag. We may sign extend or zero extend. */
|
if (buf[0] == '-') {
|
||||||
switch (last) {
|
tval.invert();
|
||||||
case BIT4_0:
|
tval += (int64_t) 1;
|
||||||
last = BIT4_0;
|
}
|
||||||
|
|
||||||
|
/* Find the correct padding value. */
|
||||||
|
vvp_bit4_t pad;
|
||||||
|
switch (tval.value(tval.size()-1)) {
|
||||||
|
case BIT4_X: // Pad MSB 'x' with 'x'
|
||||||
|
pad = BIT4_X;
|
||||||
break;
|
break;
|
||||||
case BIT4_1:
|
case BIT4_Z: // Pad MSB 'z' with 'z'
|
||||||
last = signed_flag? BIT4_1 : BIT4_0;
|
pad = BIT4_Z;
|
||||||
break;
|
break;
|
||||||
case BIT4_X:
|
case BIT4_1: // If negative pad MSB '1' with '1'
|
||||||
last = BIT4_X;
|
if (buf[0] == '-') {
|
||||||
break;
|
pad = BIT4_1;
|
||||||
case BIT4_Z:
|
break;
|
||||||
last = BIT4_Z;
|
}
|
||||||
|
default: // Everything else gets '0' padded/
|
||||||
|
pad = BIT4_0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (idx < vec4.size())
|
for (unsigned idx = 0 ; idx < vec4.size() ; idx += 1) {
|
||||||
vec4.set_bit(idx++, last);
|
if (idx < tval.size()) vec4.set_bit(idx, tval.value(idx));
|
||||||
|
else vec4.set_bit(idx, pad);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: vpip_bin.cc,v $
|
|
||||||
* Revision 1.4 2006/08/03 05:05:06 steve
|
|
||||||
* Fix infinite loop padding binary string to result.
|
|
||||||
*
|
|
||||||
* Revision 1.3 2006/02/21 05:31:54 steve
|
|
||||||
* Put strings for reg objects.
|
|
||||||
*
|
|
||||||
* Revision 1.2 2002/08/12 01:35:09 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.1 2002/05/11 04:39:35 steve
|
|
||||||
* Set and get memory words by string value.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,29 +33,30 @@ extern const char hex_digits[256];
|
||||||
void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
|
void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
|
||||||
{
|
{
|
||||||
unsigned str_len = strlen(str);
|
unsigned str_len = strlen(str);
|
||||||
|
unsigned skip_chars = 0;
|
||||||
char pad = '0';
|
const char*tstr = str;
|
||||||
switch (str[0]) {
|
/* Find the number of non-numeric characters. */
|
||||||
case 'x':
|
while (tstr = strpbrk(tstr, "-_")) {
|
||||||
case 'X':
|
skip_chars += 1;
|
||||||
pad = 'x';
|
tstr += 1;
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
case 'Z':
|
|
||||||
pad = 'z';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
vvp_vector4_t tval(4*(str_len-skip_chars));
|
||||||
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
|
skip_chars = 0;
|
||||||
|
for (unsigned idx = 0 ; idx < tval.size() ; idx += 1) {
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
unsigned bit_off = idx%4;
|
unsigned bit_off = idx%4;
|
||||||
unsigned str_off = idx/4;
|
unsigned str_off = idx/4;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
if (str_off >= str_len)
|
|
||||||
ch = pad;
|
assert (str_off+skip_chars < str_len);
|
||||||
else
|
/* Skip any "_" characters in the string. */
|
||||||
ch = str[str_len-str_off-1];
|
while((ch = str[str_len-str_off-1-skip_chars]) == '_') {
|
||||||
|
skip_chars += 1;
|
||||||
|
assert (str_off+skip_chars < str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we find a "-" it must be at the head of the string. */
|
||||||
|
if (ch == '-') assert(0);
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '0':
|
case '0':
|
||||||
|
|
@ -69,7 +70,7 @@ void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
tmp = ch - '0';
|
tmp = ch - '0';
|
||||||
val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
tval.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'b':
|
case 'b':
|
||||||
|
|
@ -78,7 +79,7 @@ void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'f':
|
case 'f':
|
||||||
tmp = ch - 'a' + 10;
|
tmp = ch - 'a' + 10;
|
||||||
val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
tval.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'B':
|
case 'B':
|
||||||
|
|
@ -87,22 +88,58 @@ void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
|
||||||
case 'E':
|
case 'E':
|
||||||
case 'F':
|
case 'F':
|
||||||
tmp = ch - 'A' + 10;
|
tmp = ch - 'A' + 10;
|
||||||
val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
tval.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
val.set_bit(idx, BIT4_X);
|
tval.set_bit(idx, BIT4_X);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
case 'Z':
|
case 'Z':
|
||||||
val.set_bit(idx, BIT4_Z);
|
tval.set_bit(idx, BIT4_Z);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unsupported digit %c(%d).\n", ch, ch);
|
/* Return "x" if there are invalid digits in the string. */
|
||||||
assert(0);
|
fprintf(stderr, "Warning: Invalid hex digit %c(%d) in "
|
||||||
|
"\"%s\".\n", ch, ch, str);
|
||||||
|
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
|
||||||
|
val.set_bit(idx, BIT4_X);
|
||||||
|
}
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a negative value when needed. */
|
||||||
|
if (str[0] == '-') {
|
||||||
|
tval.invert();
|
||||||
|
tval += (int64_t) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the correct padding value. */
|
||||||
|
vvp_bit4_t pad;
|
||||||
|
switch (tval.value(tval.size()-1)) {
|
||||||
|
case BIT4_X: // Pad MSB 'x' with 'x'.
|
||||||
|
pad = BIT4_X;
|
||||||
|
break;
|
||||||
|
case BIT4_Z: // Pad MSB 'z' with 'z'.
|
||||||
|
pad = BIT4_Z;
|
||||||
|
break;
|
||||||
|
case BIT4_1: // If negative pad MSB '1' with '1'.
|
||||||
|
if (str[0] == '-') {
|
||||||
|
pad = BIT4_1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: // Everything else gets '0' padded.
|
||||||
|
pad = BIT4_0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the temporary value to the real value, padding if needed. */
|
||||||
|
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
|
||||||
|
if (idx < tval.size()) val.set_bit(idx, tval.value(idx));
|
||||||
|
else val.set_bit(idx, pad);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf,
|
void vpip_vec4_to_hex_str(const vvp_vector4_t&bits, char*buf,
|
||||||
|
|
|
||||||
|
|
@ -33,29 +33,30 @@ extern const char oct_digits[64];
|
||||||
void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str)
|
void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str)
|
||||||
{
|
{
|
||||||
unsigned str_len = strlen(str);
|
unsigned str_len = strlen(str);
|
||||||
|
unsigned skip_chars = 0;
|
||||||
char pad = '0';
|
const char*tstr = str;
|
||||||
switch (str[0]) {
|
/* Find the number of non-numeric characters. */
|
||||||
case 'x':
|
while (tstr = strpbrk(tstr, "-_")) {
|
||||||
case 'X':
|
skip_chars += 1;
|
||||||
pad = 'x';
|
tstr += 1;
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
case 'Z':
|
|
||||||
pad = 'z';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
vvp_vector4_t tval(3*(str_len-skip_chars));
|
||||||
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
|
skip_chars = 0;
|
||||||
|
for (unsigned idx = 0 ; idx < tval.size() ; idx += 1) {
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
unsigned bit_off = idx%3;
|
unsigned bit_off = idx%3;
|
||||||
unsigned str_off = idx/3;
|
unsigned str_off = idx/3;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
if (str_off >= str_len)
|
|
||||||
ch = pad;
|
assert(str_off+skip_chars < str_len);
|
||||||
else
|
/* Skip any "_" characters in the string. */
|
||||||
ch = str[str_len-str_off-1];
|
while ((ch = str[str_len-str_off-1-skip_chars]) == '_') {
|
||||||
|
skip_chars += 1;
|
||||||
|
assert(str_off+skip_chars < str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we find a "-" it must be at the head of the string. */
|
||||||
|
if (ch == '-') assert(0);
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '0':
|
case '0':
|
||||||
|
|
@ -67,22 +68,59 @@ void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str)
|
||||||
case '6':
|
case '6':
|
||||||
case '7':
|
case '7':
|
||||||
tmp = ch - '0';
|
tmp = ch - '0';
|
||||||
val.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
tval.set_bit(idx, ((tmp>>bit_off)&1)? BIT4_1 : BIT4_0);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
val.set_bit(idx, BIT4_X);
|
tval.set_bit(idx, BIT4_X);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
case 'Z':
|
case 'Z':
|
||||||
val.set_bit(idx, BIT4_Z);
|
tval.set_bit(idx, BIT4_Z);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unsupported digit %c(%d).\n", ch, ch);
|
/* Return "x" if there are invalid digits in the string. */
|
||||||
assert(0);
|
fprintf(stderr, "Warning: Invalid octal digit %c(%d) in "
|
||||||
|
"\"%s\".\n", ch, ch, str);
|
||||||
|
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
|
||||||
|
val.set_bit(idx, BIT4_X);
|
||||||
|
}
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a negative value when needed. */
|
||||||
|
if (str[0] == '-') {
|
||||||
|
tval.invert();
|
||||||
|
tval += (int64_t) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the correct padding value. */
|
||||||
|
vvp_bit4_t pad;
|
||||||
|
switch (tval.value(tval.size()-1)) {
|
||||||
|
case BIT4_X: // Pad MSB 'x' with 'x'
|
||||||
|
pad = BIT4_X;
|
||||||
|
break;
|
||||||
|
case BIT4_Z: // Pad MSB 'z' with 'z'
|
||||||
|
pad = BIT4_Z;
|
||||||
|
break;
|
||||||
|
case BIT4_1: // If negative pad MSB '1' with '1'
|
||||||
|
if (str[0] == '-') {
|
||||||
|
pad = BIT4_1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: // Everything else gets '0' padded.
|
||||||
|
pad = BIT4_0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the temporary value to the real value, padding if needed. */
|
||||||
|
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
|
||||||
|
if (idx < tval.size()) val.set_bit(idx, tval.value(idx));
|
||||||
|
else val.set_bit(idx, pad);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpip_vec4_to_oct_str(const vvp_vector4_t&bits, char*buf, unsigned nbuf,
|
void vpip_vec4_to_oct_str(const vvp_vector4_t&bits, char*buf, unsigned nbuf,
|
||||||
|
|
|
||||||
|
|
@ -220,26 +220,74 @@ unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
|
void vpip_dec_str_to_vec4(vvp_vector4_t&vec, const char*buf)
|
||||||
const char*buf, bool signed_flag)
|
|
||||||
{
|
{
|
||||||
|
/* Support for [xX]_*. */
|
||||||
|
if (buf[0] == 'x' || buf[0] == 'X') {
|
||||||
|
for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) {
|
||||||
|
vec.set_bit(idx, BIT4_X);
|
||||||
|
}
|
||||||
|
const char*tbuf = buf+1;
|
||||||
|
/* See if this is a valid constant. */
|
||||||
|
while (*tbuf) {
|
||||||
|
if (*tbuf != '_') {
|
||||||
|
fprintf(stderr, "Warning: Invalid decimal \"x\" "
|
||||||
|
"value \"%s\".\n", buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tbuf += 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support for [zZ]_*. */
|
||||||
|
if (buf[0] == 'z' || buf[0] == 'Z') {
|
||||||
|
const char*tbuf = buf+1;
|
||||||
|
/* See if this is a valid constant, if not return "x". */
|
||||||
|
while (*tbuf) {
|
||||||
|
if (*tbuf != '_') {
|
||||||
|
fprintf(stderr, "Warning: Invalid decimal \"z\" "
|
||||||
|
"value \"%s\".\n", buf);
|
||||||
|
for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) {
|
||||||
|
vec.set_bit(idx, BIT4_X);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tbuf += 1;
|
||||||
|
}
|
||||||
|
for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) {
|
||||||
|
vec.set_bit(idx, BIT4_Z);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* The str string is the decimal value with the least
|
/* The str string is the decimal value with the least
|
||||||
significant digit first. This loop creates that string by
|
significant digit first. This loop creates that string by
|
||||||
reversing the order of the buf string. For example, if the
|
reversing the order of the buf string. For example, if the
|
||||||
input is "1234", str gets "4321". */
|
input is "1234", str gets "4321". */
|
||||||
unsigned slen = strlen(buf);
|
unsigned slen = strlen(buf);
|
||||||
char*str = new char[slen + 1];
|
char*str = new char[slen + 1];
|
||||||
int is_negative = 0;
|
bool is_negative = false;
|
||||||
for (unsigned idx = 0 ; idx < slen ; idx += 1) {
|
for (unsigned idx = 0 ; idx < slen ; idx += 1) {
|
||||||
if (idx == slen-1 && buf[slen-idx-1] == '-') {
|
if (idx == slen-1 && buf[slen-idx-1] == '-') {
|
||||||
is_negative = 1;
|
is_negative = true;
|
||||||
slen--;
|
slen--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
while (buf[slen-idx-1] == '_') {
|
||||||
|
slen--;
|
||||||
|
}
|
||||||
if (isdigit(buf[slen-idx-1]))
|
if (isdigit(buf[slen-idx-1]))
|
||||||
str[idx] = buf[slen-idx-1];
|
str[idx] = buf[slen-idx-1];
|
||||||
else
|
else {
|
||||||
str[idx] = '0';
|
/* Return "x" if there are invalid digits in the string. */
|
||||||
|
fprintf(stderr, "Warning: Invalid decimal digit %c(%d) in "
|
||||||
|
"\"%s.\"\n", buf[slen-idx-1], buf[slen-idx-1], buf);
|
||||||
|
for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) {
|
||||||
|
vec.set_bit(idx, BIT4_X);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
str[slen] = 0;
|
str[slen] = 0;
|
||||||
|
|
@ -274,7 +322,7 @@ void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
|
||||||
|
|
||||||
if (is_negative) {
|
if (is_negative) {
|
||||||
vec.invert();
|
vec.invert();
|
||||||
vec += 1;
|
vec += (int64_t) 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[]str;
|
delete[]str;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue