diff --git a/vpi/Makefile.in b/vpi/Makefile.in index 4b8bca964..f9b28a57d 100644 --- a/vpi/Makefile.in +++ b/vpi/Makefile.in @@ -59,7 +59,8 @@ O = sys_table.o sys_convert.o sys_deposit.o sys_display.o sys_fileio.o \ sys_finish.o sys_icarus.o sys_plusargs.o sys_random.o sys_random_mti.o \ sys_readmem.o sys_readmem_lex.o sys_scanf.o sys_sdf.o \ sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o \ -mt19937int.o priv.o sdf_lexor.o sdf_parse.o stringheap.o +mt19937int.o sys_priv.o sdf_lexor.o sdf_parse.o stringheap.o \ +vams_simparam.o ifeq (@HAVE_LIBZ@,yes) ifeq (@HAVE_LIBBZ2@,yes) diff --git a/vpi/priv.c b/vpi/priv.c deleted file mode 100644 index 8d6b534cf..000000000 --- a/vpi/priv.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2003 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 - */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: priv.c,v 1.2 2003/10/06 21:26:27 steve Exp $" -#endif - -# include "sys_priv.h" - -PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time) -{ - PLI_UINT64 tmp; - - tmp = time->high; - tmp <<= 32; - tmp |= (PLI_UINT64) time->low; - return tmp; -} - -/* - * $Log: priv.c,v $ - * Revision 1.2 2003/10/06 21:26:27 steve - * Include sys_priv.h instead of priv.h - * - * Revision 1.1 2003/10/02 21:16:11 steve - * Include timerec_to_time64 implementation. - * - */ - diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 8b559fb15..7d29b13a5 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -60,16 +60,6 @@ struct strobe_cb_info { unsigned mcd; }; -int is_constant(vpiHandle obj) -{ - if (vpi_get(vpiType, obj) == vpiConstant) - return vpiConstant; - if (vpi_get(vpiType, obj) == vpiParameter) - return vpiParameter; - - return 0; -} - // The number of decimal digits needed to represent a // nr_bits binary number is floor(nr_bits*log_10(2))+1, // where log_10(2) = 0.30102999566398.... and I approximate @@ -665,7 +655,7 @@ static int format_str_char(vpiHandle scope, unsigned int mcd, return 0; } - if (is_constant(argv[idx]) + if (is_constant_obj(argv[idx]) && (vpi_get(vpiConstType, argv[idx]) == vpiRealConst)) { value.format = vpiRealVal; @@ -2187,12 +2177,7 @@ static PLI_INT32 sys_printtimescale_calltf(PLI_BYTE8*xx) vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle scope; if (!argv) { - vpiHandle parent = vpi_handle(vpiScope, sys); - scope = NULL; /* fallback value if parent is NULL */ - while (parent) { - scope = parent; - parent = vpi_handle(vpiScope, scope); - } + scope = sys_func_module(sys); } else { scope = vpi_scan(argv); vpi_free_object(argv); diff --git a/vpi/sys_fileio.c b/vpi/sys_fileio.c index 996566640..df07a2768 100644 --- a/vpi/sys_fileio.c +++ b/vpi/sys_fileio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-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: sys_fileio.c,v 1.10 2007/03/14 04:05:51 steve Exp $" -#endif # include "vpi_user.h" # include "sys_priv.h" @@ -60,7 +57,7 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8*name) return 0; } - if (! is_constant(item)) { + if (! is_constant_obj(item)) { vpi_printf("ERROR: %s mode argument must be a constant\n", name); vpi_control(vpiFinish, 1); } @@ -918,4 +915,3 @@ void sys_fileio_register() vpi_register_systf(&tf_data); } - diff --git a/vpi/sys_icarus.c b/vpi/sys_icarus.c index af92be7db..a493c2b06 100644 --- a/vpi/sys_icarus.c +++ b/vpi/sys_icarus.c @@ -16,38 +16,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "vpi_config.h" #include #include - - -/* - * Routine to return the width in bits of a CPU word (long). - */ -static PLI_INT32 vvp_cpu_wordsize_calltf(PLI_BYTE8* ud) -{ - vpiHandle callh = vpi_handle(vpiSysTfCall, 0); - assert(callh != 0); - s_vpi_value val; - (void) ud; /* Not used! */ - - /* Calculate the result */ - val.format = vpiIntVal; - val.value.integer = 8*sizeof(long); - - /* Return the result */ - vpi_put_value(callh, &val, 0, vpiNoDelay); - - return 0; -} - -static PLI_INT32 size_32(PLI_BYTE8* ud) -{ - (void) ud; /* Not used! */ - - return 32; -} - +#include "sys_priv.h" /* * Routine to finish the simulation and return a value to the @@ -56,8 +27,8 @@ static PLI_INT32 size_32(PLI_BYTE8* ud) static PLI_INT32 finish_and_return_compiletf(PLI_BYTE8* ud) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); + assert(callh); vpiHandle argv = vpi_iterate(vpiArgument, callh); - vpiHandle arg; (void) ud; /* Not used! */ /* We must have at least one argument. */ @@ -70,42 +41,19 @@ static PLI_INT32 finish_and_return_compiletf(PLI_BYTE8* ud) } /* This must be a numeric argument. */ - arg = vpi_scan(argv); - switch(vpi_get(vpiType, arg)) { - case vpiConstant: - case vpiParameter: - /* String constants are invalid numeric values. */ - if (vpi_get(vpiConstType, arg) == vpiStringConst) { - vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), - (int)vpi_get(vpiLineNo, callh)); - vpi_printf("The argument to $finish_and_return must be numeric.\n"); - vpi_control(vpiFinish, 1); - return 0; - } - break; - - case vpiIntegerVar: - case vpiMemoryWord: - case vpiNet: - case vpiRealVar: - case vpiReg: - case vpiTimeVar: - break; - - default: + if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("The argument to $finish_and_return must be numeric.\n"); vpi_control(vpiFinish, 1); return 0; - break; } /* We can only have one argument. */ if (vpi_scan(argv) != 0) { vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); - vpi_printf("$finish_and_return takes a single argument.\n"); + vpi_printf("$finish_and_return takes only a single argument.\n"); vpi_control(vpiFinish, 1); return 0; } @@ -142,15 +90,6 @@ void sys_special_register(void) { s_vpi_systf_data tf_data; - tf_data.type = vpiSysFunc; - tf_data.sysfunctype = vpiIntFunc; - tf_data.calltf = vvp_cpu_wordsize_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = size_32; - tf_data.tfname = "$vvp_cpu_wordsize"; - tf_data.user_data = 0; - vpi_register_systf(&tf_data); - tf_data.type = vpiSysTask; tf_data.calltf = finish_and_return_calltf; tf_data.compiletf = finish_and_return_compiletf; diff --git a/vpi/sys_priv.c b/vpi/sys_priv.c new file mode 100644 index 000000000..51625a214 --- /dev/null +++ b/vpi/sys_priv.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2003-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 + * 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 + */ + +#include +#include "sys_priv.h" + +PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time) +{ + PLI_UINT64 tmp; + + tmp = time->high; + tmp <<= 32; + tmp |= (PLI_UINT64) time->low; + + return tmp; +} + +/* + * This routine returns 1 if the argument is a constant value, + * otherwise it returns 0. + */ +unsigned is_constant_obj(vpiHandle obj) +{ + assert(obj); + unsigned rtn = 0; + + switch(vpi_get(vpiType, obj)) { + case vpiConstant: + case vpiParameter: + rtn = 1; + break; + } + + return rtn; +} + +/* + * This routine returns 1 if the argument supports has a numeric value, + * otherwise it returns 0. + */ +unsigned is_numeric_obj(vpiHandle obj) +{ + assert(obj); + unsigned rtn = 0; + + switch(vpi_get(vpiType, obj)) { + case vpiConstant: + case vpiParameter: + /* These cannot be a string constant. */ + if (vpi_get(vpiConstType, obj) != vpiStringConst) rtn = 1; + break; + + /* These can have a valid numeric value. */ + case vpiIntegerVar: + case vpiMemoryWord: + case vpiNet: + case vpiPartSelect: + case vpiRealVar: + case vpiReg: + case vpiTimeVar: + rtn = 1;; + break; + } + + return rtn; +} + + +/* + * This routine returns 1 if the argument supports a valid string value, + * otherwise it returns 0. + */ +unsigned is_string_obj(vpiHandle obj) +{ + assert(obj); + unsigned rtn = 0; + + switch(vpi_get(vpiType, obj)) { + case vpiConstant: + case vpiParameter: { + /* These must be a string or binary constant. */ + PLI_INT32 ctype = vpi_get(vpiConstType, obj); + if (ctype == vpiStringConst || ctype == vpiBinaryConst) rtn = 1; + break; + } + + /* These can have a valid string value. */ + case vpiIntegerVar: + case vpiMemoryWord: + case vpiNet: + case vpiPartSelect: + case vpiReg: + case vpiTimeVar: + rtn = 1;; + break; + } + + return rtn; +} + + +/* + * Find the enclosing module. + */ +vpiHandle sys_func_module(vpiHandle obj) +{ + assert(obj); + + while (vpi_get(vpiType, obj) != vpiModule) { + obj = vpi_handle(vpiScope, obj); + assert(obj); + } + + return obj; +} diff --git a/vpi/sys_priv.h b/vpi/sys_priv.h index 41d3bde52..31a09a7bd 100644 --- a/vpi/sys_priv.h +++ b/vpi/sys_priv.h @@ -1,7 +1,7 @@ #ifndef __vpi_sys_priv_H #define __vpi_sys_priv_H /* - * 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 @@ -18,12 +18,9 @@ * 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_priv.h,v 1.8 2007/03/14 04:05:51 steve Exp $" -#endif -# include "vpi_config.h" -# include "vpi_user.h" +#include "vpi_config.h" +#include "vpi_user.h" /* * Context structure for PRNG in mt19937int.c @@ -36,9 +33,6 @@ struct context_s { extern void sgenrand(struct context_s *context, unsigned long seed); extern unsigned long genrand(struct context_s *context); - -extern int is_constant(vpiHandle obj); - extern PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time); struct timeformat_info_s { @@ -50,4 +44,10 @@ struct timeformat_info_s { extern struct timeformat_info_s timeformat_info; +extern unsigned is_constant_obj(vpiHandle obj); +extern unsigned is_numeric_obj(vpiHandle obj); +extern unsigned is_string_obj(vpiHandle obj); + +extern vpiHandle sys_func_module(vpiHandle obj); + #endif diff --git a/vpi/sys_table.c b/vpi/sys_table.c index 9658a469e..4560744e7 100644 --- a/vpi/sys_table.c +++ b/vpi/sys_table.c @@ -38,6 +38,7 @@ extern void sys_time_register(); extern void sys_vcd_register(); extern void sys_vcdoff_register(); extern void sys_special_register(); +extern void vams_simparam_register(); #ifdef HAVE_LIBZ #ifdef HAVE_LIBBZ2 @@ -180,5 +181,6 @@ void (*vlog_startup_routines[])() = { sys_lxt_or_vcd_register, sys_sdf_register, sys_special_register, + vams_simparam_register, 0 }; diff --git a/vpi/sys_time.c b/vpi/sys_time.c index 2a1785805..034a7ce70 100644 --- a/vpi/sys_time.c +++ b/vpi/sys_time.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-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,36 +16,14 @@ * 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_time.c,v 1.12 2007/03/14 04:05:51 steve Exp $" -#endif -# include "vpi_config.h" +#include "vpi_config.h" -# include "vpi_user.h" -# include -# include -# include - -static vpiHandle module_of_function(vpiHandle obj) -{ - while (vpi_get(vpiType, obj) != vpiModule) { - obj = vpi_handle(vpiScope, obj); - assert(obj); - } - - return obj; -} - -static PLI_INT32 sys_time_sizetf(PLI_BYTE8*x) -{ - return 64; -} - -static PLI_INT32 sys_stime_sizetf(PLI_BYTE8*x) -{ - return 32; -} +#include "vpi_user.h" +#include +#include +#include +#include static PLI_INT32 sys_time_calltf(PLI_BYTE8*name) { @@ -60,7 +38,7 @@ static PLI_INT32 sys_time_calltf(PLI_BYTE8*name) call_handle = vpi_handle(vpiSysTfCall, 0); assert(call_handle); - mod = module_of_function(call_handle); + mod = sys_func_module(call_handle); now.type = vpiSimTime; vpi_get_time(0, &now); @@ -113,7 +91,7 @@ static PLI_INT32 sys_realtime_calltf(PLI_BYTE8*name) call_handle = vpi_handle(vpiSysTfCall, 0); assert(call_handle); - mod = module_of_function(call_handle); + mod = sys_func_module(call_handle); now.type = vpiSimTime; vpi_get_time(0, &now); @@ -134,82 +112,39 @@ void sys_time_register() { s_vpi_systf_data tf_data; - tf_data.type = vpiSysFunc; - tf_data.tfname = "$time"; - tf_data.calltf = sys_time_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = sys_time_sizetf; - tf_data.user_data = "$time"; + tf_data.type = vpiSysFunc; + tf_data.tfname = "$time"; + tf_data.sysfunctype = vpiTimeFunc; + tf_data.calltf = sys_time_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + tf_data.user_data = "$time"; vpi_register_systf(&tf_data); - tf_data.type = vpiSysFunc; - tf_data.tfname = "$realtime"; - tf_data.calltf = sys_realtime_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = 0; - tf_data.user_data = "$realtime"; + tf_data.type = vpiSysFunc; + tf_data.tfname = "$realtime"; + tf_data.sysfunctype = vpiRealFunc; + tf_data.calltf = sys_realtime_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + tf_data.user_data = "$realtime"; vpi_register_systf(&tf_data); - tf_data.type = vpiSysFunc; - tf_data.tfname = "$stime"; - tf_data.calltf = sys_time_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = sys_stime_sizetf; - tf_data.user_data = "$stime"; + tf_data.type = vpiSysFunc; + tf_data.tfname = "$stime"; + tf_data.sysfunctype = vpiIntFunc; + tf_data.calltf = sys_time_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + tf_data.user_data = "$stime"; vpi_register_systf(&tf_data); - tf_data.type = vpiSysFunc; - tf_data.tfname = "$simtime"; - tf_data.calltf = sys_time_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = sys_time_sizetf; - tf_data.user_data = "$simtime"; + tf_data.type = vpiSysFunc; + tf_data.tfname = "$simtime"; + tf_data.sysfunctype = vpiTimeFunc; + tf_data.calltf = sys_time_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + tf_data.user_data = "$simtime"; vpi_register_systf(&tf_data); } - -/* - * $Log: sys_time.c,v $ - * Revision 1.12 2007/03/14 04:05:51 steve - * VPI tasks take PLI_BYTE* by the standard. - * - * Revision 1.11 2006/10/30 22:45:37 steve - * Updates for Cygwin portability (pr1585922) - * - * Revision 1.10 2004/01/21 01:22:53 steve - * Give the vip directory its own configure and vpi_config.h - * - * Revision 1.9 2003/06/18 00:54:28 steve - * Account for all 64 bits in results of $time. - * - * Revision 1.8 2003/02/07 02:44:25 steve - * Properly round inter time values from $time. - * - * Revision 1.7 2003/01/28 04:41:55 steve - * Use more precise pow function to scale time by units. - * - * Revision 1.6 2003/01/27 00:14:37 steve - * Support in various contexts the $realtime - * system task. - * - * Revision 1.5 2002/12/21 00:55:58 steve - * The $time system task returns the integer time - * scaled to the local units. Change the internal - * implementation of vpiSystemTime the $time functions - * to properly account for this. Also add $simtime - * to get the simulation time. - * - * Revision 1.4 2002/08/12 01:35:05 steve - * conditional ident string using autoconfig. - * - * Revision 1.3 2002/01/11 05:20:59 steve - * Add the stime system function. - * - * Revision 1.2 2001/07/25 03:10:50 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.1 2000/11/01 03:19:36 steve - * Add the general $time system function. - * - */ - diff --git a/vpi/system.sft b/vpi/system.sft index 555f7cc37..d6ff0a311 100644 --- a/vpi/system.sft +++ b/vpi/system.sft @@ -14,4 +14,6 @@ $dist_poisson vpiSysFuncInt $dist_chi_square vpiSysFuncInt $dist_t vpiSysFuncInt $dist_erlang vpiSysFuncInt -$vvp_cpu_wordsize vpiSysFuncInt + +$simparam vpiSysFuncReal +$simparam$str vpiSysFuncSized 1024 unsigned diff --git a/vpi/vams_simparam.c b/vpi/vams_simparam.c new file mode 100644 index 000000000..6c0616de8 --- /dev/null +++ b/vpi/vams_simparam.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2008 Cary R. (cygcary@yahoo.com) + * + * This program is free software; you can redistribute it and/or modify + * it 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#ifdef HAVE_MALLOC_H +# include +#endif +#include +#include +#include +#include +#include +#include "sys_priv.h" + +/* Once we have real string objects replace this with a dynamic string. */ +#define MAX_STRING_RESULT 1024 + + +/* + * Check that the routines are called with the correct arguments. + */ +static PLI_INT32 simparam_compiletf(PLI_BYTE8* ud) +{ + vpiHandle callh = vpi_handle(vpiSysTfCall, 0); + assert(callh != 0); + vpiHandle argv = vpi_iterate(vpiArgument, callh); + vpiHandle arg; + + /* We must have at least one argument. */ + if (argv == 0) { + vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("$simparam%s requires an argument.\n", ud); + vpi_control(vpiFinish, 1); + return 0; + } + + /* 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), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("The first argument to $simparam%s must be a string.\n", ud); + vpi_control(vpiFinish, 1); + return 0; + } + + /* The second argument (default value) is optional. */ + arg = vpi_scan(argv); + if (arg == 0) return 0; + /* For the string version the default must also be a string. */ + if (strcmp(ud, "$str") == 0) { + if (! is_string_obj(arg)) { + vpi_printf("ERROR: %s line %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", ud); + vpi_control(vpiFinish, 1); + return 0; + } + /* 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), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("When provided the second argument to $simparam%s" + "must be numeric.\n", ud); + vpi_control(vpiFinish, 1); + return 0; + } + } + + /* We can only have two argument. */ + if (vpi_scan(argv) != 0) { + vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("$simparam%s takes at most two arguments.\n", ud); + vpi_control(vpiFinish, 1); + return 0; + } + + return 0; +} + +static PLI_INT32 simparam_calltf(PLI_BYTE8* ud) +{ + vpiHandle callh = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, callh); + vpiHandle arg; + s_vpi_value val; + char *param; + unsigned have_def_val = 0; + double retval, defval = 0.0; + + /* Get the parameter we are looking for. */ + arg = vpi_scan(argv); + val.format = vpiStringVal; + vpi_get_value(arg, &val); + param = strdup(val.value.str); + + /* See if there is a default value. */ + arg = vpi_scan(argv); + if (arg != 0) { + vpi_free_object(argv); + have_def_val = 1; + val.format = vpiRealVal; + vpi_get_value(arg, &val); + defval = val.value.real; + } + + /* Now check the various things we can return. */ + if (strcmp(param, "gdev") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "gmin") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "imax") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "imelt") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "iteration") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "scale") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "shrink") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "simulatorSubversion") == 0) { + retval = 0.0; + } else if (strcmp(param, "simulatorVersion") == 0) { + retval = 0.9; + } else if (strcmp(param, "sourceScaleFactor") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "tnom") == 0) { + retval = 0.0; /* Nothing for now. */ + } else if (strcmp(param, "timeUnit") == 0) { + retval = pow(10, vpi_get(vpiTimeUnit, sys_func_module(callh))); + } else if (strcmp(param, "timePrecision") == 0) { + retval = pow(10, vpi_get(vpiTimePrecision, sys_func_module(callh))); + } else if (strcmp(param, "CPUWordSize") == 0) { + retval = 8.0*sizeof(long); + } else { + if (! have_def_val) { + vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("unknown parameter name \"%s\".\n", param); + } + retval = defval; + } + + free(param); + + /* Return the value to the system. */ + val.format = vpiRealVal; + val.value.real = retval; + vpi_put_value(callh, &val, 0, vpiNoDelay); + + return 0; +} + +static PLI_INT32 simparam_str_calltf(PLI_BYTE8* ud) +{ + vpiHandle callh = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, callh); + vpiHandle arg; + s_vpi_value val; + char *param; + char *retval, *defval = NULL; + + /* Get the parameter we are looking for. */ + arg = vpi_scan(argv); + val.format = vpiStringVal; + vpi_get_value(arg, &val); + param = strdup(val.value.str); + + /* See if there is a default value. */ + arg = vpi_scan(argv); + if (arg != 0) { + vpi_free_object(argv); + val.format = vpiStringVal; + vpi_get_value(arg, &val); + defval = strdup(val.value.str); + } + + /* Now check the various things we can return. */ + /* For now we limit the result to 1024 characters. */ + if (strcmp(param, "analysis_name") == 0) { + retval = strdup("N/A"); /* Nothing for now. */ + } else if (strcmp(param, "analysis_type") == 0) { + retval = strdup("N/A"); /* Nothing for now. */ + } else if (strcmp(param, "cwd") == 0) { + char path [MAX_STRING_RESULT]; + char *ptr = getcwd(path, MAX_STRING_RESULT); + if (ptr == NULL) { + ptr = strcpy(path, ""); + } + retval = strdup(path); + } else if (strcmp(param, "module") == 0) { + retval = strdup(vpi_get_str(vpiDefName, sys_func_module(callh))); + } else if (strcmp(param, "instance") == 0) { + retval = strdup(vpi_get_str(vpiFullName, sys_func_module(callh))); + } else if (strcmp(param, "path") == 0) { + retval = strdup(vpi_get_str(vpiFullName, + vpi_handle(vpiScope,callh))); + } else { + if (defval == 0) { + vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("unknown parameter name \"%s\".\n", param); + defval = strdup(""); + } + retval = defval; + } + + free(param); + + /* Return the value to the system. */ + val.format = vpiStringVal; + val.value.str = retval; + vpi_put_value(callh, &val, 0, vpiNoDelay); + free(retval); + + return 0; +} + +static PLI_INT32 simparam_str_sizetf(PLI_BYTE8* ud) +{ + (void) ud; //* Not used! */ + + return MAX_STRING_RESULT; // 128 characters max! +} + +/* + * Register the function with Verilog. + */ +void vams_simparam_register(void) +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysFunc; + tf_data.sysfunctype = vpiRealFunc; + tf_data.calltf = simparam_calltf; + tf_data.compiletf = simparam_compiletf; + tf_data.sizetf = 0; + tf_data.tfname = "$simparam"; + tf_data.user_data = ""; + vpi_register_systf(&tf_data); + + tf_data.type = vpiSysFunc; + tf_data.sysfunctype = vpiSizedFunc; /* What should this be? */ + tf_data.calltf = simparam_str_calltf; + tf_data.compiletf = simparam_compiletf; + tf_data.sizetf = simparam_str_sizetf; /* Only 128 characters! */ + tf_data.tfname = "$simparam$str"; + tf_data.user_data = "$str"; + vpi_register_systf(&tf_data); +} diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index fdad4ffc3..403125406 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -198,7 +198,6 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int) } break; - case vpiScalarVal: switch (vp->value.scalar) { case vpi0: @@ -219,6 +218,29 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int) } break; + case vpiStringVal: { + unsigned len = strlen(vp->value.str) - 1; + assert(len*8 <= (unsigned)rfp->vwid); + for (unsigned wdx = 0 ; wdx < (unsigned)rfp->vwid ; wdx += 8) { + unsigned word = wdx / 8; + char bits; + if (word <= len) { + bits = vp->value.str[len-word]; + } else { + bits = 0; + } + for (unsigned idx = 0 ; (wdx+idx) < (unsigned)rfp->vwid && + idx < 8; idx += 1) { + vvp_bit4_t bit4 = BIT4_0; + if (bits & 1) bit4 = BIT4_1; + vthread_put_bit(vpip_current_vthread, + rfp->vbit+wdx+idx, bit4); + bits >>= 1; + } + } + break; + } + case vpiVectorVal: for (unsigned wdx = 0 ; wdx < (unsigned)rfp->vwid ; wdx += 32) {