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.
This commit is contained in:
parent
fa1160c4ab
commit
ddea64445c
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <stdio.h>
|
||||
# include <string.h>
|
||||
# include <math.h>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* 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 <assert.h>
|
||||
# include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
150
vpi/sys_random.c
150
vpi/sys_random.c
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
# include "sys_priv.h"
|
||||
# include "sys_random.h"
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <assert.h>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <vpi_user.h>
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -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 <vpi_user.h>
|
||||
# include <assert.h>
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue