Merge branch 'master' of ssh://steve-icarus@icarus.com/~steve-icarus/git/verilog

This commit is contained in:
Stephen Williams 2008-11-14 22:18:20 -08:00
commit 574c8a870d
20 changed files with 638 additions and 408 deletions

View File

@ -59,7 +59,7 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
scope = des->find_scope(scope, path_list);
if (scope->is_auto() && li) {
if (scope && scope->is_auto() && li) {
cerr << li->get_fileline() << ": error: Hierarchical "
"reference to automatically allocated item "
"`" << key << "' in path `" << path << "'" << endl;

View File

@ -446,22 +446,25 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
static vhdl_expr *translate_select(ivl_expr_t e)
{
vhdl_var_ref *from =
dynamic_cast<vhdl_var_ref*>(translate_expr(ivl_expr_oper1(e)));
if (NULL == from) {
error("Can only select from variable reference");
vhdl_expr *from = translate_expr(ivl_expr_oper1(e));
if (NULL == from)
return NULL;
}
ivl_expr_t o2 = ivl_expr_oper2(e);
if (o2) {
vhdl_var_ref *from_var_ref = dynamic_cast<vhdl_var_ref*>(from);
if (NULL == from_var_ref) {
error("Can only select from variable reference");
return NULL;
}
vhdl_expr *base = translate_expr(ivl_expr_oper2(e));
if (NULL == base)
return NULL;
vhdl_type integer(VHDL_TYPE_INTEGER);
from->set_slice(base->cast(&integer), ivl_expr_width(e) - 1);
return from;
from_var_ref->set_slice(base->cast(&integer), ivl_expr_width(e) - 1);
return from_var_ref;
}
else
return from->resize(ivl_expr_width(e));

View File

@ -275,12 +275,25 @@ static string make_safe_name(ivl_signal_t sig)
const char *base = ivl_signal_basename(sig);
if (base[0] == '_')
return string("VL") + base;
// This is the complete list of VHDL reserved words
const char *vhdl_reserved[] = {
"in", "out", "entity", "architecture", "inout", "array",
"is", "not", "and", "or", "bus", "bit", "line", // Etc...
"abs", "access", "after", "alias", "all", "and", "architecture",
"array", "assert", "attribute", "begin", "block", "body", "buffer",
"bus", "case", "component", "configuration", "constant", "disconnect",
"downto", "else", "elsif", "end", "entity", "exit", "file", "for",
"function", "generate", "generic", "group", "guarded", "if", "impure",
"in", "inertial", "inout", "is", "label", "library", "linkage",
"literal", "loop", "map", "mod", "nand", "new", "next", "nor", "not",
"null", "of", "on", "open", "or", "others", "out", "package", "port",
"postponed", "procedure", "process", "pure", "range", "record", "register",
"reject", "rem", "report", "return", "rol", "ror", "select", "severity",
"signal", "shared", "sla", "sll", "sra", "srl", "subtype", "then", "to",
"transport", "type", "unaffected", "units", "until", "use", "variable",
"wait", "when", "while", "with", "xnor", "xor",
NULL
};
for (const char **p = vhdl_reserved; *p != NULL; p++) {
if (strcasecmp(*p, base) == 0) {
return string("VL_") + base;

View File

@ -69,7 +69,7 @@ static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
/* We must have an argument. */
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));
vpi_printf("$clog2 requires one numeric argument.\n");
vpi_control(vpiFinish, 1);
@ -79,7 +79,7 @@ static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
/* The argument must be numeric. */
arg = vpi_scan(argv);
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));
vpi_printf("The first argument to $clog2 must be numeric.\n");
vpi_control(vpiFinish, 1);
@ -90,7 +90,7 @@ static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));

View File

@ -85,7 +85,7 @@ static void double2bits(double real, PLI_UINT32 bits[2])
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));
vpi_printf(msg, vpi_get_str(vpiName, callh));
vpi_control(vpiFinish, 1);

View File

