Skip to content

Commit

Permalink
Add $plusargs system functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
steve committed Apr 7, 2002
1 parent fa97ba0 commit 07bee5c
Show file tree
Hide file tree
Showing 3 changed files with 342 additions and 4 deletions.
6 changes: 3 additions & 3 deletions vpi/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
333 changes: 333 additions & 0 deletions vpi/sys_plusargs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
/*
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* 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 <vpi_user.h>
# include <string.h>
# include <stdlib.h>
# include <assert.h>

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.
*
*/

7 changes: 6 additions & 1 deletion vpi/sys_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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();
Expand Down Expand Up @@ -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,
Expand All @@ -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.
*
Expand Down

0 comments on commit 07bee5c

Please sign in to comment.