增加pli的书和源代码

This commit is contained in:
fengbh 2025-03-04 09:56:46 +08:00
parent bd4cc71c66
commit 903d50d4d8
421 changed files with 25173 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,12 @@
TARGETS:
cd util; make
cd vpi; make
cd pli; make
clean:
cd util; make clean
cd vpi; make clean
cd pli; make clean
rm -f lib/*

View File

@ -0,0 +1,18 @@
ARCHDEBUG = -g
ARCHLIBFLAGS =
ARCHEXT = o
ARCHEXE =
ARCHCFLAGS = +Z -Aa -Ae
ARCHDEFINES =
ARCHDYNEXT = sl
ARCHDYNEXTL = sl
ARCLIB = a
ARCHDYNLD = -b
ARCHLDFLAG = -l
ARCHLDOUT = -o
ARCHCCOUT = -o
ARCHDYNLIB = -lm
ARCHPLILIB =
RM = rm
LD = ld

View File

@ -0,0 +1,15 @@
ARCHDEBUG = -g
ARCHLIBFLAGS =
ARCHEXT = o
ARCHEXE =
ARCHCFLAGS = -fPIC -Wall
ARCHDEFINES =
ARCHDYNEXT = so
ARCHDYNEXTL = so
ARCLIB = a
ARCHDYNLD = -G -export-dynamic
ARCHLDFLAG = -l
ARCHLDOUT = -o
ARCHCCOUT = -o
ARCHDYNLIB = -lm
ARCHPLILIB =

View File

@ -0,0 +1,15 @@
ARCHDEBUG = -g -xs
ARCHLIBFLAGS = -lsocket -lnsl
ARCHEXT = o
ARCHEXE =
ARCHCFLAGS = -KPIC
ARCHDEFINES = -DSUN4V
ARCHDYNEXT = so
ARCHDYNEXTL = so
ARCLIB = a
ARCHDYNLD = -G
ARCHLDFLAG = -l
ARCHLDOUT = -o
ARCHCCOUT = -o
ARCHDYNLIB = -lm
ARCHPLILIB =

View File

@ -0,0 +1,18 @@
MSD = ${MSDIR}\VC
ARCHDEBUG =
ARCHLIBFLAGS = wsock32.lib kernel32.lib
ARCHEXT = obj
ARCHEXE = .exe
ARCHCFLAGS = -I${MSD}\include
ARCHDEFINES = -DWINNT
ARCHDYNEXT = dll
ARCHDYNEXTL = lib
ARCLIB = a
ARCHDYNLD = /dll /pdb:none /debug
ARCHLDFLAG = lib
ARCHLDOUT = /out:
ARCHCCOUT = /Fe
ARCHDYNLIB = /libpath:${MSD}\lib wsock32.lib kernel32.lib
ARCHLDDYNEXT = .lib
ARCHPLILIB = ${PLILIB}

View File

@ -0,0 +1,67 @@
To be able to build and run these examples you will need to set two
environment variables, ARCH and PLIINC
ARCH - must be set to one of the following
linux for a pc running linux
sun4v for a solaris machine
hppa for a HP PA-RISK machine
winnt for either Win-95/98 or WINNT
PLIINC - must be set to contain the path to where the different PLI
include files are stored.
Windows (Win95/Win98/WinNT) need two other environment variabels set
MSDIR - Path to the microsoft compilier. ex D:/msdev/DevStudio
PLILIB - Path to the simulator's import library
ex:
d:/XYZ/tools/verilog/lib/verilog.lib (VerilogXL)
or
d:/XYZ/tools/lib/pliinterface.lib (NC-Verilog)
or
...
NOTE: The assumption is that you are running in something like the
MKS corn shell and have a real make installed in you search
path. Sorry I am a UNIX bigot at heart. Also seeing that I
was able to make one command "make" work on four different
platforms consistency was a good thing.
To get started type:
make
This will walk down to the util directory and build the different
common utility(s) that will be used by the different example(s). When
the build is completed the required libraries/objects will be copied
into the ./lib directory and the required include files into the
directory ./include.
It will then walk into the different PLI example directory(s) and build
the PLI/VPI code used by the exmple(s).
At this point you can cd to the directory vpi or pli /<example> and
read the file "README" in the given directory.
When you are done playing around and want to clean up you can type
make clean
from this directory. All the generated file will be removed.
**********************************************************************
All the include/Makefile/*.c/*.h files in this directory and lower
directories are free for the taking with no restriction on their usage
being imposed and or implied. While some testing has been done to
make sure the basic functionality works no guarantees are being made
either.
enjoy

View File

@ -0,0 +1,24 @@
=======================================================================
COPYRIGHTS AND OWNERSHIP AND DISCLAIMERS:
The electronic text files in the directory "socket_example_PC" are
provided by David Roberts. These files are provided with no
restrictions on usage, copying or distribution. David Roberts, and
Sutherland HDL, Inc. shall not be liable for damage in connection
with, or arising out of, the furnishing, performance or use of this
information.
This directory contains an example of using sockets to communicate
between a PLI application and another C program. This example was
created by David Roberts. Stuart Sutherland and Sutherland HDL have
no involvement in this example, beyond including the example with
the CD which accompanies "The PLI Handbook" by Stuart Sutherland.
Sutherland HDL includes this example on its web site for informational
purposes only. We hope you find the example useful in learning and
understanding the very complex topic of the Verilog Programming
Language Interface!
Stu Sutherland
=======================================================================

View File

@ -0,0 +1,16 @@
/*
* Use this to export symbols on the Windows Ports
*/
#ifdef WINNT
#ifdef EXPDEF
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif
#define DECLEXP __declspec(dllexport)
#define DECLIMP __declspec(dllimport)
#else
#define DECLSPEC
#define DECLEXP
#define DECLIMP
#endif

View File

@ -0,0 +1,12 @@
/*
* Use this to export symbols on the Windows Ports
*/
#ifdef WIN32
#ifdef EXPDEF
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif
#else
#define DECLSPEC
#endif

View File

@ -0,0 +1,66 @@
/*
* Make sure to import or export the library functions if we are running
* under windows (Win95/98 or WinNT)
*
* HP also has a default mode where we can TAG which symbols are to be
* exported.
*
* Project do the same for the HP port and remove the
*
*/
/*
* Get a line of data from the socket.
* If the arg "nb" is non 0 then do not block if there is no data.
*/
DECLSPEC
char *sockGetLine(int fd, int nb);
/*
* Put a line of data to the socket.
*/
DECLSPEC
int sockPutLine(int fd, char *buf);
/*
* Make a client socket connection to the specified port and host.
*
* A value of -1 will be returned if an error is detected.
*/
DECLSPEC
int sockMakeClient(int port, char *host);
/*
* Make server to accept a connection. If block is non zero the call will
* block socket blocking.
*
* A value of -1 will be returned if an error is detected.
*/
DECLSPEC
int sockMakeServer(int port, int block);
/*
* Accept a connection on a socket created by sockMakeServer. If the
* socket was created with blocking then the call will block until somebody
* connects to the socket.
*
* If there was a connection was made the point to a char * will contain
* the string identifying who made the connection.
*
* A value of -1 will be returned if an error is detected.
*/
DECLSPEC
int sockAcceptServer(int listener, char **who);
/*
* Shut a server socket down.
*/
DECLSPEC
void sockCloseServer(int fd, int listener);
/*
* Get the text for the last error generated from a call to the socket
* utility.
*/
DECLSPEC
char *sockGetLastError();

View File

@ -0,0 +1,6 @@
TARGETS:
cd dispargs; make
clean:
cd dispargs; make clean

View File

@ -0,0 +1,46 @@
UTILNAME = dispargs
BASEDIR = ../..
include ${BASEDIR}/Makefile.${ARCH}
UTILLIBS =
INCDIRS = -I${BASEDIR}/include -I${PLIINC}
#DFLAGS = ${ARCHDEBUG}
DFLAGs =
CFLAGS = ${ARCHDEFINES} ${ARCHCFLAGS} ${DFLAGS} ${ARCHGNU} ${INCDIRS}
TARGETS = \
${PLILIBS}
PLIOBJ = dispargs.${ARCHEXT}
PLILIBS = dispargs.${ARCHDYNEXT}
CFILES = \
${MODEL.${ARCHEXT}=.c}
.c.${ARCHEXT}:
$(CC) -c $< ${CFLAGS} ${ARCHLIBFLAGS} ${INCDIRS}
target: ${TARGETS}
dispargs.${ARCHDYNEXT}: dispargs.${ARCHEXT}
$(LD) ${ARCHDYNLD} ${ARCHLDOUT}dispargs.${ARCHDYNEXT} dispargs.${ARCHEXT} ${ARCHPLILIB} ${ARCHLIBFLAGS}
TAGS: ${CFILES} ${HFILES}
etags -tTa ${HFILES} ${CFILES}
clean:
-$(RM) *~ TAGS *.${ARCHEXT} ${UTILNAME}.tar* *.log *.key ${TARGETS}
ship:
-$(RM) ${UTILNAME}.tar.gz
tar -cvf ${UTILNAME}.tar Makefile ${CFILES} ${HFILES}
gzip ${UTILNAME}.tar
depend:
makedepend ${INCDIRS} ${CFILES}
# DO NOT DELETE

View File

@ -0,0 +1,7 @@
This example will dump all the command line arguments. It will also
dump out the contents of any -f <file> being used.
To run the test case:
<simulator> -f run.vc

View File

@ -0,0 +1,93 @@
#include <stdio.h>
#include "veriuser.h"
#include "vxl_veriuser.h"
#include "acc_user.h"
#include "com_exp.h"
int indent = 5;
static void processFileArgs(char **args)
{
int cnt;
io_printf(" %s\n", *args++);
indent += 5;
while(*args != NULL)
{
for (cnt=0;cnt<indent;cnt++)
{
io_printf(" ");
}
io_printf("%s", *args);
if (strcmp("-f", *args) == 0)
{
args++;
cnt++;
processFileArgs(((char **)*args));
}
else
{
io_printf("\n");
}
args++;
}
indent -= 5;
}
static int dispArgs(int data, int reason)
{
int cnt;
char **args;
int numArgs;
args = acc_fetch_argv();
numArgs = acc_fetch_argc();
io_printf("Commandline args used by the simulator: %s\n", *args);
args++;
for (cnt=1;cnt<numArgs;cnt++)
{
io_printf(" %s", *(args));
if (strcmp("-f", *args) == 0)
{
args++;
cnt++;
processFileArgs(((char **)*args));
}
else
{
io_printf("\n");
}
args++;
}
io_printf("\n\n");
return(0);
}
/*
* boot strap for
*
* +loadpli1=dispargs:regDispArgs
* or
* -loadpli1 dispargs:regDispArgs
*
* If using the old veriusertfs method cut and paste the first line
* below into your veriuserts array.
*
*/
static s_tfcell tfTasks[] =
{
{usertask, 0, NULL, NULL, dispArgs, NULL, "$dumpargs", 1},
{0}
};
DECLEXP
p_tfcell regDispArgs()
{
return(&tfTasks[0]);
}

View File

@ -0,0 +1,4 @@
-q
test.v
-f test1.vc
+loadpli1=./dispargs:regDispArgs

View File

@ -0,0 +1,7 @@
module top;
wire a;
initial
$dumpargs;
endmodule

View File

@ -0,0 +1,5 @@
+a
+b
+c
+d
-f test2.vc

View File

@ -0,0 +1,3 @@
+a2
+b2
+c2

View File

@ -0,0 +1,6 @@
TARGETS:
cd socket; make; make install
clean:
cd socket; make clean

View File

@ -0,0 +1,59 @@
UTILNAME = socketUtil
BASEDIR = ../..
include ${BASEDIR}/Makefile.${ARCH}
INCDIRS =
CFLAGS = ${ARCHDEFINES} ${ARCHCFLAGS} ${ARCHDEBUG} -I${BASEDIR}/include
SOCKETUTIL = \
socketUtil.${ARCHEXT}
SOCKETLIB = libSocketUtil.${ARCHDYNEXT}
SOCKETINC = socketUtil.h
INCS = \
${SOCKETINC}
LIBS = \
${SOCKETLIB}
TARGETS = \
${LIBS}
CFILES = \
${SOCKETUTIL:.${ARCHEXT}=.c}
HFILES = \
socketUtil.h
.c.${ARCHEXT}:
$(CC) -c $< -o $*.${ARCHEXT} ${CFLAGS} ${ARCHLIBFLAGS} ${INCDIRS}
all: ${TARGETS}
install: ${TARGETS}
cp ${LIBS} *.${ARCHDYNEXTL} ${BASEDIR}/lib
cp ${INCS} ${BASEDIR}/include
${SOCKETLIB}: ${SOCKETUTIL}
-$(RM) ${SOCKETLIB}
$(LD) ${ARCHDYNLD} ${ARCHLDOUT}${SOCKETLIB} ${SOCKETUTIL} ${ARCHLIBFLAGS}
TAGS: ${CFILES} ${HFILES}
etags -tTa ${HFILES} ${CFILES}
clean:
-$(RM) *~ TAGS *.${ARCHEXT} ${UTILNAME}.tar* ${TARGETS}
ship:
-$(RM) ${UTILNAME}.tar.gz
tar -cvf ${UTILNAME}.tar Makefile* ${CFILES} ${HFILES}
gzip ${UTILNAME}.tar
depend:
makedepend ${INCDIRS} ${CFILES}
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,8 @@
A general purpose utility to send/receive string data from different
machines using sockets.
To do:
Add a mode to the utility that uses the datagram level of sockets.
This sould be much faster the the present stream mode.

View File

@ -0,0 +1,326 @@
#define SOCKUTIL_C
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#ifndef WINNT
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#if defined(SUN4V)
#include <sys/file.h>
#endif
#else
#include <winsock.h>
#endif
#include <errno.h>
#include <string.h>
#define EXPDEF
#include "com_exp.h"
#include "socketUtil.h"
#undef EXPDEF
static char sockErrBuffer[1024];
static int initSocketInterface = 1; /* Initialize the socket environ if needed */
static int initSocket()
{
#ifdef WINNT
WORD wVersionRequested;WSADATA wsaData;int err;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/* Tell the user that we couldn't find a usable */
/* WinSock DLL. */
return(1);
}
/* Confirm that the WinSock DLL supports 2.0.*/
/* Note that if the DLL supports versions greater */
/* than 2.0 in addition to 2.0, it will still return */
/* 2.0 in wVersion since that is the version we */
/* requested. */
#if 0
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
/* Tell the user that we couldn't find a usable */
/* WinSock DLL. */
WSACleanup( );
return(1);
}
#endif
#endif
/* The WinSock DLL is acceptable. Proceed. */
return(0);
}
static struct sockaddr *mkSockAddr(unsigned int port, char *host)
{
static struct hostent *hp = NULL;
static struct sockaddr_in addrIn;
memset(&addrIn, 0, sizeof(addrIn));
/* If !host do not tie socket to a machine name */
if (host)
{
hp = gethostbyname(host);
if (!hp)
{
sprintf(&sockErrBuffer[0], "failed to aquire host info!\n");
return(NULL);
}
else
{
memcpy(&addrIn.sin_addr, hp->h_addr, hp->h_length);
addrIn.sin_family = hp->h_addrtype;
}
}
addrIn.sin_family = AF_INET;
addrIn.sin_port = htons((unsigned short)port);
return((struct sockaddr *)&addrIn);
}
int sockMakeClient(int port, char *host)
{
int fd;
struct sockaddr *servAddr;
int fdCon;
char *defaultHost = "localhost";
if (!host)
host = defaultHost;
if (initSocketInterface)
{
if (initSocket())
{
sprintf(&sockErrBuffer[0], "Sorry could not initialize the SOCKET interfacen!\n");
return(-1);
}
initSocketInterface=0;
}
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
#ifdef WINNT
int errorCode = WSAGetLastError();
sprintf(&sockErrBuffer[0], "ERROR code was: %d\n", errorCode);
#endif
sprintf(&sockErrBuffer[0], "Sorry barfed on creating a socket!\n%s\n",
strerror(errno));
return(-1);
}
servAddr = mkSockAddr(port, host);
if (!servAddr)
{
return(-1); /* Unable to grab the socket */
}
fdCon = connect(fd, servAddr, sizeof(struct sockaddr));
if (fdCon < 0)
{
return(-1);
}
return(fd);
}
int sockMakeServer(int port, int block)
{
int fd;
struct sockaddr *servAddr;
int retVal;
if (initSocketInterface)
{
if (initSocket())
{
sprintf(&sockErrBuffer[0], "Sorry could not initialize the SOCKET interfacen!\n");
return(-1);
}
initSocketInterface=0;
}
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
#ifdef WINNT
int errorCode = WSAGetLastError();
sprintf(&sockErrBuffer[0], "ERROR code was: %d\n", errorCode);
#endif
sprintf(&sockErrBuffer[0], "Sorry barfed on creating a socket!\n%s\n",
strerror(errno));
return(-1);
}
/* See if we need to make in non blocking */
if (!block)
{
#ifndef WINNT
if (fcntl(fd, F_SETFL, FNDELAY))
{
sprintf(&sockErrBuffer[0], "blocking was requested but could be granted!\n");
return(-1);
}
#endif
}
servAddr = mkSockAddr(port, NULL);
if (!servAddr)
{
return(-1);
}
retVal = bind(fd, servAddr, sizeof(struct sockaddr));
if (retVal != 0)
{
switch(errno)
{
case EBADF:
sprintf(&sockErrBuffer[0], "Server: bad sockfd!\n");
break;
case EINVAL:
sprintf(&sockErrBuffer[0], "Server: socket already bound!\n");
break;
default:
sprintf(&sockErrBuffer[0], "Server Failed to bind to a socket: %s!\n", strerror(errno));
break;
}
return(-1);
}
retVal = listen(fd, 100);
if (retVal != 0)
{
sprintf(&sockErrBuffer[0], "Server Failed to listen to a socket!\n");
return(-1);
}
return(fd);
}
int sockAcceptServer(int listener, char **who)
{
struct sockaddr servAddr;
int clientSize = sizeof(struct sockaddr);
int fd;
static char *buffer = NULL;
static int bufLen = 0;
fd = accept(listener, &servAddr, &clientSize);
if (who)
{
*who = NULL;
if (clientSize >=0)
{
/* See if we can figure out who has connected */
if (fd >=0)
{
struct hostent *hs;
hs = gethostbyaddr(
((char *) &((struct sockaddr_in *)&servAddr)->sin_addr.s_addr),
sizeof(long), AF_INET);
if (hs && hs->h_name)
{
if ((strlen(hs->h_name)+1) > bufLen)
{
bufLen = strlen(hs->h_name)+1;
buffer = malloc(bufLen);
}
strcpy(buffer, hs->h_name);
*who = buffer;
}
}
}
}
return(fd);
}
void sockCloseServer(int fd, int listener)
{
close(fd);
close(listener);
}
int sockPutLine(int fd, char *buf)
{
int retVal = 0;
static int stdTestOut = -1;
if (stdTestOut == -1)
stdTestOut = fileno(stdout);
if (fd == stdTestOut)
{
write(stdTestOut, buf, strlen(buf)+1);
}
else
{
retVal = send(fd, buf, strlen(buf)+1, 0);
}
return(retVal);
}
char *sockGetLine(int fd, int nb)
{
static char buffer[1024];
int cnt;
int status;
fd_set readfd;
struct timeval timeOut;
int retVal;
static int stdTestIn = -1;
if (stdTestIn == -1)
stdTestIn = fileno(stdin);
if (fd == stdTestIn)
{
int len;
fgets(&buffer[0], 1024, stdin);
len = strlen(&buffer[0]);
buffer[len-1] = '\0';
}
else
{
if (nb)
{
/* See if there is any data available */
FD_ZERO(&readfd);
FD_SET(fd, &readfd);
timeOut.tv_sec = 0;
timeOut.tv_usec = 0;
retVal = select(fd+1, &readfd, NULL, NULL, &timeOut);
if (retVal == 0)
return(NULL);
}
for (cnt=0;cnt<1024;cnt++)
{
status = recv(fd, &buffer[cnt], 1, 0);
if (status < 0)
{
/* Most likely the socket was shut down */
return(NULL);
}
if (buffer[cnt] == '\0')
return(&buffer[0]);
}
}
buffer[1023] = '\0';
return(&buffer[0]);
}
/*
* If somebody is interested give them the text from the last
* generated error.
*/
char *sockGetLastError()
{
return(&sockErrBuffer[0]);
}

View File

@ -0,0 +1,66 @@
/*
* Make sure to import or export the library functions if we are running
* under windows (Win95/98 or WinNT)
*
* HP also has a default mode where we can TAG which symbols are to be
* exported.
*
* Project do the same for the HP port and remove the
*
*/
/*
* Get a line of data from the socket.
* If the arg "nb" is non 0 then do not block if there is no data.
*/
DECLSPEC
char *sockGetLine(int fd, int nb);
/*
* Put a line of data to the socket.
*/
DECLSPEC
int sockPutLine(int fd, char *buf);
/*
* Make a client socket connection to the specified port and host.
*
* A value of -1 will be returned if an error is detected.
*/
DECLSPEC
int sockMakeClient(int port, char *host);
/*
* Make server to accept a connection. If block is non zero the call will
* block socket blocking.
*
* A value of -1 will be returned if an error is detected.
*/
DECLSPEC
int sockMakeServer(int port, int block);
/*
* Accept a connection on a socket created by sockMakeServer. If the
* socket was created with blocking then the call will block until somebody
* connects to the socket.
*
* If there was a connection was made the point to a char * will contain
* the string identifying who made the connection.
*
* A value of -1 will be returned if an error is detected.
*/
DECLSPEC
int sockAcceptServer(int listener, char **who);
/*
* Shut a server socket down.
*/
DECLSPEC
void sockCloseServer(int fd, int listener);
/*
* Get the text for the last error generated from a call to the socket
* utility.
*/
DECLSPEC
char *sockGetLastError();

View File

@ -0,0 +1,8 @@
TARGETS:
cd dispargs; make
cd remmodel; make
clean:
cd dispargs; make clean
cd remmodel; make clean

Binary file not shown.

View File

@ -0,0 +1,48 @@
UTILNAME = dispargs
BASEDIR = ../..
PLIINC = ../../pliinc
include ${BASEDIR}/Makefile.${ARCH}
UTILLIBS =
INCDIRS = -I${BASEDIR}/include -I${PLIINC}
DFLAGS = ${ARCHDEBUG}
#DFLAGs =
CFLAGS = ${ARCHDEFINES} ${ARCHCFLAGS} ${DFLAGS} ${ARCHGNU} ${INCDIRS}
TARGETS = \
${PLILIBS}
PLIOBJ = dispargs.${ARCHEXT}
PLILIBS = dispargs.${ARCHDYNEXT}
CFILES = \
${MODEL.${ARCHEXT}=.c}
.c.${ARCHEXT}:
$(CC) -c $< ${CFLAGS} ${ARCHLIBFLAGS} ${INCDIRS}
target: ${TARGETS}
dispargs.${ARCHDYNEXT}: dispargs.${ARCHEXT}
$(LD) ${ARCHDYNLD} ${ARCHLDOUT}dispargs.${ARCHDYNEXT} dispargs.${ARCHEXT} ${ARCHPLILIB} ${ARCHLIBFLAGS}
TAGS: ${CFILES} ${HFILES}
etags -tTa ${HFILES} ${CFILES}
clean:
-$(RM) *~ TAGS *.${ARCHEXT} ${UTILNAME}.tar* *.log *.key ${TARGETS}
ship:
-$(RM) ${UTILNAME}.tar.gz
tar -cvf ${UTILNAME}.tar Makefile ${CFILES} ${HFILES}
gzip ${UTILNAME}.tar
depend:
makedepend ${INCDIRS} ${CFILES}
# DO NOT DELETE

View File

@ -0,0 +1,7 @@
This example will dump all the command line arguments. It will also
dump out the contents of any -f <file> being used.
To run the test case:
<simulator> -f run.vc

View File

@ -0,0 +1,96 @@
#include <stdio.h>
#include "vpi_user.h"
#include "com_exp.h"
int indent = 5;
static void processFileArgs(char **args)
{
int cnt;
vpi_printf(" %s\n", *args++);
indent += 5;
while(*args != NULL)
{
for (cnt=0;cnt<indent;cnt++)
{
vpi_printf(" ");
}
vpi_printf("%s", *args);
if (strcmp("-f", *args) == 0)
{
args++;
cnt++;
processFileArgs(((char **)*args));
}
else
{
vpi_printf("\n");
}
args++;
}
indent -= 5;
}
static int dispArgs(p_cb_data cbData)
{
s_vpi_vlog_info vlogInfo;
int cnt;
char **args;
vpi_get_vlog_info(&vlogInfo);
args = vlogInfo.argv;
vpi_printf("Commandline args used by the simulator: %s\n", *args);
args++;
for (cnt=1;cnt<vlogInfo.argc;cnt++)
{
vpi_printf(" %s", *(args));
if (strcmp("-f", *args) == 0)
{
args++;
cnt++;
processFileArgs(((char **)*args));
}
else
{
vpi_printf("\n");
}
args++;
}
vpi_printf("\n\n");
return(0);
}
/*
* boot strap for
*
* +loadvpi=dispargs:regDispArgs
* or
* -loadvpi dispargs:regDispArgs
*
* If using the old vlog_start_array method add the routine regDispArgs
* to the array.
*
*/
DECLEXP
void regDispArgs()
{
s_cb_data cbData;
vpiHandle retHand;
cbData.reason = cbStartOfSimulation;
cbData.time = NULL;
cbData.value = NULL;
cbData.user_data = NULL;
cbData.cb_rtn = dispArgs;
retHand = vpi_register_cb(&cbData);
if (retHand)
{
vpi_free_object(retHand);
}
}

View File

@ -0,0 +1,4 @@
-q
test.v
-f test1.vc
+loadvpi=dispargs:regDispArgs

View File

@ -0,0 +1,4 @@
module top;
wire a;
endmodule

View File

@ -0,0 +1,5 @@
+a
+b
+c
+d
-f test2.vc

View File

@ -0,0 +1,3 @@
+a2
+b2
+c2

View File

@ -0,0 +1,59 @@
UTILNAME = dumpToServer
BASEDIR = ../..
PLIINC = ../../pliinc
include ${BASEDIR}/Makefile.${ARCH}
UTILLIBS = -L${BASEDIR}/lib -lSocketUtil
INCDIRS = -I${BASEDIR}/include -I${PLIINC}
DFLAGS = ${ARCHDEBUG}
#DFLAGs =
CFLAGS = ${ARCHDEFINES} ${ARCHCFLAGS} ${DFLAGS} ${ARCHGNU} ${INCDIRS}
TARGETS = \
runModel${ARCHEXE} \
${REMLIB}
MODEL = modelMain.${ARCHEXT} \
runModel.${ARCHEXT}
REMOBJ = remmodel.${ARCHEXT}
REMLIB = librem.${ARCHDYNEXT}
CFILES = \
${MODEL.${ARCHEXT}=.c}
.c.${ARCHEXT}:
$(CC) -c $< ${CFLAGS} ${ARCHLIBFLAGS} ${INCDIRS}
target: ${TARGETS}
${REMLIB}: ${REMOBJ}
-$(RM) ${REMLIB}
$(LD) ${ARCHDYNLD} ${ARCHLDOUT}${REMLIB} ${REMOBJ} ${BASEDIR}/lib/libSocketUtil.${ARCHDYNEXTL} ${ARCHPLILIB} ${ARCHLIBFLAGS}
libvpi.${ARCHDYNEXT}: ${REMOBJ} vlogmodel.${ARCHEXT}
-$(RM) libvpi.dll
$(LD) ${ARCHDYNLD} ${ARCHLDOUT}libvpi.${ARCHDYNEXT} ${ARCHLIBFLAGS} ${REMOBJ} vlogmodel.${ARCHEXT} ${BASEDIR}/lib/libSocketUtil.${ARCHDYNEXTL} ${ARCHPLILIB}
runModel${ARCHEXE}: ${MODEL}
$(CC) ${ARCHCCOUT}$@ ${MODEL} ${BASEDIR}/lib/libSocketUtil.${ARCHDYNEXTL} ${ARCHLIBFLAGS}
TAGS: ${CFILES} ${HFILES}
etags -tTa ${HFILES} ${CFILES}
clean:
-$(RM) *~ TAGS *.${ARCHEXT} ${UTILNAME}.tar* *.log *.key ${TARGETS}
ship:
-$(RM) ${UTILNAME}.tar.gz
tar -cvf ${UTILNAME}.tar Makefile ${CFILES} ${HFILES}
gzip ${UTILNAME}.tar
depend:
makedepend ${INCDIRS} ${CFILES}
# DO NOT DELETE

View File

@ -0,0 +1,16 @@
To run this example first type make. This will build the dynamic
library that will be used by the simulator to communicate with some
remote simulator. It will also build an exe that is a simple stand
alone model of a multibit latch.
Next to start the remote model running type:
runModel 5511
You can now start the simulator in a different window on the HDL
file test.v by using the command file "run.vc"
<simulator> -f run.vc

View File

@ -0,0 +1,91 @@
#include <stdio.h>
#include <stdlib.h>
#ifndef WINNT
#include <unistd.h>
#endif
#include "com_exp.h"
#include "socketUtil.h"
#include "runModel.h"
extern char *modelWho;
int main(int argc, char *argv[])
{
char *port = NULL;
char *host = NULL;
char *data = NULL;
int cnt = 1;
int fd = fileno(stdin);
int fdOut = fileno(stdout);
int server = -1;
if (argc > 1)
{
while(cnt<argc)
{
if (argv[cnt][0] == '-')
{
if (!strcmp(argv[cnt], "host"))
{
host = argv[cnt];
}
else
{
fprintf(stderr, "Bad argument: %s", argv[cnt]);
exit(1);
}
}
else
{
if (!port)
{
port = argv[cnt];
}
else
{
fprintf(stderr, "The port was already given!\n");
exit(1);
}
}
cnt++;
}
}
if (port)
{
server = sockMakeServer(atoi(port), 1);
if (server == -1)
{
printf("Failed to open the desired socket: %s\n", port);
exit(1);
}
printf("Monitoring port: %s\n", port);
fd = sockAcceptServer(server, &modelWho);
fdOut = fd;
printf("Received connection from host ");
if (modelWho)
{
printf("%s\n", modelWho);
}
else
{
printf("<unknown>\n");
}
}
else
{
fd = fileno(stdin);
fdOut = fileno(stdout);
}
while((data = sockGetLine(fd, 0)))
{
runModel(fdOut, server, data);
}
close(fd);
exit(0);
}