@ -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. */
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));
vpi_printf("%s requires a string file name argument.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
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));
vpi_printf("%s's file name argument must be a string.\n", name);
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. */
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));
vpi_printf("%s's type argument must be a string.\n", name);
vpi_control(vpiFinish, 1);
@ -71,7 +71,7 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
@ -106,7 +106,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
vpi_get_value(mode, &val);
/* Verify that we have a string and that it is not NULL. */
if (val.format != vpiStringVal || !*(val.value.str)) {
vpi_printf("WARNING: %s line %d: ",
vpi_printf("WARNING: %s:%d: ",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
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. */
if (strlen(val.value.str) > 3) {
vpi_printf("WARNING: %s line %d: ",
vpi_printf("WARNING: %s:%d: ",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
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;
default:
vpi_printf("WARNING: %s line %d: ",
vpi_printf("WARNING: %s:%d: ",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
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. */
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));
vpi_printf("%s's file name argument is not a valid string.\n",
name);
@ -185,7 +185,7 @@ static PLI_INT32 sys_fopen_calltf(PLI_BYTE8*name)
for (idx = 0; idx < len; idx++) {
if (! isprint(val.value.str[idx])) {
char msg [64];
snprintf(msg, 64, "WARNING: %s line %d:",
snprintf(msg, 64, "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
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. */
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));
vpi_printf("%s's file name argument is not a valid string.\n",
name);
@ -251,7 +251,7 @@ static PLI_INT32 sys_fopenrwa_calltf(PLI_BYTE8*name)
for (idx = 0; idx < len; idx++) {
if (! isprint(val.value.str[idx])) {
char msg [64];
snprintf(msg, 64, "WARNING: %s line %d:",
snprintf(msg, 64, "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
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);
val.format = vpiIntVal;
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));
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
name);
@ -378,7 +378,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
* register and that the second is numeric.
*/
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));
vpi_printf("%s requires two arguments.\n", name);
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) {
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));
vpi_printf("%s's first argument must be a reg.\n", name);
vpi_control(vpiFinish, 1);
@ -394,7 +394,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
arg = vpi_scan(argv);
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));
vpi_printf("%s requires a second (numeric) argument.\n", name);
vpi_control(vpiFinish, 1);
@ -402,7 +402,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
}
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));
vpi_printf("%s's second argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -413,7 +413,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, 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. */
fp = vpi_get_file(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));
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
name);
@ -519,7 +519,7 @@ static PLI_INT32 sys_ungetc_calltf(PLI_BYTE8*name)
/* Return EOF if this is not a valid fd. */
fp = vpi_get_file(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));
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
name);
@ -545,7 +545,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
/* Check that there are three numeric arguments. */
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));
vpi_printf("%s requires three arguments.\n", name);
vpi_control(vpiFinish, 1);
@ -554,7 +554,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
/* Check that the first argument is numeric. */
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));
vpi_printf("%s's first argument must be numeric.\n", name);
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. */
arg = vpi_scan(argv);
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));
vpi_printf("%s requires a second (numeric) argument.\n", name);
vpi_control(vpiFinish, 1);
@ -571,7 +571,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
}
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));
vpi_printf("%s's second argument must be numeric.\n", name);
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. */
arg = vpi_scan(argv);
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));
vpi_printf("%s requires a third (numeric) argument.\n", name);
vpi_control(vpiFinish, 1);
@ -588,7 +588,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
}
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));
vpi_printf("%s's third argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -599,7 +599,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, 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. */
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));
vpi_printf("%s's operation must be 0, 1 or 2 given %d.\n",
name, oper);
@ -660,7 +660,7 @@ static PLI_INT32 sys_fseek_calltf(PLI_BYTE8*name)
/* Return EOF if this is not a valid fd. */
fp = vpi_get_file(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));
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
name);
@ -696,7 +696,7 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
/* Return EOF if this is not a valid fd. */
fp = vpi_get_file(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));
vpi_printf("invalid file descriptor (0x%x) given to %s.\n", fd_mcd,
name);
@ -721,7 +721,7 @@ static PLI_INT32 sys_common_fd_calltf(PLI_BYTE8*name)
val.value.integer = fgetc(fp);
break;
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));
vpi_printf("%s cannot be processed with this routine.\n", name);
assert(0);

View File

@ -435,7 +435,7 @@ static void open_dumpfile(vpiHandle callh)
dump_file = lt_init(dump_path);
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));
vpi_printf("Unable to open %s for output.\n", dump_path);
vpi_control(vpiFinish, 1);

View File

@ -433,7 +433,7 @@ static void open_dumpfile(vpiHandle callh)
dump_file = lxt2_wr_init(dump_path);
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));
vpi_printf("Unable to open %s for output.\n", dump_path);
vpi_control(vpiFinish, 1);

View File

