diff --git a/vpi/Makefile.in b/vpi/Makefile.in index 47c34d50a..09d34eab0 100644 --- a/vpi/Makefile.in +++ b/vpi/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.30 2002/03/09 21:54:48 steve Exp $" +#ident "$Id: Makefile.in,v 1.31 2002/04/07 04:37:53 steve Exp $" # # SHELL = /bin/sh @@ -55,8 +55,8 @@ all: system.vpi $(CC) -Wall -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o mv $*.d dep -O = sys_table.o sys_deposit.o sys_display.o sys_finish.o sys_random.o \ -sys_readmem.o sys_readmem_lex.o sys_time.o sys_vcd.o \ +O = sys_table.o sys_deposit.o sys_display.o sys_finish.o sys_plusargs.o \ +sys_random.o sys_readmem.o sys_readmem_lex.o sys_time.o sys_vcd.o \ sys_lxt.o lxt_write.o \ mt19937int.o diff --git a/vpi/sys_plusargs.c b/vpi/sys_plusargs.c new file mode 100644 index 000000000..dd45d38d4 --- /dev/null +++ b/vpi/sys_plusargs.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2002 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ident "$Id: sys_plusargs.c,v 1.1 2002/04/07 04:37:53 steve Exp $" + +# include +# include +# include +# include + +static int sys_plusargs_sizetf(char*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 int sys_test_plusargs_compiletf(char*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_sim_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_sim_control(vpiFinish, 1); + return 0; + } + break; + + default: + vpi_printf("ERROR: Argument of $test$plusargs " + " must be a constant string.\n"); + vpi_sim_control(vpiFinish, 1); + return 0; + } + + + arg = vpi_scan(argv); + if (arg != 0) { + vpi_printf("ERROR: too many arguments to $test$plusargs\n"); + vpi_sim_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 int sys_test_plusargs_calltf(char*xx) +{ + 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); + + value.format = vpiStringVal; + vpi_get_value(arg, &value); + slen = strlen(value.value.str); + + vpi_get_vlog_info(&info); + + /* Look for a +arg that matches the prefix supplied. */ + for (idx = 0 ; idx < info.argc ; idx += 1) { + + /* Skip arguments that are not +args. */ + if (info.argv[idx][0] != '+') + continue; + + len = strlen(info.argv[idx]+1); + if (len < slen) + continue; + + if (strncmp(value.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); + + return 0; +} + +static int sys_value_plusargs_compiletf(char*xx) +{ + s_vpi_value value; + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + vpiHandle arg; + + if (argv == 0) { + vpi_printf("ERROR: $value$plusargs requires two arguments\n"); + vpi_sim_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: First argument of $value$plusargs " + " must be a constant string.\n"); + vpi_sim_control(vpiFinish, 1); + return 0; + } + break; + + default: + vpi_printf("ERROR: First argument of $value$plusargs " + " must be a constant string.\n"); + vpi_sim_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_sim_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_sim_control(vpiFinish, 1); + return 0; + } + + if (*cp != 0) { + vpi_printf("ERROR: Trailing junk after value format" + ": %s\n", fmt); + vpi_sim_control(vpiFinish, 1); + return 0; + } + } + + arg = vpi_scan(argv); + if (argv == 0) { + vpi_printf("ERROR: $value$plusargs requires two arguments\n"); + vpi_sim_control(vpiFinish, 1); + return 0; + } + + switch (vpi_get(vpiType, arg)) { + + case vpiReg: + break; + + default: + vpi_printf("ERROR: value field doesn\'t match format: %s\n", + value.value.str); + vpi_sim_control(vpiFinish, 1); + return 0; + } + + arg = vpi_scan(argv); + if (arg != 0) { + vpi_printf("ERROR: too many arguments to $value$plusargs\n"); + vpi_sim_control(vpiFinish, 1); + return 0; + } + + return 0; +} + +static int sys_value_plusargs_calltf(char*xx) +{ + 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); + + format.format = vpiStringVal; + vpi_get_value(arg1, &format); + + vpi_get_vlog_info(&info); + + cp = strchr(format.value.str, '%'); + assert(cp); + slen = cp - format.value.str; + + cp += 1; + if (*cp == '0') + cp += 1; + + for (idx = 0 ; idx < info.argc ; idx += 1) { + + if (info.argv[idx][0] != '+') + continue; + + len = strlen(info.argv[idx]+1); + if (len < slen) + continue; + + if (strncmp(format.value.str, info.argv[idx]+1, slen) != 0) + continue; + + switch (*cp) { + case 'd': + result.format = vpiIntVal; + result.value.integer = strtoul(info.argv[idx]+1+slen,0,10); + break; + case 'o': + result.format = vpiIntVal; + result.value.integer = strtoul(info.argv[idx]+1+slen,0,8); + break; + case 'h': + result.format = vpiIntVal; + result.value.integer = strtoul(info.argv[idx]+1+slen,0,16); + break; + case 'b': + result.format = vpiIntVal; + result.value.integer = strtoul(info.argv[idx]+1+slen,0,12); + break; + case 's': + result.format = vpiStringVal; + result.value.str = info.argv[idx]+1+slen; + break; + default: + assert(0); + } + + vpi_put_value(arg2, &result, 0, vpiNoDelay); + flag = 1; + break; + } + + result.format = vpiIntVal; + result.value.integer = flag; + vpi_put_value(sys, &result, 0, vpiNoDelay); + + return 0; +} + +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; + 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; + vpi_register_systf(&tf_data); + +} + +/* + * $Log: sys_plusargs.c,v $ + * Revision 1.1 2002/04/07 04:37:53 steve + * Add $plusargs system functions. + * + */ + diff --git a/vpi/sys_table.c b/vpi/sys_table.c index a1a217f8f..b6f5b3bbd 100644 --- a/vpi/sys_table.c +++ b/vpi/sys_table.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: sys_table.c,v 1.15 2002/04/06 21:33:29 steve Exp $" +#ident "$Id: sys_table.c,v 1.16 2002/04/07 04:37:53 steve Exp $" #endif # include "config.h" @@ -29,6 +29,7 @@ extern void sys_finish_register(); extern void sys_deposit_register(); extern void sys_display_register(); +extern void sys_plusargs_register(); extern void sys_random_register(); extern void sys_readmem_register(); extern void sys_time_register(); @@ -74,6 +75,7 @@ void (*vlog_startup_routines[])() = { sys_finish_register, sys_deposit_register, sys_display_register, + sys_plusargs_register, sys_random_register, sys_readmem_register, sys_time_register, @@ -84,6 +86,9 @@ void (*vlog_startup_routines[])() = { /* * $Log: sys_table.c,v $ + * Revision 1.16 2002/04/07 04:37:53 steve + * Add $plusargs system functions. + * * Revision 1.15 2002/04/06 21:33:29 steve * allow runtime selection of VCD vs LXT. *