View File

@ -0,0 +1,550 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <assert.h>
#include "veriuser.h"
#include "vpi_user.h"
#include "com_exp.h"
#include "socketUtil.h"
/*
* Data structures
*/
typedef struct remPort {
struct remPort *next;
char *name;
int changed;
int id;
int size;
char *val;
vpiHandle obj;
vpiHandle obj2;
struct remModel *root;
} s_remPort, *p_remPort;
typedef struct remModel {
vpiHandle inst;
int conn;
int connIn;
int server;
int numPorts;
p_remPort in;
p_remPort out;
p_remPort inout;
int synched;
p_remPort *portArray;
} s_remModel, *p_remModel;
/*
* Utility routines
*/
static void remError(char *fmt, ...)
{
char buffer[10048]; /* A Large buffer */
va_list ap;
va_start(ap, fmt);
vsprintf(&buffer[0], fmt, ap);
/*
* Use tf_error() to stop things until VPI has an error interface added
*/
tf_error(&buffer[0]);
va_end(ap);
tf_dostop();
}
static void *remAlloc(int size)
{
void *retVal;
assert(size>0);
retVal = malloc(size);
memset(retVal, 0, size);
return(retVal);
}
/*
* Send data down to the remote and get a response if requested
*/
static char *remSendData(int conn, int expectData, char *fmt, ...)
{
char buffer[2048]; /* Cheap lazy large buffer....
* Watch this if you start using large vectors or
* something
*/
char *retVal = NULL;
va_list ap;
va_start(ap, fmt);
vsprintf(&buffer[0], fmt, ap);
sockPutLine(conn , &buffer[0]);
if (expectData)
{
retVal = sockGetLine(expectData, 0);
}
return(retVal);
}
static void remGetOutputs(p_remModel modelStr)
{
char *retVal;
static char *buffer = NULL;
static int bufferLen = 0;
char *tmp;
s_vpi_value valStr;
p_remPort *array = modelStr->portArray;
int len;
int id;
if (modelStr->conn == -1)
return; /* The model has become disfunctional */
/* Tell model all data has been sent */
remSendData(modelStr->conn, FALSE, "done");
while((retVal = sockGetLine(modelStr->connIn, FALSE)))
{
/* See if we are done */
if (!strcmp(retVal, "done"))
{
break;
}
len = strlen(retVal);
if (len+1 > bufferLen)
{
if (buffer)
{
free(buffer);
}
bufferLen = (((len+1)+256)/256)*256; /* Some multiple of 256 */
buffer = remAlloc(bufferLen);
}
strcpy(buffer, retVal);
/* Get the ID */
tmp = strtok(buffer, " ");
id = atoi(tmp);
/* Get the value */
tmp = strtok(NULL, " ");
valStr.format = vpiBinStrVal;
valStr.value.str = tmp;
vpi_put_value((*(array+id))->obj, &valStr, NULL, vpiNoDelay);
}
}
/*
* run time routines
*/
static int remFinishSim(p_cb_data cbData)
{
p_remModel modelStr = (p_remModel)cbData->user_data;
remSendData(modelStr->conn, FALSE, "finished");
close(modelStr->conn);
close(modelStr->connIn);
close(modelStr->server);
vpi_printf("Remote model: %s\n", vpi_get_str(vpiFullName, modelStr->inst));
vpi_printf(" has been terminated\n");
return(0);
}
static int remSynch(p_cb_data cbData)
{
int cnt;
p_remModel modelStr = (p_remModel)cbData->user_data;
p_remPort *ports = modelStr->portArray;
modelStr->synched = FALSE;
/* Send over the value of all the ports that have changed value */
for (cnt=0;cnt<modelStr->numPorts;cnt++)
{
if ((*(ports+cnt))->changed)
{
remSendData(modelStr->conn, FALSE, "set %d %d %s",
(*(ports+cnt))->id, (*(ports+cnt))->size,
(*(ports+cnt))->val);
(*(ports+cnt))->changed = FALSE;
}
}
/* Get any outputs from the model */
remGetOutputs(modelStr);
return(0);
}
static int remCbInput(p_cb_data cbData)
{
p_remPort port = (p_remPort)cbData->user_data;
static s_vpi_time time = {vpiSimTime, 0, 0, 0.0};
static s_cb_data synch = {cbReadWriteSynch, remSynch, NULL, &time, NULL};
/* Schedule a wake up at the end of the present time slice */
if (!port->root->synched)
{
/*
* Register a callback for the end of the time slice.
* remember to free the callback handle, seeing that we will never
* cancel the callback.
*/
vpiHandle hCb;
synch.user_data = (char *)port->root;
hCb = vpi_register_cb(&synch);
vpi_free_object(hCb);
port->root->synched = TRUE;
}
port->changed = TRUE;
strcpy(port->val, cbData->value->value.str);
return(0);
}
static void setupRemModel(p_remModel modelStr)
{
s_vpi_value valStr;
p_remPort port;
char *retOk;
/*
* Now dump the information to the remote model and synch up
*/
valStr.format = vpiBinStrVal;
port = modelStr->in;
while(port)
{
vpi_get_value(port->obj, &valStr);
retOk = remSendData(modelStr->conn, modelStr->connIn,
"init %s %d %d %s", port->name, port->size,
port->id, valStr.value.str);
if (strcmp(retOk, "OK") != 0)
{
remError("model received bad return from remote model -- %s", retOk);
}
port = port->next;
}
port = modelStr->out;
while(port)
{
vpi_get_value(port->obj, &valStr);
retOk = remSendData(modelStr->conn, modelStr->connIn, "init %s %d %d %s",
port->name, port->size,
port->id, valStr.value.str);
if (strcmp(retOk, "OK") != 0)
{
remError("model received bad return from remote model -- %s", retOk);
}
port = port->next;
}
port = modelStr->inout;
while(port)
{
vpi_get_value(port->obj, &valStr);
retOk = remSendData(modelStr->conn, modelStr->connIn, "init %s %d %d %s",
port->name, port->size,
port->id, valStr.value.str);
if (strcmp(retOk, "OK") != 0)
{
remError("model received bad return from remote model -- %s", retOk);
}
port = port->next;
}
}
/*
* Build the models interface and sync up with the remote model.
*/
static int remModelCall(char *data)
{
vpiHandle hModule, hThisTask;
vpiHandle hPortIter, hPort;
vpiHandle hDriverIter, hDriver;
vpiHandle hConn, hLhs;
vpiHandle hArgIter, hArg;
s_vpi_value valStr;
s_cb_data cbData;
int cntId = 0;
int server;
int portNo, portNoIn;
char *remMachine = NULL;
int conn, fdOut;
p_remModel modelStr;
p_remPort port;
char buffer[1024];
/*
* See if we can establish a connection to the remote model.
*/
hThisTask = vpi_handle(vpiSysTfCall, NULL);
hArgIter = vpi_iterate(vpiArgument, hThisTask);
hArg = vpi_scan(hArgIter);
valStr.format = vpiIntVal;
vpi_get_value(hArg, &valStr);
portNo = valStr.value.integer;
hArg = vpi_scan(hArgIter);
if (hArg)
{
if ((vpi_get(vpiType, hArg) == vpiConstant) &&
(vpi_get(vpiConstType, hArg)))
{
valStr.format = vpiStringVal;
vpi_get_value(hArg, &valStr);
remMachine = valStr.value.str;
}
}
vpi_printf("Starting connection for: %s\n",
vpi_get_str(vpiFullName, vpi_handle(vpiScope, hThisTask)));
vpi_printf(" on port = %d\n", portNo);
if (remMachine)
{
vpi_printf(" machine = %s\n", remMachine);
}
/*
* See if we can find a port to receive input on
*/
server = -1;
portNoIn = portNo;
while(server == -1)
{
portNoIn++;
server = sockMakeServer(portNoIn, 1);
}
conn = sockMakeClient(portNo, remMachine);
if (conn == -1)
{
sprintf(&buffer[0],
"Failed to make a connection to the remote model at port = %d ",
portNo);
if (remMachine)
{
strcat(&buffer[0], "machine = ");
strcat(&buffer[0], remMachine);
}
strcat(&buffer[0], " \n");
remError(&buffer[0]);
return(0);
}
/* Now tell the other machine where to send data back */
sprintf(&buffer[0], "port %d", portNoIn);
sockPutLine(conn, &buffer[0]);
fdOut = sockAcceptServer(server, NULL);
/*
* Now start building up the main data structure.
*/
modelStr = remAlloc(sizeof(s_remModel));
modelStr->conn = conn;
modelStr->connIn = fdOut;
modelStr->server = server;
/*
* Before we do anything else lets register for simulation
* finish so we can shut down the remote connection if needed.
*/
cbData.reason = cbEndOfSimulation;
cbData.user_data = (char *)modelStr;
cbData.time = NULL;
cbData.value = NULL;
cbData.obj = NULL;
cbData.cb_rtn = remFinishSim;
vpi_register_cb(&cbData);
/*
* Get the port data.
*/
hModule = vpi_handle(vpiScope, hThisTask);
modelStr->inst = hModule;
hPortIter = vpi_iterate(vpiPort, hModule);
if (!hPortIter)
{
return(0);
}
/* See how many ports there are */
while((hPort = vpi_scan(hPortIter)))
{
cntId++;
}
modelStr->numPorts = cntId;
modelStr->portArray = remAlloc(cntId * sizeof(p_remPort *));
hPortIter = vpi_iterate(vpiPort, hModule);
cntId = 0;
valStr.format = vpiBinStrVal;
while((hPort = vpi_scan(hPortIter)))
{
hConn = vpi_handle(vpiLowConn, hPort);
if (!hConn)
{
/* hmmm an empty port connection */
continue;
}
port = remAlloc(sizeof(s_remPort));
port->id = cntId;
port->root = modelStr;
port->obj = hConn;
port->size = vpi_get(vpiSize, hConn);
port->val = remAlloc(port->size+1);
port->name = strdup(vpi_get_str(vpiName, hConn));
*(modelStr->portArray+cntId) = port;
cntId++;
switch(vpi_get(vpiDirection, hPort))
{
case vpiInput:
port->next = modelStr->in;
modelStr->in = port;
cbData.reason = cbValueChange;
cbData.user_data = (char *)port;
cbData.time = NULL;
cbData.value = &valStr;
cbData.obj = hConn;
cbData.cb_rtn = remCbInput;
vpi_register_cb(&cbData);
break;
case vpiOutput:
port->next = modelStr->out;
modelStr->out = port;
break;
case vpiInout:
port->next = modelStr->inout;
modelStr->inout = port;
cbData.reason = cbValueChange;
cbData.user_data = (char *)port;
cbData.time = NULL;
cbData.value = &valStr;
cbData.obj = hConn;
cbData.cb_rtn = remCbInput;
vpi_register_cb(&cbData);
/* find the reg */
hDriverIter = vpi_iterate(vpiContAssign, hModule);
while((hDriver = vpi_scan(hDriverIter)))
{
hLhs = vpi_handle(vpiLhs, hDriver);
if (vpi_compare_objects(hLhs, hConn))
{
port->obj2 = vpi_handle(vpiRhs, hDriver);
vpi_free_object(hDriverIter);
break;
}
}
break;
case vpiMixedIO:
default:
/* Should never get here */
break;
}
}
setupRemModel(modelStr);
return(0);
}
/*
* Verify the port list is consistent with remote model.
* Walk through the ports
* Verify that all
* inputs are wires
* outputs are registers
* inouts are wires with implicit cont assign with a register
*
*/
static int remModelCompile(char *data)
{
vpiHandle hPortIter, hPort;
vpiHandle hModule, hThisTask;
vpiHandle hLowConn;
vpiHandle hArgIter, hArg;
hThisTask = vpi_handle(vpiSysTfCall, NULL);
hArgIter = vpi_iterate(vpiArgument, hThisTask);
if (!hArgIter)
{
remError("This system task must have a socket number\n");
return(0);
}
hArg = vpi_scan(hArgIter);
if (vpi_get(vpiType, hArg))
{
if (vpi_get(vpiConstType, hArg) == vpiDecConst)
{
}
}
hModule = vpi_handle(vpiScope, hThisTask);
if (hModule == NULL)
{
remError("This system task (%s) must be executed from inside a module\n",
vpi_get_str(vpiName, hThisTask));
return(0);
}
hPortIter = vpi_iterate(vpiPort, hModule);
if (!hPortIter)
{
vpi_printf("There does not appear to be any port. Nothing much is going to happen\n");
return(0);
}
while((hPort = vpi_scan(hPortIter)))
{
hLowConn = vpi_handle(vpiLowConn, hPort);
if (!hLowConn)
{
/* hmmm an empty port connection */
continue;
}
switch(vpi_get(vpiDirection, hPort))
{
case vpiInput:
break;
case vpiOutput:
break;
case vpiInout:
break;
case vpiMixedIO:
default:
break;
}
}
return(0);
}
DECLEXP
void regRemModel()
{
s_vpi_systf_data systf;
systf.type = vpiSysTask;
systf.sysfunctype = 0;
systf.tfname = "$remModel";
systf.calltf = remModelCall;
systf.compiletf = remModelCompile;
systf.sizetf = NULL;
systf.user_data = NULL;
vpi_register_systf(&systf);
}

View File

@ -0,0 +1,5 @@
-q
+accwarn
+loadvpi=librem:regRemModel
test.v

View File