@ -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
* 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
* 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 <string.h>
# include <stdlib.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
* passed to the $test$plusargs. If there is a simulator argument that
* 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 flag = 0;
size_t slen, len;
s_vpi_vlog_info info;
s_vpi_value value;
s_vpi_value result;
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle arg = vpi_scan(argv);
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh);
value.format = vpiStringVal;
vpi_get_value(arg, &value);
slen = strlen(value.value.str);
val.format = vpiStringVal;
vpi_get_value(vpi_scan(argv), &val);
slen = strlen(val.value.str);
vpi_get_vlog_info(&info);
@ -111,97 +56,52 @@ static PLI_INT32 sys_test_plusargs_calltf(PLI_BYTE8*xx)
if (len < slen)
continue;
if (strncmp(value.value.str, info.argv[idx]+1, slen) != 0)
if (strncmp(val.value.str, info.argv[idx]+1, slen) != 0)
continue;
flag = 1;
break;
}
result.format = vpiIntVal;
result.value.integer = flag;
vpi_put_value(sys, &result, 0, vpiNoDelay);
val.format = vpiIntVal;
val.value.integer = flag;
vpi_put_value(callh, &val, 0, vpiNoDelay);
vpi_free_object(argv);
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 sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh);
vpiHandle arg;
/* Check that there are arguments. */
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);
return 0;
}
/* Check that the first argument is a string. */
arg = vpi_scan(argv);
assert(arg != 0);
switch (vpi_get(vpiType, arg)) {
case vpiConstant:
if (vpi_get(vpiConstType, arg) != vpiStringConst) {
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");
if ( ! is_string_obj(arg)) {
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s's first argument must be a string.\n", name);
vpi_control(vpiFinish, 1);
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);
if (argv == 0) {
vpi_printf("ERROR: $value$plusargs requires two arguments\n");
if (! arg) {
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);
return 0;
}
@ -210,55 +110,129 @@ static PLI_INT32 sys_value_plusargs_compiletf(PLI_BYTE8*xx)
case vpiReg:
case vpiIntegerVar:
case vpiRealVar:
case vpiTimeVar:
break;
default:
vpi_printf("ERROR: value field doesn\'t match format: %s\n",
value.value.str);
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
(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);
return 0;
}
arg = vpi_scan(argv);
if (arg != 0) {
vpi_printf("ERROR: too many arguments to $value$plusargs\n");
/* Make sure there are no extra arguments. */
if (vpi_scan(argv) != 0) {
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);
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;
int idx;
int flag = 0;
size_t slen, len;
s_vpi_vlog_info info;
s_vpi_value format;
s_vpi_value result;
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle arg1 = vpi_scan(argv);
vpiHandle arg2 = vpi_scan(argv);
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh);
format.format = vpiStringVal;
vpi_get_value(arg1, &format);
fmt.format = vpiStringVal;
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);
cp = strchr(format.value.str, '%');
assert(cp);
slen = cp - format.value.str;
cp += 1;
if (*cp == '0')
cp += 1;
/* Look for a +arg that matches the prefix supplied. */
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] != '+')
continue;
@ -266,43 +240,146 @@ static PLI_INT32 sys_value_plusargs_calltf(PLI_BYTE8*xx)
if (len < slen)
continue;
if (strncmp(format.value.str, info.argv[idx]+1, slen) != 0)
if (strncmp(fmt.value.str, info.argv[idx]+1, slen) != 0)
continue;
sp = info.argv[idx]+1+slen;
sp_len = strlen(sp);
switch (*cp) {
case 'd':
result.format = vpiIntVal;
result.value.integer = strtoul(info.argv[idx]+1+slen,0,10);
case 'D':
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;
case 'o':
result.format = vpiIntVal;
result.value.integer = strtoul(info.argv[idx]+1+slen,0,8);
case 'O':
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;
case 'h':
result.format = vpiIntVal;
result.value.integer = strtoul(info.argv[idx]+1+slen,0,16);
case 'H':
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;
case 'b':
result.format = vpiIntVal;
result.value.integer = strtoul(info.argv[idx]+1+slen,0,12);
case 'B':
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;
case 's':
result.format = vpiStringVal;
result.value.str = info.argv[idx]+1+slen;
case 'S':
res.format = vpiStringVal;
res.value.str = sp;
break;
default:
assert(0);
}
vpi_put_value(arg2, &result, 0, vpiNoDelay);
vpi_put_value(vpi_scan(argv), &res, 0, vpiNoDelay);
flag = 1;
break;
}
result.format = vpiIntVal;
result.value.integer = flag;
vpi_put_value(sys, &result, 0, vpiNoDelay);
res.format = vpiIntVal;
res.value.integer = flag;
vpi_put_value(callh, &res, 0, vpiNoDelay);
vpi_free_object(argv);
return 0;
}
@ -311,44 +388,22 @@ void sys_plusargs_register()
s_vpi_systf_data tf_data;
tf_data.type = vpiSysFunc;
tf_data.tfname = "$test$plusargs";
tf_data.calltf = sys_test_plusargs_calltf;
tf_data.compiletf = sys_test_plusargs_compiletf;
tf_data.sizetf = sys_plusargs_sizetf;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiIntFunc;
tf_data.tfname = "$test$plusargs";
tf_data.calltf = sys_test_plusargs_calltf;
tf_data.compiletf = sys_one_string_arg_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = "$test$plusargs";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.tfname = "$value$plusargs";
tf_data.calltf = sys_value_plusargs_calltf;
tf_data.compiletf = sys_value_plusargs_compiletf;
tf_data.sizetf = sys_plusargs_sizetf;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiIntFunc;
tf_data.tfname = "$value$plusargs";
tf_data.calltf = sys_value_plusargs_calltf;
tf_data.compiletf = sys_value_plusargs_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = "$value$plusargs";
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.
*
*/

