From ddea64445c5d48fc5b9c4386ff952a9838cb4dfa Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 26 Feb 2009 15:22:21 -0800 Subject: [PATCH] More compiletf cleanup and refactoring. This patch adds compiletf routines for the mti random functions and adds a common routine to check for extra arguments. It also adds file and line information to the rest of the compiletf routines that were missing them. --- vpi/sys_clog2.c | 4 +- vpi/sys_convert.c | 10 +-- vpi/sys_deposit.c | 38 +++++------ vpi/sys_display.c | 38 +---------- vpi/sys_fileio.c | 52 +-------------- vpi/sys_plusargs.c | 17 +---- vpi/sys_priv.c | 96 +++++++++------------------ vpi/sys_priv.h | 7 +- vpi/sys_random.c | 150 +++++++++++++++++++++++-------------------- vpi/sys_random.h | 30 +++++++++ vpi/sys_random_mti.c | 100 ++++++++++------------------- vpi/sys_readmem.c | 18 +----- 12 files changed, 209 insertions(+), 351 deletions(-) create mode 100644 vpi/sys_random.h diff --git a/vpi/sys_clog2.c b/vpi/sys_clog2.c index df85720bd..34c7442a3 100644 --- a/vpi/sys_clog2.c +++ b/vpi/sys_clog2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2008-2009 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 @@ -48,7 +48,7 @@ static unsigned is_numeric_obj(vpiHandle obj) case vpiRealVar: case vpiReg: case vpiTimeVar: - rtn = 1;; + rtn = 1; break; } diff --git a/vpi/sys_convert.c b/vpi/sys_convert.c index d55465791..d8dd175c6 100644 --- a/vpi/sys_convert.c +++ b/vpi/sys_convert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) + * Copyright (c) 2003-2009 Michael Ruff (mruff at chiaro.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 @@ -19,6 +19,7 @@ # include "vpi_config.h" # include "vpi_user.h" +# include "sys_priv.h" # include # include # include @@ -119,13 +120,8 @@ static PLI_INT32 sys_convert_compiletf(PLI_BYTE8*name) vpi_put_userdata(callh, (void *) arg); /* These functions only take one argument. */ - arg = vpi_scan(argv); - if (arg != 0) { - error_message(callh, "%s takes only one argument.\n"); - return 0; - } + check_for_extra_args(argv, callh, name, "one argument", 0); - /* vpi_scan() returning 0 (NULL) had already freed argv. */ return 0; } diff --git a/vpi/sys_deposit.c b/vpi/sys_deposit.c index e0170d075..401916aa2 100644 --- a/vpi/sys_deposit.c +++ b/vpi/sys_deposit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2000 Stephan Boettcher * * This source code is free software; you can redistribute it @@ -18,10 +18,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -# include "vpi_config.h" - +# include "vpi_config.h" # include "vpi_user.h" +# include "sys_priv.h" # include +# include static PLI_INT32 sys_deposit_compiletf(PLI_BYTE8 *name) { @@ -31,18 +32,22 @@ static PLI_INT32 sys_deposit_compiletf(PLI_BYTE8 *name) /* Check that there are arguments. */ if (argv == 0) { - vpi_printf("ERROR: %s requires two arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; + 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 there are at least two arguments. */ target = vpi_scan(argv); /* This should never be zero. */ value = vpi_scan(argv); if (value == 0) { - vpi_printf("ERROR: %s requires two arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; + 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; } assert(target); @@ -53,18 +58,15 @@ static PLI_INT32 sys_deposit_compiletf(PLI_BYTE8 *name) case vpiReg: break; default: - vpi_printf("ERROR: invalid target type for %s.\n", name); - vpi_control(vpiFinish, 1); - return 0; + vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("invalid target type (%s) for %s.\n", + vpi_get_str(vpiType, target), name); + vpi_control(vpiFinish, 1); } /* Check that there is at most two arguments. */ - target = vpi_scan(argv); - if (target != 0) { - vpi_printf("ERROR: %s takes at most two arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; - } + check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 0527a74c0..1bb5fd4d9 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -1685,24 +1685,7 @@ static PLI_INT32 sys_timeformat_compiletf(PLI_BYTE8*name) } /* 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 a single numeric argument.\n", msg, - name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, - argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "four arguments", 0); } return 0; @@ -1807,24 +1790,7 @@ static PLI_INT32 sys_printtimescale_compiletf(PLI_BYTE8*name) } /* 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 a single argument with a module.\n", - msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, - argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "one argument", 1); } return 0; diff --git a/vpi/sys_fileio.c b/vpi/sys_fileio.c index 24234cd99..58dd74f62 100644 --- a/vpi/sys_fileio.c +++ b/vpi/sys_fileio.c @@ -67,23 +67,7 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8 *name) } /* 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 at most two string arguments.\n", - msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "two string arguments", 1); return 0; } @@ -377,22 +361,7 @@ static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name) } /* 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); - } + check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } @@ -563,22 +532,7 @@ static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name) } /* 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 three arguments.\n", msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "three arguments", 0); return 0; } diff --git a/vpi/sys_plusargs.c b/vpi/sys_plusargs.c index 9c6d53934..09ee65f4a 100644 --- a/vpi/sys_plusargs.c +++ b/vpi/sys_plusargs.c @@ -124,22 +124,7 @@ static PLI_INT32 sys_value_plusargs_compiletf(PLI_BYTE8*name) } /* 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); - } + check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } diff --git a/vpi/sys_priv.c b/vpi/sys_priv.c index 926c1e710..231001d1a 100644 --- a/vpi/sys_priv.c +++ b/vpi/sys_priv.c @@ -34,7 +34,7 @@ PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time) return tmp; } -char * as_escaped(char *arg) +char *as_escaped(char *arg) { unsigned idx, cur, cnt, len = strlen(arg); char *res = (char *) malloc(sizeof(char *) * len); @@ -60,7 +60,7 @@ char * as_escaped(char *arg) * The result is duplicated so call free when the name is no * longer needed. Returns 0 (NULL) for an error. */ -char * get_filename(vpiHandle callh, char *name, vpiHandle file) +char *get_filename(vpiHandle callh, char *name, vpiHandle file) { s_vpi_value val; unsigned len, idx; @@ -101,6 +101,29 @@ char * get_filename(vpiHandle callh, char *name, vpiHandle file) return strdup(val.value.str); } +void check_for_extra_args(vpiHandle argv, vpiHandle callh, char *name, + char *arg_str, unsigned opt) +{ + /* Check that 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 %s%s.\n", msg, name, + opt ? "at most ": "", arg_str); + vpi_printf("%*s Found %u extra argument%s.\n", + (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); + vpi_control(vpiFinish, 1); + } +} + /* * This routine returns 1 if the argument is a constant value, * otherwise it returns 0. @@ -260,22 +283,7 @@ PLI_INT32 sys_one_numeric_arg_compiletf(PLI_BYTE8 *name) } /* 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 a single numeric argument.\n", msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "a single numeric argument", 0); return 0; } @@ -297,23 +305,7 @@ PLI_INT32 sys_one_opt_numeric_arg_compiletf(PLI_BYTE8 *name) } /* 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 at most one numeric argument.\n", - msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "one numeric argument", 1); return 0; } @@ -358,22 +350,7 @@ PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name) } /* 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 numeric arguments.\n", msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "two numeric arguments", 0); return 0; } @@ -400,22 +377,7 @@ PLI_INT32 sys_one_string_arg_compiletf(PLI_BYTE8 *name) } /* 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 a single string argument.\n", msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "a single string argument", 0); return 0; } diff --git a/vpi/sys_priv.h b/vpi/sys_priv.h index a5cc66ff6..07e2c60d6 100644 --- a/vpi/sys_priv.h +++ b/vpi/sys_priv.h @@ -35,8 +35,11 @@ extern unsigned long genrand(struct context_s *context); extern PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time); -extern char * as_escaped(char *arg); -extern char * get_filename(vpiHandle callh, char *name, vpiHandle file); +extern char *as_escaped(char *arg); +extern char *get_filename(vpiHandle callh, char *name, vpiHandle file); + +extern void check_for_extra_args(vpiHandle argv, vpiHandle callh, + char *name, char *arg_str, unsigned opt); struct timeformat_info_s { int units; diff --git a/vpi/sys_random.c b/vpi/sys_random.c index 866ab53c1..bf9f05e22 100644 --- a/vpi/sys_random.c +++ b/vpi/sys_random.c @@ -18,6 +18,7 @@ */ # include "sys_priv.h" +# include "sys_random.h" # include # include @@ -364,6 +365,30 @@ static double erlangian(long *seed, long k, long mean) return x; } +/* A seed can only be an integer/time variable or a register. */ +static unsigned is_seed_obj(vpiHandle obj, vpiHandle callh, char *name) +{ + unsigned rtn = 0; + + assert(obj); + + switch (vpi_get(vpiType, obj)) { + case vpiTimeVar: + case vpiIntegerVar: + case vpiReg: + rtn = 1; + break; + default: + vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("%s's seed must be an integer/time" + " variable or a register.\n", name); + vpi_control(vpiFinish, 1); + } + + return rtn; +} + static PLI_INT32 sys_rand_two_args_compiletf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); @@ -372,46 +397,43 @@ static PLI_INT32 sys_rand_two_args_compiletf(PLI_BYTE8 *name) /* Check that there are arguments. */ if (argv == 0) { - vpi_printf("ERROR: %s requires two arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; + 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 there are at least two arguments. */ seed = vpi_scan(argv); /* This should never be zero. */ arg2 = vpi_scan(argv); if (arg2 == 0) { - vpi_printf("ERROR: %s requires two arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; + 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; } /* The seed must be a time/integer variable or a register. */ - switch (vpi_get(vpiType, seed)) { - case vpiTimeVar: - case vpiIntegerVar: - case vpiReg: - break; - default: - vpi_printf("ERROR: %s's seed must be an integer/time" - " variable or a register.\n", name); - vpi_control(vpiFinish, 1); - return 0; + if (! is_seed_obj(seed, callh, name)) return 0; + + /* The second argument must be numeric. */ + if (! is_numeric_obj(arg2)) { + vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("%s second argument must be numeric.\n", name); + vpi_control(vpiFinish, 1); + return 0; } - /* These functions takes at most two argument. */ - seed = vpi_scan(argv); - if (seed != 0) { - vpi_printf("ERROR: %s takes at most two argument.\n", name); - vpi_control(vpiFinish, 1); - return 0; - } + /* Check that there is at most two arguments. */ + check_for_extra_args(argv, callh, name, "two arguments", 0); - /* vpi_scan returning 0 (NULL) has already freed argv. */ return 0; } -static PLI_INT32 sys_rand_three_args_compiletf(PLI_BYTE8 *name) +PLI_INT32 sys_rand_three_args_compiletf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); @@ -419,9 +441,11 @@ static PLI_INT32 sys_rand_three_args_compiletf(PLI_BYTE8 *name) /* Check that there are arguments. */ if (argv == 0) { - vpi_printf("ERROR: %s requires three arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; + 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); + return 0; } /* Check that there are at least three arguments. */ @@ -433,68 +457,54 @@ static PLI_INT32 sys_rand_three_args_compiletf(PLI_BYTE8 *name) arg3 = 0; } if (arg2 == 0 || arg3 == 0) { - vpi_printf("ERROR: %s requires three arguments.\n", name); - vpi_control(vpiFinish, 1); - return 0; + 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); + return 0; } /* The seed must be a time/integer variable or a register. */ - switch (vpi_get(vpiType, seed)) { - case vpiTimeVar: - case vpiIntegerVar: - case vpiReg: - break; - default: - vpi_printf("ERROR: %s's seed must be an integer/time" - " variable or a register.\n", name); - vpi_control(vpiFinish, 1); - return 0; + if (! is_seed_obj(seed, callh, name)) return 0; + + /* The second argument must be numeric. */ + if (! is_numeric_obj(arg2)) { + vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("%s second argument must be numeric.\n", name); + vpi_control(vpiFinish, 1); + return 0; } - /* These functions takes at most three argument. */ - seed = vpi_scan(argv); - if (seed != 0) { - vpi_printf("ERROR: %s takes at most three argument.\n", name); - vpi_control(vpiFinish, 1); - return 0; + /* The third argument must be numeric. */ + if (! is_numeric_obj(arg3)) { + vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), + (int)vpi_get(vpiLineNo, callh)); + vpi_printf("%s third argument must be numeric.\n", name); + vpi_control(vpiFinish, 1); + return 0; } - /* vpi_scan returning 0 (NULL) has already freed argv. */ + /* Check that there is at most three arguments. */ + check_for_extra_args(argv, callh, name, "three arguments", 0); + return 0; } -static PLI_INT32 sys_random_compiletf(PLI_BYTE8 *name) +PLI_INT32 sys_random_compiletf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); - vpiHandle seed; /* The seed is optional. */ if (argv == 0) return 0; - seed = vpi_scan(argv); /* The seed must be a time/integer variable or a register. */ - switch (vpi_get(vpiType, seed)) { - case vpiTimeVar: - case vpiIntegerVar: - case vpiReg: - break; - default: - vpi_printf("ERROR: %s's seed must be an integer/time" - " variable or a register.\n", name); - vpi_control(vpiFinish, 1); - return 0; - } + if (! is_seed_obj(vpi_scan(argv), callh, name)) return 0; - /* random takes at most one argument (the seed). */ - seed = vpi_scan(argv); - if (seed != 0) { - vpi_printf("ERROR: %s takes at most one argument.\n", name); - vpi_control(vpiFinish, 1); - return 0; - } + /* Check that there no extra arguments. */ + check_for_extra_args(argv, callh, name, "one argument", 1); - /* vpi_scan returning 0 (NULL) has already freed argv. */ return 0; } diff --git a/vpi/sys_random.h b/vpi/sys_random.h new file mode 100644 index 000000000..ca94b9c7d --- /dev/null +++ b/vpi/sys_random.h @@ -0,0 +1,30 @@ +#ifndef __vpi_sys_rand_H +#define __vpi_sys_rand_H +/* + * Copyright (c) 2000-2009 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 + +/* + * Common compiletf routines for the different random implementations. + */ +extern PLI_INT32 sys_rand_three_args_compiletf(PLI_BYTE8 *name); +extern PLI_INT32 sys_random_compiletf(PLI_BYTE8 *name); + +#endif diff --git a/vpi/sys_random_mti.c b/vpi/sys_random_mti.c index 8945ca9e8..7294e0f6a 100644 --- a/vpi/sys_random_mti.c +++ b/vpi/sys_random_mti.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2009 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,6 +18,7 @@ */ # include "sys_priv.h" +# include "sys_random.h" # include # include @@ -46,8 +47,7 @@ static struct context_s global_context = { static long mti_dist_uniform(long*seed, long start, long end) { - if (start >= end) - return start; + if (start >= end) return start; if ((start > LONG_MIN) || (end < LONG_MAX)) { long range = end - start; @@ -57,34 +57,18 @@ static long mti_dist_uniform(long*seed, long start, long end) } } - static PLI_INT32 sys_mti_dist_uniform_calltf(PLI_BYTE8*name) { + vpiHandle callh, argv, seed, start, end; s_vpi_value val; - vpiHandle call_handle; - vpiHandle argv; - vpiHandle seed = 0, start, end; - long i_seed, i_start, i_end; - call_handle = vpi_handle(vpiSysTfCall, 0); - assert(call_handle); - - argv = vpi_iterate(vpiArgument, call_handle); - if (argv == 0) { - vpi_printf("ERROR: %s requires parameters " - "(seed, start, end)\n", name); - return 0; - } - + /* Get the argument handles and convert them. */ + callh = vpi_handle(vpiSysTfCall, 0); + argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); - assert(seed); start = vpi_scan(argv); - assert(start); end = vpi_scan(argv); - assert(end); - - vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); @@ -96,74 +80,61 @@ static PLI_INT32 sys_mti_dist_uniform_calltf(PLI_BYTE8*name) vpi_get_value(end, &val); i_end = val.value.integer; - val.format = vpiIntVal; + /* Calculate and return the result. */ val.value.integer = mti_dist_uniform(&i_seed, i_start, i_end); - vpi_put_value(call_handle, &val, 0, vpiNoDelay); + vpi_put_value(callh, &val, 0, vpiNoDelay); - val.format = vpiIntVal; + /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); + vpi_free_object(argv); return 0; } -static PLI_INT32 sys_mti_dist_uniform_sizetf(PLI_BYTE8*x) -{ - return 32; -} - static PLI_INT32 sys_mti_random_calltf(PLI_BYTE8*name) { + vpiHandle callh, argv, seed = 0; s_vpi_value val; - vpiHandle call_handle; - vpiHandle argv; - vpiHandle seed = 0; - int i_seed = 0; + int i_seed = COOKIE; struct context_s *context; - call_handle = vpi_handle(vpiSysTfCall, 0); - assert(call_handle); - /* Get the argument list and look for a seed. If it is there, get the value and reseed the random number generator. */ - argv = vpi_iterate(vpiArgument, call_handle); + callh = vpi_handle(vpiSysTfCall, 0); + argv = vpi_iterate(vpiArgument, callh); + val.format = vpiIntVal; if (argv) { seed = vpi_scan(argv); vpi_free_object(argv); - - val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; /* Since there is a seed use the current context or create a new one */ - context = (struct context_s *)vpi_get_userdata(call_handle); + context = (struct context_s *)vpi_get_userdata(callh); if (!context) { context = (struct context_s *)calloc(1, sizeof(*context)); context->mti = NP1; - assert(context); /* squirrel away context */ - vpi_put_userdata(call_handle, (void *)context); + vpi_put_userdata(callh, (void *)context); } /* If the argument is not the Icarus cookie, then reseed context */ - if (i_seed != COOKIE) - sgenrand(context, i_seed); + if (i_seed != COOKIE) sgenrand(context, i_seed); } else { /* use global context */ context = &global_context; } - val.format = vpiIntVal; + /* Calculate and return the result */ val.value.integer = genrand(context); - - vpi_put_value(call_handle, &val, 0, vpiNoDelay); + vpi_put_value(callh, &val, 0, vpiNoDelay); /* mark seed with cookie */ if (seed && i_seed != COOKIE) { - val.format = vpiIntVal; val.value.integer = COOKIE; vpi_put_value(seed, &val, 0, vpiNoDelay); } @@ -171,29 +142,24 @@ static PLI_INT32 sys_mti_random_calltf(PLI_BYTE8*name) return 0; } -static PLI_INT32 sys_mti_random_sizetf(PLI_BYTE8*x) -{ - return 32; -} - void sys_random_mti_register() { s_vpi_systf_data tf_data; - tf_data.type = vpiSysFunc; - tf_data.tfname = "$mti_random"; - tf_data.calltf = sys_mti_random_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = sys_mti_random_sizetf; - tf_data.user_data = "$mti_random"; + tf_data.type = vpiSysFunc; + tf_data.sysfunctype = vpiSysFuncInt; + tf_data.tfname = "$mti_random"; + tf_data.calltf = sys_mti_random_calltf; + tf_data.compiletf = sys_random_compiletf; + tf_data.user_data = "$mti_random"; vpi_register_systf(&tf_data); - tf_data.type = vpiSysFunc; - tf_data.tfname = "$mti_dist_uniform"; - tf_data.calltf = sys_mti_dist_uniform_calltf; - tf_data.compiletf = 0; - tf_data.sizetf = sys_mti_dist_uniform_sizetf; - tf_data.user_data = "$mti_dist_uniform"; + tf_data.type = vpiSysFunc; + tf_data.sysfunctype = vpiSysFuncInt; + tf_data.tfname = "$mti_dist_uniform"; + tf_data.calltf = sys_mti_dist_uniform_calltf; + tf_data.compiletf = sys_rand_three_args_compiletf; + tf_data.user_data = "$mti_dist_uniform"; vpi_register_systf(&tf_data); } diff --git a/vpi/sys_readmem.c b/vpi/sys_readmem.c index ccbc9fd98..9d25d09a2 100644 --- a/vpi/sys_readmem.c +++ b/vpi/sys_readmem.c @@ -249,23 +249,7 @@ static PLI_INT32 sys_mem_compiletf(PLI_BYTE8*name) } /* 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 at most four arguments.\n", - msg, name); - vpi_printf("%*s Found %u extra argument%s.\n", - (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); - vpi_control(vpiFinish, 1); - } + check_for_extra_args(argv, callh, name, "four arguments", 1); return 0; }