@ -0,0 +1,378 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>
#ifndef WINNT
#include <unistd.h>
#endif
#include "com_exp.h"
#include "socketUtil.h"
#define IDEN 0
#define IDIN 1
#define IDOUT 2
typedef struct port {
char *name;
int id;
int realId;
int size;
int changed;
char *value;
} *p_port, s_port;
static s_port enable = {"enable", 0, IDEN, -1, 0, NULL};
static s_port input = {"in", 0, IDIN, -1, 0, NULL};
static s_port output = {"out", 0, IDOUT, -1, 0, NULL};
static p_port portArray[3];
static char buffer[1025];
char *modelWho = NULL;
static void *modelAlloc(int size)
{
void *retVal;
assert(size>0);
retVal = malloc(size);
memset(retVal, 0, size);
return(retVal);
}
static void modelError(int fd, char *fmt, ...)
{
char buffer[2048]; /* Cheap lazy large buffer....
* Watch this if you start using large vectors or
* something
*/
va_list ap;
va_start(ap, fmt);
vsprintf(&buffer[0], fmt, ap);
sockPutLine(fd , &buffer[0]);
exit(1);
}
/*
* Different routines for the different string commands the model supports
*/
static void process_done(int fd, int fdRet)
{
static out = 0;
char *c;
int cnt;
/*
* Ok folks here is the model.
* Yes it's very simple. So what!
*/
out = 0;
if (input.changed || enable.changed)
{
enable.changed = 0;
input.changed = 0;
/* Calculate the new output value */
/* update the output if enable == 1 */
if ((*enable.value == '1') || (*enable.value == 'x'))
{
/* If enable is and X set the output to an X (Quick and dirty) */
if (*enable.value == 'x')
{
if (strcmp(output.value, input.value) != 0)
{
/* If the input has changed then make the output an X */
c = output.value;
for (cnt = 0; cnt < output.size; cnt++)
*(c++) = 'x';
out = 1;
}
}
else
{
if (!strcmp(output.value, input.value))
{
out = 0;
}
else
{
strcpy(output.value, input.value);
out = 1;
}
}
}
if (out)
{
sprintf(buffer, "out %s", output.value);
if (fdRet != -1)
{
sockPutLine(fdRet, buffer);
}
out = 0;
}
if (fdRet != -1)
{
sockPutLine(fdRet, "done");
}
}
return;
}
static void process_init(int fd, int fdRet)
{
char *c;
char *cSize, *cVal;
char *cId;
int id, size;
int cnt;
c = strtok(NULL, " "); /* Get the name of the net */
if ( c == NULL )
{
modelError(fdRet, "Bad init line - missing NAME");
}
cSize = strtok(NULL, " "); /* Get the size of the net */
if ( cSize == NULL )
{
modelError(fdRet, "Bad init line - missing SIZE");
}
cId = strtok(NULL, " "); /* Get the ID */
if ( cId == NULL )
{
modelError(fdRet, "Bad init line - missing ID");
}
cVal = strtok(NULL, " ");
if ( cVal == NULL )
{
modelError(fdRet, "Bad init line - missing VALUE");
}
id = atoi(cId);
size = atoi(cSize);
if ((id < 0) || (id > 2))
{
modelError(fdRet, "ID out of range >>> 0 - 2");
}
if (!strcmp(c, "out"))
{
if (input.size != -1)
{
if (input.size != size)
{
modelError(fdRet, "port input must have the same size of output");
}
}
portArray[id] = &output;
}
else if (!strcmp(c, "in"))
{
if (output.size != -1)
{
if (output.size != size)
{
modelError(fdRet, "port input must have the same size of output");
}
}
portArray[id] = &input;
}
else if (!strcmp(c, "enable"))
{
if (size != 1)
{
modelError(fdRet, "Port enable can only be one bit");
}
portArray[id] = &enable;
}
else
{
modelError(fdRet, "Bad port name - %s", c);
}
portArray[id]->id = id;
portArray[id]->size = size;
portArray[id]->value = modelAlloc(size + 1);
portArray[id]->changed = 1;
c = portArray[id]->value;
for (cnt=0; cnt < size; cnt++)
*c++ = *cVal++;
*c = '\0';
sockPutLine(fdRet, "OK");
}
static void process_set(int fd, int fdRet)
{
char *cId, *cSize, *cVal;
int size;
int id;
cId = strtok(NULL, " ");
if ( cId == NULL )
{
modelError(fdRet, "Bad set line - missing ID");
}
cSize = strtok(NULL, " ");
if ( cSize == NULL )
{
modelError(fdRet, "Bad set line - missing size");
}
cVal = strtok(NULL, " ");
if ( cVal == NULL )
{
modelError(fdRet, "Bad set line - missing value");
}
id = atoi(cId);
if ((id < 0) || (id > 2))
{
modelError(fdRet, "Bad id in set command - %s", cId);
}
size = atoi(cSize);
if (size != portArray[id]->size)
{
modelError(fdRet, "Bad size in set command, does not match objects size");
}
switch(portArray[id]->realId)
{
case IDEN:
case IDIN:
strcpy(portArray[id]->value, cVal);
portArray[id]->changed = 1;
break;
case IDOUT:
modelError(fdRet, "Cannot set a value to the output port");
break;
default:
break;
}
return;
}
static void process_value(int fd, int fdRet)
{
char *cId;
int id;
cId = strtok(NULL, " "); /* Get the id of the net */
if ( cId == NULL )
{
modelError(fdRet, "Bad value line - missing ID");
}
id = atoi(cId);
if ((id < 0) || (id > 2))
{
modelError(fdRet, "Bad id in set command - %s", cId);
}
sockPutLine(fdRet, portArray[id]->value);
}
void runModel(int fd, int fdSrv, char *data)
{
char *c;
static fdRet = -1;
char *cId;
c = strtok(data, " ");
if (c == NULL)
return;
if (*c == '\0')
return;
switch(*c)
{
case 'd':
if (!strcmp(c, "done"))
{
process_done(fd, fdRet);
}
break;
case 'f':
{
if (!strcmp(c, "finished"))
{
if (fdRet > 0)
{
close(fdRet);
}
close(fd);
if (fdSrv > 0)
{
close(fdSrv);
}
printf("Shutting down!\n");
exit(0);
}
break;
}
case 'i':
if (!strcmp(c, "init"))
{
process_init(fd, fdRet);
}
break;
case 'p':
if (!strcmp(c, "port")) /* update an input value */
{
cId = strtok(NULL, " ");
if ( cId == NULL )
{
modelError(fdRet, "Bad portno - missing ID");
}
fdRet = sockMakeClient(atoi(cId), modelWho);
}
break;
case 's':
if (!strcmp(c, "set")) /* update an input value */
{
process_set(fd, fdRet);
}
break;
case 'v':
if (!strcmp(c, "value"))
{
process_value(fd, fdRet);
}
break;
default:
modelError(fdRet, "Bad input command");
break;
}
return;
}

View File

@ -0,0 +1 @@
char *runModel(int fd, int fdServ, char *data);

View File