View File

@ -80,7 +80,7 @@ unsigned is_numeric_obj(vpiHandle obj)
case vpiRealVar:
case vpiReg:
case vpiTimeVar:
rtn = 1;;
rtn = 1;
break;
}
@ -114,7 +114,7 @@ unsigned is_string_obj(vpiHandle obj)
case vpiPartSelect:
case vpiReg:
case vpiTimeVar:
rtn = 1;;
rtn = 1;
break;
}
@ -152,7 +152,7 @@ PLI_INT32 sys_no_arg_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, 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. */
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));
vpi_printf("%s requires a single numeric argument.\n", name);
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))) {
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));
vpi_printf("%s's argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -195,7 +195,7 @@ PLI_INT32 sys_one_numeric_arg_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, 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 (! 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));
vpi_printf("%s's argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -232,7 +232,7 @@ PLI_INT32 sys_one_opt_numeric_arg_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, 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. */
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));
vpi_printf("%s requires two numeric arguments.\n", name);
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))) {
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));
vpi_printf("%s's first argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -274,7 +274,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
arg = vpi_scan(argv);
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));
vpi_printf("%s requires a second (numeric) argument.\n", name);
vpi_control(vpiFinish, 1);
@ -282,7 +282,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
}
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));
vpi_printf("%s's second argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -293,7 +293,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, 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. */
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));
vpi_printf("%s requires a single string argument.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
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));
vpi_printf("%s's argument must be a string.\n", name);
vpi_control(vpiFinish, 1);
@ -335,7 +335,7 @@ PLI_INT32 sys_one_string_arg_compiletf(PLI_BYTE8 *name)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));

View File

@ -378,7 +378,7 @@ static void open_dumpfile(vpiHandle callh)
dump_file = fopen(dump_path, "w");
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));
vpi_printf("Unable to open %s for output.\n", dump_path);
vpi_control(vpiFinish, 1);
@ -677,7 +677,7 @@ static int draw_scope(vpiHandle item, vpiHandle callh)
case vpiNamedFork: type = "fork"; break;
case vpiModule: type = "module"; break;
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),
(int)vpi_get(vpiLineNo, callh), vpi_get(vpiType, item));
assert(0);

View File

@ -44,7 +44,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
/* We must have at least one argument. */
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));
vpi_printf("$simparam%s requires a string argument.\n", name_ext);
vpi_control(vpiFinish, 1);
@ -54,7 +54,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
/* The first argument must be a string. */
arg = vpi_scan(argv);
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));
vpi_printf("The first argument to $simparam%s must be a string.\n",
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. */
if (strcmp(name_ext, "$str") == 0) {
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));
vpi_printf("When provided, the second argument to $simparam%s"
"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. */
} else {
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));
vpi_printf("When provided, the second argument to $simparam%s"
"must be numeric.\n", name_ext);
@ -90,7 +90,7 @@ static PLI_INT32 simparam_compiletf(PLI_BYTE8 *name_ext)
char msg [64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s line %d:",
snprintf(msg, 64, "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
@ -164,7 +164,7 @@ static PLI_INT32 simparam_calltf(PLI_BYTE8 *name_ext)
retval = 8.0*sizeof(long);
} else {
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));
vpi_printf("$simparam%s unknown parameter name \"%s\".\n",
name_ext, param);
@ -229,7 +229,7 @@ static PLI_INT32 simparam_str_calltf(PLI_BYTE8 *name_ext)
vpi_handle(vpiScope,callh)));
} else {
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));
vpi_printf("$simparam%s unknown parameter name \"%s\".\n",
name_ext, param);