@ -0,0 +1,63 @@
`timescale 1ns / 1ns
`celldefine
module latch(out, in, enable);
input [3:0] in;
output [3:0] out;
reg [3:0] out;
wire [3:0] outW;
input enable;
initial
$remModel(5510,,out, in, enable);
endmodule
`endcelldefine
module test;
reg enable;
reg [3:0] in;
wire [3:0] out0;
latch u0(out0, in, enable);
initial
begin
$timeformat(-9, 0, "ns", 6);
$monitor("%t", $time, " enable=", enable, " in=%b", in, " out -> %b", out0);
end
initial
begin
// #0 $stop;
#10 enable = 0;
in = 4'b0100;
#10 enable = 1;
#10 enable = 0;
#10 enable = 1'bx;
#10 in = 4'b1000;
// #10 $display("Saving Simulation to file: data.1");
// $save("data.1");
#10 enable = 1;
#10 enable = 1'bx;
// #10 $display("Incremental Save data.2");
// $save("data.2");
#10 in = 4'b0110;
#10 enable = 1;
#10 enable = 0;
#10 enable = 1'bx;
#10 in = 4'b0001;
// #10 $display("Incremental Save data.3");
// $incsave("data.3");
#10 enable = 0;
#10 enable = 1;
#10 enable = 0;
end
endmodule

View File

@ -0,0 +1,10 @@
extern void regRemModel();
#ifdef WINNT
__declspec(dllexport)
#endif
void (*vlog_startup_routines[])() =
{
regRemModel,
0
};

View File

@ -0,0 +1,19 @@
#
# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows
#
MTI_INSTALL_DIR=c:\progra~1\ModelTech
SOURCES = \
hello_vpi.c \
show_value_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(MTI_INSTALL_DIR)\include -MD
.c.obj:
$(CC) $(CFLAGS) -c $<
../mti_pli.dll: $(OBJS)
link -dll /out:$@ $(OBJS) -EXPORT:vlog_startup_routines $(MTI_INSTALL_DIR)/win32/mtipli.lib

View File

@ -0,0 +1,19 @@
#
# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
hello_vpi.c \
show_value_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,18 @@
#
# sample NMAKE makefile to make libvpi.dll with VisualC++ on Windows
# see windows.txt for more details.
#
SOURCES = \
hello_vpi.c \
show_value_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,5 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
Hello World!
Simulation complete via $finish(1) at time 10 NS + 0

View File

@ -0,0 +1,20 @@
/**********************************************************************
* $hello example -- Verilog HDL test bench.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
initial
begin
$hello;
// #10 $stop;
#10 $finish;
end
endmodule
/**********************************************************************/

View File

@ -0,0 +1,45 @@
/**********************************************************************
* $hello example -- PLI application using VPI routines
*
* C source to print "Hello World" as a PLI application.
*
* Usage: $hello;
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_hello_calltf(PLI_BYTE8 *user_data)
{
vpi_printf("\nHello World!\n\n");
return(0);
}
/**********************************************************************
* $hello Registration Data
* (add this function name to the vlog_startup_routines array)
*********************************************************************/
void PLIbook_hello_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$hello";
tf_data.calltf = PLIbook_hello_calltf;
tf_data.compiletf = NULL;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}

View File

@ -0,0 +1,7 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
Signal test.sum has the value 1
Signal test.co has the value 0
Signal test.i1.n3 has the value 0
Simulation complete via $finish(1) at time 30 NS + 0

View File

@ -0,0 +1,57 @@
/**********************************************************************
* $show_value example -- Verilog HDL test bench.
*
* Verilog test bench to test the $show_value PLI application on a
* 1-bit adder modeled using gate primitives.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
reg a, b, ci, clk;
wire sum, co;
addbit i1 (a, b, ci, sum, co);
initial
begin
// $monitor("At %0d: \t a=%b b=%b ci=%b sum=%b co=%b",
// $time, a, b, ci, sum, co);
clk = 0;
a = 0;
b = 0;
ci = 0;
#10 a = 1;
#10 b = 1;
$show_value(sum);
$show_value(co);
$show_value(i1.n3);
// #10 $stop;
#10 $finish;
end
endmodule
/*** A gate level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci, sum, co,
n1, n2, n3;
xor (n1, a, b);
xor #2 (sum, n1, ci);
and (n2, a, b);
and (n3, n1, ci);
or #2 (co, n2, n3);
endmodule
/**********************************************************************/

View File

@ -0,0 +1,117 @@
/**********************************************************************
* $show_value example -- PLI application using VPI routines
*
* C source to print the name and current logic value of a net.
*
* Usage: $show_value(<signal_name>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of routines in this PLI application */
PLI_INT32 PLIbook_ShowVal_compiletf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_ShowVal_calltf(PLI_BYTE8 *user_data);
/**********************************************************************
* $show_value Registration Data
* (add this function name to the vlog_startup_routines array)
*********************************************************************/
void PLIbook_ShowVal_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$show_value";
tf_data.calltf = PLIbook_ShowVal_calltf;
tf_data.compiletf = PLIbook_ShowVal_compiletf;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
return;
}
/**********************************************************************
* compiletf application
*********************************************************************/
PLI_INT32 PLIbook_ShowVal_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, arg_handle;
PLI_INT32 arg_type;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
if (systf_handle == NULL) {
vpi_printf("ERROR: $show_value failed to obtain systf handle\n");
vpi_control(vpiFinish,0); /* abort simulation */
return(0);
}
/* obtain handles to system task arguments */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
vpi_printf("ERROR: $show_value requires 1 argument\n");
vpi_control(vpiFinish,0); /* abort simulation */
return(0);
}
/* check the type of object in system task arguments */
arg_handle = vpi_scan(arg_iterator);
arg_type = vpi_get(vpiType, arg_handle);
if (arg_type != vpiNet && arg_type != vpiReg) {
vpi_printf("ERROR: $show_value arg must be a net or reg\n");
vpi_free_object(arg_iterator); /* free iterator memory */
vpi_control(vpiFinish,0); /* abort simulation */
return(0);
}
/* check that there are no more system task arguments */
arg_handle = vpi_scan(arg_iterator);
if (arg_handle != NULL) {
vpi_printf("ERROR: $show_value can only have 1 argument\n");
vpi_free_object(arg_iterator); /* free iterator memory */
vpi_control(vpiFinish,0); /* abort simulation */
return(0);
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowVal_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, arg_handle, net_handle;
s_vpi_value current_value;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handle to system task argument
compiletf has already verified only 1 arg with correct type */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
net_handle = vpi_scan(arg_iterator);
vpi_free_object(arg_iterator); /* free iterator memory */
/* read current value */
current_value.format = vpiBinStrVal; /* read value as a string */
vpi_get_value(net_handle, &current_value);
vpi_printf("Signal %s ", vpi_get_str(vpiFullName, net_handle));
vpi_printf("has the value %s\n", current_value.value.str);
return(0);
}
/*********************************************************************/

View File

@ -0,0 +1,5 @@
// Example Synopsys VCS PLI table to register PLI applications
// For the book, "The Verilog PLI Handbook"
$hello call=PLIbook_hello_calltf data=0
$show_value check=PLIbook_ShowVal_compiletf call=PLIbook_ShowVal_calltf data=0 acc+=read:*

View File

@ -0,0 +1,25 @@
/**********************************************************************
* Example vpi_user.c file
*
* vpi_user.c file to register PLI applications using the VPI library.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#include "vpi_user.h"
/* prototypes of the PLI registration routines */
extern void PLIbook_hello_register();
extern void PLIbook_ShowVal_register();
void (*vlog_startup_routines[])() =
{
/*** add user entries here ***/
PLIbook_hello_register,
PLIbook_ShowVal_register,
0 /*** final entry must be 0 ***/
};

View File

@ -0,0 +1,19 @@
#
# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows
#
MTI_INSTALL_DIR=c:\progra~1\ModelTech
SOURCES = \
pow_vpi.c \
user_data_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(MTI_INSTALL_DIR)\include -MD
.c.obj:
$(CC) $(CFLAGS) -c $<
../mti_pli.dll: $(OBJS)
link -dll /out:$@ $(OBJS) -EXPORT:vlog_startup_routines $(MTI_INSTALL_DIR)/win32/mtipli.lib

View File

@ -0,0 +1,19 @@
#
# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
pow_vpi.c \
user_data_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,20 @@
#
# sample NMAKE makefile to make libvpi.dll with VisualC++ on Windows
# see windows.txt for more details.
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
pow_vpi.c \
user_data_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,7 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
$pow PLI application is being used.
$pow(2,3) returns 8
$pow(a,b) returns 1 (a=1 b=0)
Simulation complete via $finish(1) at time 4 NS + 0

View File

@ -0,0 +1,41 @@
/**********************************************************************
* $pow example -- Verilog HDL test bench.
*
* Verilog test bench to test the $pow PLI application.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
reg [32:0] result;
reg a, b;
buf i1 (c,a);
initial
begin
a = 1;
b = 0;
/* Test $pow with invalid arguments */
/* These invalid calls will need to be commented out to use */
/* the valid calls to $pow in simulation */
// #1 result = $pow;
// #1 result = $pow();
// #1 result = $pow(1);
// #1 result = $pow(2,i1);
// #1 result = $pow(1,2,3);
/* Test $pow with valid values */
#1 $display("$pow(2,3) returns %d", $pow(2,3));
#1 result = $pow(a,b);
#1 $display("$pow(a,b) returns %d (a=%d b=%d)", result, a, b);
// #1 $stop;
#1 $finish;
end
endmodule
/*********************************************************************/

View File

@ -0,0 +1,172 @@
/**********************************************************************
* $pow example -- PLI application using VPI routines
*
* C source to calculate the result of a number to the power of an
* exponent. The result is returned as a 32-bit integer.
*
* Usage: result = $pow(<base>,<exponent>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of PLI application routine names */
PLI_INT32 PLIbook_PowSizetf(PLI_BYTE8 *user_data),
PLIbook_PowCalltf(PLI_BYTE8 *user_data),
PLIbook_PowCompiletf(PLI_BYTE8 *user_data),
PLIbook_PowStartOfSim(s_cb_data *callback_data);
/**********************************************************************
* $pow Registration Data
* (add this function name to the vlog_startup_routines array)
*********************************************************************/
void PLIbook_pow_register()
{
s_vpi_systf_data tf_data;
s_cb_data cb_data_s;
vpiHandle callback_handle;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$pow";
tf_data.calltf = PLIbook_PowCalltf;
tf_data.compiletf = PLIbook_PowCompiletf;
tf_data.sizetf = PLIbook_PowSizetf;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
cb_data_s.reason = cbStartOfSimulation;
cb_data_s.cb_rtn = PLIbook_PowStartOfSim;
cb_data_s.obj = NULL;
cb_data_s.time = NULL;
cb_data_s.value = NULL;
cb_data_s.user_data = NULL;
callback_handle = vpi_register_cb(&cb_data_s);
vpi_free_object(callback_handle); /* don't need callback handle */
}
/**********************************************************************
* Sizetf application
*********************************************************************/
PLI_INT32 PLIbook_PowSizetf(PLI_BYTE8 *user_data)
{
return(32); /* $pow returns 32-bit values */
}
/**********************************************************************
* compiletf application to verify valid systf args.
*********************************************************************/
PLI_INT32 PLIbook_PowCompiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_itr, arg_handle;
PLI_INT32 tfarg_type;
int err_flag = 0;
do { /* group all tests, so can break out of group on error */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
arg_itr = vpi_iterate(vpiArgument, systf_handle);
if (arg_itr == NULL) {
vpi_printf("ERROR: $pow requires 2 arguments; has none\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $pow arg1 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
if (arg_handle == NULL) {
vpi_printf("ERROR: $pow requires 2nd argument\n");
err_flag = 1;
break;
}
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $pow arg2 must be number, variable or net\n");
err_flag = 1;
break;
}
if (vpi_scan(arg_itr) != NULL) {
vpi_printf("ERROR: $pow requires 2 arguments; has too many\n");
vpi_free_object(arg_itr);
err_flag = 1;
break;
}
} while (0 == 1); /* end of test group; only executed once */
if (err_flag) {
vpi_control(vpiFinish, 1); /* abort simulation */
}
return(0);
}
/**********************************************************************
* calltf to calculate base to power of exponent and return result.
*********************************************************************/
#include <math.h>
PLI_INT32 PLIbook_PowCalltf(PLI_BYTE8 *user_data)
{
s_vpi_value value_s;
vpiHandle systf_handle, arg_itr, arg_handle;
PLI_INT32 base, exp;
double result;
systf_handle = vpi_handle(vpiSysTfCall, NULL);
arg_itr = vpi_iterate(vpiArgument, systf_handle);
if (arg_itr == NULL) {
vpi_printf("ERROR: $pow failed to obtain systf arg handles\n");
return(0);
}
/* read base from systf arg 1 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
value_s.format = vpiIntVal;
vpi_get_value(arg_handle, &value_s);
base = value_s.value.integer;
/* read exponent from systf arg 2 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_free_object(arg_itr); /* not calling scan until returns null */
vpi_get_value(arg_handle, &value_s);
exp = value_s.value.integer;
/* calculate result of base to power of exponent */
result = pow( (double)base, (double)exp );
/* write result to simulation as return value $pow */
value_s.value.integer = (PLI_INT32)result;
vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay);
return(0);
}
/**********************************************************************
* Start-of-simulation application
*********************************************************************/
PLI_INT32 PLIbook_PowStartOfSim(s_cb_data *callback_data)
{
vpi_printf("\n$pow PLI application is being used.\n\n");
return(0);
}
/*********************************************************************/

View File

@ -0,0 +1,75 @@
/*********************************************************************/
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
PLI_INT32 PLIbook_GetVectorCalltf(PLI_BYTE8 *user_data),
PLIbook_GetVectorCompiletf(PLI_BYTE8 *user_data),
PLIbook_GetVectorSizetf(PLI_BYTE8 *user_data);
/**********************************************************************
* VPI Registration Data for $test_user_data_1;
*********************************************************************/
void PLIbook_test_user_data_register()
{
s_vpi_systf_data tf_data;
char *id1 = malloc(sizeof(int)); /* allocate user_data storage */
char *id2 = malloc(sizeof(int)); /* allocate user_data storage */
*id1 = 1;
*id2 = 2;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$get_vector_bin";
tf_data.calltf = PLIbook_GetVectorCalltf;
tf_data.compiletf = PLIbook_GetVectorCompiletf;
tf_data.sizetf = PLIbook_GetVectorSizetf;
tf_data.user_data = (PLI_BYTE8 *)id1;
vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$get_vector_hex";
tf_data.calltf = PLIbook_GetVectorCalltf;
tf_data.compiletf = PLIbook_GetVectorCompiletf;
tf_data.sizetf = PLIbook_GetVectorSizetf;
tf_data.user_data = (PLI_BYTE8 *)id2;
vpi_register_systf(&tf_data);
}
/**********************************************************************
* sizetf routine
*********************************************************************/
PLI_INT32 PLIbook_GetVectorSizetf(PLI_BYTE8 *user_data)
{
vpi_printf("\nIn sizetf,\tuser_data = %d\n", *user_data);
return(8);
}
/**********************************************************************
* compiletf routine
*********************************************************************/
PLI_INT32 PLIbook_GetVectorCompiletf(PLI_BYTE8 *user_data)
{
vpi_printf("\nIn compiletf,\tuser_data = %d\n", *user_data);
return(0);
}
/**********************************************************************
* test calltf routine
*********************************************************************/
PLI_INT32 PLIbook_GetVectorCalltf(PLI_BYTE8 *user_data)
{
vpi_printf("\nIn calltf,\tuser_data = %d\n", *user_data);
if (*user_data == 1) {
vpi_printf("calltf was invoked by $get_vector_bin()\n");
/* read test vectors as binary values */
}
else if (*user_data == 2) {
vpi_printf("calltf was invoked by $get_vector_hex()\n");
/* read test vectors as hex values */
}
return(0);
}/*********************************************************************/

View File

@ -0,0 +1,26 @@
/**********************************************************************
* $get_vector* example -- Verilog HDL test bench.
*
* Verilog test bench to test the $get_vector* PLI application.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
reg [7:0] vector;
initial
begin
#1 vector = $get_vector_bin;
#1 vector = $get_vector_hex;
#1 $finish;
end
endmodule
/*********************************************************************/

View File

@ -0,0 +1,4 @@
// Example Synopsys VCS PLI table to register PLI applications
// For the book, "The Verilog PLI Handbook"
$pow call=PLIbook_PowCalltf check=PLIbook_PowCompiletf size=32 data=0

View File

@ -0,0 +1,25 @@
/**********************************************************************
* Example vpi_user.c file
*
* vpi_user.c file to register PLI applications using the VPI library.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#include "vpi_user.h"
/* prototypes of the PLI application routines */
extern void PLIbook_pow_register();
extern void PLIbook_test_user_data_register();
void (*vlog_startup_routines[])() =
{
/*** add user entries here ***/
PLIbook_pow_register,
PLIbook_test_user_data_register,
0 /*** final entry must be 0 ***/
};

View File

@ -0,0 +1,21 @@
#
# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows
#
MTI_INSTALL_DIR=c:\progra~1\ModelTech
SOURCES = \
show_all_nets_vpi.c \
show_all_signals_1_vpi.c \
# show_all_signals_2_vpi.c \
# show_all_signals_3_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(MTI_INSTALL_DIR)\include -MD
.c.obj:
$(CC) $(CFLAGS) -c $<
../mti_pli.dll: $(OBJS)
link -dll /out:$@ $(OBJS) -EXPORT:vlog_startup_routines $(MTI_INSTALL_DIR)/win32/mtipli.lib

View File

@ -0,0 +1,21 @@
#
# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
show_all_nets_vpi.c \
show_all_signals_1_vpi.c \
# show_all_signals_2_vpi.c \
# show_all_signals_3_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,22 @@
#
# sample NMAKE makefile to make libvpi.dll with VisualC++ on Windows
# see windows.txt for more details.
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
show_all_nets_vpi.c \
show_all_signals_1_vpi.c \
# show_all_signals_2_vpi.c \
# show_all_signals_3_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,15 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
At time 20.00, nets in module top (top):
net results value is 10 (binary)
At time 30.00, nets in module top.i1 (addbit):
net a value is 1 (binary)
net b value is 1 (binary)
net ci value is 0 (binary)
net sum value is 0 (binary)
net co value is 1 (binary)
net n1 value is 0 (binary)
net n2 value is 1 (binary)
net n3 value is 0 (binary)
Simulation complete via $finish(1) at time 40 NS + 0

View File

@ -0,0 +1,50 @@
/**********************************************************************
* $show_all_nets example -- Verilog HDL test bench.
*
* Verilog test bench to test the $show_all_nets PLI application on a
* 1-bit adder modeled using gate primitives.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module top;
reg [2:0] test;
tri [1:0] results;
addbit i1 (test[0], test[1], test[2], results[0], results[1]);
initial
begin
test = 3'b000;
#10 test = 3'b011;
#10 $show_all_nets(top);
#10 $show_all_nets(i1);
// #10 $stop;
#10 $finish;
end
endmodule
/*** A gate level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci, sum, co,
n1, n2, n3;
xor (n1, a, b);
xor #2 (sum, n1, ci);
and (n2, a, b);
and (n3, n1, ci);
or #2 (co, n2, n3);
endmodule
/*********************************************************************/

View File

@ -0,0 +1,135 @@
/**********************************************************************
* $show_all_nets example -- PLI application using VPI routines
*
* C source to scan through a module and list the names of all nets in
* the module with the current logic value.
*
* Usage: $show_all_nets(<module_instance>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_ShowNets_compiletf(PLI_BYTE8 *user_data),
PLIbook_ShowNets_calltf(PLI_BYTE8 *user_data);
/**********************************************************************
* $show_all_nets Registration Data
*********************************************************************/
void PLIbook_ShowNets_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$show_all_nets";
tf_data.calltf = PLIbook_ShowNets_calltf;
tf_data.compiletf = PLIbook_ShowNets_compiletf;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
return;
}
/**********************************************************************
* compiletf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowNets_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, arg_handle;
PLI_INT32 tfarg_type;
int err_flag = 0;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handles to system task arguments */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
vpi_printf("ERROR: $show_all_nets requires 1 argument\n");
err_flag = 1;
}
else {
/* check the type of object in system task arguments */
arg_handle = vpi_scan(arg_iterator);
tfarg_type = vpi_get(vpiType, arg_handle);
if (tfarg_type != vpiModule) {
vpi_printf("ERROR: $show_all_nets arg must be module instance\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
}
else {
/* check that there is only 1 system task argument */
arg_handle = vpi_scan(arg_iterator);
if (arg_handle != NULL) {
vpi_printf("ERROR: $show_all_nets can only have 1 argument\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
} } } /* end of if-else-if-else-if sequence */
if (err_flag) {
vpi_control(vpiFinish, 1); /* abort simulation */
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowNets_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, module_handle,
net_iterator, net_handle;
s_vpi_time current_time;
s_vpi_value current_value;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handle to system task argument */
/* compiletf has already verified only 1 arg with correct type */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
module_handle = vpi_scan(arg_iterator);
vpi_free_object(arg_iterator); /* free iterator memory */
/* read current simulation time */
current_time.type = vpiScaledRealTime;
vpi_get_time(systf_handle, &current_time);
vpi_printf("\nAt time %2.2f, ", current_time.real);
vpi_printf("nets in module %s ",
vpi_get_str(vpiFullName, module_handle));
vpi_printf("(%s):\n", vpi_get_str(vpiDefName, module_handle));
/* obtain handles to nets in module and read current value */
net_iterator = vpi_iterate(vpiNet, module_handle);
if (net_iterator == NULL)
vpi_printf(" no nets found in this module\n");
else {
current_value.format = vpiBinStrVal; /* read values as a string */
while ( (net_handle = vpi_scan(net_iterator)) != NULL ) {
vpi_get_value(net_handle, &current_value);
vpi_printf(" net %-10s value is %s (binary)\n",
vpi_get_str(vpiName, net_handle),
current_value.value.str);
}
}
return(0);
}
/*********************************************************************/

View File

@ -0,0 +1,17 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
At time 20.00, signals in module top (top):
net results value is 10 (binary)
integer test value is 3 (decimal)
real foo value is 3.14
time bar value is f000000ac000000e
At time 30.00, signals in module top.i1 (addbit):
net a value is 1 (binary)
net b value is 1 (binary)
net ci value is 0 (binary)
reg sum value is 0 (binary)
reg co value is 1 (binary)
Simulation complete via $finish(1) at time 40 NS + 0

View File

@ -0,0 +1,56 @@
/**********************************************************************
* $show_all_signals example 1 -- Verilog HDL test bench.
*
* Verilog test bench to test the $show_all_signals PLI application on
* a 1-bit adder modeled using gate primitives.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module top;
tri [1:0] results;
integer test;
real foo;
time bar;
addbit i1 (test[0], test[1], test[2], results[0], results[1]);
initial
begin
test = 3'b000;
foo = 3.14;
bar = 0;
bar[63:60] = 4'hF;
bar[35:32] = 4'hA;
bar[31:28] = 4'hC;
bar[03:00] = 4'hE;
#10 test = 3'b011;
#10 $show_all_signals(top);
#10 $show_all_signals(i1);
// #10 $stop;
#10 $finish;
end
endmodule
/*** An RTL level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci;
reg sum, co;
always @(a or b or ci)
{co, sum} = a + b + ci;
endmodule
/*********************************************************************/

View File

@ -0,0 +1,193 @@
/**********************************************************************
* $show_all_signals example 1 -- PLI application using VPI routines
*
* C source to scan through a module and list the names of all nets,
* reg and variables in the module, with their current logic value.
*
* Usage: $show_all_signals(<module_instance>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_ShowSignals_compiletf(PLI_BYTE8 *user_data),
PLIbook_ShowSignals_calltf(PLI_BYTE8 *user_data);
void PLIbook_PrintSignalValues(vpiHandle signal_iterator);
/**********************************************************************
* $show_all_signals Registration Data
*********************************************************************/
void PLIbook_ShowSignals_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$show_all_signals";
tf_data.calltf = PLIbook_ShowSignals_calltf;
tf_data.compiletf = PLIbook_ShowSignals_compiletf;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
return;
}
/**********************************************************************
* compiletf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowSignals_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, arg_handle;
PLI_INT32 tfarg_type;
int err_flag = 0;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handles to system task arguments */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
vpi_printf("ERROR: $show_all_signals requires 1 argument\n");
err_flag = 1;
}
else {
/* check the type of object in system task arguments */
arg_handle = vpi_scan(arg_iterator);
tfarg_type = vpi_get(vpiType, arg_handle);
if (tfarg_type != vpiModule) {
vpi_printf("ERROR: $show_all_signals arg 1");
vpi_printf(" must be a module instance\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
}
else {
/* check that there is only 1 system task argument */
arg_handle = vpi_scan(arg_iterator);
if (arg_handle != NULL) {
vpi_printf("ERROR: $show_all_signals can only have 1 argument\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
} } } /* end of if-else-if-else-if sequence */
if (err_flag) {
vpi_control(vpiFinish, 1); /* abort simulation */
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowSignals_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, module_handle,
signal_iterator;
PLI_INT32 format;
s_vpi_time current_time;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handle to system task argument
compiletf has already verified only 1 arg with correct type */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
module_handle = vpi_scan(arg_iterator);
vpi_free_object(arg_iterator); /* free iterator memory */
/* read current simulation time */
current_time.type = vpiScaledRealTime;
vpi_get_time(systf_handle, &current_time);
vpi_printf("\nAt time %2.2f, ", current_time.real);
vpi_printf("signals in module %s ",
vpi_get_str(vpiFullName, module_handle));
vpi_printf("(%s):\n", vpi_get_str(vpiDefName, module_handle));
/* obtain handles to nets in module and read current value */
signal_iterator = vpi_iterate(vpiNet, module_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
/* obtain handles to regs in module and read current value */
signal_iterator = vpi_iterate(vpiReg, module_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
/* obtain handles to variables in module and read current value */
signal_iterator = vpi_iterate(vpiVariables, module_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
vpi_printf("\n"); /* add some white space to output */
return(0);
}
void PLIbook_PrintSignalValues(vpiHandle signal_iterator)
{
vpiHandle signal_handle;
PLI_INT32 signal_type;
s_vpi_value current_value;
while ( (signal_handle = vpi_scan(signal_iterator)) != NULL ) {
signal_type = vpi_get(vpiType, signal_handle);
switch (signal_type) {
case vpiNet:
current_value.format = vpiBinStrVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" net %-10s value is %s (binary)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.str);
break;
case vpiReg:
current_value.format = vpiBinStrVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" reg %-10s value is %s (binary)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.str);
break;
case vpiIntegerVar:
current_value.format = vpiIntVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" integer %-10s value is %d (decimal)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.integer);
break;
case vpiRealVar:
current_value.format = vpiRealVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" real %-10s value is %0.2f\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.real);
break;
case vpiTimeVar:
current_value.format = vpiTimeVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" time %-10s value is %x%x\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.time->high,
current_value.value.time->low);
break;
}
}
return;
}
/*********************************************************************/

View File

@ -0,0 +1,37 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
At time 0.00, signals in scope top.i1:
net a value is 0 (binary)
net b value is 0 (binary)
net ci value is 0 (binary)
reg sum value is 0 (binary)
reg co value is 0 (binary)
At time 10.00, signals in scope top:
net results value is 00 (binary)
integer test value is 0 (decimal)
real foo value is 3.14
time bar value is f000000ac000000e
At time 20.00, signals in scope top.i1:
net a value is 0 (binary)
net b value is 1 (binary)
net ci value is 0 (binary)
reg sum value is 1 (binary)
reg co value is 0 (binary)
At time 30.00, signals in scope top.local:
reg foobar value is x (binary)
At time 40.00, signals in scope top.i1:
net a value is 0 (binary)
net b value is 1 (binary)
net ci value is 0 (binary)
reg sum value is 1 (binary)
reg co value is 0 (binary)
Simulation complete via $finish(1) at time 50 NS + 0

View File

@ -0,0 +1,61 @@
/**********************************************************************
* $show_all_signals example 2 -- Verilog HDL test bench.
*
* Verilog test bench to test the $show_all_signals PLI application on
* a 1-bit adder modeled using gate primitives.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module top;
tri [1:0] results;
integer test;
real foo;
time bar;
addbit i1 (test[0], test[1], test[2], results[0], results[1]);
initial
begin
test = 3'b000;
foo = 3.14;
bar = 0;
bar[63:60] = 4'hF;
bar[35:32] = 4'hA;
bar[31:28] = 4'hC;
bar[03:00] = 4'hE;
#10 $show_all_signals;
begin: local
reg foobar;
#10 test = 3'b010;
#10 $show_all_signals;
#10 $show_all_signals(top.i1);
end
// #10 $stop;
#10 $finish;
end
endmodule
/*** An RTL level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci;
reg sum, co;
always @(a or b or ci)
{co, sum} = a + b + ci;
always @(sum)
$show_all_signals();
endmodule
/*********************************************************************/

View File

@ -0,0 +1,217 @@
/**********************************************************************
* $show_all_signals example 2 -- PLI application using VPI routines
*
* C source to scan through a scope and list the names of all nets,
* reg and variables in the scope, with their current logic value.
* - No argument or a null argument to $show_all_signals() is
* interpreted as the scope instance that called the application.
*
* Usage: $show_all_signals(<scope_instance>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_ShowSignals_compiletf(PLI_BYTE8 *user_data),
PLIbook_ShowSignals_calltf(PLI_BYTE8 *user_data);
void PLIbook_PrintSignalValues(vpiHandle signal_iterator);
/**********************************************************************
* $show_all_signals Registration Data
*********************************************************************/
void PLIbook_ShowSignals_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$show_all_signals";
tf_data.calltf = PLIbook_ShowSignals_calltf;
tf_data.compiletf = PLIbook_ShowSignals_compiletf;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
return;
}
/**********************************************************************
* compiletf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowSignals_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, arg_handle;
PLI_INT32 tfarg_type;
int err_flag = 0;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handles to system task arguments */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
return(0); /* no arguments OK; skip remaining checks */
}
/* check the type of object in system task arguments */
arg_handle = vpi_scan(arg_iterator);
tfarg_type = vpi_get(vpiType, arg_handle);
switch (tfarg_type) {
case vpiModule:
case vpiTask:
case vpiFunction:
case vpiNamedBegin:
case vpiNamedFork:
break; /* arg is a scope instance; continue to next check */
case vpiOperation:
if (vpi_get(vpiOpType, arg_handle) == vpiNullOp)
break; /* null argument OK; continue to next check */
default:
/* wrong type specified for an argument */
vpi_printf("ERROR: $show_all_signals arg 1");
vpi_printf(" must be a scope instance or null\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
}
if (err_flag == 0) {
/* check that there is only 1 system task argument */
arg_handle = vpi_scan(arg_iterator);
if (arg_handle != NULL) {
vpi_printf("ERROR: $show_all_signals can only have 1 argument\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
} } /* end of tests */
if (err_flag) {
vpi_control(vpiFinish, 1); /* abort simulation */
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowSignals_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, scope_handle,
signal_iterator;
PLI_INT32 format;
s_vpi_time current_time;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handle to system task argument */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
/* no arguments -- use scope that called this application */
scope_handle = vpi_handle(vpiScope, systf_handle);
}
else {
/* compiletf has already verified arg is scope instance or null */
scope_handle = vpi_scan(arg_iterator);
vpi_free_object(arg_iterator); /* free iterator memory */
if (vpi_get(vpiType, scope_handle) != vpiModule)
/* arg isn't a module instance; assume it is null */
scope_handle = vpi_handle(vpiScope, systf_handle);
}
/* read current simulation time */
current_time.type = vpiScaledRealTime;
vpi_get_time(systf_handle, &current_time);
vpi_printf("\nAt time %2.2f, signals in scope %s:\n",
current_time.real,
vpi_get_str(vpiFullName, scope_handle));
/* obtain handles to nets in module and read current value */
/* nets can only exist if scope is a module */
if (vpi_get(vpiType, scope_handle) == vpiModule) {
signal_iterator = vpi_iterate(vpiNet, scope_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
}
/* obtain handles to regs in scope and read current value */
signal_iterator = vpi_iterate(vpiReg, scope_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
/* obtain handles to variables in scope and read current value */
signal_iterator = vpi_iterate(vpiVariables, scope_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
vpi_printf("\n"); /* add some white space to output */
return(0);
}
void PLIbook_PrintSignalValues(vpiHandle signal_iterator)
{
vpiHandle signal_handle;
int signal_type;
s_vpi_value current_value;
while ( (signal_handle = vpi_scan(signal_iterator)) != NULL ) {
signal_type = vpi_get(vpiType, signal_handle);
switch (signal_type) {
case vpiNet:
current_value.format = vpiBinStrVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" net %-10s value is %s (binary)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.str);
break;
case vpiReg:
current_value.format = vpiBinStrVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" reg %-10s value is %s (binary)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.str);
break;
case vpiIntegerVar:
current_value.format = vpiIntVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" integer %-10s value is %d (decimal)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.integer);
break;
case vpiRealVar:
current_value.format = vpiRealVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" real %-10s value is %0.2f\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.real);
break;
case vpiTimeVar:
current_value.format = vpiTimeVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" time %-10s value is %x%x\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.time->high,
current_value.value.time->low);
break;
}
}
return;
}
/*********************************************************************/

View File

@ -0,0 +1,36 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
At time 0.00, signals in scope top.i1 (addbit):
net a value is 0 (binary)
net b value is 0 (binary)
net ci value is 0 (binary)
reg sum value is 0 (binary)
reg co value is 0 (binary)
At time 10.00, signals in scope top.i1 (addbit):
net a value is 1 (binary)
net b value is 0 (binary)
net ci value is 0 (binary)
reg sum value is 1 (binary)
reg co value is 0 (binary)
At time 20.00, signals in scope top.i1 (addbit):
net a value is 1 (binary)
net b value is 0 (binary)
net ci value is 0 (binary)
reg sum value is 1 (binary)
reg co value is 0 (binary)
At time 20.00, signals in scope top (top):
net results value is 01 (binary)
integer test value is 1 (decimal)
At time 20.00, signals in scope top (top):
net results value is 01 (binary)
integer test value is 1 (decimal)
Simulation complete via $finish(1) at time 30 NS + 0

View File

@ -0,0 +1,49 @@
/**********************************************************************
* $show_all_signals example 3 -- Verilog HDL test bench.
*
* Verilog test bench to test the $show_all_signals PLI application on
* a 1-bit adder modeled using gate primitives.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module top;
integer test;
tri [1:0] results;
addbit i1 (test[0], test[1], test[2], results[0], results[1]);
initial
begin
test = 3'b000;
#10 test = 3'b001;
#10 $show_all_signals(top.i1, ,top); /* second arg is null */
// #10 $stop;
#10 $finish;
end
endmodule
/*** An RTL level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci;
reg sum, co;
always @(a or b or ci)
{co, sum} = a + b + ci;
always @(sum)
$show_all_signals;
endmodule
/*********************************************************************/

View File

@ -0,0 +1,226 @@
/**********************************************************************
* $show_all_signals example 3 -- PLI application using VPI routines
*
* C source to scan through a scope and list the names of all nets,
* reg and variables in the scope, with their current logic value.
* - No argument or a null argument to $show_all_signals() is
* interpreted as the scope instance that called the application.
* - Any number of scope instances can be passed to
* $show_all_instances().
*
* Usage: $show_all_signals(<scope_instance>, <scope_instance>, ...);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_ShowSignals_compiletf(PLI_BYTE8 *user_data),
PLIbook_ShowSignals_calltf(PLI_BYTE8 *user_data);
void PLIbook_GetAllSignals(vpiHandle scope_handle,
p_vpi_time current_time),
PLIbook_PrintSignalValues(vpiHandle signal_iterator);
/**********************************************************************
* $show_all_signals Registration Data
*********************************************************************/
void PLIbook_ShowSignals_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$show_all_signals";
tf_data.calltf = PLIbook_ShowSignals_calltf;
tf_data.compiletf = PLIbook_ShowSignals_compiletf;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
return;
}
/**********************************************************************
* compiletf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowSignals_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, arg_handle;
PLI_INT32 tfarg_type;
int err_flag = 0, tfarg_num = 0;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* obtain handles to system task arguments */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
return(0); /* no arguments OK; skip remaining checks */
}
/* check each argument */
while ( (arg_handle = vpi_scan(arg_iterator)) != NULL ) {
tfarg_num++;
/* check the type of object in system task arguments */
tfarg_type = vpi_get(vpiType, arg_handle);
switch (tfarg_type) {
case vpiModule:
case vpiTask:
case vpiFunction:
case vpiNamedBegin:
case vpiNamedFork:
break; /* arg is a scope instance; continue to next check */
case vpiOperation:
if (vpi_get(vpiOpType, arg_handle) == vpiNullOp) {
break; /* null argument OK; continue to next check */
}
default:
/* wrong type specified for an argument */
vpi_printf("ERROR: $show_all_signals arg %d", tfarg_num);
vpi_printf(" must be a scope instance or null\n");
vpi_free_object(arg_iterator); /* free iterator memory */
err_flag = 1;
}
} /* end of tests */
if (err_flag) {
vpi_control(vpiFinish, 1); /* abort simulation */
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_ShowSignals_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle, arg_iterator, scope_handle;
PLI_INT32 format;
s_vpi_time current_time;
/* obtain a handle to the system task instance */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
/* read current simulation time */
current_time.type = vpiScaledRealTime;
vpi_get_time(systf_handle, &current_time);
/* obtain handle to system task argument */
arg_iterator = vpi_iterate(vpiArgument, systf_handle);
if (arg_iterator == NULL) {
/* no arguments -- use scope that called this application */
scope_handle = vpi_handle(vpiScope, systf_handle);
PLIbook_GetAllSignals(scope_handle, &current_time);
}
else {
/* compiletf has already verified arg is scope instance or null */
while ( (scope_handle = vpi_scan(arg_iterator)) != NULL ) {
if (vpi_get(vpiType, scope_handle) != vpiModule) {
/* arg isn't a module instance; assume it is null */
scope_handle = vpi_handle(vpiScope, systf_handle);
}
PLIbook_GetAllSignals(scope_handle, &current_time);
}
}
return(0);
}
void PLIbook_GetAllSignals(vpiHandle scope_handle, p_vpi_time current_time)
{
vpiHandle signal_iterator;
vpi_printf("\nAt time %2.2f, ", current_time->real);
vpi_printf("signals in scope %s ",
vpi_get_str(vpiFullName, scope_handle));
vpi_printf("(%s):\n", vpi_get_str(vpiDefName, scope_handle));
/* obtain handles to nets in module and read current value */
/* nets can only exist if scope is a module */
if (vpi_get(vpiType, scope_handle) == vpiModule) {
signal_iterator = vpi_iterate(vpiNet, scope_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
}
/* obtain handles to regs in scope and read current value */
signal_iterator = vpi_iterate(vpiReg, scope_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
/* obtain handles to variables in scope and read current value */
signal_iterator = vpi_iterate(vpiVariables, scope_handle);
if (signal_iterator != NULL)
PLIbook_PrintSignalValues(signal_iterator);
vpi_printf("\n"); /* add some white space to output */
return;
}
void PLIbook_PrintSignalValues(vpiHandle signal_iterator)
{
vpiHandle signal_handle;
int signal_type;
s_vpi_value current_value;
while ( (signal_handle = vpi_scan(signal_iterator)) != NULL ) {
signal_type = vpi_get(vpiType, signal_handle);
switch (signal_type) {
case vpiNet:
current_value.format = vpiBinStrVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" net %-10s value is %s (binary)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.str);
break;
case vpiReg:
current_value.format = vpiBinStrVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" reg %-10s value is %s (binary)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.str);
break;
case vpiIntegerVar:
current_value.format = vpiIntVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" integer %-10s value is %d (decimal)\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.integer);
break;
case vpiRealVar:
current_value.format = vpiRealVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" real %-10s value is %0.2f\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.real);
break;
case vpiTimeVar:
current_value.format = vpiTimeVal;
vpi_get_value(signal_handle, &current_value);
vpi_printf(" time %-10s value is %x%x\n",
vpi_get_str(vpiName, signal_handle),
current_value.value.time->high,
current_value.value.time->low);
break;
}
}
return;
}
/*********************************************************************/

View File

@ -0,0 +1,6 @@
// Example Synopsys VCS PLI table to register PLI applications
// For the book, "The Verilog PLI Handbook"
$show_all_nets call=PLIbook_ShowNets_calltf check=PLIbook_ShowNets_compiletf data=0 acc+=read:*
$show_all_signals call=PLIbook_ShowSignals_calltf check=PLIbook_ShowSignals_compiletf data=0 acc+=read:*

View File

@ -0,0 +1,25 @@
/**********************************************************************
* Example vpi_user.c file
*
* vpi_user.c file to register PLI applications using the VPI library.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#include "vpi_user.h"
/* prototypes of the PLI registration routines */
extern void PLIbook_ShowNets_register();
extern void PLIbook_ShowSignals_register();
void (*vlog_startup_routines[])() =
{
/*** add user entries here ***/
PLIbook_ShowNets_register,
PLIbook_ShowSignals_register,
0 /*** final entry must be 0 ***/
};

View File

@ -0,0 +1,23 @@
#
# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows
#
MTI_INSTALL_DIR=c:\progra~1\ModelTech
SOURCES = \
count_args_vpi_test.c \
get_arg_handle_vpi_test.c \
list_pathout_ports_vpi.c \
port_info_vpi.c \
count_all_prims_vpi.c \
invoke_options_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(MTI_INSTALL_DIR)\include -MD
.c.obj:
$(CC) $(CFLAGS) -c $<
../mti_pli.dll: $(OBJS)
link -dll /out:$@ $(OBJS) -EXPORT:vlog_startup_routines $(MTI_INSTALL_DIR)/win32/mtipli.lib

View File

@ -0,0 +1,23 @@
#
# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
count_args_vpi_test.c \
get_arg_handle_vpi_test.c \
list_pathout_ports_vpi.c \
port_info_vpi.c \
count_all_prims_vpi.c \
invoke_options_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,24 @@
#
# sample NMAKE makefile to make libvpi.dll with VisualC++ on Windows
# see windows.txt for more details.
#
CDS_INST_DIR=C:/progra~1/cds/
SOURCES = \
count_args_vpi_test.c \
get_arg_handle_vpi_test.c \
list_pathout_ports_vpi.c \
port_info_vpi.c \
count_all_prims_vpi.c \
invoke_options_vpi.c \
vpi_user.c
OBJS = $(SOURCES:.c=.obj)
CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2
.c.obj:
$(CC) $(CFLAGS) -c $<
libvpi.dll: $(OBJS)
link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib

View File

@ -0,0 +1,5 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
Total number of primitives is 6
Simulation complete via $finish(1) at time 2 NS + 0

View File

@ -0,0 +1,49 @@
/**********************************************************************
* $count_primitives example -- Verilog HDL test bench.
*
* Verilog test bench to test the $count_primitives PLI application
* on a 1-bit adder modeled using gate primitives.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
reg a, b, ci, clk;
wire sum, co, sum2;
addbit i1 (a, b, ci, sum, co);
buf (sum2, sum);
initial
begin
#1 $count_primitives;
#1 $finish;
end
endmodule
/*** A gate level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci, sum, co,
n1, n2, n3;
xor (n1, a, b);
xor #2 (sum, n1, ci);
and (n2, a, b);
and (n3, n1, ci);
or #2 (co, n2, n3);
specify
(a *> sum) = 5;
(b *> sum, co) = 5;
endspecify
endmodule
/*********************************************************************/

View File

@ -0,0 +1,116 @@
/**********************************************************************
* $count_primitives example -- PLI application using VPI routines
*
* C source to find and count all primitives in a design, beginning
* with the top-level module and all levels of hierarchy below the top.
*
* Usage: $count_primitives;
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_CountPrims_compiletf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_CountPrims_calltf(PLI_BYTE8 *user_data);
int PLIbook_find_child_mod(vpiHandle this_mod_h);
int PLIbook_count_local_prims(vpiHandle module_h);
/**********************************************************************
* VPI Registration Data
*********************************************************************/
void PLIbook_CountPrims_register()
{
s_vpi_systf_data tf_data; /* allocate register data structure */
tf_data.type = vpiSysTask;
tf_data.tfname = "$count_primitives";
tf_data.calltf = PLIbook_CountPrims_calltf;
tf_data.compiletf = PLIbook_CountPrims_compiletf;
tf_data.sizetf = NULL;
vpi_register_systf(&tf_data);
}
/*********************************************************************/
/**********************************************************************
* Compiletf application
*********************************************************************/
PLI_INT32 PLIbook_CountPrims_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_h, tfarg_itr, tfarg_h;
systf_h = vpi_handle(vpiSysTfCall, NULL);
if (systf_h == NULL) {
vpi_printf("ERROR: $count_primitives could not obtain handle to systf call\n");
vpi_control(vpiFinish, 1); /* abort simulation */
return(0);
}
tfarg_itr = vpi_iterate(vpiArgument, systf_h);
if (tfarg_itr != NULL) {
vpi_printf("WARNING: arguments to $count_primitives are ignored.\n");
vpi_free_object(tfarg_itr); /* because not scanning until null */
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_CountPrims_calltf(PLI_BYTE8 *user_data)
{
vpiHandle top_mod_itr, top_mod_h;
int total_prims = 0;
top_mod_itr = vpi_iterate(vpiModule, NULL); /*get top modules*/
while (top_mod_h = vpi_scan(top_mod_itr)) {
total_prims += PLIbook_find_child_mod(top_mod_h);
}
vpi_printf("\nTotal number of primitives is %d\n\n", total_prims);
return(0);
}
/**********************************************************************
* Function to look for module instances in local scope.
* THIS FUNCTION CALLS ITSELF RECURSIVELY.
*********************************************************************/
int PLIbook_find_child_mod(vpiHandle this_mod_h)
{
vpiHandle child_mod_itr, child_mod_h;
int prims_in_child;
prims_in_child = PLIbook_count_local_prims(this_mod_h);
child_mod_itr = vpi_iterate(vpiModule, this_mod_h);
if (child_mod_itr != NULL)
while (child_mod_h = vpi_scan(child_mod_itr))
prims_in_child += PLIbook_find_child_mod(child_mod_h);
return(prims_in_child);
}
/**********************************************************************
* Function to count primitives in local scope.
*********************************************************************/
int PLIbook_count_local_prims(vpiHandle module_h)
{
vpiHandle prim_itr, prim_h;
int prims_in_mod = 0;
prim_itr = vpi_iterate(vpiPrimitive, module_h);
if (prim_itr != NULL)
while (prim_h = vpi_scan(prim_itr))
prims_in_mod++;
return (prims_in_mod);
}
/*********************************************************************/

View File

@ -0,0 +1,8 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
Testing PLIbook_numargs_vpi()...
Number of args found = 6: EXPECTED 6
*** All Tests Completed ***
Simulation complete via $finish(1) at time 20 NS + 0

View File

@ -0,0 +1,46 @@
/**********************************************************************
* $count_args_vpi example -- Verilog HDL test bench.
*
* Verilog test bench to test the VPI utility applications.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
reg a, b, ci;
wire sum, co;
real r1;
addbit i1 (a, b, ci, sum, co);
initial
begin
a = 0; b = 1; ci = 1;
r1 = 0.5;
#10 $count_args_vpi(b, r1, "Hello world", i1, /*null arg*/, sum );
#10 $finish;
end
endmodule
/*** A gate level 1 bit adder model ***/
`timescale 1ns / 1ns
module addbit (a, b, ci, sum, co);
input a, b, ci;
output sum, co;
wire a, b, ci, sum, co,
n1, n2, n3;
xor (n1, a, b);
xor #2 (sum, n1, ci);
and (n2, a, b);
and (n3, n1, ci);
or #2 (co, n2, n3);
endmodule
/**********************************************************************/