View File

@ -204,7 +204,7 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
/* The first argument is the numeric level. */
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));
vpi_printf("%s's argument must be numeric.\n", name);
vpi_control(vpiFinish, 1);
@ -215,7 +215,7 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
switch(vpi_get(vpiType, arg)) {
case vpiMemoryWord:
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));
vpi_printf("%s cannot dump a non-constant select %s.\n", name,
vpi_get_str(vpiType, arg));
@ -235,7 +235,7 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
case vpiRealVar:
break;
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));
vpi_printf("%s cannot dump a %s.\n", name,
vpi_get_str(vpiType, arg));

View File

@ -562,8 +562,6 @@ extern unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4,
char *buf, unsigned int nbuf,
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,
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,
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_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 vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid);

View File

@ -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)
{
vvp_vector4_t vec4(1024);
double result;
bool is_signed = false;
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp
= (struct __vpiRealVar*)ref;
vvp_net_ptr_t destination (rfp->net, 0);
switch (vp->format) {
case vpiRealVal:
vvp_send_real(destination, vp->value.real,
vthread_get_wt_context());
result = vp->value.real;
break;
case vpiIntVal:
vvp_send_real(destination, (double)vp->value.integer,
vthread_get_wt_context());
result = (double)vp->value.integer;
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;
default:
@ -160,8 +174,12 @@ static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int)
vp->format);
assert(0);
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;
}

View File

@ -804,13 +804,13 @@ vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid)
}
break;
case vpiBinStrVal:
vpip_bin_str_to_vec4(val, vp->value.str, false);
vpip_bin_str_to_vec4(val, vp->value.str);
break;
case vpiOctStrVal:
vpip_oct_str_to_vec4(val, vp->value.str);
break;
case vpiDecStrVal:
vpip_dec_str_to_vec4(val, vp->value.str, false);
vpip_dec_str_to_vec4(val, vp->value.str);
break;
case vpiHexStrVal:
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:
val = from_stringval(vp->value.str, wid);
break;
case vpiRealVal:
val = vvp_vector4_t(wid, vp->value.real);
break;
default:
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)
{
vpiHandle obj = vpip_make_net(name, msb,lsb, signed_flag, vec);
struct __vpiSignal*rfp = (struct __vpiSignal*)obj;
obj->vpi_type = &vpip_reg_rt;
return obj;
}

View File