View File

@ -0,0 +1,83 @@
/**********************************************************************
* VPI PLIbook_count_args_vpi Example -- PLI application using VPI
* routines
*
* C code to test the VPI "PLIbook_count_args_vpi()" application.
*
* NOTE: THIS ROUTINE IS PROVIDED AS SHORT EXAMPLE ON HOW TO ACCESS
* TASK/FUNCTION ARGUMENTS, AND HOW TO PERFORM ERROR CHECKING ON IF
* THE DESIRED INFORMATION WAS OBTAINED. THIS EXAMPLE IS NOT
* INTENDED TO BE AN EFFICIENT PLI APPLICATION. THE FILE
* get_arg_handle_vpi_efficient CONTAINS A MORE EFFICIENT VERSION
* OF THIS EXAMPLE.
*
* Usage:
* numargs = PLIbook_count_args_vpi(<any_number_and_type_of_args>);
* Returns the number of system task/function arguments.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define PLIbookDebug 1 /* set to non-zero for verbose debug messages */
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* Prototypes of the utility applications */
int PLIbook_count_args_vpi();
/**********************************************************************
* PLIbook_count_args_vpi()
* Counts the number of system task/function arguments. Similar to
* tf_nump().
*********************************************************************/
int PLIbook_count_args_vpi()
{
vpiHandle systf_h, arg_itr, arg_h;
int tfnum = 0;
s_vpi_error_info err; /* structure for error handling */
systf_h = vpi_handle(vpiSysTfCall, NULL);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_count_args_vpi() could not obtain handle to systf call\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (systf_h == NULL)
vpi_printf("ERROR: PLIbook_count_args_vpi() could not obtain handle to systf call\n");
#endif
arg_itr = vpi_iterate(vpiArgument, systf_h);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_count_args_vpi() could not obtain iterator to systf args\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (arg_itr == NULL)
vpi_printf("ERROR: PLIbook_count_args_vpi() could not obtain iterator to systf args\n");
#endif
while (arg_h = vpi_scan(arg_itr) ) {
tfnum++;
}
return(tfnum);
}
/*********************************************************************/

View File

@ -0,0 +1,57 @@
/**********************************************************************
* $count_args_vpi example -- PLI application using VPI routines
*
* Tests the VPI PLIbook_count_args_vpi() application.
*
* Usage: initial $count_args_vpi(<any_number_and_type_of_arguments>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_CountArgsTestCall(PLI_BYTE8 *user_data);
#include "count_args_vpi.c" /* include the VPI application */
/* #include "get_arg_handle_vpi_efficient.c" /* include VPI app. */
/**********************************************************************
* VPI Registration Data
*********************************************************************/
void PLIbook_CountArgsTest_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$count_args_vpi";
tf_data.calltf = PLIbook_CountArgsTestCall;
tf_data.compiletf = NULL;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}
/**********************************************************************/
/**********************************************************************
* calltf routine to exercise various utility functions.
*********************************************************************/
PLI_INT32 PLIbook_CountArgsTestCall(PLI_BYTE8 *user_data)
{
int num_args;
vpi_printf("\n Testing PLIbook_numargs_vpi()...\n");
num_args = PLIbook_count_args_vpi();
vpi_printf(" Number of args found = %d: EXPECTED 6\n", num_args);
vpi_printf("\n*** All Tests Completed ***\n\n");
return(0);
}
/*********************************************************************/

View File

@ -0,0 +1,18 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
Testing PLIbook_get_arg_handle_vpi() With Good Values...
PLIbook_get_arg_handle_vpi() is allocating workarea storage for task args
Handle to arg 1 is a: EXPECTED a
Handle to arg 3 is sum: EXPECTED sum
Testing PLIbook_get_arg_handle_vpi_vpi() with invalid index numbers...
ERROR: PLIbook_get_arg_handle_vpi() arg index of 0 is invalid
Handle to arg 0 is 0: EXPECTED 0 (NULL)
ERROR: PLIbook_get_arg_handle_vpi() arg index of 6 is out-of-range
Handle to arg 6 is 0: EXPECTED 0 (NULL)
*** All Tests Completed ***
Simulation complete via $finish(1) at time 20 NS + 0

View File

@ -0,0 +1,26 @@
/**********************************************************************
* $get_arg_handle_test example -- Verilog HDL test bench.
*
* Verilog test bench to test the VPI get_arg_handle application.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
`timescale 1ns / 1ns
module test;
reg a, b, ci;
wire sum, co;
initial
begin
a = 0; b = 1; ci = 1;
#10 $get_arg_handle_test(a, b, sum);
#10 $finish;
end
endmodule
/**********************************************************************/

View File

@ -0,0 +1,199 @@
/**********************************************************************
* PLIbook_count_args_vpi and PLIbook_get_arg_handle_vpi Examples
* PLI application using VPI routines
*
* C source for functions to access handles of system task/function
* arguments.
*
* Usage:
* numargs = PLIbook_count_args_vpi(<any_number_and_type_of_args>);
* Returns the number of system task/function arguments.
*
* arg_handle = PLIbook_get_arg_handle_vpi(arg_index_number);
* Returns a handke for a system task/function argument,
* using the index number of the argument, beginning with 1.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define PLIbookDebug 1 /* set to non-zero for verbose debug messages */
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* Prototypes of the applications */
int PLIbook_count_args_vpi();
vpiHandle PLIbook_get_arg_handle_vpi(int argNum);
vpiHandle *create_arg_array(vpiHandle systf_h);
/**********************************************************************
* PLIbook_count_args_vpi() -- Efficient Version
* Counts the number of system task/function arguments. Similar to
* tf_nump().
*********************************************************************/
int PLIbook_count_args_vpi()
{
vpiHandle systf_h, arg_itr, arg_h;
int tfnum = 0;
vpiHandle *arg_array; /* array pointer to store arg handles */
#if PLIbookDebug
s_vpi_error_info err; /* structure for error handling */
#endif
systf_h = vpi_handle(vpiSysTfCall, NULL);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_count_args_vpi() could not obtain handle to systf call\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (systf_h == NULL)
vpi_printf("ERROR: PLIbook_count_args_vpi() could not obtain handle to systf call\n");
#endif
/* retrieve pointer to array with all argument handles */
arg_array = (vpiHandle *)vpi_get_userdata(systf_h);
if (arg_array == NULL) {
/* array with all argument handles doesn't exist, create it */
arg_array = create_arg_array(systf_h);
}
return((int)arg_array[0]);
}
/**********************************************************************
* PLIbook_get_arg_handle_vpi() -- Efficient Version
* Obtain a handle to a system task/function argument, using the
* argument index number. Similar to acc_handle_tfarg().
*
* ARGUMENTS ARE NUMBERED FROM LEFT TO RIGHT, BEGINNING WITH 1.
*
* This version is more efficient because it allocates memory and
* stores the task arg handles so that vpi_iterate() and vpi_scan()
* do not need to be called each time this application is called.
*********************************************************************/
vpiHandle PLIbook_get_arg_handle_vpi(int argNum)
{
vpiHandle systf_h, arg_h;
vpiHandle *arg_array; /* array pointer to store arg handles */
#if PLIbookDebug
s_vpi_error_info err; /* structure for error handling */
#endif
if (argNum < 1) {
#if PLIbookDebug /* if error, generate verbose debug message */
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() arg index of %d is invalid\n",
argNum);
#endif
return(NULL);
}
systf_h = vpi_handle(vpiSysTfCall, NULL);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain handle to systf call\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (systf_h == NULL) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain handle to systf call\n");
return(NULL);
}
#endif
/* retrieve pointer to array with all argument handles */
arg_array = (vpiHandle *)vpi_get_userdata(systf_h);
if (arg_array == NULL) {
/* array with all argument handles doesn't exist, create it */
arg_array = create_arg_array(systf_h);
}
if (argNum > (int)arg_array[0]) {
#if PLIbookDebug /* if error, generate verbose debug message */
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() arg index of %d is out-of-range\n",
argNum);
#endif
return(NULL);
}
/* get requested tfarg handle from array */
arg_h = (vpiHandle)arg_array[argNum];
return(arg_h);
}
/**********************************************************************
* Subroutine to allocate an array and store the number of arguments
* and all argument handles in the array.
*********************************************************************/
vpiHandle *create_arg_array(vpiHandle systf_h)
{
vpiHandle arg_itr, arg_h;
vpiHandle *arg_array; /* array pointer to store arg handles */
int i, tfnum = 0;
#if PLIbookDebug
s_vpi_error_info err; /* structure for error handling */
#endif
/* allocate array based on the number of task/function arguments */
arg_itr = vpi_iterate(vpiArgument, systf_h);
if (arg_itr == NULL) {
vpi_printf("ERROR: PLIbook_numargs_vpi() could not obtain iterator to systf args\n");
return(NULL);
}
while (arg_h = vpi_scan(arg_itr) ) { /* count number of args */
tfnum++;
}
arg_array = (vpiHandle *)malloc(sizeof(vpiHandle) * (tfnum + 1));
/* store pointer to array in simulator-allocated user_data storage
that is unique for each task/func instance */
vpi_put_userdata(systf_h, (void *)arg_array);
/* store number of arguments in first address in array */
arg_array[0] = (vpiHandle)tfnum;
/* fill the array with handles to each task/function argument */
arg_itr = vpi_iterate(vpiArgument, systf_h);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain iterator to systf args\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (systf_h == NULL) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain iterator to systf args\n");
return(NULL);
}
#endif
for (i=1; i<=tfnum; i++) {
arg_h = vpi_scan(arg_itr);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain handle to systf arg %d\n", i);
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#endif
arg_array[i] = arg_h;
}
if (arg_h != NULL)
vpi_free_object(arg_itr); /* free iterator--didn't scan all args */
return(arg_array);
}
/*********************************************************************/