@ -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
* 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
* 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 "vpi_priv.h"
@ -31,69 +28,89 @@
#endif
# include <assert.h>
void vpip_bin_str_to_vec4(vvp_vector4_t&vec4,
const char*buf, bool signed_flag)
void vpip_bin_str_to_vec4(vvp_vector4_t&vec4, const char*buf)
{
const char*ebuf = buf + strlen(buf);
vvp_bit4_t last = BIT4_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) {
vvp_bit4_t val;
if (idx == vec4.size())
break;
ebuf -= 1;
switch (*ebuf) {
case '0': val = BIT4_0; break;
case '1': val = BIT4_1; break;
case 'x':
case 'X': val = BIT4_X; break;
case 'z':
case 'Z': val = BIT4_Z; break;
default: val = BIT4_0; break;
/* Skip any "_" characters in the string. */
while (*ebuf == '_') {
ebuf -= 1;
assert(ebuf > buf);
}
/* If we find a "-" it must be at the head of the string. */
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;
}
/* Calculate the pad value based on the top bit and the signed
flag. We may sign extend or zero extend. */
switch (last) {
case BIT4_0:
last = BIT4_0;
/* Make a negative value when needed. */
if (buf[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_1:
last = signed_flag? BIT4_1 : BIT4_0;
case BIT4_Z: // Pad MSB 'z' with 'z'
pad = BIT4_Z;
break;
case BIT4_X:
last = BIT4_X;
break;
case BIT4_Z:
last = BIT4_Z;
case BIT4_1: // If negative pad MSB '1' with '1'
if (buf[0] == '-') {
pad = BIT4_1;
break;
}
default: // Everything else gets '0' padded/
pad = BIT4_0;
break;
}
while (idx < vec4.size())
vec4.set_bit(idx++, last);
for (unsigned idx = 0 ; idx < vec4.size() ; idx += 1) {
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.
*
*/

View File

@ -33,29 +33,30 @@ extern const char hex_digits[256];
void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
{
unsigned str_len = strlen(str);
char pad = '0';
switch (str[0]) {
case 'x':
case 'X':
pad = 'x';
break;
case 'z':
case 'Z':
pad = 'z';
break;
unsigned skip_chars = 0;
const char*tstr = str;
/* Find the number of non-numeric characters. */
while (tstr = strpbrk(tstr, "-_")) {
skip_chars += 1;
tstr += 1;
}
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
vvp_vector4_t tval(4*(str_len-skip_chars));
skip_chars = 0;
for (unsigned idx = 0 ; idx < tval.size() ; idx += 1) {
unsigned tmp;
unsigned bit_off = idx%4;
unsigned str_off = idx/4;
char ch;
if (str_off >= str_len)
ch = pad;
else
ch = str[str_len-str_off-1];
assert (str_off+skip_chars < str_len);
/* Skip any "_" characters in the string. */
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) {
case '0':
@ -69,7 +70,7 @@ void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
case '8':
case '9':
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;
case 'a':
case 'b':
@ -78,7 +79,7 @@ void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
case 'e':
case 'f':
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;
case 'A':
case 'B':
@ -87,22 +88,58 @@ void vpip_hex_str_to_vec4(vvp_vector4_t&val, const char*str)
case 'E':
case 'F':
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;
case 'x':
case 'X':
val.set_bit(idx, BIT4_X);
tval.set_bit(idx, BIT4_X);
break;
case 'z':
case 'Z':
val.set_bit(idx, BIT4_Z);
tval.set_bit(idx, BIT4_Z);
break;
default:
fprintf(stderr, "Unsupported digit %c(%d).\n", ch, ch);
assert(0);
/* Return "x" if there are invalid digits in the string. */
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;
}
}
/* 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,

View File

@ -33,29 +33,30 @@ extern const char oct_digits[64];
void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str)
{
unsigned str_len = strlen(str);
char pad = '0';
switch (str[0]) {
case 'x':
case 'X':
pad = 'x';
break;
case 'z':
case 'Z':
pad = 'z';
break;
unsigned skip_chars = 0;
const char*tstr = str;
/* Find the number of non-numeric characters. */
while (tstr = strpbrk(tstr, "-_")) {
skip_chars += 1;
tstr += 1;
}
for (unsigned idx = 0 ; idx < val.size() ; idx += 1) {
vvp_vector4_t tval(3*(str_len-skip_chars));
skip_chars = 0;
for (unsigned idx = 0 ; idx < tval.size() ; idx += 1) {
unsigned tmp;
unsigned bit_off = idx%3;
unsigned str_off = idx/3;
char ch;
if (str_off >= str_len)
ch = pad;
else
ch = str[str_len-str_off-1];
assert(str_off+skip_chars < str_len);
/* Skip any "_" characters in the string. */
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) {
case '0':
@ -67,22 +68,59 @@ void vpip_oct_str_to_vec4(vvp_vector4_t&val, const char*str)
case '6':
case '7':
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;
case 'x':
case 'X':
val.set_bit(idx, BIT4_X);
tval.set_bit(idx, BIT4_X);
break;
case 'z':
case 'Z':
val.set_bit(idx, BIT4_Z);
tval.set_bit(idx, BIT4_Z);
break;
default:
fprintf(stderr, "Unsupported digit %c(%d).\n", ch, ch);
assert(0);
/* Return "x" if there are invalid digits in the string. */
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;
}
}
/* 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,

View File

@ -220,26 +220,74 @@ unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4,
return 0;
}
void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
const char*buf, bool signed_flag)
void vpip_dec_str_to_vec4(vvp_vector4_t&vec, const char*buf)
{
/* 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
significant digit first. This loop creates that string by
reversing the order of the buf string. For example, if the
input is "1234", str gets "4321". */
unsigned slen = strlen(buf);
char*str = new char[slen + 1];
int is_negative = 0;
bool is_negative = false;
for (unsigned idx = 0 ; idx < slen ; idx += 1) {
if (idx == slen-1 && buf[slen-idx-1] == '-') {
is_negative = 1;
is_negative = true;
slen--;
continue;
}
while (buf[slen-idx-1] == '_') {
slen--;
}
if (isdigit(buf[slen-idx-1]))
str[idx] = buf[slen-idx-1];
else
str[idx] = '0';
else {
/* 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;
@ -274,7 +322,7 @@ void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
if (is_negative) {
vec.invert();
vec += 1;
vec += (int64_t) 1;
}
delete[]str;