View File

@ -0,0 +1,119 @@
/**********************************************************************
* PLIbook_get_arg_handle_vpi Example -- PLI application using VPI
* routines
*
* C source for function to access handles of system task/function
* arguments.
*
* NOTE: THIS ROUTINE IS PROVIDED AS A SHORT EXAMPLE ON HOW TO ACCESS
* TASK/FUNCTION ARGUMENTS, AND HOW TO PERFORM ERROR CHECKING ON IF
* THE DESIRED INFORMATION WAS OBTAINED. THE EXAMPLE IS NOT
* INTENDED TO BE A COMPLETE PLI APPLICATION IN AND OF ITSELF, AND
* IS NOT EFFICIENT FOR SIMULATION PERFORMACE.
*
* Usage:
* arg_handle = PLIbook_get_arg_handle_vpi(arg_index_number);
* Returns a handke for a system task/function argument,
* using the index number of the argument, beginning with 1.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define PLIbookDebug 1 /* set to non-zero for verbose debug messages */
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* Prototypes of the applications */
vpiHandle PLIbook_get_arg_handle_vpi(int argNum);
/**********************************************************************
* PLIbook_get_arg_handle_vpi()
* Obtain a handle to a system task/function argument, using the
* argument index number. Similar to acc_handle_tfarg().
*
* ARGUMENTS ARE NUMBERED FROM LEFT TO RIGHT, BEGINNING WITH 1.
*
* The method used in this version is not as efficient as it could be,
* because this example must call vpi_iterate() and vpi_scan() each
* time this application is called.
*********************************************************************/
vpiHandle PLIbook_get_arg_handle_vpi(int argNum)
{
vpiHandle systf_h, arg_itr, arg_h;
int i;
#if PLIbookDebug
s_vpi_error_info err; /* structure for error handling */
#endif
if (argNum < 1) {
#if PLIbookDebug /* if error, generate verbose debug message */
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() arg index of %d is invalid\n",
argNum);
#endif
return(NULL);
}
systf_h = vpi_handle(vpiSysTfCall, NULL);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain handle to systf call\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (systf_h == NULL) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain handle to systf call\n");
return(NULL);
}
#endif
arg_itr = vpi_iterate(vpiArgument, systf_h);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain iterator to systf args\n");
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#else /* if error, generate brief error message */
if (systf_h == NULL) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain iterator to systf args\n");
return(NULL);
}
#endif
for (i=1; i<=argNum; i++) {
arg_h = vpi_scan(arg_itr);
#if PLIbookDebug /* if error, generate verbose debug message */
if (vpi_chk_error(&err)) {
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() could not obtain handle to systf arg %d\n", i);
vpi_printf("File %s, Line %d: %s\n",
err.file, err.line, err.message);
}
#endif
if (arg_h == NULL) {
#if PLIbookDebug /* if error, generate verbose debug message */
vpi_printf("ERROR: PLIbook_get_arg_handle_vpi() arg index of %d is out-of-range\n",
argNum);
#endif
return(NULL);
}
}
if (arg_h != NULL)
vpi_free_object(arg_itr); /* free iterator--didn't scan all args */
return(arg_h);
}
/*********************************************************************/

View File

@ -0,0 +1,78 @@
/**********************************************************************
* $get_arg_handle_test example -- PLI application using VPI routines
*
* C code to test the VPI "PLIbook_get_arg_handle_vpi() application.
*
* Usage: initial
* $get_arg_handle_test(arg1, arg2, arg3);
*
* The arguments can be any Verilog data type.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
/* prototypes of the PLI application routines */
PLI_INT32 PLIbook_GetArgTestCall(PLI_BYTE8 *user_data);
/* #include "get_arg_handle_vpi_inefficient.c" /* include VPI app. */
#include "get_arg_handle_vpi_efficient.c" /* include VPI app. */
/**********************************************************************
* VPI Registration Data
*********************************************************************/
void PLIbook_GetArgTest_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.sysfunctype = 0;
tf_data.tfname = "$get_arg_handle_test";
tf_data.calltf = PLIbook_GetArgTestCall;
tf_data.compiletf = NULL;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}
/**********************************************************************/
/**********************************************************************
* calltf routine to exercise various utility functions.
*********************************************************************/
PLI_INT32 PLIbook_GetArgTestCall(PLI_BYTE8 *user_data)
{
vpiHandle arg0_h, arg1_h, arg2_h, arg3_h, arg4_h, arg5_h, arg6_h;
vpi_printf("\nTesting PLIbook_get_arg_handle_vpi() With Good Values...\n\n");
arg1_h = PLIbook_get_arg_handle_vpi(1);
vpi_printf(" Handle to arg 1 is %s: EXPECTED a\n",
vpi_get_str(vpiName, arg1_h));
arg3_h = PLIbook_get_arg_handle_vpi(3);
vpi_printf(" Handle to arg 3 is %s: EXPECTED sum\n",
vpi_get_str(vpiName, arg3_h));
vpi_printf("\nTesting PLIbook_get_arg_handle_vpi_vpi() with invalid index numbers...\n\n");
arg0_h = PLIbook_get_arg_handle_vpi(0);
vpi_printf(" Handle to arg 0 is %d: EXPECTED 0 (NULL)\n",
arg0_h);
arg6_h = PLIbook_get_arg_handle_vpi(6);
vpi_printf(" Handle to arg 6 is %d: EXPECTED 0 (NULL)\n",
arg6_h);
vpi_printf("\n*** All Tests Completed ***\n\n");
return(0);
}
/*********************************************************************/

View File

@ -0,0 +1,41 @@
ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc.
ncverilog
+a
+b
-f
invoke_options_test1.f
invoke_options_test.v
+a1
+b1
-f
invoke_options_test2.f
+a2
+b2
+test2
+c2
+c1
+c
Simulation was NOT invoked with a +test1 option
ncverilog
+a
+b
-f
invoke_options_test1.f
invoke_options_test.v
+a1
+b1
-f
invoke_options_test2.f
+a2
+b2
+test2
+c2
+c1
+c
Simulation WAS invoked with a +test2 option
Simulation complete via $finish(1) at time 1 NS + 0

View File

@ -0,0 +1,37 @@
/**************************************************************************
* $test_invoke_options example -- Verilog test bench source code
*
* Verilog test bench to test the $test_invoke_options PLI application.
*
* NOTE: This test uses two supplemental files: invoke_options_test1.f and
* invoke_options_test1.f. This test is designed to be invoked as follows:
*
* <simulator_compile_command> invoke_options_test.v
* <simulator_run_command> +a +b -f invoke_options_test1.f +c
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*************************************************************************/
`timescale 1ns / 1ns
module test;
reg option_exists;
initial
begin
option_exists = $test_invoke_options("+test1");
if (option_exists)
$display("\nSimulation WAS invoked with a +test1 option\n");
else
$display("\nSimulation was NOT invoked with a +test1 option\n");
if ($test_invoke_options("+test2"))
$display("\nSimulation WAS invoked with a +test2 option\n");
else
$display("\nSimulation was NOT invoked with a +test2 option\n");
#1 $finish;
end
endmodule

View File

@ -0,0 +1,7 @@
//command file
invoke_options_test.v
+a1
+b1
//+test1
-f invoke_options_test2.f
+c1

View File

@ -0,0 +1,5 @@
//command file
+a2
+b2
+test2
+c2

View File

@ -0,0 +1,189 @@
/**********************************************************************
* $test_invoke_options example -- PLI application using VPI routines
*
* C source to test for aany simulation invocation option, including
* user-defined options. The system function will return 1 if an
* invocation option was present when simulation was invoked, and will
* return 0 if the option did not exist.
*
* Usage: reg flag;
flag = $test_invoke_options("<invocation_option>");
* Where <invocation_option can be any + or - option.
*
* Debug tip: Uncomment the line "#define PLIbook_verbose" to enable
* this application to list all simulation invocation options.
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland-hdl.com
*********************************************************************/
#define PLIbook_verbose 1 /* set to non-zero for verbose messages */
#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#if VPI_1995
#include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */
#endif
/* prototypes of routines in this PLI application */
PLI_INT32 PLIbook_TestInvokeOptions_calltf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_TestInvokeOptions_compiletf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_TestInvokeOptions_sizetf(PLI_BYTE8 *user_data);
int PLIbook_GetOptions(char *option, int argc, char **argv);
void PLIbook_ScanCommandFile(char *option, char **arg);
/**********************************************************************
* VPI Registration Data
*********************************************************************/
void PLIbook_TestInvokeOptions_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$test_invoke_options";
tf_data.calltf = PLIbook_TestInvokeOptions_calltf;
tf_data.compiletf = PLIbook_TestInvokeOptions_compiletf;
tf_data.sizetf = PLIbook_TestInvokeOptions_sizetf;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}
/**********************************************************************
* sizetf application
*********************************************************************/
PLI_INT32 PLIbook_TestInvokeOptions_sizetf(PLI_BYTE8 *user_data)
{
return(1); /* $test_invoke_options returns a 1-bit value */
}
/**********************************************************************
* calltf routine
*********************************************************************/
PLI_INT32 PLIbook_TestInvokeOptions_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_h, arg_itr, arg_h;
char *option_name;
s_vpi_value value_s;
s_vpi_vlog_info sim_info;
int found;
vpi_get_vlog_info(&sim_info);
/* get system function arg--compiletf already verified correctness */
systf_h = vpi_handle(vpiSysTfCall, NULL);
arg_itr = vpi_iterate(vpiArgument, systf_h);
arg_h = vpi_scan(arg_itr);
vpi_free_object(arg_itr); /* free iterator -- did not scan to null */
/* read target option name from first tfarg */
value_s.format = vpiStringVal;
vpi_get_value(arg_h, &value_s);
option_name = value_s.value.str;
/* test for target option and return true/false to system function */
found = PLIbook_GetOptions((char *)option_name,
(int)sim_info.argc,
(char **)sim_info.argv );
value_s.format = vpiIntVal;
value_s.value.integer = found;
vpi_put_value(systf_h, &value_s, NULL, vpiNoDelay);
return(0);
}
int PLIbook_optfound = 0; /* global variable for option found flag */
int PLIbook_indent = 0; /* global variable to format text indenting */
int PLIbook_GetOptions(char *option, int argc, char **argv)
{
int i;
PLIbook_optfound = 0;
PLIbook_indent = 0;
for (i=0; i<argc; i++) {
#if PLIbook_verbose
vpi_printf("%s\n", *argv);
#endif
if (strcmp(*argv, option) == 0) {
PLIbook_optfound = 1;
}
if (strcmp(*argv, "-f") == 0) {
argv++; /* next arg is address to array of strings */
i++;
PLIbook_ScanCommandFile(option, (char **)*argv);
}
argv++; /* increment to next argument */
}
return(PLIbook_optfound);
}
void PLIbook_ScanCommandFile(char *option, char **arg)
{
int i;
#if PLIbook_verbose
PLIbook_indent += 4; /* increase text indentation */
#endif
while ( *arg != NULL ) { /* loop until null termination */
#if PLIbook_verbose
for (i=0; i<=PLIbook_indent; i++)
vpi_printf(" ");
vpi_printf("%s\n", *arg);
#endif
if (strcmp(*arg, option) == 0) {
PLIbook_optfound = 1;
}
if (strcmp(*arg, "-f") == 0) {
arg++; /* next arg is address to array of strings */
PLIbook_ScanCommandFile(option, (char **)*arg);
}
arg++;
}
#if PLIbook_verbose
PLIbook_indent -= 4; /* decrease text indentation */
#endif
return;
}
/**********************************************************************
* compiletf routine
*********************************************************************/
PLI_INT32 PLIbook_TestInvokeOptions_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_h, arg_itr, arg_h;
int err = 0;
systf_h = vpi_handle(vpiSysTfCall, NULL);
arg_itr = vpi_iterate(vpiArgument, systf_h);
if (arg_itr == NULL) {
vpi_printf("ERROR: $test_invoke_options requires 1 argument\n");
vpi_control(vpiFinish, 1); /* abort simulation */
return(0);
}
arg_h = vpi_scan(arg_itr); /* get handle for first tfarg */
if (vpi_get(vpiType, arg_h) != vpiConstant) {
vpi_printf("$test_invoke_options arg must be a quoted name\n");
err = 1;
}
else if (vpi_get(vpiConstType, arg_h) != vpiStringConst) {
vpi_printf("$test_invoke_options arg must be a string\n");
err = 1;
}
if (vpi_scan(arg_itr) != NULL) {
vpi_printf("test_invoke_options requires only 1 argument\n");
vpi_free_object(arg_itr);
err = 1;
}
if (err)
vpi_control(vpiFinish, 1); /* abort simulation */
return(0);
}
/*********************************************************************/

Some files were not shown because too many files have changed in this diff Show More