diff --git a/me250300_pli/The Verilog PLI Handbook.pdf b/me250300_pli/The Verilog PLI Handbook.pdf new file mode 100644 index 0000000..2fc0155 Binary files /dev/null and b/me250300_pli/The Verilog PLI Handbook.pdf differ diff --git a/me250300_pli/pli_socket_example_unix/Makefile b/me250300_pli/pli_socket_example_unix/Makefile new file mode 100644 index 0000000..ad62d32 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/Makefile @@ -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/* + + diff --git a/me250300_pli/pli_socket_example_unix/Makefile.hppa b/me250300_pli/pli_socket_example_unix/Makefile.hppa new file mode 100644 index 0000000..6c37959 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/Makefile.hppa @@ -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 diff --git a/me250300_pli/pli_socket_example_unix/Makefile.linux b/me250300_pli/pli_socket_example_unix/Makefile.linux new file mode 100644 index 0000000..6f0b79c --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/Makefile.linux @@ -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 = diff --git a/me250300_pli/pli_socket_example_unix/Makefile.sun4v b/me250300_pli/pli_socket_example_unix/Makefile.sun4v new file mode 100644 index 0000000..4b43d0e --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/Makefile.sun4v @@ -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 = diff --git a/me250300_pli/pli_socket_example_unix/Makefile.winnt b/me250300_pli/pli_socket_example_unix/Makefile.winnt new file mode 100644 index 0000000..a5a2846 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/Makefile.winnt @@ -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} diff --git a/me250300_pli/pli_socket_example_unix/README b/me250300_pli/pli_socket_example_unix/README new file mode 100644 index 0000000..f05ff08 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/README @@ -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 / 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 diff --git a/me250300_pli/pli_socket_example_unix/README_FIRST b/me250300_pli/pli_socket_example_unix/README_FIRST new file mode 100644 index 0000000..6600f25 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/README_FIRST @@ -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 + +======================================================================= diff --git a/me250300_pli/pli_socket_example_unix/include/com_exp.h b/me250300_pli/pli_socket_example_unix/include/com_exp.h new file mode 100644 index 0000000..9169395 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/include/com_exp.h @@ -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 diff --git a/me250300_pli/pli_socket_example_unix/include/com_exp.h~ b/me250300_pli/pli_socket_example_unix/include/com_exp.h~ new file mode 100644 index 0000000..e83c7cb --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/include/com_exp.h~ @@ -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 diff --git a/me250300_pli/pli_socket_example_unix/include/socketUtil.h b/me250300_pli/pli_socket_example_unix/include/socketUtil.h new file mode 100644 index 0000000..607ea35 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/include/socketUtil.h @@ -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(); diff --git a/me250300_pli/pli_socket_example_unix/pli/Makefile b/me250300_pli/pli_socket_example_unix/pli/Makefile new file mode 100644 index 0000000..269f7d0 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/pli/Makefile @@ -0,0 +1,6 @@ +TARGETS: + cd dispargs; make + +clean: + cd dispargs; make clean + diff --git a/me250300_pli/pli_socket_example_unix/pli/dispargs/Makefile b/me250300_pli/pli_socket_example_unix/pli/dispargs/Makefile new file mode 100644 index 0000000..10c6c84 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/pli/dispargs/Makefile @@ -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 diff --git a/me250300_pli/pli_socket_example_unix/pli/dispargs/README b/me250300_pli/pli_socket_example_unix/pli/dispargs/README new file mode 100644 index 0000000..e7870dd --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/pli/dispargs/README @@ -0,0 +1,7 @@ +This example will dump all the command line arguments. It will also +dump out the contents of any -f being used. + + +To run the test case: + + -f run.vc diff --git a/me250300_pli/pli_socket_example_unix/pli/dispargs/dispargs.c b/me250300_pli/pli_socket_example_unix/pli/dispargs/dispargs.c new file mode 100644 index 0000000..775da5e --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/pli/dispargs/dispargs.c @@ -0,0 +1,93 @@ +#include + +#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 +#include +#include +#include +#include + +#ifndef WINNT +#include +#include +#include +#include +#include +#if defined(SUN4V) +#include +#endif +#else +#include +#endif + +#include +#include + +#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]); +} diff --git a/me250300_pli/pli_socket_example_unix/util/socket/socketUtil.h b/me250300_pli/pli_socket_example_unix/util/socket/socketUtil.h new file mode 100644 index 0000000..607ea35 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/util/socket/socketUtil.h @@ -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(); diff --git a/me250300_pli/pli_socket_example_unix/vpi/Makefile b/me250300_pli/pli_socket_example_unix/vpi/Makefile new file mode 100644 index 0000000..7ac2600 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/Makefile @@ -0,0 +1,8 @@ +TARGETS: + cd dispargs; make + cd remmodel; make + +clean: + cd dispargs; make clean + cd remmodel; make clean + diff --git a/me250300_pli/pli_socket_example_unix/vpi/dispargs/.so b/me250300_pli/pli_socket_example_unix/vpi/dispargs/.so new file mode 100644 index 0000000..a1653f6 Binary files /dev/null and b/me250300_pli/pli_socket_example_unix/vpi/dispargs/.so differ diff --git a/me250300_pli/pli_socket_example_unix/vpi/dispargs/Makefile b/me250300_pli/pli_socket_example_unix/vpi/dispargs/Makefile new file mode 100644 index 0000000..a3e48a0 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/dispargs/Makefile @@ -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 diff --git a/me250300_pli/pli_socket_example_unix/vpi/dispargs/README b/me250300_pli/pli_socket_example_unix/vpi/dispargs/README new file mode 100644 index 0000000..e7870dd --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/dispargs/README @@ -0,0 +1,7 @@ +This example will dump all the command line arguments. It will also +dump out the contents of any -f being used. + + +To run the test case: + + -f run.vc diff --git a/me250300_pli/pli_socket_example_unix/vpi/dispargs/dispargs.c b/me250300_pli/pli_socket_example_unix/vpi/dispargs/dispargs.c new file mode 100644 index 0000000..369d945 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/dispargs/dispargs.c @@ -0,0 +1,96 @@ +#include + +#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 -f run.vc + + + diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/modelMain.c b/me250300_pli/pli_socket_example_unix/vpi/remmodel/modelMain.c new file mode 100644 index 0000000..93d86a6 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/modelMain.c @@ -0,0 +1,91 @@ +#include +#include +#ifndef WINNT +#include +#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\n"); + } + + } + else + { + fd = fileno(stdin); + fdOut = fileno(stdout); + } + + + while((data = sockGetLine(fd, 0))) + { + runModel(fdOut, server, data); + } + close(fd); + exit(0); +} diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/remmodel.c b/me250300_pli/pli_socket_example_unix/vpi/remmodel/remmodel.c new file mode 100644 index 0000000..86f4bef --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/remmodel.c @@ -0,0 +1,550 @@ +#include +#include +#include +#include +#include + +#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;cntnumPorts;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); +} + diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/run.vc b/me250300_pli/pli_socket_example_unix/vpi/remmodel/run.vc new file mode 100644 index 0000000..1b1980e --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/run.vc @@ -0,0 +1,5 @@ +-q ++accwarn ++loadvpi=librem:regRemModel +test.v + diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/runModel.c b/me250300_pli/pli_socket_example_unix/vpi/remmodel/runModel.c new file mode 100644 index 0000000..2657c02 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/runModel.c @@ -0,0 +1,378 @@ +#include +#include +#include +#include +#include +#include +#ifndef WINNT +#include +#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; +} + + + + diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/runModel.h b/me250300_pli/pli_socket_example_unix/vpi/remmodel/runModel.h new file mode 100644 index 0000000..c2abad4 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/runModel.h @@ -0,0 +1 @@ +char *runModel(int fd, int fdServ, char *data); diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/test.v b/me250300_pli/pli_socket_example_unix/vpi/remmodel/test.v new file mode 100644 index 0000000..62992d4 --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/test.v @@ -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 + + + + + diff --git a/me250300_pli/pli_socket_example_unix/vpi/remmodel/vlogmodel.c b/me250300_pli/pli_socket_example_unix/vpi/remmodel/vlogmodel.c new file mode 100644 index 0000000..91795af --- /dev/null +++ b/me250300_pli/pli_socket_example_unix/vpi/remmodel/vlogmodel.c @@ -0,0 +1,10 @@ +extern void regRemModel(); + +#ifdef WINNT +__declspec(dllexport) +#endif +void (*vlog_startup_routines[])() = +{ + regRemModel, + 0 +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.01/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.01/build_MTI.mak new file mode 100644 index 0000000..f7f88a7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/build_MTI.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.01/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.01/build_NC.mak new file mode 100644 index 0000000..574fcab --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/build_NC.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.01/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.01/build_XL.mak new file mode 100644 index 0000000..e96d0a3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/build_XL.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.01/hello_test.log b/me250300_pli/plibook_examples_unix/chapter.01/hello_test.log new file mode 100644 index 0000000..7adfdf1 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/hello_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.01/hello_test.v b/me250300_pli/plibook_examples_unix/chapter.01/hello_test.v new file mode 100644 index 0000000..c0b7283 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/hello_test.v @@ -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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.01/hello_vpi.c b/me250300_pli/plibook_examples_unix/chapter.01/hello_vpi.c new file mode 100644 index 0000000..361483e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/hello_vpi.c @@ -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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} diff --git a/me250300_pli/plibook_examples_unix/chapter.01/show_value_test.log b/me250300_pli/plibook_examples_unix/chapter.01/show_value_test.log new file mode 100644 index 0000000..358af78 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/show_value_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.01/show_value_test.v b/me250300_pli/plibook_examples_unix/chapter.01/show_value_test.v new file mode 100644 index 0000000..1644762 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/show_value_test.v @@ -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 +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.01/show_value_vpi.c b/me250300_pli/plibook_examples_unix/chapter.01/show_value_vpi.c new file mode 100644 index 0000000..bbc4b64 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/show_value_vpi.c @@ -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(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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, ¤t_value); + vpi_printf("Signal %s ", vpi_get_str(vpiFullName, net_handle)); + vpi_printf("has the value %s\n", current_value.value.str); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.01/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.01/veriuser_VCS.tab new file mode 100644 index 0000000..8c46dcf --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/veriuser_VCS.tab @@ -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:* diff --git a/me250300_pli/plibook_examples_unix/chapter.01/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.01/vpi_user.c new file mode 100644 index 0000000..47ec9c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.01/vpi_user.c @@ -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 ***/ +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.02/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.02/build_MTI.mak new file mode 100644 index 0000000..f1f4740 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/build_MTI.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.02/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.02/build_NC.mak new file mode 100644 index 0000000..b4b1362 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/build_NC.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.02/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.02/build_XL.mak new file mode 100644 index 0000000..7c97bac --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/build_XL.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.02/pow_test.log b/me250300_pli/plibook_examples_unix/chapter.02/pow_test.log new file mode 100644 index 0000000..0b9667b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/pow_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.02/pow_test.v b/me250300_pli/plibook_examples_unix/chapter.02/pow_test.v new file mode 100644 index 0000000..49b4375 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/pow_test.v @@ -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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.02/pow_vpi.c b/me250300_pli/plibook_examples_unix/chapter.02/pow_vpi.c new file mode 100644 index 0000000..3610431 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/pow_vpi.c @@ -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(,); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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 +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); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.02/user_data_vpi.c b/me250300_pli/plibook_examples_unix/chapter.02/user_data_vpi.c new file mode 100644 index 0000000..5489ea8 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/user_data_vpi.c @@ -0,0 +1,75 @@ +/*********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +}/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.02/user_data_vpi_test.v b/me250300_pli/plibook_examples_unix/chapter.02/user_data_vpi_test.v new file mode 100644 index 0000000..67da317 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/user_data_vpi_test.v @@ -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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.02/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.02/veriuser_VCS.tab new file mode 100644 index 0000000..40fa4f2 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/veriuser_VCS.tab @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.02/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.02/vpi_user.c new file mode 100644 index 0000000..8e3a25e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.02/vpi_user.c @@ -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 ***/ +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.03/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.03/build_MTI.mak new file mode 100644 index 0000000..85791fb --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/build_MTI.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.03/build_NC.mak new file mode 100644 index 0000000..1b778ae --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/build_NC.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.03/build_XL.mak new file mode 100644 index 0000000..d21a568 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/build_XL.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_test.log b/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_test.log new file mode 100644 index 0000000..7b1c094 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_test.v b/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_test.v new file mode 100644 index 0000000..88a00b3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_test.v @@ -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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_vpi.c b/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_vpi.c new file mode 100644 index 0000000..eafd6b7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_nets_vpi.c @@ -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(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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, ¤t_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, ¤t_value); + vpi_printf(" net %-10s value is %s (binary)\n", + vpi_get_str(vpiName, net_handle), + current_value.value.str); + } + } + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_test.log b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_test.log new file mode 100644 index 0000000..e3a6bf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_test.v b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_test.v new file mode 100644 index 0000000..e3f854c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_test.v @@ -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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_vpi.c b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_vpi.c new file mode 100644 index 0000000..ada4d2b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_1_vpi.c @@ -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(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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; +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_test.log b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_test.log new file mode 100644 index 0000000..1744fc7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_test.v b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_test.v new file mode 100644 index 0000000..593df0d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_test.v @@ -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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_vpi.c b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_vpi.c new file mode 100644 index 0000000..d0b66cb --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_2_vpi.c @@ -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(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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; +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_test.log b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_test.log new file mode 100644 index 0000000..ce0056f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_test.v b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_test.v new file mode 100644 index 0000000..122318f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_test.v @@ -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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_vpi.c b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_vpi.c new file mode 100644 index 0000000..a7f9e4c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/show_all_signals_3_vpi.c @@ -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(, , ...); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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, ¤t_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; +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.03/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.03/veriuser_VCS.tab new file mode 100644 index 0000000..aa384a4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/veriuser_VCS.tab @@ -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:* diff --git a/me250300_pli/plibook_examples_unix/chapter.03/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.03/vpi_user.c new file mode 100644 index 0000000..e8d5091 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.03/vpi_user.c @@ -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 ***/ +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.04/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.04/build_MTI.mak new file mode 100644 index 0000000..0005448 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/build_MTI.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.04/build_NC.mak new file mode 100644 index 0000000..7822241 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/build_NC.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.04/build_XL.mak new file mode 100644 index 0000000..f2221aa --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/build_XL.mak @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_test.log b/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_test.log new file mode 100644 index 0000000..157c0c1 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_test.v b/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_test.v new file mode 100644 index 0000000..b0c5da3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_test.v @@ -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 +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_vpi.c b/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_vpi.c new file mode 100644 index 0000000..557a9dc --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_all_prims_vpi.c @@ -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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_args_test.log b/me250300_pli/plibook_examples_unix/chapter.04/count_args_test.log new file mode 100644 index 0000000..b2e27af --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_args_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_args_test.v b/me250300_pli/plibook_examples_unix/chapter.04/count_args_test.v new file mode 100644 index 0000000..931b4a8 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_args_test.v @@ -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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_args_vpi.c b/me250300_pli/plibook_examples_unix/chapter.04/count_args_vpi.c new file mode 100644 index 0000000..1ed50ff --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_args_vpi.c @@ -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(); + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/count_args_vpi_test.c b/me250300_pli/plibook_examples_unix/chapter.04/count_args_vpi_test.c new file mode 100644 index 0000000..6092d46 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/count_args_vpi_test.c @@ -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(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_test.log b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_test.log new file mode 100644 index 0000000..935dbf7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_test.v b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_test.v new file mode 100644 index 0000000..11a971a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_test.v @@ -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 + +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_efficient.c b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_efficient.c new file mode 100644 index 0000000..7a492b7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_efficient.c @@ -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(); + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_inefficient.c b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_inefficient.c new file mode 100644 index 0000000..54d3761 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_inefficient.c @@ -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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_test.c b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_test.c new file mode 100644 index 0000000..2571e30 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/get_arg_handle_vpi_test.c @@ -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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test.log b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test.log new file mode 100644 index 0000000..7787834 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test.log @@ -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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test.v b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test.v new file mode 100644 index 0000000..eb3f11a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test.v @@ -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: + * + * invoke_options_test.v + * +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 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test1.f b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test1.f new file mode 100644 index 0000000..7983ead --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test1.f @@ -0,0 +1,7 @@ +//command file +invoke_options_test.v ++a1 ++b1 +//+test1 +-f invoke_options_test2.f ++c1 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test2.f b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test2.f new file mode 100644 index 0000000..0bddd3e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_test2.f @@ -0,0 +1,5 @@ +//command file ++a2 ++b2 ++test2 ++c2 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_vpi.c b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_vpi.c new file mode 100644 index 0000000..27a7f0f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/invoke_options_vpi.c @@ -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(""); + * Where /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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 sum) = 5; + (b *> sum, co) = 5; + endspecify + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.04/list_pathout_ports_vpi.c b/me250300_pli/plibook_examples_unix/chapter.04/list_pathout_ports_vpi.c new file mode 100644 index 0000000..c8694b7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/list_pathout_ports_vpi.c @@ -0,0 +1,137 @@ +/********************************************************************** + * $list_pathout_ports example -- PLI application using VPI routines + * + * C source to find module ports which are connected to the outputs + * of pin-to-pin path delays. + * + * Usage: $list_pathout_ports(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ListPorts_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ListPorts_calltf(PLI_BYTE8 *user_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ListPorts_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$list_pathout_ports"; + tf_data.calltf = PLIbook_ListPorts_calltf; + tf_data.compiletf = PLIbook_ListPorts_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * Compiletf application + *********************************************************************/ +PLI_INT32 PLIbook_ListPorts_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: list_pathout_ports could not obtain handle to systf call\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + tfarg_itr = vpi_iterate(vpiArgument, systf_h); + if (systf_h == NULL) { + vpi_printf("ERROR: list_pathout_ports could not obtain iterator to systf args\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + tfarg_h = vpi_scan(tfarg_itr); + if (vpi_get(vpiType, tfarg_h) != vpiModule) { + vpi_printf("ERROR: $list_pathout_ports arg must be module instance\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + if (vpi_scan(tfarg_itr) != NULL) { + tf_error("ERROR: $list_pathout_ports requires 1 argument\n"); + vpi_free_object(tfarg_itr); /* because not scanning until null */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ListPorts_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle module_handle, systf_h, arg_itr, + path_itr, path_handle, + term_itr, term_handle, + port_itr, port_handle, + net_handle; + + /* get module handle from first system task argument. Assume the */ + /* compiletf routine has already verified correct argument type. */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + if (systf_h == NULL) { + vpi_printf("ERROR: list_pathout_ports could not obtain handle to systf call\n"); + return(0); + } + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (systf_h == NULL) { + vpi_printf("ERROR: list_pathout_ports could not obtain iterator to systf args\n"); + return(0); + } + module_handle = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free itr since didn't scan until null */ + + vpi_printf("\nModule %s\n", vpi_get_str(vpiDefName, module_handle)); + + path_itr = vpi_iterate(vpiModPath, module_handle); + if (path_itr == NULL) { + vpi_printf(" No module paths found\n"); + return(0); + } + while (path_handle = vpi_scan(path_itr)) { + term_itr = vpi_iterate(vpiModPathOut, path_handle); + if (term_itr == NULL) { + vpi_printf(" No path output terminal found\n"); + break; /* go to next path */ + } + while (term_handle = vpi_scan(term_itr)) { + net_handle = vpi_handle(vpiExpr, term_handle); + port_itr = vpi_iterate(vpiPorts, net_handle); + if (port_itr == NULL) { + vpi_printf(" Path output does not connect to a port\n"); + break; /* go to next path output terminal */ + } + while (port_handle = vpi_scan(port_itr)) { + vpi_printf(" Port %s is connected to a path delay output\n", + vpi_get_str(vpiName, port_handle)); + } + } + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/port_info_test.log b/me250300_pli/plibook_examples_unix/chapter.04/port_info_test.log new file mode 100644 index 0000000..cf393ce --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/port_info_test.log @@ -0,0 +1,29 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Module addbit (instance test.i1) + Port name is a + Size is 1 + Direction is input + Low conn data type is vpiNet + High conn data type is vpiReg + Port name is b + Size is 1 + Direction is input + Low conn data type is vpiNet + High conn data type is vpiReg + Port name is ci + Size is 1 + Direction is input + Low conn data type is vpiNet + High conn data type is vpiReg + Port name is sum + Size is 1 + Direction is output + Low conn data type is vpiNet + High conn data type is vpiNet + Port name is co + Size is 1 + Direction is output + Low conn data type is vpiNet + High conn data type is vpiNet +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.04/port_info_test.v b/me250300_pli/plibook_examples_unix/chapter.04/port_info_test.v new file mode 100644 index 0000000..ff12062 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/port_info_test.v @@ -0,0 +1,45 @@ +/********************************************************************** + * $port_info example -- C source code using VPI PLI routines + * + * For the book, "The Verilog PLI Handbook", Chapter 4 + * Copyright 1998, Sutherland HDL Inc, Tualatin Oregon. + * + * Verilog test bench to test the $port_info() PLI application. + * + *********************************************************************/ +`timescale 1ns / 1ns +module test; + reg a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + begin + #1 $port_info(i1); + #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 +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/port_info_vpi.c b/me250300_pli/plibook_examples_unix/chapter.04/port_info_vpi.c new file mode 100644 index 0000000..984617c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/port_info_vpi.c @@ -0,0 +1,141 @@ +/********************************************************************** + * $port_info example -- PLI application using VPI routines + * + * C source to print information about module ports. + * + * Usage: $port_info(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_PortInfo_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_PortInfo_calltf(PLI_BYTE8 *user_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_PortInfo_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$port_info"; + tf_data.calltf = PLIbook_PortInfo_calltf; + tf_data.compiletf = PLIbook_PortInfo_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + + +/********************************************************************** + * Compiletf application + *********************************************************************/ +PLI_INT32 PLIbook_PortInfo_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: list_pathout_ports could not obtain handle to systf call\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + tfarg_itr = vpi_iterate(vpiArgument, systf_h); + if (systf_h == NULL) { + vpi_printf("ERROR: list_pathout_ports could not obtain iterator to systf args\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + tfarg_h = vpi_scan(tfarg_itr); + if (vpi_get(vpiType, tfarg_h) != vpiModule) { + vpi_printf("ERROR: $list_pathout_ports arg must be module instance\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + if (vpi_scan(tfarg_itr) != NULL) { + tf_error("ERROR: $list_pathout_ports requires 1 argument\n"); + vpi_free_object(tfarg_itr); /* because not scanning until null */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_PortInfo_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, mod_h, + port_itr, port_h, lowconn_h, highconn_h; + PLI_INT32 lowconn_type, highconn_type; + + /* get module handle from first system task argument. Assume the */ + /* compiletf routine has already verified correct argument type. */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + if (systf_h == NULL) { + vpi_printf("ERROR: list_pathout_ports could not obtain handle to systf call\n"); + return(0); + } + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (systf_h == NULL) { + vpi_printf("ERROR: list_pathout_ports could not obtain iterator to systf args\n"); + return(0); + } + mod_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free itr since did not scan until nul */ + + vpi_printf("\nModule %s (instance %s)\n", + vpi_get_str(vpiDefName, mod_h), + vpi_get_str(vpiFullName, mod_h)); + + port_itr = vpi_iterate(vpiPort, mod_h); + if (!port_itr) { + vpi_printf(" No ports found\n"); + return(0); + } + while (port_h = vpi_scan(port_itr)) { + vpi_printf(" Port name is %s\n", vpi_get_str(vpiName, port_h)); + vpi_printf(" Size is %d\n", vpi_get(vpiSize, port_h)); + switch (vpi_get(vpiDirection, port_h)) { + case vpiInput: vpi_printf(" Direction is input\n"); break; + case vpiOutput: vpi_printf(" Direction is output\n"); break; + case vpiInout: vpi_printf(" Direction is inout\n"); break; + } + + lowconn_h = vpi_handle(vpiLowConn, port_h); + lowconn_type = vpi_get(vpiType, lowconn_h); + vpi_printf(" Low conn data type is %s\n", + vpi_get_str(vpiType, lowconn_h)); /* Verilog-2001 property */ + + highconn_h = vpi_handle(vpiHighConn, port_h); + if (!highconn_h) { + vpi_printf(" No high conn\n"); + return(0); + } + highconn_type = vpi_get(vpiType, highconn_h); + vpi_printf(" High conn data type is %s\n", + vpi_get_str(vpiType, highconn_h)); /* Verilog-2001 property */ + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.04/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.04/veriuser_VCS.tab new file mode 100644 index 0000000..8b5bf25 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/veriuser_VCS.tab @@ -0,0 +1,15 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$count_args_vpi call=PLIbook_CountArgsTestCall data=0 acc+=read:* + +$get_arg_handle_test call=PLIbook_GetArgTestCall data=0 acc+=read:* + +$list_pathout_ports call=PLIbook_ListPorts_calltf check=PLIbook_ListPorts_compiletf data=0 acc+=read:* + +$port_info call=PLIbook_PortInfo_calltf check=PLIbook_PortInfo_compiletf data=0 acc+=read:* + +$count_primitives call=PLIbook_CountPrims_calltf check=PLIbook_CountPrims_compiletf data=0 acc+=read:* + +$test_invoke_options call=PLIbook_TestInvokeOptions_calltf check=PLIbook_TestInvokeOptions_compiletf size=1 data=0 acc+=read:* + diff --git a/me250300_pli/plibook_examples_unix/chapter.04/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.04/vpi_user.c new file mode 100644 index 0000000..da466d4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.04/vpi_user.c @@ -0,0 +1,34 @@ +/********************************************************************** + * 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_CountArgsTest_register(); /* */ +extern void PLIbook_GetArgTest_register(); /* */ +extern void PLIbook_ListPorts_register(); /* */ +extern void PLIbook_PortInfo_register(); /* */ +extern void PLIbook_CountPrims_register(); /* */ +extern void PLIbook_TestInvokeOptions_register(); /* */ + +void (*vlog_startup_routines[])() = +{ + PLIbook_CountArgsTest_register, /* */ + PLIbook_GetArgTest_register, /* */ + PLIbook_ListPorts_register, /* */ + PLIbook_PortInfo_register, /* */ + PLIbook_CountPrims_register, /* */ + PLIbook_TestInvokeOptions_register, /* */ + 0 /*** final entry must be 0 ***/ + +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.05/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.05/build_MTI.mak new file mode 100644 index 0000000..cb144a0 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/build_MTI.mak @@ -0,0 +1,25 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = \ + get_arg_val_vpi_test.c \ + read_vecval_vpi.c \ + read_strengthval_vpi.c \ + read_timeval_vpi.c \ + realpow_vpi.c \ + read_attribute_const_vpi.c \ + read_delays_vpi.c \ + set_mipd_delays_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.05/build_NC.mak new file mode 100644 index 0000000..46ffb47 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/build_NC.mak @@ -0,0 +1,25 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = \ + get_arg_val_vpi_test.c \ + read_vecval_vpi.c \ + read_strengthval_vpi.c \ + read_timeval_vpi.c \ + realpow_vpi.c \ + read_attribute_const_vpi.c \ + read_delays_vpi.c \ + set_mipd_delays_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.05/build_XL.mak new file mode 100644 index 0000000..94bdeb7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/build_XL.mak @@ -0,0 +1,26 @@ +# +# 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 = \ + get_arg_val_vpi_test.c \ + read_vecval_vpi.c \ + read_strengthval_vpi.c \ + read_timeval_vpi.c \ + realpow_vpi.c \ + read_attribute_const_vpi.c \ + read_delays_vpi.c \ + set_mipd_delays_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/get_arg_handle_vpi_efficient.c b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_handle_vpi_efficient.c new file mode 100644 index 0000000..41c2617 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_handle_vpi_efficient.c @@ -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(); + * 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 1 /* set to non-zero for Verilog-1995 compatibility */ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_test.log b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_test.log new file mode 100644 index 0000000..f232427 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_test.log @@ -0,0 +1,61 @@ +// EDITOR'S NOTES: +// +// 1. The "ERROR" messages in this log file were generated by the NC-Verilog +// simulator. These message may be different, or non-existant, in other +// simulators. +// +// 2. The version of NC-Verilog used to generate this log file has a bug. +// The simulator reports an error when reading a real number in a string +// format (the 5th test, below). + +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +*** Testing Utility Apps With Good Values *** + + Testing PLIbook_get_arg_int_val_vpi()... + Value of arg 1 is 1: EXPECTED 1 + + Testing PLIbook_get_arg_real_val_vpi()... + Value of arg 2 is 0.5: EXPECTED 0.5 + + Testing PLIbook_get_arg_string_val_vpi()... + Value of arg 3 is Hello world: EXPECTED Hello world + + Testing PLIbook_get_arg_int_val_vpi() to read a real value... + Value of arg 2 is 1: EXPECTED 1 (0.5 rounded) + + Testing PLIbook_get_arg_string_val_vpi() on a real number... +ERROR: VPI NOVALOB + Object of type vpiRealVar does not have a value. + .\get_arg_val_test.v, 24: $get_arg_val_test(b,r1,"Hello world",test.i1) + Value of arg 2 is : EXPECTED 0.5 + +*** Testing Utility Routines With Bad Values *** + + Testing PLIbook_get_arg_int_val_vpi() on a module instance... +ERROR: VPI NOVALOB + Object of type vpiModule does not have a value. + .\get_arg_val_test.v, 24: $get_arg_val_test(b,r1,"Hello world",test.i1) + Value of arg 4 is 0: EXPECTED 0 + + Testing PLIbook_get_arg_real_val_vpi() on a module instance... +ERROR: VPI NOVALOB + Object of type vpiModule does not have a value. + .\get_arg_val_test.v, 24: $get_arg_val_test(b,r1,"Hello world",test.i1) + Value of arg 4 is 0.0: EXPECTED 0.0 + + Testing PLIbook_get_arg_str_val_vpi() on a module instance... +ERROR: VPI NOVALOB + Object of type vpiModule does not have a value. + .\get_arg_val_test.v, 24: $get_arg_val_test(b,r1,"Hello world",test.i1) + Value of arg 4 is : EXPECTED + + Testing PLIbook_get_arg_int_val_vpi() to read a literal string... +ERROR: VPI NOVALOB + Object of type vpiConstant does not have a value. + .\get_arg_val_test.v, 24: $get_arg_val_test(b,r1,"Hello world",test.i1) + Value of arg 3 is 0 (hex): EXPECTED 0 (hex) + +*** All Tests Completed *** + +Simulation complete via $finish(1) at time 20 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_test.v b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_test.v new file mode 100644 index 0000000..0ebc038 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_test.v @@ -0,0 +1,46 @@ +/********************************************************************** + * $get_arg_val_test example -- Verilog HDL test bench. + * + * Verilog test bench to test the VPI get arg value 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 $get_arg_val_test(b, r1, "Hello world", i1 ); + #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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_vpi.c new file mode 100644 index 0000000..8b7d46d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_vpi.c @@ -0,0 +1,138 @@ +/********************************************************************** + * VPI Examples to read task/function argument values -- PLI + * application using VPI routines + * + * C source for functions to the logic value of system task/function + * arguments. + * + * NOTE: THESE ROUTINES A PROVIDED AS SHORT EXAMPLES ON HOW TO ACCESS + * TASK/FUNCTION ARGUMENTS, AND HOW TO PERFORM ERROR CHECKING ON IF + * THE DESIRED INFORMATION WAS OBTAINED. THESE EXAMPLES ARE NOT + * INTENDED TO BE COMPLETE PLI APPLICATION IN AND OF THEMSELVES. + * + * Usage: + * arg_val = PLIbook_get_arg_int_val_vpi(arg_index_number); + * Returns a value as an int for a system task/function argument, + * using the index number of the argument, beginning with 1. + * + * arg_val = PLIbook_get_arg_real_val_vpi(arg_index_number); + * Returns a value as a double for a system task/function arg, + * using the index number of the argument, beginning with 1. + * + * arg_val = PLIbook_get_arg_string_val_vpi(arg_index_number); + * Returns a value as a string pointer for a system task/func arg, + * 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 */ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* ANSI C standard arguments library */ +#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */ + +#include "get_arg_handle_vpi_efficient.c" /* example from Chapter 4 */ + +/* Prototypes of the utility applications */ +int PLIbook_get_arg_int_val_vpi(int argNum); +double PLIbook_get_arg_real_val_vpi(int argNum); +char *PLIbook_get_arg_string_val_vpi(int argNum); + + +/********************************************************************** + * PLIbook_get_arg_int_val_vpi() + * Return the value of a system task/function argument as an integer. + * Similar to acc_fetch_tfarg_int() + *********************************************************************/ +int PLIbook_get_arg_int_val_vpi(int argNum) +{ + vpiHandle arg_h; + s_vpi_value argVal; + s_vpi_error_info err; /* structure for error handling */ + + arg_h = PLIbook_get_arg_handle_vpi(argNum); + if (arg_h == NULL) { + vpi_printf("ERROR: PLIbook_get_arg_int_val_vpi() could not obtain arg handle\n"); + return(0); + } + argVal.format = vpiIntVal; + vpi_get_value(arg_h, &argVal); + if (vpi_chk_error(&err)) { + #if PLIbookDebug /* if error, generate verbose debug message */ + vpi_printf("ERROR: PLIbook_get_arg_int_val_vpi() could not obtain arg value\n"); + vpi_printf("File %s, Line %d: %s\n", err.file, err.line, + err.message); + #endif + return(0); + } + return(argVal.value.integer); +} + + +/********************************************************************** + * PLIbook_get_arg_real_val_vpi() + * Return the value of a system task/function argument as a double. + * Similar to acc_fetch_tfarg() + *********************************************************************/ +double PLIbook_get_arg_real_val_vpi(int argNum) +{ + vpiHandle arg_h; + s_vpi_value argVal; + s_vpi_error_info err; /* structure for error handling */ + + arg_h = PLIbook_get_arg_handle_vpi(argNum); + if (arg_h == NULL) { + vpi_printf("ERROR: PLIbook_get_arg_real_val_vpi() could not obtain arg handle\n"); + return(0); + } + argVal.format = vpiRealVal; + vpi_get_value(arg_h, &argVal); + if (vpi_chk_error(&err)) { + #if PLIbookDebug /* if error, generate verbose debug message */ + vpi_printf("ERROR: PLIbook_get_arg_real_val_vpi() could not obtain arg value\n"); + vpi_printf("File %s, Line %d: %s\n", err.file, err.line, + err.message); + #endif + return(0.0); + } + return(argVal.value.real); +} + + +/********************************************************************** + * PLIbook_get_arg_string_val_vpi() + * Return the value of a system task/function argument as a string. + * Similar to acc_fetch_tfarg_str() + *********************************************************************/ +char *PLIbook_get_arg_string_val_vpi(int argNum) +{ + vpiHandle arg_h; + s_vpi_value argVal; + s_vpi_error_info err; /* structure for error handling */ + static char null_string[1] = {'\0'}; + + arg_h = PLIbook_get_arg_handle_vpi(argNum); + if (arg_h == NULL) { + vpi_printf("ERROR: PLIbook_get_arg_string_val_vpi() could not obtain arg handle\n"); + return(0); + } + argVal.format = vpiStringVal; + vpi_get_value(arg_h, &argVal); + if (vpi_chk_error(&err)) { + #if PLIbookDebug /* if error, generate verbose debug message */ + vpi_printf("ERROR: PLIbook_get_arg_string_val_vpi() could not obtain arg value\n"); + vpi_printf("File %s, Line %d: %s\n", err.file, err.line, + err.message); + #endif + return(null_string); + } + return(argVal.value.str); +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_vpi_test.c b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_vpi_test.c new file mode 100644 index 0000000..30c2f37 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/get_arg_val_vpi_test.c @@ -0,0 +1,111 @@ +/********************************************************************** + * $get_arg_val_test example -- PLI application using VPI routines + * + * C code to test the VPI "PLIbook_get_arg_val_vpi() application. + * + * Usage: initial + * $get_arg_val_test(arg1, arg2, arg3, arg4); + * + * Where: arg1 is a reg or integer variable + * arg2 is a real number or variable + * arg3 is a literal string + * arg4 is a module instance 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 + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* ANSI C standard arguments library */ +#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */ + +/* prototypes of the PLI application routines */ +PLI_INT32 PLIbook_GetArgValTestCall(PLI_BYTE8 *user_data); + +#include "get_arg_val_vpi.c" /* include the VPI applications */ + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_GetArgValTest_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$get_arg_val_test"; + tf_data.calltf = PLIbook_GetArgValTestCall; + 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_GetArgValTestCall(PLI_BYTE8 *user_data) +{ + int int1; + double real1; + PLI_BYTE8 *string1; + vpiHandle arg0_h, arg1_h, arg2_h, arg3_h, arg4_h, arg5_h, arg6_h; + + vpi_printf("\n*** Testing Utility Apps With Good Values ***\n"); + + /* test PLIbook_get_arg_int_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_int_val_vpi()...\n"); + int1 = PLIbook_get_arg_int_val_vpi(1); + vpi_printf(" Value of arg 1 is %d: EXPECTED 1\n", int1); + + /* test PLIbook_get_arg_real_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_real_val_vpi()...\n"); + real1 = PLIbook_get_arg_real_val_vpi(2); + vpi_printf(" Value of arg 2 is %1.1f: EXPECTED 0.5\n", real1); + + /* test PLIbook_get_arg_string_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_string_val_vpi()...\n"); + string1 = PLIbook_get_arg_string_val_vpi(3); + vpi_printf(" Value of arg 3 is %s: EXPECTED Hello world\n", string1); + + /* test PLIbook_get_arg_int_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_int_val_vpi() to read a real value...\n"); + int1 = PLIbook_get_arg_int_val_vpi(2); + vpi_printf(" Value of arg 2 is %d: EXPECTED 1 (0.5 rounded)\n", int1); + + /* test PLIbook_get_arg_string_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_string_val_vpi() on a real number...\n"); + string1 = PLIbook_get_arg_string_val_vpi(2); + vpi_printf(" Value of arg 2 is %s: EXPECTED 0.5\n", string1); + + + vpi_printf("\n*** Testing Utility Routines With Bad Values ***\n"); + + /* test PLIbook_get_arg_real_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_int_val_vpi() on a module instance...\n"); + int1 = PLIbook_get_arg_int_val_vpi(4); + vpi_printf(" Value of arg 4 is %d: EXPECTED 0\n", int1); + + /* test PLIbook_get_arg_real_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_real_val_vpi() on a module instance...\n"); + real1 = PLIbook_get_arg_real_val_vpi(4); + vpi_printf(" Value of arg 4 is %1.1f: EXPECTED 0.0\n", real1); + + /* test PLIbook_get_arg_real_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_str_val_vpi() on a module instance...\n"); + string1 = PLIbook_get_arg_string_val_vpi(4); + vpi_printf(" Value of arg 4 is %s: EXPECTED \n", string1); + + /* test PLIbook_get_arg_int_val_vpi() */ + vpi_printf("\n Testing PLIbook_get_arg_int_val_vpi() to read a literal string...\n"); + int1 = PLIbook_get_arg_int_val_vpi(3); + vpi_printf(" Value of arg 3 is %x (hex): EXPECTED 0 (hex)\n", int1); + + vpi_printf("\n*** All Tests Completed ***\n\n"); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_test.log b/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_test.log new file mode 100644 index 0000000..3928d7d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_test.log @@ -0,0 +1,16 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Module addbit: + Port name = a, attribute InputLoad$ for this port = 1.10 + Port name = b, attribute InputLoad$ for this port = 2.20 + Port name = ci, attribute InputLoad$ for this port = 3.30 + Port name = sum, attribute InputLoad$ for this port = 3.30 + Port name = co, attribute InputLoad$ for this port = 3.30 + +Module addbit: + Port name = a, attribute Foo$ for this port = 9.90 + Port name = b, attribute Foo$ for this port = 9.90 + Port name = ci, attribute Foo$ for this port = 9.90 + Port name = sum, attribute Foo$ for this port = 9.90 + Port name = co, attribute Foo$ for this port = 9.90 +Simulation complete via $finish(1) at time 3 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_test.v b/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_test.v new file mode 100644 index 0000000..d4b2e79 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_test.v @@ -0,0 +1,50 @@ +/********************************************************************** + * $read_attribute_constant example -- Verilog HDL test bench. + * + * Verilog test bench to test the $read_attribute 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 a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + begin + #1 $read_attribute_constant(i1, "InputLoad$"); + #1 $read_attribute_constant(i1, "Foo$"); + #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 + specparam InputLoad$a = 1.1; + specparam InputLoad$b = 2.2; + specparam InputLoad$ = 3.3; + endspecify + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_vpi.c new file mode 100644 index 0000000..196cd06 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_attribute_const_vpi.c @@ -0,0 +1,175 @@ +/********************************************************************** + * $read_attribute_constant example--PLI application using VPI routines + * + * C source to read specparam attribute values of Verilog objects. + * Prints the names of all ports in the module and the value of the + * specified attribute associated with each port. If an object + * specific attribute is not found, the value of the general attribute + * is returned. If a general attribute is not found, then a default + * of 99.9 is returned. + * + * Usage: $read_attribute_constant(, ); + * + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadAttributeConst_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadAttributeConst_compiletf(PLI_BYTE8 *user_data); +double PLIbook_GetAttribute(vpiHandle obj_h, PLI_BYTE8 *attribute, + double default_value); +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadAttributeConst_register() +{ + s_vpi_systf_data tf_data; /* allocate register data structure */ + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$read_attribute_constant"; + tf_data.calltf = PLIbook_ReadAttributeConst_calltf; + tf_data.compiletf = PLIbook_ReadAttributeConst_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * compiletf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadAttributeConst_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h; + PLI_INT32 tfarg_type; + + systf_h = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_attribute requires 2 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + arg_h = vpi_scan(arg_itr); + if (vpi_get(vpiType, arg_h) != vpiModule) { + vpi_printf("ERROR: $read_attribute arg1 must be module instance\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + arg_h = vpi_scan(arg_itr); + if (vpi_get(vpiType, arg_h) != vpiConstant) { + vpi_printf("$read_attribute arg2 must be quoted attribute name\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + else if (vpi_get(vpiConstType, arg_h) != vpiStringConst) { + vpi_printf("$read_attribute arg2 must be quoted attribute name\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + if (vpi_scan(arg_itr) != NULL) { + vpi_printf("ERROR: $realpow requires only 2 arguments\n"); + vpi_free_object(arg_itr); + tf_dofinish(); + vpi_control(vpiFinish, 1); /* abort simulation */ + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadAttributeConst_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, mod_h, arg_itr, arg2_h, port_itr, port_h; + double attribute_value; + PLI_BYTE8 *attribute_name; + s_vpi_value attribute_name_s; + + /* obtain handle to system task arguments; + compiletf has already verified only 2 args with correct types */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_h); + mod_h = vpi_scan(arg_itr); + + /* read base value of system function arg 2 */ + arg2_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator--did not scan till null */ + attribute_name_s.format = vpiStringVal; + vpi_get_value(arg2_h, &attribute_name_s); + attribute_name = attribute_name_s.value.str; + + vpi_printf("\nModule %s:\n", vpi_get_str(vpiDefName, mod_h)); + port_itr = vpi_iterate(vpiPort, mod_h); + while ( (port_h = vpi_scan(port_itr)) != NULL) { + attribute_value = PLIbook_GetAttribute(port_h, attribute_name, 9.9); + vpi_printf(" Port name = %s, attribute %s for this port = %2.2f\n", + vpi_get_str(vpiName, port_h), + attribute_name, attribute_value); + } + return(0); +} + +/********************************************************************** + * Function to return a specparam attribute value. Inputs are: + * vpiHandle obj_h: handle for any object. + * char *attribute: pointer to string with name of attribute. + * double default_value: value to return if attribute is not found + *********************************************************************/ +double PLIbook_GetAttribute(vpiHandle obj_h, PLI_BYTE8 *attribute, + double default_value) +{ + vpiHandle module_h, param_h; + char *object_name; + char param_name[1024]; /* character string to hold attribute name */ + s_vpi_value param_val; /* structure to receive attribute value */ + + param_val.format = vpiRealVal; + module_h = vpi_handle(vpiModule, obj_h); /* get parent module */ + + /* build specparam name out of object name and attribute name */ + object_name = vpi_get_str(vpiName, obj_h); + strcpy(param_name, attribute); + strcat(param_name, object_name); + + /* try to get a handle to the object specific attribute */ + param_h = vpi_handle_by_name(param_name, module_h); + if (!vpi_chk_error(NULL)) { + vpi_get_value(param_h, ¶m_val); + if (!vpi_chk_error(NULL)) + return(param_val.value.real); /* found specific attribute */ + } + + /* try to get a handle to a general attribute */ + strcpy(param_name, attribute); + param_h = vpi_handle_by_name(param_name, module_h); + if (!vpi_chk_error(NULL)) { + vpi_get_value(param_h, ¶m_val); + if (!vpi_chk_error(NULL)) + return(param_val.value.real); /* found general attribute */ + } + + /* failed to find object-specific or general attribute specparam */ + return(default_value); +} + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.05/read_delays_test.log new file mode 100644 index 0000000..cef49bd --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_delays_test.log @@ -0,0 +1,6 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Module addbit paths: +Delays for a$sum = (3.00:3.00:3.00, 5.00:5.00:5.00) +Delays for b$sum = (1.00:1.00:1.00, 2.00:2.00:2.00) +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.05/read_delays_test.v new file mode 100644 index 0000000..a44bc39 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_delays_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $list_delays example -- Verilog HDL test bench. + * + * Verilog test bench to test the $list_delays 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 a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + begin + #1 $read_delays(i1); + #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) = (3, 5); + (b *> sum, co) = (1.3, 2.2); + endspecify + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_delays_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/read_delays_vpi.c new file mode 100644 index 0000000..18d6c5d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_delays_vpi.c @@ -0,0 +1,177 @@ +/********************************************************************** + * $read_delays example -- PLI application using VPI routines + * + * C source to read path delay values of Verilog module paths. Prints + * the names of all path delays in the module and rise and fall delay + * of each path. Note that module paths do not have a name, so a name + * is created by concatenating the names of the input and output + * terminals togehter, with a dollar sign between the names. + * + * Usage: $read_delays(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadDelays_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadDelays_compiletf(PLI_BYTE8 *user_data); +void PLIbook_PrintDelays(vpiHandle modpath_h); +char *PLIbook_BuildPathName(); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadDelays_register() +{ + s_vpi_systf_data tf_data; /* allocate register data structure */ + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$read_delays"; + tf_data.calltf = PLIbook_ReadDelays_calltf; + tf_data.compiletf = PLIbook_ReadDelays_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * compiletf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadDelays_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h; + PLI_INT32 tfarg_type; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handles to system task arguments */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_delays requires 1 argument\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check the type of object in system task arguments */ + arg_h = vpi_scan(arg_itr); + tfarg_type = vpi_get(vpiType, arg_h); + if (tfarg_type != vpiModule) { + vpi_printf("ERROR: $read_delays arg1 must be a module instance\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check that there is only 1 system task argument */ + arg_h = vpi_scan(arg_itr); + if (arg_h != NULL) { + vpi_printf("ERROR: $read_delays can only have 1 argument\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadDelays_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, mod_h, path_itr, path_h; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handle to system task argument; */ + /* compiletf has already verified only 1 arg with correct type */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + mod_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + vpi_printf("\nModule %s paths:\n", vpi_get_str(vpiDefName, mod_h)); + path_itr = vpi_iterate(vpiModPath, mod_h); + if (path_itr != NULL) + while ((path_h = vpi_scan(path_itr)) != NULL) { + PLIbook_PrintDelays(path_h); + } + else + vpi_printf(" No path delays found.\n"); + return(0); +} + +void PLIbook_PrintDelays(vpiHandle modpath_h) +{ + char *path_name; /* pointer to path name string */ + s_vpi_delay delay_struct; /* structure to setup delays */ + s_vpi_time delay_array[6]; /* structure to receive delays */ + + delay_struct.da = delay_array; + delay_struct.no_of_delays = 2; + delay_struct.time_type = vpiScaledRealTime; + delay_struct.mtm_flag = 1; + delay_struct.append_flag = 0; + delay_struct.pulsere_flag = 0; + + vpi_get_delays(modpath_h, &delay_struct); + path_name = PLIbook_BuildPathName(modpath_h); + + vpi_printf("Delays for %s = (%.2f:%.2f:%.2f, %.2f:%.2f:%.2f)\n", + path_name, + delay_array[0].real, delay_array[1].real, delay_array[2].real, + delay_array[3].real, delay_array[4].real, delay_array[5].real); +} + +char *PLIbook_BuildPathName(vpiHandle modpath_h) +{ + vpiHandle term_itr, term_h, net_h; + static char path_name[2050]; /* character array to hold path name */ + char *term_name; + + path_name[0] = '\0'; /* clear the path name string */ + + term_itr = vpi_iterate(vpiModPathIn, modpath_h); + if (term_itr == NULL) + return("UNKNOWN PATH NAME"); + term_h = vpi_scan(term_itr); + net_h = vpi_handle(vpiExpr, term_h); + if (net_h == NULL) + return("UNKNOWN PATH NAME"); + term_name = vpi_get_str(vpiName, net_h); + strcat(path_name, term_name); + vpi_free_object(term_itr); /* free iterator--did not scan to null */ + + strcat(path_name, "$"); + + term_itr = vpi_iterate(vpiModPathOut, modpath_h); + if (term_itr == NULL) + return("UNKNOWN PATH NAME"); + term_h = vpi_scan(term_itr); + net_h = vpi_handle(vpiExpr, term_h); + if (net_h == NULL) + return("UNKNOWN PATH NAME"); + term_name = vpi_get_str(vpiName, net_h); + strcat(path_name, term_name); + vpi_free_object(term_itr); /* free iterator--did not scan to null */ + + return(path_name); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_test.log b/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_test.log new file mode 100644 index 0000000..2b1b7e6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_test.log @@ -0,0 +1,23 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Net a: value=0 strength0=40(hex) strength1= 0(hex) + + +Net b: value=1 strength0= 0(hex) strength1=40(hex) + + +Net c: value=Z strength0= 1(hex) strength1= 1(hex) + + +Net d: value=X strength0=40(hex) strength1=40(hex) + + +Net e: value=X strength0=20(hex) strength1=20(hex) + + +Net f: value=X strength0=40(hex) strength1= 1(hex) + + +Net g: value=X strength0= 1(hex) strength1=40(hex) + +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_test.v b/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_test.v new file mode 100644 index 0000000..4ead2b1 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_test.v @@ -0,0 +1,43 @@ +/********************************************************************** + * $read_strengthval example -- Verilog HDL test bench. + * + * Verilog test bench to test the $read_strengthval 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; + wire a = 1'b0; + wire b = 1'b1; + wire c = 1'bz; + wire d = 1'bx; + wire e; + assign (pull0, pull1) e = 1'b1; /* wired logic on e */ + assign (pull1, pull0) e = 1'b0; + + wire f; + bufif1 (f, 1'b0, 1'bx); /* ambiguous output 'L' */ + + wire g; + notif1 (g, 1'b0, 1'bx); /* ambiguous output 'H' */ + + initial + begin + #1 + $read_strengthval(a); + $read_strengthval(b); + $read_strengthval(c); + $read_strengthval(d); + $read_strengthval(e); + $read_strengthval(f); + $read_strengthval(g); + #1 $finish; + end +endmodule + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_vpi.c new file mode 100644 index 0000000..526eb63 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_strengthval_vpi.c @@ -0,0 +1,146 @@ +/********************************************************************** + * $read_strengthval example -- PLI application using VPI routines + * + * C source to read logic values and strength levels of scalar nets. + * + * Usage: $read_strengthval(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadStrengthVal_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadStrengthVal_compiletf(PLI_BYTE8 *user_data); +char PLIbook_DecodeBitValue(); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadStrengthVal_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$read_strengthval"; + tf_data.calltf = PLIbook_ReadStrengthVal_calltf; + tf_data.compiletf = PLIbook_ReadStrengthVal_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * compiletf application + *********************************************************************/ +PLI_INT32 PLIbook_ReadStrengthVal_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h; + PLI_INT32 arg_type; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + if (systf_h == NULL) { + vpi_printf("ERROR: $read_strengthval failed to obtain systf handle\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* obtain handles to system task arguments */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_strengthval requires 1 argument\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check the type of object in system task arguments */ + arg_h = vpi_scan(arg_itr); + arg_type = vpi_get(vpiType, arg_h); + if (arg_type != vpiNet) { + vpi_printf("ERROR: $read_strengthval arg must be a net\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check the bit size of object in system task arguments */ + if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("ERROR: $read_strengthval arg must be scalar\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check that there are no more system task arguments */ + arg_h = vpi_scan(arg_itr); + if (arg_h != NULL) { + vpi_printf("ERROR: $read_strengthval can only have 1 argument\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadStrengthVal_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h, net_h; + s_vpi_value net_val; /* structure to receive net value */ + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handle to system task argument + compiletf has already verified only 1 arg with correct type */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + net_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator memory */ + + net_val.format = vpiStrengthVal; /* set value format field */ + + vpi_get_value(net_h, &net_val); /* read net's strength value */ + + vpi_printf("\nNet %s: ", vpi_get_str(vpiName, net_h)); + vpi_printf("value=%c strength0=%2x(hex) strength1=%2x(hex)\n\n", + PLIbook_DecodeBitValue(net_val.value.strength->logic), + net_val.value.strength->s0, + net_val.value.strength->s1); + return(0); +} + +/********************************************************************** + * Function to convert VPI logic constant to a character + *********************************************************************/ +char PLIbook_DecodeBitValue(int bit_constant) +{ + switch (bit_constant) { + case vpi0: return('0'); break; + case vpi1: return('1'); break; + case vpiZ: return('Z'); break; + case vpiX: return('X'); break; + case vpiL: return('L'); break; + case vpiH: return('H'); break; + case vpiDontCare: return('?'); break; + default: return('U'); /* undefined value passed in */ + } +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_test.log b/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_test.log new file mode 100644 index 0000000..b992397 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_test.log @@ -0,0 +1,5 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Time Variable T: hi-word/lo-word = 1/2 + +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_test.v b/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_test.v new file mode 100644 index 0000000..95fb17b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_test.v @@ -0,0 +1,27 @@ +/********************************************************************** + * $read_timeval example -- Verilog HDL test bench. + * + * Verilog test bench to test the $read_timeval 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; + time T; + + initial + begin + T = 0; + T[1] = 1; + T[32] = 1; + #1 $read_timeval(T); + #1 $finish; + end +endmodule + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_vpi.c new file mode 100644 index 0000000..5a6526e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_timeval_vpi.c @@ -0,0 +1,120 @@ +/********************************************************************** + * $read_timeval example -- PLI application using VPI routines + * + * C source to read time variable values of Verilog objects. + * + * Usage: $read_timeval(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadTimeVal_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadTimeVal_compiletf(PLI_BYTE8 *user_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadTimeVal_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$read_timeval"; + tf_data.calltf = PLIbook_ReadTimeVal_calltf; + tf_data.compiletf = PLIbook_ReadTimeVal_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * compiletf application + *********************************************************************/ +PLI_INT32 PLIbook_ReadTimeVal_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h; + PLI_INT32 arg_type; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + if (systf_h == NULL) { + vpi_printf("ERROR: $read_timeval failed to obtain systf handle\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* obtain handles to system task arguments */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_timeval requires 1 argument\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check the type of object in system task arguments */ + arg_h = vpi_scan(arg_itr); + arg_type = vpi_get(vpiType, arg_h); + if (arg_type != vpiTimeVar) { + vpi_printf("ERROR: $read_timeval arg must be a time variable\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check that there are no more system task arguments */ + arg_h = vpi_scan(arg_itr); + if (arg_h != NULL) { + vpi_printf("ERROR: $read_timeval can only have 1 argument\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadTimeVal_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h, timevar_h; + s_vpi_value timevar_val; /* structure to receive variable value */ + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handle to system task argument + compiletf has already verified only 1 arg with correct type */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + timevar_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator memory */ + + timevar_val.format = vpiTimeVal; /* set value format field */ + + vpi_get_value(timevar_h, &timevar_val); /* read variable's value */ + + vpi_printf("\nTime Variable %s: ", vpi_get_str(vpiName, timevar_h)); + vpi_printf(" hi-word/lo-word = %d/%d\n\n", + timevar_val.value.time->high, + timevar_val.value.time->low); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_test.log b/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_test.log new file mode 100644 index 0000000..937cf67 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_test.log @@ -0,0 +1,44 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Vector data encoded value: + bit[ 0] aval/bval = 1/0 4-state value = 1 + bit[ 1] aval/bval = 0/0 4-state value = 0 + bit[ 2] aval/bval = 0/0 4-state value = 0 + bit[ 3] aval/bval = 0/0 4-state value = 0 + bit[ 4] aval/bval = 0/0 4-state value = 0 + bit[ 5] aval/bval = 0/0 4-state value = 0 + bit[ 6] aval/bval = 0/0 4-state value = 0 + bit[ 7] aval/bval = 0/0 4-state value = 0 + bit[ 8] aval/bval = 0/0 4-state value = 0 + bit[ 9] aval/bval = 0/0 4-state value = 0 + bit[10] aval/bval = 0/0 4-state value = 0 + bit[11] aval/bval = 0/0 4-state value = 0 + bit[12] aval/bval = 0/0 4-state value = 0 + bit[13] aval/bval = 0/0 4-state value = 0 + bit[14] aval/bval = 0/0 4-state value = 0 + bit[15] aval/bval = 0/0 4-state value = 0 + bit[16] aval/bval = 0/1 4-state value = z + bit[17] aval/bval = 0/0 4-state value = 0 + bit[18] aval/bval = 0/0 4-state value = 0 + bit[19] aval/bval = 0/0 4-state value = 0 + bit[20] aval/bval = 0/0 4-state value = 0 + bit[21] aval/bval = 0/0 4-state value = 0 + bit[22] aval/bval = 0/0 4-state value = 0 + bit[23] aval/bval = 0/0 4-state value = 0 + bit[24] aval/bval = 0/0 4-state value = 0 + bit[25] aval/bval = 0/0 4-state value = 0 + bit[26] aval/bval = 0/0 4-state value = 0 + bit[27] aval/bval = 0/0 4-state value = 0 + bit[28] aval/bval = 0/0 4-state value = 0 + bit[29] aval/bval = 0/0 4-state value = 0 + bit[30] aval/bval = 0/0 4-state value = 0 + bit[31] aval/bval = 0/0 4-state value = 0 + bit[32] aval/bval = 0/0 4-state value = 0 + bit[33] aval/bval = 0/0 4-state value = 0 + bit[34] aval/bval = 0/0 4-state value = 0 + bit[35] aval/bval = 0/0 4-state value = 0 + bit[36] aval/bval = 0/0 4-state value = 0 + bit[37] aval/bval = 0/0 4-state value = 0 + bit[38] aval/bval = 0/0 4-state value = 0 + bit[39] aval/bval = 1/1 4-state value = x +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_test.v b/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_test.v new file mode 100644 index 0000000..ea1b4a4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_test.v @@ -0,0 +1,28 @@ +/********************************************************************** + * $read_vecval example -- Verilog HDL test bench. + * + * Verilog test bench to test the $read_vecval 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 [39:0] data; + + initial + begin + data = 40'b0; + data[0] = 1'b1; + data[16] = 1'bz; + data[39] = 1'bx; + #1 $read_vecval(data); + #1 $finish; + end +endmodule + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_vpi.c new file mode 100644 index 0000000..806bc2c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/read_vecval_vpi.c @@ -0,0 +1,167 @@ +/********************************************************************** + * $read_vecval example -- PLI application using VPI routines + * + * C source to read logic values of a net and print the net name and + * current logic value. + * + * Usage: $read_vecval(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadVecVal_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadVecVal_compiletf(PLI_BYTE8 *user_data); +int PLIbook_getbit(PLI_INT32 word, int bit_num); +char PLIbook_get_4state_val(int aval, int bval); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadVecVal_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$read_vecval"; + tf_data.calltf = PLIbook_ReadVecVal_calltf; + tf_data.compiletf = PLIbook_ReadVecVal_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * compiletf application + *********************************************************************/ +PLI_INT32 PLIbook_ReadVecVal_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h; + PLI_INT32 arg_type; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + if (systf_h == NULL) { + vpi_printf("ERROR: $read_vecval failed to obtain systf handle\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* obtain handles to system task arguments */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_vecval requires 1 argument\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check the type of object in system task arguments */ + arg_h = vpi_scan(arg_itr); + arg_type = vpi_get(vpiType, arg_h); + if (arg_type != vpiNet && arg_type != vpiReg) { + vpi_printf("ERROR: $read_vecval arg must be a net or reg\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check that there are no more system task arguments */ + arg_h = vpi_scan(arg_itr); + if (arg_h != NULL) { + vpi_printf("ERROR: $read_vecval can only have 1 argument\n"); + vpi_free_object(arg_itr); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadVecVal_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h, vector_h; + s_vpi_value vector_val; /* structure to receive vector value */ + PLI_INT32 vector_size, array_size; + int i, bit_num, avalbit, bvalbit; + char vlogval; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handle to system task argument + compiletf has already verified only 1 arg with correct type */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + vector_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator memory */ + + vector_size = vpi_get(vpiSize, vector_h); /* determine number of...*/ + array_size = ((vector_size-1) / 32 + 1); /* ...elements in array */ + + vector_val.format = vpiVectorVal; /* set value format field */ + + vpi_get_value(vector_h, &vector_val); /* read vector's logic value */ + + vpi_printf("\nVector %s encoded value:\n", + vpi_get_str(vpiName,vector_h)); + for (i=0; i,); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_RealPow_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_RealPow_compiletf(PLI_BYTE8 *user_data); + +/********************************************************************** + * $realpow_func Registration Data + * (add this function name to the vlog_startup_array) + *********************************************************************/ +void PLIbook_RealPow_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysFunc; + tf_data.sysfunctype = vpiSysFuncReal; + tf_data.tfname = "$realpow"; + tf_data.calltf = PLIbook_RealPow_calltf; + tf_data.compiletf = PLIbook_RealPow_compiletf; + tf_data.sizetf = NULL; /*sizetf is not used for real functions*/ + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * calltf to calculate base to power of exponent and return result. + *********************************************************************/ +#include /* ANSI C standard input/output library */ +PLI_INT32 PLIbook_RealPow_calltf(PLI_BYTE8 *user_data) +{ + s_vpi_value value_s; + vpiHandle systf_handle, arg_itr, arg_handle; + double base, exp, result; + + value_s.format = vpiRealVal; + + /* obtain handle to system task arguments; + compiletf has already verified only 2 args with correct types */ + systf_handle = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_handle); + + /* read base value of system function arg 1 */ + arg_handle = vpi_scan(arg_itr); + vpi_get_value(arg_handle, &value_s); + base = value_s.value.real; + + /* read base value of system function arg 2 */ + arg_handle = vpi_scan(arg_itr); + vpi_get_value(arg_handle, &value_s); + exp = value_s.value.real; + vpi_free_object(arg_itr); /* free iterator--did not scan till null */ + + /* calculate result of base to power of exponent */ + result = pow(base,exp ); + + /* write result to simulation as return value $realpow_func */ + value_s.value.real = result; + vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay); + + return(0); +} + +/********************************************************************** + * compiletf application to verify valid systf args. + *********************************************************************/ +PLI_INT32 PLIbook_RealPow_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_handle, arg_itr, arg_handle; + int tfarg_type; + + systf_handle = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_handle); + if (arg_itr == NULL) { + vpi_printf("ERROR: $realpow requires 2 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + arg_handle = vpi_scan(arg_itr); + tfarg_type = vpi_get(vpiType, arg_handle); + if ( (tfarg_type != vpiReg) && + (tfarg_type != vpiIntegerVar) && + (tfarg_type != vpiRealVar) && + (tfarg_type != vpiConstant) ) { + vpi_printf("ERR: $realpow arg1 must be number, variable or net\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + arg_handle = vpi_scan(arg_itr); + if (arg_handle == NULL) { + vpi_printf("ERROR: $realpow requires 2nd argument\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + tfarg_type = vpi_get(vpiType, arg_handle); + if ( (tfarg_type != vpiReg) && + (tfarg_type != vpiIntegerVar) && + (tfarg_type != vpiRealVar) && + (tfarg_type != vpiConstant) ) { + vpi_printf("ERR: $realpow arg2 must be number, variable or net\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + if (vpi_scan(arg_itr) != NULL) { + vpi_printf("ERROR: $realpow requires only 2 arguments\n"); + vpi_free_object(arg_itr); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_test.log new file mode 100644 index 0000000..a0fbfda --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_test.log @@ -0,0 +1,9 @@ +VERILOG-XL 3.0.p001 Nov 4, 2001 22:19:33 + +At 0.00: a=0 b=0 ci0 sum=x co=0 +At 2.40: a=0 b=0 ci0 sum=0 co=0 +At 10.00: a=1 b=0 ci0 sum=0 co=0 +At 12.30: a=1 b=0 ci0 sum=1 co=0 +At 20.00: a=1 b=1 ci0 sum=0 co=1 +At 30.00: a=0 b=1 ci0 sum=0 co=1 +L26 "set_mipd_delays_test.v": $finish at simulation time 3100 diff --git a/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_test.v new file mode 100644 index 0000000..7bfb449 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_test.v @@ -0,0 +1,52 @@ +/********************************************************************** + * $set_mipd_delays example -- Verilog HDL test bench. + * + * Verilog test bench to test the $set_mipd_delays 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 / 10ps +module test; + reg a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + begin + $set_mipd_delays(i1.a, 2.3, 2.4, 2.5); + a = 0; b = 0; ci = 0; + #10 a = 1; + #10 b = 1; + #10 a = 0; + #1 $finish; + end + + initial + $monitor("At %0.2f: a=%d b=%d ci%d sum=%d co=%d", + $realtime, a, b, ci, sum, co); + +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 10ps +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 (sum, n1, ci); + and (n2, a, b); + and (n3, n1, ci); + or (co, n2, n3); + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_vpi.c b/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_vpi.c new file mode 100644 index 0000000..43f58d3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/set_mipd_delays_vpi.c @@ -0,0 +1,141 @@ +/********************************************************************** + * $set_mipd_delays example -- PLI application using VPI routines + * + * C source to write Module Input Port Delays onto input ports. + * + * Usage: + * $mipd_delays(module_input_port, rise_delay, fall_delay, toZ_delay); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_SetMipd_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_SetMipd_compiletf(PLI_BYTE8 *user_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_SetMipd_register() +{ + s_vpi_systf_data tf_data; /* allocate register data structure */ + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$set_mipd_delays"; + tf_data.calltf = PLIbook_SetMipd_calltf; + tf_data.compiletf = PLIbook_SetMipd_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} +/*********************************************************************/ + +/********************************************************************** + * compiletf routine + *********************************************************************/ +PLI_INT32 PLIbook_SetMipd_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, tfarg_itr, tfarg_h, port_itr, port_h; + int i; + + systf_h = vpi_handle(vpiSysTfCall, NULL); + tfarg_itr = vpi_iterate(vpiArgument, systf_h); + if (tfarg_itr == NULL) { + vpi_printf("ERROR: $mipd_delays requires 4 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + tfarg_h = vpi_scan(tfarg_itr); + if (vpi_get(vpiType, tfarg_h) != vpiNet) { + vpi_printf("ERROR: $mipd_delays arg1 must be module input\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + port_itr = vpi_iterate(vpiPorts, tfarg_h); + if (port_itr == NULL) { + vpi_printf("$mipd_delays arg1 not connected to module port\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + port_h = vpi_scan(port_itr); + vpi_free_object(port_itr); /* free iterator--did not scan to null */ + if (vpi_get(vpiType, port_h) != vpiPort) { + vpi_printf("$mipd_delays arg1 not connected to an input port\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + for (i=2; i<=4; i++) { + tfarg_h = vpi_scan(tfarg_itr); + if (vpi_get(vpiType, tfarg_h) != vpiConstant) { + vpi_printf("$mipd_delays arg %d must be a number\n", i); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + } + if (vpi_scan(tfarg_itr) != NULL) { + vpi_printf("ERROR: $mipd_delays requires only 4 arguments\n"); + vpi_free_object(tfarg_itr); /* free iterator--did not scan to null*/ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_SetMipd_calltf(PLI_BYTE8 *user_data) { + vpiHandle tfarg_itr, tfarg_h, port_itr, port_h; + int i; + s_vpi_delay delay_struct; /* structure to delay setup */ + s_vpi_time delay_array[3]; /* structure to hold delays */ + s_vpi_value tfarg_value; /* structure to hold tfarg values */ + + delay_struct.da = delay_array; + delay_struct.no_of_delays = 3; + delay_struct.time_type = vpiScaledRealTime; + delay_struct.mtm_flag = 0; + delay_struct.append_flag = 0; + delay_struct.pulsere_flag = 0; + tfarg_value.format = vpiRealVal; + + /* obtain handle to system task arguments; + compiletf has already verified only 4 args with correct types */ + tfarg_itr = vpi_iterate(vpiArgument, vpi_handle(vpiSysTfCall, NULL)); + tfarg_h = vpi_scan(tfarg_itr); /* read 1st tfarg */ + port_itr = vpi_iterate(vpiPorts, tfarg_h); + port_h = vpi_scan(port_itr); + if (port_h != NULL) + vpi_free_object(port_itr); /* free iterator-did not scan to null */ + for (i=0; i<=2; i++) { + vpi_get_value(vpi_scan(tfarg_itr), &tfarg_value); /* read tfargs */ + delay_array[i].real = tfarg_value.value.real; + } + vpi_free_object(tfarg_itr); /* free iterator--did not scan to null */ + + vpi_put_delays(port_h, &delay_struct); + + return(0); +} + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.05/veriuser_VCS.tab new file mode 100644 index 0000000..c3524cb --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/veriuser_VCS.tab @@ -0,0 +1,19 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$get_arg_val_test call=PLIbook_GetArgValTestCall data=0 acc+=read:* + +$read_vecval call=PLIbook_ReadVecVal_calltf check=PLIbook_ReadVecVal_compiletf data=0 acc+=read:* + +$read_strengthval call=PLIbook_ReadStrengthVal_calltf check=PLIbook_ReadStrengthVal_compiletf data=0 acc+=read:* + +$read_timeval call=PLIbook_ReadTimeVal_calltf check=PLIbook_ReadTimeVal_compiletf data=0 acc+=read:* + +$realpow call=PLIbook_RealPow_calltf check=PLIbook_RealPow_compiletf size=r data=0 acc+=read_write:* + +$read_attribute_constant call=PLIbook_ReadAttributeConst_calltf check=PLIbook_ReadAttributeConst_compiletf data=0 acc+=read:* + +$read_delays call=PLIbook_ReadDelays_calltf check=PLIbook_ReadDelays_compiletf data=0 acc+=read:* + +$set_mipd_delays call=PLIbook_SetMipd_calltf check=PLIbook_SetMipd_compiletf data=0 acc+=read:* acc+=mip:addbit + diff --git a/me250300_pli/plibook_examples_unix/chapter.05/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.05/vpi_user.c new file mode 100644 index 0000000..50f34e4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.05/vpi_user.c @@ -0,0 +1,38 @@ +/********************************************************************** + * 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_GetArgValTest_register(); /* */ +extern void PLIbook_ReadVecVal_register(); /* */ +extern void PLIbook_ReadStrengthVal_register(); /* */ +extern void PLIbook_ReadTimeVal_register(); /* */ +extern void PLIbook_RealPow_register(); /* */ +extern void PLIbook_ReadAttributeConst_register(); /* */ +extern void PLIbook_ReadDelays_register(); /* */ +extern void PLIbook_SetMipd_register(); /* */ + +void (*vlog_startup_routines[])() = +{ + PLIbook_GetArgValTest_register, /* */ + PLIbook_ReadVecVal_register, /* */ + PLIbook_ReadStrengthVal_register, /* */ + PLIbook_ReadTimeVal_register, /* */ + PLIbook_RealPow_register, /* */ + PLIbook_ReadAttributeConst_register, /* */ + PLIbook_ReadDelays_register, /* */ + PLIbook_SetMipd_register, /* */ + 0 /*** final entry must be 0 ***/ + +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.06/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.06/build_MTI.mak new file mode 100644 index 0000000..5b490b9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/build_MTI.mak @@ -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 = \ + read_test_vector_vpi.c \ + my_strobe_vpi.c \ + read_stimulus_vpi.c \ + my_monitor_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.06/build_NC.mak new file mode 100644 index 0000000..39985b0 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/build_NC.mak @@ -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 = \ + read_test_vector_vpi.c \ + my_strobe_vpi.c \ + read_stimulus_vpi.c \ + my_monitor_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.06/build_XL.mak new file mode 100644 index 0000000..23e6b35 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/build_XL.mak @@ -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 = \ + read_test_vector_vpi.c \ + my_strobe_vpi.c \ + read_stimulus_vpi.c \ + my_monitor_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_test.log b/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_test.log new file mode 100644 index 0000000..2e87723 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_test.log @@ -0,0 +1,27 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Adding monitors to all nets in module addbit: + +At time 0.00: test.i1.ci = 0 +At time 0.00: test.i1.b = 0 +At time 0.00: test.i1.a = 0 +At time 0.00: test.i1.n1 = 0 +At time 0.00: test.i1.n2 = 0 +At time 0.00: test.i1.n3 = 0 +At time 0.00: test.i1.co = 0 +At time 0.00: test.i1.sum = 0 +At time 10.00: test.i1.a = 1 +At time 10.00: test.i1.n1 = 1 +At time 10.00: test.i1.sum = 1 +At time 20.00: test.i1.a = 0 +At time 20.00: test.i1.n1 = 0 +At time 20.00: test.i1.sum = 0 +At time 30.00: test.i1.b = 1 +At time 30.00: test.i1.n1 = 1 +At time 30.00: test.i1.sum = 1 +At time 40.00: test.i1.a = 1 +At time 40.00: test.i1.n1 = 0 +At time 40.00: test.i1.n2 = 1 +At time 40.00: test.i1.co = 1 +At time 40.00: test.i1.sum = 0 +Simulation complete via $finish(1) at time 50 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_test.v b/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_test.v new file mode 100644 index 0000000..418a9a5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_test.v @@ -0,0 +1,51 @@ +/********************************************************************** + * $my_monitor example -- Verilog HDL test bench. + * + * Verilog test bench to test the $my_monitor 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 a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + $my_monitor(i1); + + initial + begin + a = 0; b = 0; ci = 0; + #10 a = 1; + #10 a = 0; + #10 b = 1; + #10 a = 1; + #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 (sum, n1, ci); + and (n2, a, b); + and (n3, n1, ci); + or (co, n2, n3); + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_vpi.c b/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_vpi.c new file mode 100644 index 0000000..8fef776 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/my_monitor_vpi.c @@ -0,0 +1,149 @@ +/********************************************************************** + * $my_monitor example -- PLI application using VPI routines + * + * C source to place value change callbacks on all nets in a module + * instance, and print the simulation time and new value whenever + * any net changes value. + * + * Usage: $my_monitor(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_MyMonitor_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_MyMonitor_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_MyMonitor_callback(p_cb_data cb_data_p); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_MyMonitor_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$my_monitor"; + tf_data.calltf = PLIbook_MyMonitor_calltf; + tf_data.compiletf = PLIbook_MyMonitor_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * compiletf application + *********************************************************************/ +PLI_INT32 PLIbook_MyMonitor_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_handle, arg_iterator, arg_handle; + PLI_INT32 tfarg_type; + + /* 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: $my_monitor requires 1 argument\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* 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: $my_monitor arg1 must be module instance\n"); + vpi_free_object(arg_iterator); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check that there is only 1 system task argument */ + arg_handle = vpi_scan(arg_iterator); + if (arg_handle != NULL) { + vpi_printf("ERROR: $my_monitor can only have 1 argument\n"); + vpi_free_object(arg_iterator); /* free iterator memory */ + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_MyMonitor_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, mod_h, net_itr, net_h, cb_h; + s_vpi_time time_s; + s_vpi_value value_s; + s_cb_data cb_data_s; + PLI_BYTE8 *net_name_temp, *net_name_keep; + + /* setup value change callback options */ + time_s.type = vpiScaledRealTime; + value_s.format = vpiBinStrVal; + + cb_data_s.reason = cbValueChange; + cb_data_s.cb_rtn = PLIbook_MyMonitor_callback; + cb_data_s.time = &time_s; + cb_data_s.value = &value_s; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handle to system task argument */ + /* compiletf has already verified only 1 arg with correct type */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + mod_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + /* add value change callback for each net in module named in tfarg */ + vpi_printf("\nAdding monitors to all nets in module %s:\n\n", + vpi_get_str(vpiDefName, mod_h)); + + net_itr = vpi_iterate(vpiNet, mod_h); + while ((net_h = vpi_scan(net_itr)) != NULL) { + net_name_temp = vpi_get_str(vpiFullName, net_h); + net_name_keep = malloc(strlen((char *)net_name_temp)+1); + strcpy((char *)net_name_keep, (char *)net_name_temp); + cb_data_s.obj = net_h; + cb_data_s.user_data = net_name_keep; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + } + return(0); +} + +/********************************************************************** + * Value change callback application + *********************************************************************/ +PLI_INT32 PLIbook_MyMonitor_callback(p_cb_data cb_data_p) +{ + vpi_printf("At time %0.2f:\t %s = %s\n", + cb_data_p->time->real, + cb_data_p->user_data, + cb_data_p->value->value.str); + return(0); +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_test.log b/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_test.log new file mode 100644 index 0000000..e045a90 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_test.log @@ -0,0 +1,30 @@ +// NOTE: the order of $strobe, $monitor and $my_strobe can be different +// in different simulators. These events are all in "slot 4" of the +// time slots illustrated in the PLI Handbook. Concurrent events +// within a slot can be processed in any order. + +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +$display : At 0: test.sum = x +$strobe : At 0: test.sum = 0 +$my_strobe: At 0: test.sum = 0 +$monitor : At 0: test.sum = 0 + +$display : At 10: test.sum = 0 +$my_strobe: At 10: test.sum = 1 +$strobe : At 10: test.sum = 1 +$monitor : At 10: test.sum = 1 + +$display : At 20: test.sum = 1 +$my_strobe: At 20: test.sum = 0 +$strobe : At 20: test.sum = 0 +$monitor : At 20: test.sum = 0 + +$display : At 30: test.sum = 0 +$display : At 30: test.sum = 0 +$strobe : At 30: test.sum = 0 +$my_strobe: At 30: test.sum = 0 +$my_strobe: At 30: test.sum = 0 +$strobe : At 30: test.sum = 0 + +Simulation complete via $finish(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_test.v b/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_test.v new file mode 100644 index 0000000..895072c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_test.v @@ -0,0 +1,75 @@ +/********************************************************************** + * $my_strobe example -- Verilog HDL test bench. + * + * Verilog test bench to test the $my_strobe 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 a, b, ci, clk; + reg sum, co; + + always @(a or b or ci) + {co,sum} = a + b + ci; + + initial + begin + $strobe ("$strobe : At %0d: \t %m.sum = %d",$time, sum); + $display("$display : At %0d: \t %m.sum = %d",$time, sum); + $my_strobe(sum); + a = 0; b = 0; ci = 0; + + #10 $display(""); + a = 1; + $my_strobe(sum); + $strobe ("$strobe : At %0d: \t %m.sum = %d",$time, sum); + $display("$display : At %0d: \t %m.sum = %d",$time, sum); + + #10 $display(""); + a = 0; + $my_strobe(sum); + $display("$display : At %0d: \t %m.sum = %d",$time, sum); + $strobe ("$strobe : At %0d: \t %m.sum = %d",$time, sum); + + #10 $display(""); + b = 1; + $strobe ("$strobe : At %0d: \t %m.sum = %d",$time, sum); + $my_strobe(sum); + $display("$display : At %0d: \t %m.sum = %d",$time, sum); + a = 1; + $my_strobe(sum); + $strobe ("$strobe : At %0d: \t %m.sum = %d",$time, sum); + $display("$display : At %0d: \t %m.sum = %d",$time, sum); + + #10 $display(""); + $finish; + end + + initial + $monitor("$monitor : At %0d: \t %m.sum = %d",$time, sum); + +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 (sum, n1, ci); + and (n2, a, b); + and (n3, n1, ci); + or (co, n2, n3); + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_vpi.c b/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_vpi.c new file mode 100644 index 0000000..f1dcb58 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/my_strobe_vpi.c @@ -0,0 +1,137 @@ +/********************************************************************** + * $my_strobe example -- PLI application using VPI routines + * + * C source to print the simulation time and new value of a system + * task argument at the end of a simulation time step. + * + * Usage: $my_strobe(); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_MyStrobe_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_MyStrobe_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_EndOfTimeStep_callback(p_cb_data cb_data_p); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_MyStrobe_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$my_strobe"; + tf_data.calltf = PLIbook_MyStrobe_calltf; + tf_data.compiletf = PLIbook_MyStrobe_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * compiletf application to verify valid systf args. + *********************************************************************/ +PLI_INT32 PLIbook_MyStrobe_compiletf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_handle, arg_itr, arg_handle; + PLI_INT32 tfarg_type; + + systf_handle = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_handle); + if (arg_itr == NULL) { + vpi_printf("ERROR: $my_strobe requires 1 argument.\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + arg_handle = vpi_scan(arg_itr); + tfarg_type = vpi_get(vpiType, arg_handle); + if ( (tfarg_type != vpiReg) && + (tfarg_type != vpiIntegerVar) && + (tfarg_type != vpiRealVar) ) { + vpi_printf("ERROR:$my_strobe arg must be a reg or variable.\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + if (vpi_scan(arg_itr) != NULL) { + vpi_printf("ERROR: $my_strobe only supports 1 argument.\n"); + vpi_free_object(arg_itr); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_MyStrobe_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle systf_h, arg_itr, arg_h, cb_h; + s_vpi_time time_s; + s_cb_data cb_data_s; + + /* obtain a handle to the system task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handle to system task argument; */ + /* compiletf has already verified only 1 arg with correct type */ + 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 */ + + /* setup end-of-time step callback */ + time_s.low = 0; + time_s.high = 0; + time_s.type = vpiSimTime; + cb_data_s.reason = cbReadOnlySynch; + cb_data_s.cb_rtn = PLIbook_EndOfTimeStep_callback; + cb_data_s.obj = arg_h; + cb_data_s.time = &time_s; + cb_data_s.value = NULL; /* not used */ + cb_data_s.index = 0; /* not used */ + cb_data_s.user_data = (PLI_BYTE8 *)arg_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + return(0); +} + +/********************************************************************** + * Value change callback application + *********************************************************************/ +PLI_INT32 PLIbook_EndOfTimeStep_callback(p_cb_data cb_data_p) +{ + s_vpi_time time_s; + s_vpi_value value_s; + vpiHandle arg_h; + + arg_h = (vpiHandle)cb_data_p->user_data; + value_s.format = vpiBinStrVal; + vpi_get_value(arg_h, &value_s); + vpi_printf("$my_strobe: At %d: \t %s = %s\n", + cb_data_p->time->low, + vpi_get_str(vpiFullName, arg_h), + value_s.value.str); + return(0); +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.log b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.log new file mode 100644 index 0000000..7d26d4d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.log @@ -0,0 +1,25 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + + 0 ns: a=xxxx b=xxxx ci=x sum=xxxx co=x + 10 ns: a=0000 b=0000 ci=0 sum=xxxx co=x + 12 ns: a=0000 b=0000 ci=0 sum=xxx0 co=0 + 14 ns: a=0000 b=0000 ci=0 sum=0000 co=0 + 30 ns: a=0000 b=0001 ci=0 sum=0000 co=0 + 32 ns: a=0000 b=0001 ci=0 sum=0001 co=0 + 50 ns: a=0001 b=0001 ci=0 sum=0001 co=0 + 52 ns: a=0001 b=0001 ci=0 sum=0000 co=0 + 54 ns: a=0001 b=0001 ci=0 sum=0010 co=0 + 70 ns: a=0001 b=1111 ci=0 sum=0010 co=0 + 72 ns: a=0001 b=1111 ci=0 sum=1000 co=0 + 76 ns: a=0001 b=1111 ci=0 sum=0000 co=1 + 90 ns: a=0000 b=1111 ci=0 sum=0000 co=1 + 92 ns: a=0000 b=1111 ci=0 sum=0001 co=1 + 94 ns: a=0000 b=1111 ci=0 sum=0011 co=1 + 96 ns: a=0000 b=1111 ci=0 sum=0111 co=1 + 98 ns: a=0000 b=1111 ci=0 sum=1111 co=0 + 110 ns: a=1111 b=0000 ci=1 sum=1111 co=0 + 112 ns: a=1111 b=0000 ci=1 sum=1110 co=0 + 114 ns: a=1111 b=0000 ci=1 sum=1100 co=0 + 116 ns: a=1111 b=0000 ci=1 sum=1000 co=0 + 118 ns: a=1111 b=0000 ci=1 sum=0000 co=1 +$read_stimulus_?? reached End-Of-File. diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.pat b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.pat new file mode 100644 index 0000000..be7e351 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.pat @@ -0,0 +1,7 @@ + 10 000000000 + 30 000000001 + 50 000010001 + 70 000011111 + 90 000001111 +110 111110000 +130 000000000 \ No newline at end of file diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.v b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.v new file mode 100644 index 0000000..acbba39 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_test.v @@ -0,0 +1,68 @@ +/********************************************************************** + * $read_stimulus_ba example -- Verilog HDL test bench. + * + * Verilog test bench to test the $read_stimulus_ba PLI application. + * NOTE: this test uses a data file called "read_stimulus_test.pat", + * which has several 9-bit binary test vector values (represented in + * ASCII) and the simulation time in which each value is to be applied. + * + * 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 [8:0] input_vector; + wire [3:0] a, b, sum; + wire ci, co; + + add4 i1 (a, b, ci, sum, co); + + assign {ci, a, b} = input_vector; + + initial + begin + $timeformat(-9,0," ns",10); + $monitor("%t: a=%b b=%b ci=%b sum=%b co=%b", + $time, a, b, ci, sum, co); + $read_stimulus_ba("read_stimulus_test.pat", input_vector); + end +endmodule + +/*** A netlist level 4-bit adder model ***/ +`timescale 1ns / 1ns +module add4 (a, b, ci, sum, co); + input [3:0] a, b; + input ci; + output [3:0] sum; + output co; + + wire [3:0] a, b, sum; + wire ci, c0, c1, c2, co; + + addbit u0 (a[0], b[0], ci, sum[0], c0); + addbit u1 (a[1], b[1], c0, sum[1], c1); + addbit u2 (a[2], b[2], c1, sum[2], c2); + addbit u3 (a[3], b[3], c2, sum[3], co); + +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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_vpi.c b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_vpi.c new file mode 100644 index 0000000..1ba0952 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_stimulus_vpi.c @@ -0,0 +1,344 @@ +/********************************************************************** + * $read_stimulus_?? example -- PLI application using VPI routines + * + * C source to read a stimulu value from a file and apply the stimulus + * value to a Verilog simulation and the simulation time specified in + * in the file. + * + * Each line in the test vector file contains a delay time and a vector + * value, separated by white space. Delay values define when the + * vector is to be applied to simulation. Delays may be relative to + * the previous time, or absolute to time 0. The test vector value + * may be in binary or hex. An example file is: + * + * 100 00000000 + * 70 10111001 + * ... + * + * Usage: + * + * initial + * $read_stimulus_("file_name", verilog_reg); + * + * where: + * is b or h (for binary or hex vectors). + * is r or a for relative or absolute times. + * "file_name" is the name of the file to be read, in quotes. + * verilog_reg is a verilog register data type of the same bit + * width as the patterns to be read. + * + * Output: none + * + * Verbose debugging output is enabled with a +readstim_debug + * invocation option to the simulation + * + * NOTES: + * There is no error checking on the data read from the file. + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadStim_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadStim_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_StartOfSim(p_cb_data cb_data); +PLI_INT32 PLIbook_ReadNextStim(p_cb_data cb_data); +PLI_INT32 PLIbook_ReadStimEnd(p_cb_data cb_data); + +/********************************************************************** + * Define storage structure for file pointer and vector handle. + *********************************************************************/ +typedef struct ReadStimData { + FILE *file_ptr; /* test vector file pointer */ + vpiHandle obj_h; /* pointer to store handle for a Verilog object */ + int mode; /* 0 & 1 = binary values, 2 & 3 = hex values */ + /* 0 & 2 = absolute time, 1 & 3 = relative time */ + int debug; /* print debug messages if true */ +} s_ReadStimData, *p_ReadStimData; + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadStim_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.calltf = PLIbook_ReadStim_calltf; + tf_data.compiletf = PLIbook_ReadStim_compiletf; + tf_data.sizetf = NULL; + + tf_data.tfname = "$read_stimulus_ba"; /* binary, absolute time*/ + tf_data.user_data = "ba"; + vpi_register_systf(&tf_data); + + tf_data.tfname = "$read_stimulus_br"; /* binary, relative time*/ + tf_data.user_data = "br"; + vpi_register_systf(&tf_data); + + tf_data.tfname = "$read_stimulus_ha"; /* hex, absolute time */ + tf_data.user_data = "ha"; + vpi_register_systf(&tf_data); + + tf_data.tfname = "$read_stimulus_hr"; /* hex, relative time */ + tf_data.user_data = "hr"; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * compiletf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadStim_compiletf(PLI_BYTE8 *user_data) +{ + s_cb_data cb_data_s; + vpiHandle systf_h, arg_itr, arg_h, cb_h; + PLI_INT32 tfarg_type; + int err = 0; + char *file_name; + + systf_h = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_stimulus_?? requires 2 arguments\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("$read_stimulus_?? arg 1 must be a quoted file name\n"); + err = 1; + } + else if (vpi_get(vpiConstType, arg_h) != vpiStringConst) { + vpi_printf("$read_stimulus_?? arg 1 must be a string\n"); + err = 1; + } + arg_h = vpi_scan(arg_itr); /* get handle for second tfarg */ + tfarg_type = vpi_get(vpiType, arg_h); + if ( (tfarg_type != vpiReg) && + (tfarg_type != vpiIntegerVar) && + (tfarg_type != vpiTimeVar) ) { + vpi_printf("$read_stimulus_?? arg 2 must be a register type\n"); + err = 1; + } + if (vpi_scan(arg_itr) != NULL) { + vpi_printf("read_stimulus_?? requires only 2 arguments\n"); + vpi_free_object(arg_itr); + err = 1; + } + if (err) { + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* setup a callback for start of simulation */ + cb_data_s.reason = cbStartOfSimulation; + cb_data_s.cb_rtn = PLIbook_StartOfSim; + cb_data_s.obj = NULL; + cb_data_s.time = NULL; + cb_data_s.value = NULL; + cb_data_s.user_data = (PLI_BYTE8 *)systf_h; /* pass systf_h */ + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * calltf routine -- registers an immediate callback to the + * ReadNextStim application. + *********************************************************************/ +PLI_INT32 PLIbook_ReadStim_calltf(PLI_BYTE8 *user_data) +{ + s_cb_data data_s; + s_vpi_time time_s; + vpiHandle systf_h, cb_h; + p_ReadStimData StimData; /* pointer to a ReadStimData structure */ + + /* get ReadStimData pointer from work area for this task instance */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + StimData = (p_ReadStimData)vpi_get_userdata(systf_h); + + /* look at user data to set the stimulus mode flag */ + if (strcmp(user_data, "ba") == 0) StimData->mode = 0; + else if (strcmp(user_data, "br") == 0) StimData->mode = 1; + else if (strcmp(user_data, "ha") == 0) StimData->mode = 2; + else StimData->mode = 3; + + /* setup immediate callback to ReadNextStim routine */ + systf_h = vpi_handle(vpiSysTfCall, NULL); + time_s.type = vpiSimTime; + time_s.low = 0; + time_s.high = 0; + data_s.reason = cbReadWriteSynch; + data_s.cb_rtn = PLIbook_ReadNextStim; + data_s.obj = NULL; + data_s.time = &time_s; + data_s.value = NULL; + data_s.user_data = (PLI_BYTE8 *)systf_h; + cb_h = vpi_register_cb(&data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + return(0); +} + +/********************************************************************** + * ReadNextStim callback -- Reads a time and vector from a file. + * Schedules the vector to be applied at the specified time. + * Schedules a callback to self that same time (to read next line). + *********************************************************************/ +PLI_INT32 PLIbook_ReadNextStim(p_cb_data cb_data) +{ + char vector[1024]; /* fixed max. size, should use malloc instead */ + int delay; + vpiHandle systf_h, cb_h; + s_cb_data data_s; + s_vpi_time time_s; + s_vpi_value value_s; + p_ReadStimData StimData; /* pointer to a ReadStimData structure */ + + /* retrieve system task handle from user_data */ + systf_h = (vpiHandle)cb_data->user_data; + + /* get ReadStimData pointer from work area for this task instance */ + StimData = (p_ReadStimData)vpi_get_userdata(systf_h); + + /* read next line from the file */ + if ( (fscanf(StimData->file_ptr,"%d %s\n", &delay, vector)) == EOF) { + /* At EOF, schedule ReadStimEnd callback at end of this time */ + time_s.type = vpiSimTime; + time_s.low = 0; + time_s.high = 0; + data_s.reason = cbReadOnlySynch; + data_s.cb_rtn = PLIbook_ReadStimEnd; + data_s.obj = NULL; + data_s.time = &time_s; + data_s.value = NULL; + data_s.user_data = (PLI_BYTE8 *)StimData->file_ptr; + cb_h = vpi_register_cb(&data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + return(0); + } + + if (StimData->debug) { + vpi_printf("Values read from file: delay=%d vector=%s\n", + delay, vector); + } + + /* convert absolute delay from file to relative delay if needed */ + time_s.type = vpiScaledRealTime; + if (StimData->mode == 0 || StimData->mode == 2) { + vpi_get_time(cb_data->obj, &time_s); + time_s.real = ((double)delay - time_s.real); + } + else + time_s.real = (double)delay; + + /* schedule the vector to be applied after the delay period */ + if (StimData->mode == 0 || StimData->mode == 1) + value_s.format = vpiBinStrVal; + else + value_s.format = vpiHexStrVal; + value_s.value.str = vector; + vpi_put_value(StimData->obj_h, &value_s, &time_s, vpiTransportDelay); + + /* schedule callback to this routine when time to read next vector */ + data_s.reason = cbAfterDelay; + data_s.cb_rtn = PLIbook_ReadNextStim; + data_s.obj = systf_h; /* object required for scaled delays */ + data_s.time = &time_s; + data_s.value = NULL; + data_s.user_data = (PLI_BYTE8 *)systf_h; + cb_h = vpi_register_cb(&data_s); + if (vpi_chk_error(NULL)) + vpi_printf("An error occurred registering ReadNextStim callback\n"); + else + vpi_free_object(cb_h); /* don't need callback handle */ + return(0); +} + +/********************************************************************** + * StartOfSim callback -- opens the test vector file and saves the + * file pointer and other info in an instance-specific work area. + *********************************************************************/ +PLI_INT32 PLIbook_StartOfSim(p_cb_data cb_data) +{ + char *file_name; + FILE *vector_file; + vpiHandle systf_h, tfarg_itr, tfarg1_h, tfarg2_h; + s_cb_data data_s; + s_vpi_time time_s; + s_vpi_value argVal; + s_vpi_vlog_info options_s; + p_ReadStimData StimData; /* pointer to a ReadStimData structure */ + int i, debug; + + /* retrieve system task handle from user_data */ + systf_h = (vpiHandle)cb_data->user_data; + + /* get tfarg handles (compiletf already verified args are correct) */ + tfarg_itr = vpi_iterate(vpiArgument, systf_h); + tfarg1_h = vpi_scan(tfarg_itr); + tfarg2_h = vpi_scan(tfarg_itr); + vpi_free_object(tfarg_itr); /* free iterator--did not scan to null */ + + /* read file name from first tfarg */ + argVal.format = vpiStringVal; + vpi_get_value(tfarg1_h, &argVal); + if (vpi_chk_error(NULL)) { + vpi_printf("ERROR: $read_stimulus_?? could not get file name\n"); + return(0); + } + file_name = argVal.value.str; + if ( !(vector_file = fopen(file_name,"r")) ) { + vpi_printf("$read_stimulus_?? could not open file %s\n",file_name); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* check for +readstim_debug invocation option */ + debug = 0; /* assume not invoked with debug flag */ + vpi_get_vlog_info(&options_s); + for (i=1; ifile_ptr = vector_file; + StimData->obj_h = tfarg2_h; + StimData->debug = debug; + vpi_put_userdata(systf_h, (PLI_BYTE8 *)StimData); + + return(0); +} + +/********************************************************************** + * End-Of-Simulation callback -- close file and exit simulation. + *********************************************************************/ +int PLIbook_ReadStimEnd(p_cb_data cb_data_p) +{ + vpi_printf("$read_stimulus_?? reached End-Of-File.\n"); + fclose((FILE *)cb_data_p->user_data); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_test.log b/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_test.log new file mode 100644 index 0000000..807f519 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_test.log @@ -0,0 +1,19 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. +at 0: clk = 0 vector = 01010101 +at 10: clk = 1 vector = 00000000 +at 20: clk = 0 vector = 10101010 +at 30: clk = 1 vector = 00001111 +at 40: clk = 0 vector = zzzzzzzz +at 50: clk = 1 vector = 11110000 +at 60: clk = 0 vector = 1xz01xz0 +at 70: clk = 1 vector = 11111111 +at 80: clk = 0 vector = 01010101 +at 90: clk = 1 vector = 00000000 +at 100: clk = 0 vector = 10101010 +at 110: clk = 1 vector = 00001111 +at 120: clk = 0 vector = zzzzzzzz +at 130: clk = 1 vector = 11110000 +at 140: clk = 0 vector = 1xz01xz0 +at 150: clk = 1 vector = 11111111 +$read_test_vector reached End-Of-File +ncverilog: v3.20.(p1): Exiting on Jul 17, 2001 at 14:50:02 (total: 00:00:01) diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_test.v b/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_test.v new file mode 100644 index 0000000..ed94930 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_test.v @@ -0,0 +1,36 @@ +/********************************************************************** + * $read_test_vector example -- Verilog HDL test bench. + * + * Verilog test bench to test the $read_test_vector PLI application. + * NOTE: this test uses two data file, "read_vector_test1.pat" and + * "read_vector_test2.pat". Each file has several 8-bit binary test + * vector values (represented in ASCII). + * + * 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; + reg clk; + + initial + begin + $monitor("at %d: clk = %b vector = %b", $stime, clk, vector); + #0 clk = 0; + forever #10 clk = ~clk; + end + + always @(posedge clk) + $read_test_vector("read_vector_test1.pat", vector); + + always @(negedge clk) + $read_test_vector("read_vector_test2.pat", vector); + + endmodule +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_vpi.c b/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_vpi.c new file mode 100644 index 0000000..4fb1f84 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_test_vector_vpi.c @@ -0,0 +1,210 @@ +/********************************************************************** + * $read_test_vector example -- PLI application using VPI routines + * + * C source to read a test vector value from a file and apply the + * vector to a Verilog simulation. The $read_test_vector application + * is intended to be used in a loop, where each time it is called, it + * reads the next vector from a file. When the last vector has been + * read, the PLI routine will stop simulation. + * + * Usage: $read_test_vector("",); + * + * Example: + * reg [11:0] vector; + * always @(negedge clk) $read_test_vector("vector.pat",vector); + * + * 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 /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ReadVector_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ReadVector_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_StartOfSim(p_cb_data cb_data); + +/********************************************************************** + * Define storage structure for file pointer and vector handle. + *********************************************************************/ +typedef struct PLIbook_Data { + FILE *file_ptr; /* test vector file pointer */ + vpiHandle obj_h; /* pointer to store handle for a Verilog object */ +} PLIbook_Data_s, *PLIbook_Data_p; + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ReadVector_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$read_test_vector"; + tf_data.calltf = PLIbook_ReadVector_calltf; + tf_data.compiletf = PLIbook_ReadVector_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * compiletf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadVector_compiletf(PLI_BYTE8 *user_data) +{ + s_cb_data cb_data_s; + vpiHandle systf_h, arg_itr, arg_h, cb_h; + PLI_INT32 tfarg_type; + int err = 0; + char *file_name; + + systf_h = vpi_handle(vpiSysTfCall, NULL); + arg_itr = vpi_iterate(vpiArgument, systf_h); + if (arg_itr == NULL) { + vpi_printf("ERROR: $read_test_vector requires 2 arguments\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("$read_test_vector arg 1 must be a quoted file name\n"); + err = 1; + } + else if (vpi_get(vpiConstType, arg_h) != vpiStringConst) { + vpi_printf("$read_test_vector arg 1 must be a string\n"); + err = 1; + } + arg_h = vpi_scan(arg_itr); /* get handle for second tfarg */ + tfarg_type = vpi_get(vpiType, arg_h); + if ( (tfarg_type != vpiReg) && + (tfarg_type != vpiIntegerVar) && + (tfarg_type != vpiTimeVar) ) { + vpi_printf("$read_test_vector arg 2 must be a register type\n"); + err = 1; + } + if (vpi_scan(arg_itr) != NULL) { + vpi_printf("read_test_vector requires only 2 arguments\n"); + vpi_free_object(arg_itr); + err = 1; + } + if (err) { + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* No syntax errors, setup a callback for start of simulation */ + cb_data_s.reason = cbStartOfSimulation; + cb_data_s.cb_rtn = PLIbook_StartOfSim; + cb_data_s.obj = NULL; + cb_data_s.time = NULL; + cb_data_s.value = NULL; + /* use user_data to pass systf_h to simulation callback so that the + callback can access the system task arguments */ + cb_data_s.user_data = (PLI_BYTE8 *)systf_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* free callback handle -- don't need it */ + + return(0); /* no syntax errors detected */ +} + +/********************************************************************** + * StartOfSim callback -- opens the test vector file and saves the + * pointer and the system task handle in the work area storage. + *********************************************************************/ +PLI_INT32 PLIbook_StartOfSim(p_cb_data cb_data) +{ + s_vpi_value argVal; + char *file_name; + FILE *vector_file; + vpiHandle systf_h, arg_itr, arg1_h, arg2_h; + + PLIbook_Data_p vector_data; /* pointer to a ReadVecData structure */ + + vector_data = (PLIbook_Data_p)malloc(sizeof(PLIbook_Data_s)); + + /* retrieve system task handle from user_data */ + systf_h = (vpiHandle)cb_data->user_data; + + /* get argument handles (compiletf already verified only 2 args) */ + arg_itr = vpi_iterate(vpiArgument, systf_h); + arg1_h = vpi_scan(arg_itr); + arg2_h = vpi_scan(arg_itr); + vpi_free_object(arg_itr); /* free iterator -- did not scan to null */ + + /* read file name from first tfarg */ + argVal.format = vpiStringVal; + vpi_get_value(arg1_h, &argVal); + if (vpi_chk_error(NULL)) { + vpi_printf("ERROR: $read_test_vector could not get file name\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + file_name = argVal.value.str; + if ( !(vector_file = fopen(file_name, "r")) ) { + vpi_printf("$read_test_vector could not open file %s", file_name); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* store file pointer and tfarg2_h in work area for this instance */ + vector_data->file_ptr = vector_file; + vector_data->obj_h = arg2_h; + vpi_put_userdata(systf_h, (void *)vector_data); + + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +PLI_INT32 PLIbook_ReadVector_calltf(PLI_BYTE8 *user_data) +{ + s_cb_data data_s; + s_vpi_time time_s; + s_vpi_value value_s; + FILE *vector_file; + vpiHandle systf_h, arg2_h; + PLIbook_Data_p vector_data; /* pointer to a ReadVecData structure */ + + char vector[1024]; /* fixed vector size, could use malloc*/ + + systf_h = vpi_handle(vpiSysTfCall, NULL); + + /* get ReadVecData pointer from work area for this task instance */ + /* the data in the work area was loaded at the start of simulation */ + vector_data = (PLIbook_Data_p)vpi_get_userdata(systf_h); + vector_file = vector_data->file_ptr; + arg2_h = vector_data->obj_h; + + /* read next line from the file */ + if ( (fscanf(vector_file,"%s\n", vector)) == EOF) { + vpi_printf("$read_test_vector reached End-Of-File\n"); + fclose(vector_data->file_ptr); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + /* write the vector to the second system task argument */ + value_s.format = vpiBinStrVal; + value_s.value.str = vector; + vpi_put_value(arg2_h, &value_s, NULL, vpiNoDelay); + + return(0); +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_vector_test1.pat b/me250300_pli/plibook_examples_unix/chapter.06/read_vector_test1.pat new file mode 100644 index 0000000..565c416 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_vector_test1.pat @@ -0,0 +1,8 @@ +00000000 +00001111 +11110000 +11111111 +00000000 +00001111 +11110000 +11111111 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/read_vector_test2.pat b/me250300_pli/plibook_examples_unix/chapter.06/read_vector_test2.pat new file mode 100644 index 0000000..a4bbac3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/read_vector_test2.pat @@ -0,0 +1,8 @@ +01010101 +10101010 +zzzzzzzz +1xz01xz0 +01010101 +10101010 +zzzzzzzz +1xz01xz0 diff --git a/me250300_pli/plibook_examples_unix/chapter.06/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.06/veriuser_VCS.tab new file mode 100644 index 0000000..d4c303f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/veriuser_VCS.tab @@ -0,0 +1,16 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$read_test_vector call=PLIbook_ReadVector_calltf check=PLIbook_ReadVector_compiletf data=0 acc+=read:* + +$my_strobe call=PLIbook_ShowVal_calltf check=PLIbook_ShowVal_compiletf data=0 acc+=read:* + +$read_test_vector call=PLIbook_MyStrobe_calltf check=PLIbook_MyStrobe_compiletf data=0 acc+=read:* + +$my_monitor call=PLIbook_MyMonitor_calltf check=PLIbook_MyMonitor_compiletf data=0 acc+=read:* + +$read_stimulus_ba call=PLIbook_ReadStim_calltf check=PLIbook_ReadStim_compiletf data="ba" acc+=read:* +$read_stimulus_br call=PLIbook_ReadStim_calltf check=PLIbook_ReadStim_compiletf data="br" acc+=read:* +$read_stimulus_ha call=PLIbook_ReadStim_calltf check=PLIbook_ReadStim_compiletf data="ha" acc+=read:* +$read_stimulus_hr call=PLIbook_ReadStim_calltf check=PLIbook_ReadStim_compiletf data="hr" acc+=read:* + diff --git a/me250300_pli/plibook_examples_unix/chapter.06/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.06/vpi_user.c new file mode 100644 index 0000000..c4199f9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.06/vpi_user.c @@ -0,0 +1,30 @@ +/********************************************************************** + * 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_ReadVector_register(); /* */ +extern void PLIbook_MyStrobe_register(); /* */ +extern void PLIbook_ReadStim_register(); /* */ +extern void PLIbook_MyMonitor_register(); /* */ + +void (*vlog_startup_routines[])() = +{ + PLIbook_ReadVector_register, /* */ + PLIbook_MyStrobe_register, /* */ + PLIbook_ReadStim_register, /* */ + PLIbook_MyMonitor_register, /* */ + 0 /*** final entry must be 0 ***/ + +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.07/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.07/build_MTI.mak new file mode 100644 index 0000000..79b11ed --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/build_MTI.mak @@ -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 = \ + sci_alu_combinational_vpi.c \ +# sci_alu_sequential_vpi.c \ +# sci_alu_synchronized_vpi.c \ +# sci_alu_latched_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.07/build_NC.mak new file mode 100644 index 0000000..0b4c9be --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/build_NC.mak @@ -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 = \ + sci_alu_combinational_vpi.c \ +# sci_alu_sequential_vpi.c \ +# sci_alu_synchronized_vpi.c \ +# sci_alu_latched_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.07/build_XL.mak new file mode 100644 index 0000000..07f0f06 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/build_XL.mak @@ -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 = \ + sci_alu_combinational_vpi.c \ +# sci_alu_sequential_vpi.c \ +# sci_alu_synchronized_vpi.c \ +# sci_alu_latched_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 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_shell.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_shell.v new file mode 100644 index 0000000..4eb1fac --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_shell.v @@ -0,0 +1,39 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_test.log b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_test.log new file mode 100644 index 0000000..f87e89a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 2 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 3 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_test.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_test.v new file mode 100644 index 0000000..5b4200c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_test.v @@ -0,0 +1,49 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_combinational_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out, excep, err); + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_vpi.c b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_vpi.c new file mode 100644 index 0000000..ab22546 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_combinational_vpi.c @@ -0,0 +1,285 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using VPI routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 +#include +#include + +void PLIbook_ScientificALU_C_model( + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err, /* output; set if input is out of range */ + double a, /* input */ + double b, /* input */ + int opcode) /* input */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ScientificALU_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ScientificALU_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$scientific_alu"; + tf_data.calltf = PLIbook_ScientificALU_calltf; + tf_data.compiletf = PLIbook_ScientificALU_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * Value change simulation callback routine: Serves as an interface + * between Verilog simulation and the C model. Called whenever the + * C model inputs change value, passes the values to the C model, and + * puts the C model outputs into simulation. + * + * NOTE: A handle to the $scientific_alu instance is passed into this + * simulation callback routine, so that this routine can access the + * arguments of the system task. + * + * A more efficient method would be to obtain all the handles one time + * in the calltf routine, save the handles, and pass a pointer to the + * saved handles to this simulation callback routine. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data) +{ + double a, b, result; + int opcode, excep, err; + s_vpi_value value_s; + vpiHandle instance_h, arg_itr; + vpiHandle a_h, b_h, opcode_h, result_h, excep_h, err_h; + + /* Retrieve handle to $scientific_alu instance from user_data */ + instance_h = (vpiHandle)cb_data->user_data; + + /* obtain handles to system task arguments */ + /* compiletf has already verified arguments are correct */ + arg_itr = vpi_iterate(vpiArgument, instance_h); + a_h = vpi_scan(arg_itr); /* 1st arg is a input */ + b_h = vpi_scan(arg_itr); /* 2nd arg is b input */ + opcode_h = vpi_scan(arg_itr); /* 3rd arg is opcode input */ + result_h = vpi_scan(arg_itr); /* 4th arg is result output */ + excep_h = vpi_scan(arg_itr); /* 5th arg is excep output */ + err_h = vpi_scan(arg_itr); /* 6th arg is error output */ + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = vpiRealVal; + vpi_get_value(a_h, &value_s); + a = value_s.value.real; + + vpi_get_value(b_h, &value_s); + b = value_s.value.real; + + value_s.format = vpiIntVal; + vpi_get_value(opcode_h, &value_s); + opcode = (int)value_s.value.integer; + + /****** Call the C model ******/ + PLIbook_ScientificALU_C_model(&result, &excep, &err, a, b, opcode); + + /* Write the C model outputs onto the Verilog signals */ + value_s.format = vpiRealVal; + value_s.value.real = result; + vpi_put_value(result_h, &value_s, NULL, vpiNoDelay); + + value_s.format = vpiIntVal; + value_s.value.integer = (PLI_INT32)excep; + vpi_put_value(excep_h, &value_s, NULL, vpiNoDelay); + + value_s.value.integer = (PLI_INT32)err; + vpi_put_value(err_h, &value_s, NULL, vpiNoDelay); + + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle instance_h, arg_itr, a_h, b_h, opcode_h, cb_h; + s_vpi_value value_s; + s_vpi_time time_s; + s_cb_data cb_data_s; + + /* obtain a handle to the system task instance */ + instance_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handles to system task arguments for model inputs */ + /* compiletf has already verified arguments are correct */ + arg_itr = vpi_iterate(vpiArgument, instance_h); + a_h = vpi_scan(arg_itr); /* 1st arg is a input */ + b_h = vpi_scan(arg_itr); /* 2nd arg is b input */ + opcode_h = vpi_scan(arg_itr); /* 3rd arg is opcode input */ + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + /* setup value change callback options */ + time_s.type = vpiSuppressTime; + cb_data_s.reason = cbValueChange; + cb_data_s.cb_rtn = PLIbook_ScientificALU_interface; + cb_data_s.time = &time_s; + cb_data_s.value = &value_s; + + /* add value change callbacks to all signals which are inputs to */ + /* pass handle to $scientific_alu instance as user_data value */ + cb_data_s.user_data = (PLI_BYTE8 *)instance_h; + value_s.format = vpiRealVal; + cb_data_s.obj = a_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + cb_data_s.obj = b_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + value_s.format = vpiIntVal; + cb_data_s.obj = opcode_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + return(0); +} + +/********************************************************************** + * compiletf routine: Verifies that $scientific_alu() is used correctly + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_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: $scientific_alu requires 6 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + arg_h = vpi_scan(arg_itr); /* 1st arg is a input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 1 (a) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 2nd arg is b input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 2 (b) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 3rd arg is opcode input */ + if (vpi_get(vpiType, arg_h) != vpiNet) { + vpi_printf("$scientific_alu arg 3 (opcode) must be a net\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 4) { + vpi_printf("$scientific_alu arg 3 (opcode) must be 4-bit vector\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 4th arg is result output */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 4 (result) must be a real var.\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 5th arg is exception output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 5 (exception) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 5 (exception) must be scalar\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 6th arg is error output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 6 (error) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 6 (error) must be scalar\n"); + err = 1; + } + + if (vpi_scan(arg_itr) != NULL) { /* should not be any more args */ + vpi_printf("ERROR: $scientific_alu requires only 6 arguments\n"); + vpi_free_object(arg_itr); + err = 1; + } + + if (err) { + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_shell.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_shell.v new file mode 100644 index 0000000..a3366fd --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, latched logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(enable, a_in, b_in, opcode, + result_out, exception, error); + input enable; + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(enable, a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_test.log b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_test.log new file mode 100644 index 0000000..9fd1692 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_test.log @@ -0,0 +1,39 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: en=1 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: en=1 result1=4.00 result2=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=1 +At 2 ns: en=1 result1=8886110.52 result2=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=2 +At 3 ns: en=1 result1=64.00 result2=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: en=1 result1=16.00 result2=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: en=1 result1=0.00 result2=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: en=1 result1=16.00 result2=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: en=1 result1=16.00 result2=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: en=1 result1=2.77 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: en=1 result1=1.20 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: en=1 result1=-0.29 result2=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: en=1 result1=-0.96 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: en=1 result1=0.30 result2=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: en=1 result1=0.00 result2=8886110.52 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: en=1 result1=0.00 result2=4.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: en=1 result1=1.51 result2=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: en=1 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +At 26 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 27 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 28 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 29 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 30 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 31 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 32 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 33 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 34 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 35 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 36 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 37 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 38 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 39 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 40 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=e +At 41 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 42 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 52 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_test.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_test.v new file mode 100644 index 0000000..b954812 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_test.v @@ -0,0 +1,61 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a latched + * logic device. + * + * 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 "sci_alu_latched_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + reg enable; + wire excep, err, excep1, err1, excep2, err2; + real a, b, result1, result2; + wire [63:0] a_in, b_in, result_out1, result_out2; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out1) result1 = $bitstoreal(result_out1); + always @(result_out2) result2 = $bitstoreal(result_out2); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (enable, a_in, b_in, opcode[3:0], result_out1, excep1, err1); + scientific_alu i2 (enable, a_in, b_in, ~opcode[3:0], result_out2, excep2, err2); + + assign err = err1 | err2; + assign excep = excep1 | excep2; + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: en=%b result1=%.2f \tresult2=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, enable, result1, result2, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + enable = 1; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + enable = 0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_vpi.c b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_vpi.c new file mode 100644 index 0000000..7411ed6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_latched_vpi.c @@ -0,0 +1,342 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using VPI routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version with latched output values. + * + * 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 + *********************************************************************/ + + +/********************************************************************** + * Structure definition to store output values when the ALU is latched. + * The structure is allocatate in the calltf routine for each instance + * of the C model. + *********************************************************************/ + typedef struct PLIbook_ScientificALU_outputs { + double result; /* stored result of previous operation */ + int excep; + int err; + } PLIbook_ALU_outputs_s, *PLIbook_ALU_outputs_p; + + +/********************************************************************** + * C model with latched outputs. When enable is 1, the ALU returns + * the currently calculated outputs, and when 0, the ALU returns the + * latched previous results. + *********************************************************************/ +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err, /* output; set if input is out of range */ + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + int enable, /* input; 0 = latched */ + PLIbook_ALU_outputs_p LatchedOutputs) /* input */ +{ + if (enable) { /* ALU is not latched, calculate outputs and store */ + switch (opcode) { + case 0x0: LatchedOutputs->result = pow (a, b); break; + case 0x1: LatchedOutputs->result = sqrt (a); break; + case 0x2: LatchedOutputs->result = exp (a); break; + case 0x3: LatchedOutputs->result = ldexp (a, (int)b); break; + case 0x4: LatchedOutputs->result = fabs (a); break; + case 0x5: LatchedOutputs->result = fmod (a, b); break; + case 0x6: LatchedOutputs->result = ceil (a); break; + case 0x7: LatchedOutputs->result = floor (a); break; + case 0x8: LatchedOutputs->result = log (a); break; + case 0x9: LatchedOutputs->result = log10 (a); break; + case 0xA: LatchedOutputs->result = sin (a); break; + case 0xB: LatchedOutputs->result = cos (a); break; + case 0xC: LatchedOutputs->result = tan (a); break; + case 0xD: LatchedOutputs->result = asin (a); break; + case 0xE: LatchedOutputs->result = acos (a); break; + case 0xF: LatchedOutputs->result = atan (a); break; + } + LatchedOutputs->excep = (errno == ERANGE);/* result out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + LatchedOutputs->err = (_isnan(*result) || /* not-a-number, or */ + errno == EDOM); /* arg out-of-range */ + #else + LatchedOutputs->err = (isnan(*result) || /* not-a-number, or */ + errno == EDOM); /* arg out-of-range */ + #endif + if (LatchedOutputs->err) LatchedOutputs->result = 0.0; + errno = 0; /* clear error flag */ + } + + /* return the values stored in the C model */ + *result = LatchedOutputs->result; + *err = LatchedOutputs->err; + *excep = LatchedOutputs->excep; + + return; +} +/*********************************************************************/ + + +#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ScientificALU_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ScientificALU_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$scientific_alu"; + tf_data.calltf = PLIbook_ScientificALU_calltf; + tf_data.compiletf = PLIbook_ScientificALU_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * Definition for a structure to hold the data to be passed from + * calltf routine to the ALU interface. Also allocates the structure + * to store the latched output values of the ALU. This structure is + * allocated in the calltf routine for each instance of the C model. + *********************************************************************/ +typedef struct PLIbook_ScientificALU_data { + vpiHandle enable_h, a_h, b_h, opcode_h, result_h, excep_h, err_h; + PLIbook_ALU_outputs_s LatchedOutputs; /* storage for outputs */ +} PLIbook_ALU_data_s, *PLIbook_ALU_data_p; + + +/********************************************************************** + * Value change simulation callback routine: Serves as an interface + * between Verilog simulation and the C model. Called whenever the + * C model inputs change value, passes the values to the C model, and + * puts the C model outputs into simulation. + * + * NOTE: The handles for the arguments to $scientific_alu were obtained + * in the calltf routine and saved in application-allocated memory. A + * pointer to this memory is passed to this callback via the user_data + * field. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data) +{ + double a, b, result; + int opcode, excep, err, enable; + s_vpi_value value_s; + + PLIbook_ALU_data_p ALUdata; + + /* Retrieve pointer to ALU data structure from callback user_data. */ + /* The structure contains the handles for the $scientific_alu args */ + ALUdata = (PLIbook_ALU_data_p)cb_data->user_data; + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = vpiRealVal; + vpi_get_value(ALUdata->a_h, &value_s); + a = value_s.value.real; + + vpi_get_value(ALUdata->b_h, &value_s); + b = value_s.value.real; + + value_s.format = vpiIntVal; + vpi_get_value(ALUdata->opcode_h, &value_s); + opcode = (int)value_s.value.integer; + + vpi_get_value(ALUdata->enable_h, &value_s); + enable = (int)value_s.value.integer; + + /****** Call the C model ******/ + PLIbook_ScientificALU_C_model(&result, &excep, &err, a, b, opcode, + enable, &ALUdata->LatchedOutputs); + + /* Write the C model outputs onto the Verilog signals */ + value_s.format = vpiRealVal; + value_s.value.real = result; + vpi_put_value(ALUdata->result_h, &value_s, NULL, vpiNoDelay); + + value_s.format = vpiIntVal; + value_s.value.integer = (PLI_INT32)excep; + vpi_put_value(ALUdata->excep_h, &value_s, NULL, vpiNoDelay); + + value_s.value.integer = (PLI_INT32)err; + vpi_put_value(ALUdata->err_h, &value_s, NULL, vpiNoDelay); + + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value. Memory to store + * the $scientific_alu argument handles and the latched output values + * is allocated here, because the calltf routine is called for each + * instance of $scientific_alu. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle instance_h, arg_itr, cb_h; + s_vpi_value value_s; + s_vpi_time time_s; + s_cb_data cb_data_s; + + PLIbook_ALU_data_p ALUdata; + + /* allocate storage to hold $scientific_alu argument handles */ + ALUdata = (PLIbook_ALU_data_p)malloc(sizeof(PLIbook_ALU_data_s)); + + /* obtain a handle to the system task instance */ + instance_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handles to system task arguments */ + /* compiletf has already verified arguments are correct */ + arg_itr = vpi_iterate(vpiArgument, instance_h); + ALUdata->enable_h = vpi_scan(arg_itr); /* 1st arg is enable input */ + ALUdata->a_h = vpi_scan(arg_itr); /* 2nd arg is a input */ + ALUdata->b_h = vpi_scan(arg_itr); /* 3rd arg is b input */ + ALUdata->opcode_h = vpi_scan(arg_itr); /* 4th arg is opcode input */ + ALUdata->result_h = vpi_scan(arg_itr); /* 5th arg is result output */ + ALUdata->excep_h = vpi_scan(arg_itr); /* 6th arg is excep output */ + ALUdata->err_h = vpi_scan(arg_itr); /* 7th arg is error output */ + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + /* setup value change callback options */ + time_s.type = vpiSuppressTime; + cb_data_s.reason = cbValueChange; + cb_data_s.cb_rtn = PLIbook_ScientificALU_interface; + cb_data_s.time = &time_s; + cb_data_s.value = &value_s; + + /* add value change callbacks to all signals which are inputs to */ + /* pass pointer to storage for handles as user_data value */ + cb_data_s.user_data = (PLI_BYTE8 *)ALUdata; + value_s.format = vpiRealVal; + cb_data_s.obj = ALUdata->a_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + cb_data_s.obj = ALUdata->b_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + value_s.format = vpiIntVal; + cb_data_s.obj = ALUdata->opcode_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + cb_data_s.obj = ALUdata->enable_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + return(0); +} + +/********************************************************************** + * compiletf routine: Verifies that $scientific_alu() is used correctly + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_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: $scientific_alu requires 7 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + arg_h = vpi_scan(arg_itr); /* 1st arg is enable input */ + if (vpi_get(vpiType, arg_h) != vpiNet) { + vpi_printf("$scientific_alu arg 1 (enable) must be a net\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 1 (enable) must be scalar\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 2nd arg is a input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 2 (a) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 3rd arg is b input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 3 (b) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 4th arg is opcode input */ + if (vpi_get(vpiType, arg_h) != vpiNet) { + vpi_printf("$scientific_alu arg 4 (opcode) must be a net\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 4) { + vpi_printf("$scientific_alu arg 4 (opcode) must be 4-bit vector\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 5th arg is result output */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 5 (result) must be a real var.\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 6th arg is exception output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 6 (exception) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 6 (exception) must be scalar\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 7th arg is error output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 7 (error) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 7 (error) must be scalar\n"); + err = 1; + } + + if (vpi_scan(arg_itr) != NULL) { /* should not be any more args */ + vpi_printf("ERROR: $scientific_alu requires only 7 arguments\n"); + vpi_free_object(arg_itr); + err = 1; + } + + if (err) { + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_shell.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_shell.v new file mode 100644 index 0000000..8d04a16 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, sequential logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(clock, a_in, b_in, opcode, + result_out, exception, error); + input clock; + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(clock, a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_test.log b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_test.log new file mode 100644 index 0000000..e2ab21f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_test.log @@ -0,0 +1,36 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: clk=0 result=0.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 5 ns: clk=1 result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 10 ns: clk=0 result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 15 ns: clk=1 result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 20 ns: clk=0 result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 25 ns: clk=1 result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 30 ns: clk=0 result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 35 ns: clk=1 result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 40 ns: clk=0 result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 45 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 50 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 55 ns: clk=1 result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 60 ns: clk=0 result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 65 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 70 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 75 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 80 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 85 ns: clk=1 result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 90 ns: clk=0 result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 95 ns: clk=1 result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 100 ns: clk=0 result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 105 ns: clk=1 result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 110 ns: clk=0 result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 115 ns: clk=1 result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 120 ns: clk=0 result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 125 ns: clk=1 result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 130 ns: clk=0 result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 135 ns: clk=1 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 140 ns: clk=0 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 145 ns: clk=1 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 150 ns: clk=0 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 155 ns: clk=1 result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f + +Simulation complete via $finish(1) at time 160 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_test.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_test.v new file mode 100644 index 0000000..a54de6d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_test.v @@ -0,0 +1,56 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a sequential + * logic device. + * + * 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 "sci_alu_sequential_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [3:0] opcode; + reg clk; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + integer i; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (clk, a_in, b_in, opcode, result_out, excep, err); + + always #5 clk = ~clk; + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + opcode = 0; + a = 16.0; + b = 2.0; + #0 clk = 0; + for (i=1; i<=15; i=i+1) + @(negedge clk) opcode = i; + #10 $display(""); + $finish; + end + + always @(clk) + $strobe("At %t: clk=%b result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, clk, result, excep, err, a, b, opcode); + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_vpi.c b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_vpi.c new file mode 100644 index 0000000..916509a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_sequential_vpi.c @@ -0,0 +1,296 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using VPI routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Sequential logic version (output values are evaluated on the + * positive edge of the input clock, but are not stored). + * + * 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 +#include +#include +void PLIbook_ScientificALU_C_model( + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err, /* output; set if input is out of range */ + double a, /* input */ + double b, /* input */ + int opcode) /* input */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + +#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ScientificALU_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ScientificALU_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$scientific_alu"; + tf_data.calltf = PLIbook_ScientificALU_calltf; + tf_data.compiletf = PLIbook_ScientificALU_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * Definition for a structure to hold the data to be passed from + * calltf routine to the ALU interface. + *********************************************************************/ +typedef struct PLIbook_ScientificALU_data { + vpiHandle clock_h, a_h, b_h, opcode_h, result_h, excep_h, err_h; +} PLIbook_ALU_data_s, *PLIbook_ALU_data_p; + + +/********************************************************************** + * Value change simulation callback routine: Serves as an interface + * between Verilog simulation and the C model. Called whenever the + * C model inputs change value, passes the values to the C model, and + * puts the C model outputs into simulation. + * + * NOTE: The handles for the arguments to $scientific_alu were obtained + * in the calltf routine and saved in application-allocated memory. A + * pointer to this memory is passed to this callback via the user_data + * field. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data) +{ + double a, b, result; + int clock, opcode, excep, err; + s_vpi_value value_s; + + PLIbook_ALU_data_p ALUdata; + + /* Retrieve pointer to ALU data structure from callback user_data. */ + /* The structure contains the handles for the $scientific_alu args */ + ALUdata = (PLIbook_ALU_data_p)cb_data->user_data; + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = vpiIntVal; + vpi_get_value(ALUdata->clock_h, &value_s); + clock = (int)value_s.value.integer; + if (clock != 1) /* abort if not a positive edge of the clock input */ + return(0); + + value_s.format = vpiRealVal; + vpi_get_value(ALUdata->a_h, &value_s); + a = value_s.value.real; + + vpi_get_value(ALUdata->b_h, &value_s); + b = value_s.value.real; + + value_s.format = vpiIntVal; + vpi_get_value(ALUdata->opcode_h, &value_s); + opcode = (int)value_s.value.integer; + + /****** Call the C model ******/ + PLIbook_ScientificALU_C_model(&result, &excep, &err, a, b, opcode); + + /* Write the C model outputs onto the Verilog signals */ + value_s.format = vpiRealVal; + value_s.value.real = result; + vpi_put_value(ALUdata->result_h, &value_s, NULL, vpiNoDelay); + + value_s.format = vpiIntVal; + value_s.value.integer = (PLI_INT32)excep; + vpi_put_value(ALUdata->excep_h, &value_s, NULL, vpiNoDelay); + + value_s.value.integer = (PLI_INT32)err; + vpi_put_value(ALUdata->err_h, &value_s, NULL, vpiNoDelay); + + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle instance_h, arg_itr, cb_h; + s_vpi_value value_s; + s_vpi_time time_s; + s_cb_data cb_data_s; + + PLIbook_ALU_data_p ALUdata; + + /* allocate storage to hold $scientific_alu argument handles */ + ALUdata = (PLIbook_ALU_data_p)malloc(sizeof(PLIbook_ALU_data_s)); + + /* obtain a handle to the system task instance */ + instance_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handles to system task arguments */ + /* compiletf has already verified arguments are correct */ + arg_itr = vpi_iterate(vpiArgument, instance_h); + ALUdata->clock_h = vpi_scan(arg_itr); /* 1st arg is clock input */ + ALUdata->a_h = vpi_scan(arg_itr); /* 2nd arg is a input */ + ALUdata->b_h = vpi_scan(arg_itr); /* 3rd arg is b input */ + ALUdata->opcode_h = vpi_scan(arg_itr); /* 4th arg is opcode input */ + ALUdata->result_h = vpi_scan(arg_itr); /* 5th arg is result output */ + ALUdata->excep_h = vpi_scan(arg_itr); /* 6th arg is excep output */ + ALUdata->err_h = vpi_scan(arg_itr); /* 7th arg is error output */ + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + /* setup value change callback options */ + time_s.type = vpiSuppressTime; + cb_data_s.reason = cbValueChange; + cb_data_s.cb_rtn = PLIbook_ScientificALU_interface; + cb_data_s.time = &time_s; + cb_data_s.value = &value_s; + + /* add value change callbacks to clock input to the C model, */ + /* pass pointer to storage for handles as user_data value */ + value_s.format = vpiSuppressVal; + cb_data_s.user_data = (PLI_BYTE8 *)ALUdata; + cb_data_s.obj = ALUdata->clock_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + return(0); +} + +/********************************************************************** + * compiletf routine: Verifies that $scientific_alu() is used correctly + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_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: $scientific_alu requires 7 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + arg_h = vpi_scan(arg_itr); /* 1st arg is clock input */ + if (vpi_get(vpiType, arg_h) != vpiNet) { + vpi_printf("$scientific_alu arg 1 (clock) must be a net\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 1 (clock) must be scalar\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 2nd arg is a input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 2 (a) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 3rd arg is b input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 3 (b) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 4th arg is opcode input */ + if (vpi_get(vpiType, arg_h) != vpiNet) { + vpi_printf("$scientific_alu arg 4 (opcode) must be a net\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 4) { + vpi_printf("$scientific_alu arg 4 (opcode) must be 4-bit vector\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 5th arg is result output */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 5 (result) must be a real var.\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 6th arg is exception output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 6 (exception) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 6 (exception) must be scalar\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 7th arg is error output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 7 (error) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 7 (error) must be scalar\n"); + err = 1; + } + + if (vpi_scan(arg_itr) != NULL) { /* should not be any more args */ + vpi_printf("ERROR: $scientific_alu requires only 7 arguments\n"); + vpi_free_object(arg_itr); + err = 1; + } + + if (err) { + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_shell.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_shell.v new file mode 100644 index 0000000..cb7ccee --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_shell.v @@ -0,0 +1,39 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_test.log b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_test.log new file mode 100644 index 0000000..6a8d32d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result1=4.00 result2=0.00 excep=0 err=x a=16.0 b=2.0 opcode=1 +At 2 ns: result1=8886110.52 result2=0.00 excep=0 err=x a=16.0 b=2.0 opcode=2 +At 3 ns: result1=64.00 result2=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result1=16.00 result2=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result1=0.00 result2=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result1=16.00 result2=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result1=16.00 result2=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result1=2.77 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result1=1.20 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result1=-0.29 result2=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result1=-0.96 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result1=0.30 result2=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result1=0.00 result2=8886110.52 excep=0 err=x a=16.0 b=2.0 opcode=d +At 14 ns: result1=0.00 result2=4.00 excep=0 err=x a=16.0 b=2.0 opcode=e +At 15 ns: result1=1.51 result2=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_test.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_test.v new file mode 100644 index 0000000..183b1b9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_test.v @@ -0,0 +1,51 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_synchronized_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result1, result2; + wire [63:0] a_in, b_in, result_out1, result_out2; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out1) result1 = $bitstoreal(result_out1); + always @(result_out2) result2 = $bitstoreal(result_out2); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out1, excep, err); + scientific_alu i2 (a_in, b_in, ~opcode[3:0], result_out2, excep, err); + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: result1=%.2f \tresult2=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result1, result2, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_vpi.c b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_vpi.c new file mode 100644 index 0000000..72dde43 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_synchronized_vpi.c @@ -0,0 +1,334 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using VPI routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version, with the interface callbacks + * synchronized to the end of the time step in which an input to + * the model changes value. + * + * 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 +#include +#include +void PLIbook_ScientificALU_C_model( + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err, /* output; set if input is out of range */ + double a, /* input */ + double b, /* input */ + int opcode) /* input */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* 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_ScientificALU_calltf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_compiletf(PLI_BYTE8 *user_data); +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data); +PLI_INT32 PLIbook_EndOfTimeStep_callback(p_cb_data cb_data); + +/********************************************************************** + * VPI Registration Data + *********************************************************************/ +void PLIbook_ScientificALU_register() +{ + s_vpi_systf_data tf_data; + tf_data.type = vpiSysTask; + tf_data.sysfunctype = 0; + tf_data.tfname = "$scientific_alu"; + tf_data.calltf = PLIbook_ScientificALU_calltf; + tf_data.compiletf = PLIbook_ScientificALU_compiletf; + tf_data.sizetf = NULL; + tf_data.user_data = NULL; + vpi_register_systf(&tf_data); +} + +/********************************************************************** + * Definition for a structure to hold the data to be passed from + * calltf routine to the ALU interface. + *********************************************************************/ +typedef struct PLIbook_ScientificALU_data { + vpiHandle clock_h, a_h, b_h, opcode_h, result_h, excep_h, err_h; + short int sync_flag; +} PLIbook_ALU_data_s, *PLIbook_ALU_data_p; + +/********************************************************************** + * Value change simulation callback routine: Schedules a read-write + * synchronize simulation callback at the end of the current time step. + * Only schedules one callback for a time step. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_interface(p_cb_data cb_data) +{ + vpiHandle cb_h; + s_cb_data cb_data_s; + s_vpi_time time_s; + PLIbook_ALU_data_p ALUdata; + + /* Retrieve pointer to ALU data structure from user_data field. */ + /* The structure contains a flag indicating if a synchronize */ + /* callback has already been scheduled (the sync_flag is set by */ + /* this routine, and cleared by the read-write synch callback. */ + + ALUdata = (PLIbook_ALU_data_p)cb_data->user_data; + if (!ALUdata->sync_flag) { + /* Schedule a synchronize simulation callback for this instance */ + ALUdata->sync_flag = 1; /* set sync_flag */ + time_s.type = vpiSimTime; + time_s.high = 0; + time_s.low = 0; + cb_data_s.reason = cbReadWriteSynch; + cb_data_s.user_data = (PLI_BYTE8 *)ALUdata; + cb_data_s.cb_rtn = PLIbook_EndOfTimeStep_callback; + cb_data_s.obj = NULL; + cb_data_s.time = &time_s; + cb_data_s.value = NULL; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + } + return(0); +} + +/********************************************************************** + * Read-write synchronize simulation callback routine: Serves as an + * interface between Verilog simulation and the C model. Passes the + * values to the C model, and puts the C model outputs into simulation. + * + * NOTE: The handles for the arguments to $scientific_alu were obtained + * in the calltf routine and saved in application-allocated memory. A + * pointer to this memory is passed to this callback via the user_data + * field. + *********************************************************************/ +PLI_INT32 PLIbook_EndOfTimeStep_callback(p_cb_data cb_data) +{ + double a, b, result; + int opcode, excep, err; + s_vpi_value value_s; + + PLIbook_ALU_data_p ALUdata; + + /* Retrieve pointer to ALU data structure from callback user_data. */ + /* The structure contains the handles for the $scientific_alu args */ + ALUdata = (PLIbook_ALU_data_p)cb_data->user_data; + + /* Set the sync_flag to 0 to indicate that this callback has been */ + /* processed */ + ALUdata->sync_flag = 0; + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = vpiRealVal; + vpi_get_value(ALUdata->a_h, &value_s); + a = value_s.value.real; + + vpi_get_value(ALUdata->b_h, &value_s); + b = value_s.value.real; + + value_s.format = vpiIntVal; + vpi_get_value(ALUdata->opcode_h, &value_s); + opcode = (int)value_s.value.integer; + + /****** Call the C model ******/ + PLIbook_ScientificALU_C_model(&result, &excep, &err, a, b, opcode); + + /* Write the C model outputs onto the Verilog signals */ + value_s.format = vpiRealVal; + value_s.value.real = result; + vpi_put_value(ALUdata->result_h, &value_s, NULL, vpiNoDelay); + + value_s.format = vpiIntVal; + value_s.value.integer = (PLI_INT32)excep; + vpi_put_value(ALUdata->excep_h, &value_s, NULL, vpiNoDelay); + + value_s.value.integer = (PLI_INT32)err; + vpi_put_value(ALUdata->err_h, &value_s, NULL, vpiNoDelay); + + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_calltf(PLI_BYTE8 *user_data) +{ + vpiHandle instance_h, arg_itr, cb_h; + s_vpi_value value_s; + s_vpi_time time_s; + s_cb_data cb_data_s; + + PLIbook_ALU_data_p ALUdata; + + /* allocate storage to hold $scientific_alu argument handles */ + ALUdata = (PLIbook_ALU_data_p)malloc(sizeof(PLIbook_ALU_data_s)); + + /* obtain a handle to the system task instance */ + instance_h = vpi_handle(vpiSysTfCall, NULL); + + /* obtain handles to system task arguments */ + /* compiletf has already verified arguments are correct */ + arg_itr = vpi_iterate(vpiArgument, instance_h); + ALUdata->a_h = vpi_scan(arg_itr); /* 1st arg is a input */ + ALUdata->b_h = vpi_scan(arg_itr); /* 2nd arg is b input */ + ALUdata->opcode_h = vpi_scan(arg_itr); /* 3rd arg is opcode input */ + ALUdata->result_h = vpi_scan(arg_itr); /* 4th arg is result output */ + ALUdata->excep_h = vpi_scan(arg_itr); /* 5th arg is excep output */ + ALUdata->err_h = vpi_scan(arg_itr); /* 6th arg is error output */ + vpi_free_object(arg_itr); /* free iterator--did not scan to null */ + + /* setup value change callback options */ + time_s.type = vpiSuppressTime; + cb_data_s.reason = cbValueChange; + cb_data_s.cb_rtn = PLIbook_ScientificALU_interface; + cb_data_s.time = &time_s; + cb_data_s.value = &value_s; + + /* add value change callbacks to all signals which are inputs to */ + /* pass pointer to storage for handles as user_data value */ + cb_data_s.user_data = (PLI_BYTE8 *)ALUdata; + value_s.format = vpiRealVal; + cb_data_s.obj = ALUdata->a_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + cb_data_s.obj = ALUdata->b_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + value_s.format = vpiIntVal; + cb_data_s.obj = ALUdata->opcode_h; + cb_h = vpi_register_cb(&cb_data_s); + vpi_free_object(cb_h); /* don't need callback handle */ + + /* clear the callback sync_flag to indicate that no read-write */ + /* synchronize callbacks have been processed */ + ALUdata->sync_flag = 0; + + return(0); +} + +/********************************************************************** + * compiletf routine: Verifies that $scientific_alu() is used correctly + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +PLI_INT32 PLIbook_ScientificALU_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: $scientific_alu requires 6 arguments\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + + arg_h = vpi_scan(arg_itr); /* 1st arg is a input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 1 (a) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 2nd arg is b input */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 2 (b) must be a real variable\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 3rd arg is opcode input */ + if (vpi_get(vpiType, arg_h) != vpiNet) { + vpi_printf("$scientific_alu arg 3 (opcode) must be a net\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 4) { + vpi_printf("$scientific_alu arg 3 (opcode) must be 4-bit vector\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 4th arg is result output */ + if (vpi_get(vpiType, arg_h) != vpiRealVar) { + vpi_printf("$scientific_alu arg 4 (result) must be a real var.\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 5th arg is exception output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 5 (exception) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 5 (exception) must be scalar\n"); + err = 1; + } + + arg_h = vpi_scan(arg_itr); /* 6th arg is error output */ + if (vpi_get(vpiType, arg_h) != vpiReg) { + vpi_printf("$scientific_alu arg 6 (error) must be a reg\n"); + err = 1; + } + else if (vpi_get(vpiSize, arg_h) != 1) { + vpi_printf("$scientific_alu arg 6 (error) must be scalar\n"); + err = 1; + } + + if (vpi_scan(arg_itr) != NULL) { /* should not be any more args */ + vpi_printf("ERROR: $scientific_alu requires only 6 arguments\n"); + vpi_free_object(arg_itr); + err = 1; + } + + if (err) { + vpi_control(vpiFinish, 1); /* abort simulation */ + return(0); + } + return(0); /* no syntax errors detected */ +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_shell.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_shell.v new file mode 100644 index 0000000..865fb71 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_shell.v @@ -0,0 +1,76 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version with pin-to-pin + * path delays. The path delays are represented using a Verilog + * specify block. + * + * NOTES: + * - Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * - Some Verilog simulators require that path delays to be used with + * models where all ports are connected to uni-directional + * primitives with nets data types connected to the inputs an outputs + * of the primitives. This model satisfies this restriction by + * adding buffers to all input and output ports. + * + * - This shell module uses the array of instances from the IEEE 1364 + * Verilog standard. Some simulators do not support this construct, + * and may require using a separate instance statement for each bit + * of a vector. + * + * 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 / 100ps +module scientific_alu(a_in, b_in, opcode_in, + result_out, exception, error); + output [63:0] result_out; + output exception, error; + input [63:0] a_in, b_in; + input [3:0] opcode_in; + + wire [63:0] result_out, result_vector; + wire [63:0] a_in, a_vector; + wire [63:0] b_in, b_vector; + wire [3:0] opcode_in, opcode_vector; + wire exception, error; + + reg exception_reg, error_reg; + real a, b, result; // real variables used in this module + + // convert real numbers to/from 64-bit vector port connections + assign result_vector = $realtobits(result); + always @(a_vector) a = $bitstoreal(a_vector); + always @(b_vector) b = $bitstoreal(b_vector); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode_vector, + result, exception_reg, error_reg); + + specify + (a_in, b_in *> result_out, exception, error) = (5.6, 4.7); + (opcode_in *> result_out, exception, error) = (3.4, 3.8); + endspecify + + // add buffers to all ports, with nets connected to each buffer + // (this example uses the array of instance syntax in the + // from the IEEE 1364-1995 Verilog standard + buf result_buf[63:0] (result_out, result_vector); + buf excep_buf (exception, exception_reg); + buf error_buf (error, error_reg); + + buf a_buf[63:0] (a_vector, a_in); + buf b_buf[63:0] (b_vector, b_in); + buf opcode_buf[3:0] (opcode_vector, opcode_in); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_test.log new file mode 100644 index 0000000..2bf6957 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_test.log @@ -0,0 +1,47 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result=0.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 3 ns: result=256.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 4 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 10 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 14 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 20 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 23 ns: result=17772221.04 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 24 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 30 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 33 ns: result=17772221.04 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 34 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 40 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 43 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 44 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 50 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 54 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 60 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 63 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 70 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 80 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 83 ns: result=22.18 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 84 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 90 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 94 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 100 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 103 ns: result=-1.21 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 104 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 110 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 113 ns: result=-1.93 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 114 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 120 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 123 ns: result=-1.98 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 124 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 130 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 133 ns: result=0.30 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 134 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 140 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 150 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 153 ns: result=1.51 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 154 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 160 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 164 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 + + +Simulation complete via $finish(1) at time 170 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_test.v new file mode 100644 index 0000000..1d1e4ba --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/sci_alu_with_delays_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_with_delays_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out, excep, err); + + initial + begin + $timeformat(-9,0," ns",7); + $monitor("At %t: result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #10 ; + + #10 $display("\n"); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.07/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.07/veriuser_VCS.tab new file mode 100644 index 0000000..4df4d16 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/veriuser_VCS.tab @@ -0,0 +1,4 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$scientific_alu call=PLIbook_ScientificALU_calltf check=PLIbook_ScientificALU_compiletf data=0 acc+=read_write:* diff --git a/me250300_pli/plibook_examples_unix/chapter.07/vpi_user.c b/me250300_pli/plibook_examples_unix/chapter.07/vpi_user.c new file mode 100644 index 0000000..8872e83 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.07/vpi_user.c @@ -0,0 +1,24 @@ +/********************************************************************** + * 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_ScientificALU_register(); + +void (*vlog_startup_routines[])() = +{ + PLIbook_ScientificALU_register, + 0 /*** final entry must be 0 ***/ + +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.08/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.08/build_MTI.mak new file mode 100644 index 0000000..6df2727 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/build_MTI.mak @@ -0,0 +1,18 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = hello_tf.c \ + show_value_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.08/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.08/build_NC.mak new file mode 100644 index 0000000..72bf7c9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/build_NC.mak @@ -0,0 +1,18 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = hello_tf.c \ + show_value_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.08/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.08/build_XL.mak new file mode 100644 index 0000000..f133238 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/build_XL.mak @@ -0,0 +1,18 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = hello_tf.c \ + show_value_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/LDV_2.2/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/LDV_2.2/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.08/hello_test.log b/me250300_pli/plibook_examples_unix/chapter.08/hello_test.log new file mode 100644 index 0000000..0c10686 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/hello_test.log @@ -0,0 +1,5 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Hello World! + +Simulation stopped via $stop(1) at time 10 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.08/hello_test.v b/me250300_pli/plibook_examples_unix/chapter.08/hello_test.v new file mode 100644 index 0000000..40258be --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/hello_test.v @@ -0,0 +1,21 @@ +/********************************************************************** + * $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; + $finish; + end +endmodule +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.08/hello_tf.c b/me250300_pli/plibook_examples_unix/chapter.08/hello_tf.c new file mode 100644 index 0000000..039007f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/hello_tf.c @@ -0,0 +1,41 @@ +/********************************************************************** + * $hello example -- PLI application using TF/ACC routines + * + * C source to print "Hello World" as a 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 + * + * Usage: $hello; + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_hello_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_hello_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$hello", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_hello_calltf(int user_data, int reason) +{ + io_printf("\nHello World!\n\n"); + return(0); +} diff --git a/me250300_pli/plibook_examples_unix/chapter.08/show_value_acc.c b/me250300_pli/plibook_examples_unix/chapter.08/show_value_acc.c new file mode 100644 index 0000000..f5c4955 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/show_value_acc.c @@ -0,0 +1,74 @@ +/********************************************************************** + * $show_value example -- C source code using TF/ACC PLI routines + * + * C source to print the names and current logic value of a signal. + * + * 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 + * + * Usage: $show_value(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ShowVal_checktf(int user_data, int reason); + * extern int PLIbook_ShowVal_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ShowVal_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ShowVal_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$show_value", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ShowVal_checktf(int user_data, int reason) +{ + PLI_INT32 arg_type; + handle arg_handle; + + acc_initialize(); + if (tf_nump() != 1) + tf_error("$show_value must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$show_value arg cannot be null."); + else { + arg_handle = acc_handle_tfarg(1); + arg_type = acc_fetch_type(arg_handle); + if (!(arg_type == accNet || arg_type == accReg)) + tf_error("$show_value arg must be a net or reg."); + } + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ShowVal_calltf(int user_data, int reason) +{ + handle arg_handle; + + acc_initialize(); + arg_handle = acc_handle_tfarg(1); + io_printf("Signal %s has the value %s\n", + acc_fetch_fullname(arg_handle), + acc_fetch_value(arg_handle, "%b", null)); + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.08/show_value_test.log b/me250300_pli/plibook_examples_unix/chapter.08/show_value_test.log new file mode 100644 index 0000000..be22da6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/show_value_test.log @@ -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 stopped via $stop(1) at time 30 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.08/show_value_test.v b/me250300_pli/plibook_examples_unix/chapter.08/show_value_test.v new file mode 100644 index 0000000..04c987c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/show_value_test.v @@ -0,0 +1,56 @@ +/********************************************************************** + * $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; + $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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.08/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.08/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.08/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.08/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.08/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.08/veriuser_VCS.tab new file mode 100644 index 0000000..9db8d5c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/veriuser_VCS.tab @@ -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_checktf call=PLIbook_ShowVal_calltf data=0 acc+=read:* diff --git a/me250300_pli/plibook_examples_unix/chapter.08/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.08/veriusertfs_table.h new file mode 100644 index 0000000..9ec8962 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.08/veriusertfs_table.h @@ -0,0 +1,43 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_hello_calltf(int user_data, int reason); +extern int PLIbook_ShowVal_checktf(int user_data, int reason); +extern int PLIbook_ShowVal_calltf(int user_data, int reason); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_hello_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$hello", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ShowVal_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ShowVal_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$show_value", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.09/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.09/build_MTI.mak new file mode 100644 index 0000000..df801de --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/build_MTI.mak @@ -0,0 +1,17 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = pow_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.09/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.09/build_NC.mak new file mode 100644 index 0000000..4e288a6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/build_NC.mak @@ -0,0 +1,17 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = pow_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.09/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.09/build_XL.mak new file mode 100644 index 0000000..f2ad48f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/build_XL.mak @@ -0,0 +1,17 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = pow_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.09/pow_acc.c b/me250300_pli/plibook_examples_unix/chapter.09/pow_acc.c new file mode 100644 index 0000000..dec6ac1 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/pow_acc.c @@ -0,0 +1,97 @@ +/********************************************************************** + * $pow example -- C source code using TF/ACC PLI routines + * + * C source to calculate the result of a number to the power of an + * exponent. The value is returned to simulation as a system function. + * + * 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 + * + * Usage: result = $pow(,); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_pow_sizetf(int user_data, int reason); + * extern int PLIbook_pow_checktf(int user_data, int reason); + * extern int PLIbook_pow_calltf(int user_data, int reason); + * extern int PLIbook_pow_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {userfunction, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_pow_checktf, /* checktf routine -/ + * PLIbook_pow_sizetf, /* sizetf routine -/ + * PLIbook_pow_calltf, /* calltf routine -/ + * PLIbook_pow_misctf, /* misctf routine -/ + * "$pow", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +/********************************************************************** + * Sizetf application + *********************************************************************/ +int PLIbook_pow_sizetf(int user_data, int reason) +{ + return(32); /* $pow returns 32-bit values */ +} + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_pow_checktf(int user_data, int reason) +{ + static PLI_INT32 valid_types[4] = {accReg, accIntegerVar, + accConstant, 0}; + handle arg_handle; + + if (tf_nump() != 2) + tf_error("$pow must have 2 arguments.\n"); + else if (tf_typep(1) == tf_nullparam) + tf_error("$pow arg 1 cannot be null.\n"); + else if (tf_typep(2) == tf_nullparam) + tf_error("$pow arg 2 cannot be null.\n"); + else { + arg_handle = acc_handle_tfarg(1); + if (!(acc_object_in_typelist(arg_handle, valid_types)) ) + tf_error("$pow arg1 must be number, variable or net.\n"); + arg_handle = acc_handle_tfarg(2); + if (!(acc_object_in_typelist(arg_handle, valid_types)) ) + tf_error("$pow arg2 must be number, variable or net.\n"); + } + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +#include +int PLIbook_pow_calltf(int user_data, int reason) +{ + PLI_INT32 base, exp, result; + + base = tf_getp(1); /* read base value from tfarg 1 */ + exp = tf_getp(2); /* read exponent value from tfarg 2 */ + result = (PLI_INT32)pow( (double)base, (double)exp ); + tf_putp(0,result); /* return result */ + return(0); +} + +/********************************************************************** + * misctf routine + *********************************************************************/ +int PLIbook_pow_misctf(int user_data, int reason, int paramvc) +{ + if (reason == reason_endofcompile) + io_printf("\n$pow PLI application is being used.\n\n"); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.09/pow_test.log b/me250300_pli/plibook_examples_unix/chapter.09/pow_test.log new file mode 100644 index 0000000..f2c831e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/pow_test.log @@ -0,0 +1,11 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +$pow PLI application is being used. + + +$pow PLI application is being used. + +$pow(2,3) returns 8 +$pow(a,b) returns 1 (a=1 b=0) + +Simulation stopped via $stop(1) at time 4 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.09/pow_test.v b/me250300_pli/plibook_examples_unix/chapter.09/pow_test.v new file mode 100644 index 0000000..020e8f4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/pow_test.v @@ -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; + $finish; + end + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.09/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.09/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.09/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.09/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.09/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.09/veriuser_VCS.tab new file mode 100644 index 0000000..1269ae3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/veriuser_VCS.tab @@ -0,0 +1,4 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$pow check=PLIbook_pow_checktf call=PLIbook_pow_calltf misc=PLIbook_pow_misctf data=0 size=32 acc+=read:* diff --git a/me250300_pli/plibook_examples_unix/chapter.09/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.09/veriusertfs_table.h new file mode 100644 index 0000000..46d9884 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.09/veriusertfs_table.h @@ -0,0 +1,31 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_pow_sizetf(int user_data, int reason); +extern int PLIbook_pow_checktf(int user_data, int reason); +extern int PLIbook_pow_calltf(int user_data, int reason); +extern int PLIbook_pow_misctf(int user_data, int reason, int pvc); +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {userfunction, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_pow_checktf, /* checktf routine */ + PLIbook_pow_sizetf, /* sizetf routine */ + PLIbook_pow_calltf, /* calltf routine */ + PLIbook_pow_misctf, /* misctf routine */ + "$pow", /* system task/function name */ + 1 /* forward reference = true */ + }, + {0} /*** final entry must be 0 ***/ +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.10/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.10/build_MTI.mak new file mode 100644 index 0000000..3c255f2 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/build_MTI.mak @@ -0,0 +1,17 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = read_vector_tf.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.10/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.10/build_NC.mak new file mode 100644 index 0000000..60e7880 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/build_NC.mak @@ -0,0 +1,17 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = read_vector_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.10/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.10/build_XL.mak new file mode 100644 index 0000000..ec4953a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/build_XL.mak @@ -0,0 +1,17 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = read_vector_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test.log b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test.log new file mode 100644 index 0000000..a437cf8 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test.log @@ -0,0 +1,20 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +at 0: clk = 0 vector = xxxxxxxx +at 10: clk = 1 vector = 00000000 +at 20: clk = 0 vector = 01010101 +at 30: clk = 1 vector = 00001111 +at 40: clk = 0 vector = 10101010 +at 50: clk = 1 vector = 11110000 +at 60: clk = 0 vector = zzzzzzzz +at 70: clk = 1 vector = 11111111 +at 80: clk = 0 vector = 1xz01xz0 +at 90: clk = 1 vector = 00000000 +at 100: clk = 0 vector = 01010101 +at 110: clk = 1 vector = 00001111 +at 120: clk = 0 vector = 10101010 +at 130: clk = 1 vector = 11110000 +at 140: clk = 0 vector = zzzzzzzz +at 150: clk = 1 vector = 11111111 +at 160: clk = 0 vector = 1xz01xz0 +".\read_vector_test.v", 29: Warning! $read_test_vector reached End-Of-File read_vector_test1.pat diff --git a/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test.v b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test.v new file mode 100644 index 0000000..2fc20a6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test.v @@ -0,0 +1,36 @@ +/********************************************************************** + * $read_test_vector example -- Verilog test bench source code + * + * Verilog test bench to test the $read_test_vector PLI application. + * NOTE: this test uses two data file, "read_vector_test1.pat" and + * "read_vector_test2.pat". Each file has several 8-bit binary values + * (represented in ASCII). + * + * 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; + reg clk; + + initial + begin + $monitor("at %d: clk = %b vector = %b", $stime, clk, vector); + clk = 0; + forever #10 clk = ~clk; + end + + always @(posedge clk) + $read_test_vector("read_vector_test1.pat", vector); + + always @(negedge clk) + $read_test_vector("read_vector_test2.pat", vector); + + endmodule +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test1.pat b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test1.pat new file mode 100644 index 0000000..565c416 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test1.pat @@ -0,0 +1,8 @@ +00000000 +00001111 +11110000 +11111111 +00000000 +00001111 +11110000 +11111111 diff --git a/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test2.pat b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test2.pat new file mode 100644 index 0000000..a4bbac3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_test2.pat @@ -0,0 +1,8 @@ +01010101 +10101010 +zzzzzzzz +1xz01xz0 +01010101 +10101010 +zzzzzzzz +1xz01xz0 diff --git a/me250300_pli/plibook_examples_unix/chapter.10/read_vector_tf.c b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_tf.c new file mode 100644 index 0000000..f77856d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/read_vector_tf.c @@ -0,0 +1,111 @@ +/********************************************************************** + * $read_test_vector example -- C source code using TF/ACC PLI routines + * + * C source to read a test vector value from a file and apply the + * value to a system task argument. + * + * 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 + * + * Usage: + * ------ + * The $read_test_vector routine is intended to be used in a loop, + * where each time it is called, it reads the next vector from a file. + * When the last vector has been read, the PLI routine will stop + * simulation. + * + * Syntax: $read_test_vector("",); + * + * Example: + * reg [11:0] vector; + * always @(negedge clk) $read_test_vector("vector.pat",vector); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ReadVector_checktf(int user_data, int reason); + * extern int PLIbook_ReadVector_calltf(int user_data, int reason); + * extern int PLIbook_ReadVector_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ReadVector_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadVector_calltf, /* calltf routine -/ + * PLIbook_ReadVector_misctf, /* misctf routine -/ + * "$read_test_vector", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ReadVector_checktf(int user_data, int reason) +{ + if (tf_nump() != 2) /* check for two system task/function */ + tf_error("Usage: $read_test_vector(\");"); + if (tf_typep(1) != TF_STRING) /* check that first arg is a string */ + tf_error("$read_test_vector arg 1 must be a quoted file name"); + if (tf_typep(2) != TF_READWRITE) /* check that 2nd arg is reg type */ + tf_error("$read_test_vector arg 2 must be a register data type"); + return(0); +} + +/********************************************************************** + * misctf routine + * Use the misctf routine to open test vector file at the beginning + * of simulation, and save the file pointer in the work area for the + * instance of $read_test_vector that called the misctf routine. + *********************************************************************/ +int PLIbook_ReadVector_misctf(int user_data, int reason, int paramvc) +{ + FILE *in_file; + char *file_name; + + if (reason == REASON_ENDOFCOMPILE) { /* time to open vector file */ + if ( (in_file = fopen((char *)tf_getcstringp(1),"r")) == NULL) + tf_error("$read_test_vector cannot open file %s", + tf_getcstringp(1)); + tf_setworkarea((PLI_BYTE8 *)in_file); /* save file pointer */ + } + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ReadVector_calltf(int user_data, int reason) +{ + FILE *in_file; + int vec_size = (int)tf_sizep(2); /* bit size of tfarg 2 */ + char *vector = malloc(vec_size+1); /* memory for vector string */ + bool VERBOSE = FALSE; /* flag for debug output */ + + if (mc_scan_plusargs("debug")) VERBOSE = TRUE; /* set verbose flag */ + + in_file = (FILE*)tf_getworkarea(); /* retrieve file pointer */ + + if ( (fscanf(in_file,"%s\n", vector)) == EOF) { /* read a vector */ + tf_warning("$read_test_vector reached End-Of-File %s", + tf_getcstringp(1)); /* get file name from task arg 1 */ + fclose(in_file); + tf_dofinish(); /* exit simulation at end-of-file */ + return(0); + } + if (VERBOSE) + io_printf("$read_test_vector: Value read from file=%s\n", vector); + + /* write test vector value onto system task arg 2 */ + if (!(tf_strdelputp(2,(PLI_INT32)vec_size,'b',vector,0,0)) ) + if (VERBOSE) + tf_error("$read_test_vector could not write to arg 2 at time %s", + tf_strgettime() ); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.10/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.10/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.10/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.10/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.10/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.10/veriuser_VCS.tab new file mode 100644 index 0000000..e960df3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/veriuser_VCS.tab @@ -0,0 +1,4 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$read_test_vector check=PLIbook_ReadVector_checktf call=PLIbook_ReadVector_calltf misc=PLIbook_ReadVector_misctf data=0 diff --git a/me250300_pli/plibook_examples_unix/chapter.10/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.10/veriusertfs_table.h new file mode 100644 index 0000000..6cd2463 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.10/veriusertfs_table.h @@ -0,0 +1,32 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_ReadVector_checktf(int user_data, int reason); +extern int PLIbook_ReadVector_calltf(int user_data, int reason); +extern int PLIbook_ReadVector_misctf(int user_data, int reason, int pvc); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ReadVector_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadVector_calltf, /* calltf routine */ + PLIbook_ReadVector_misctf, /* misctf routine */ + "$read_test_vector", /* system task/function name */ + 1 /* forward reference = true */ + }, + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.11/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.11/build_MTI.mak new file mode 100644 index 0000000..fc15187 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/build_MTI.mak @@ -0,0 +1,25 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = \ + realpow_tf.c \ + strgetp_test_tf.c \ + exprinfo_test_tf.c \ + evaluatep_test_tf.c \ + propagatep_test_tf.c \ + nodeinfo_test_tf.c \ + dump_memory_tf.c \ + fill_memory_tf.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.11/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.11/build_NC.mak new file mode 100644 index 0000000..c7e3c50 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/build_NC.mak @@ -0,0 +1,25 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = \ + realpow_tf.c \ + strgetp_test_tf.c \ + exprinfo_test_tf.c \ + evaluatep_test_tf.c \ + propagatep_test_tf.c \ + nodeinfo_test_tf.c \ + dump_memory_tf.c \ + fill_memory_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.11/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.11/build_XL.mak new file mode 100644 index 0000000..aeae222 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/build_XL.mak @@ -0,0 +1,25 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + realpow_tf.c \ + strgetp_test_tf.c \ + exprinfo_test_tf.c \ + evaluatep_test_tf.c \ + propagatep_test_tf.c \ + nodeinfo_test_tf.c \ + dump_memory_tf.c \ + fill_memory_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/LDV_2.2/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/LDV_2.2/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.11/dump_and_fill_mem_test.log b/me250300_pli/plibook_examples_unix/chapter.11/dump_and_fill_mem_test.log new file mode 100644 index 0000000..c0ccf3d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/dump_and_fill_mem_test.log @@ -0,0 +1,74 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. +ncverilog + +ncnomempack + dump_and_fill_mem_test.v + +Loading memory from Verilog HDL... + + +RAM[3] just changed to 6c6421 + + +RAM[0] just changed to 48656c + +Within Verilog: + Memory contents in hex are: + address 0: 48656c + address 1: 6c6f20 + address 2: 776f72 + address 3: 6c6421 +Within Verilog: + Memory contents in ASCII are: + Hello world! + +Accessing memory using $dump_mem... + + +Within PLI: + Memory array width=24 depth=4 ngroups=3 + + +node_ms_index = 0 node_ls_index = 0 + + Current memory contents of aval/bval groups in hex: + address 0: group 2: 48/0 group 1: 65/0 group 0: 6c/0 + address 1: group 2: 6c/0 group 1: 6f/0 group 0: 20/0 + address 2: group 2: 77/0 group 1: 6f/0 group 0: 72/0 + address 3: group 2: 6c/0 group 1: 64/0 group 0: 21/0 + + + +Within PLI: + Memory array width=24 depth=4 ngroups=3 + + +node_ms_index = 0 node_ls_index = 0 + + Current memory contents in ASCII are: + Hello world! + + +Modifying memory using $fill_mem... + + Memory contents have been modified by PLI +Within Verilog: + Memory contents in hex are: + address 0: 000000 + address 1: 000001 + address 2: 000002 + address 3: 000003 + +Within PLI: + Memory array width=24 depth=4 ngroups=3 + + +node_ms_index = 0 node_ls_index = 0 + + Current memory contents of aval/bval groups in hex: + address 0: group 2: 0/0 group 1: 0/0 group 0: 0/0 + address 1: group 2: 0/0 group 1: 0/0 group 0: 1/0 + address 2: group 2: 0/0 group 1: 0/0 group 0: 2/0 + address 3: group 2: 0/0 group 1: 0/0 group 0: 3/0 + + +Simulation complete via $finish(1) at time 13 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/dump_and_fill_mem_test.v b/me250300_pli/plibook_examples_unix/chapter.11/dump_and_fill_mem_test.v new file mode 100644 index 0000000..5aa74d7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/dump_and_fill_mem_test.v @@ -0,0 +1,107 @@ +/********************************************************************** + * $dump_mem_hex and $fill_mem example -- Verilog HDL test bench. + * + * Verilog test bench to test the $dump_mem_hex, $dump_mem_ascii + * and $fill_mem PLI 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 dump_mem_test; + + parameter LEFT_BIT = 23, RIGHT_BIT = 00, FIRST_ADDR = 0, LAST_ADDR = 3; +// parameter LEFT_BIT = 00, RIGHT_BIT = 23, FIRST_ADDR = 0, LAST_ADDR = 3; +// parameter LEFT_BIT = 23, RIGHT_BIT = 00, FIRST_ADDR = 3, LAST_ADDR = 0; +// parameter LEFT_BIT = 00, RIGHT_BIT = 23, FIRST_ADDR = 3, LAST_ADDR = 0; +// parameter LEFT_BIT = 24, RIGHT_BIT = 01, FIRST_ADDR = 0, LAST_ADDR = 3; +// parameter LEFT_BIT = 01, RIGHT_BIT = 24, FIRST_ADDR = 0, LAST_ADDR = 3; +// parameter LEFT_BIT = 23, RIGHT_BIT = 00, FIRST_ADDR = 1, LAST_ADDR = 4; +// parameter LEFT_BIT = 23, RIGHT_BIT = 00, FIRST_ADDR = 4, LAST_ADDR = 1; + + reg [LEFT_BIT:RIGHT_BIT] RAM [FIRST_ADDR:LAST_ADDR]; + + integer addr; + wire [23:0] vector1, vector2; + + initial + begin + $display("Loading memory from Verilog HDL...\n"); + fill_mem("Hello world!"); + #1 dump_mem_hex; + #1 dump_mem_ascii; + $display("Accessing memory using $dump_mem...\n"); + $dump_mem_hex(RAM[FIRST_ADDR]); /* address ignored by PLI */ + $dump_mem_ascii(RAM[FIRST_ADDR]); + + $display("\nModifying memory using $fill_mem...\n"); + $fill_mem(RAM[FIRST_ADDR], FIRST_ADDR); + #1 dump_mem_hex; + $dump_mem_hex(RAM[FIRST_ADDR]); + #10 $finish; + end + + assign vector1 = RAM[FIRST_ADDR]; + always @(vector1) + $display("\nRAM[%0d] just changed to %h\n", FIRST_ADDR, RAM[FIRST_ADDR]); + + assign vector2 = RAM[LAST_ADDR]; + always @(vector2) + $display("\nRAM[%0d] just changed to %h\n", LAST_ADDR, RAM[LAST_ADDR]); + + + task dump_mem_ascii; + begin + $write("Within Verilog:\n Memory contents in ASCII are:\n "); + if (FIRST_ADDR < LAST_ADDR) + for (addr=FIRST_ADDR; addr<=LAST_ADDR; addr=addr+1) + $write("%s", RAM[addr]); + else + for (addr=FIRST_ADDR; addr>=LAST_ADDR; addr=addr-1) + $write("%s", RAM[addr]); + $display("\n"); //terminate dump string + end + endtask + + task dump_mem_hex; + begin + $display("Within Verilog:\n Memory contents in hex are:"); + if (FIRST_ADDR < LAST_ADDR) + for (addr=FIRST_ADDR; addr<=LAST_ADDR; addr=addr+1) + $display(" address %0d:\t %h", addr, RAM[addr]); + else + for (addr=FIRST_ADDR; addr>=LAST_ADDR; addr=addr-1) + $display(" address %0d:\t %h", addr, RAM[addr]); + end + endtask + + task fill_mem; /* assumes at least 4 words, each word at least 24 bits wide */ + input [(20*8)-1:0] string; /* input for 20 ASCII characters */ + begin + if (FIRST_ADDR < LAST_ADDR) + begin + if ( (LEFT_BIT - RIGHT_BIT) !== 23 + && (RIGHT_BIT - LEFT_BIT) !== 23 ) + disable fill_mem; /* abort if word is not 24 bits wide */ + RAM[FIRST_ADDR+3] = string[23: 0]; + RAM[FIRST_ADDR+2] = string[47:24]; + RAM[FIRST_ADDR+1] = string[71:48]; + RAM[FIRST_ADDR+0] = string[95:72]; + end + else + begin + if ( (LEFT_BIT - RIGHT_BIT) !== 23 + && (RIGHT_BIT - LEFT_BIT) !== 23 ) + disable fill_mem; /* abort if word is not 24 bits wide */ + RAM[FIRST_ADDR-3] = string[23: 0]; + RAM[FIRST_ADDR-2] = string[47:24]; + RAM[FIRST_ADDR-1] = string[71:48]; + RAM[FIRST_ADDR-0] = string[95:72]; + end + end + endtask + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.11/dump_memory_tf.c b/me250300_pli/plibook_examples_unix/chapter.11/dump_memory_tf.c new file mode 100644 index 0000000..5ba65a2 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/dump_memory_tf.c @@ -0,0 +1,343 @@ +/********************************************************************** +* $dump_mem example -- C source code using TF/ACC PLI routines +* +* C source to illustrate reading 4-state logic values from all +* addresses of a Verilog memory array. +* +* The logic values are represented as characters in the C language. +* Every eight bits of a Verilog memory word are passed to/from +* Verilog as a C structure containing a pair of C bytes (of type +* PLI_BYT8), using an aval/bval encoding, where: +* 0/0 = logic 0, 1/0 = logic 1, 0/1 = logic Z, 1/1 = logic X. +* +* 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 +* +* Usage: +* ------ +* Syntax: $dump_mem_hex(); +* $dump_mem_ascii(); +* +* Note: The word select of the memory is ignored, but is +* required by the tf_nodeinfo() syntax. +* +* Example: +* reg [23:0] RAM [0:3]; +* initial $dump_mem_hex(RAM[0]); +* +* Routine definitions for a veriusertfs array: +* /* routine prototypes -/ +* extern int PLIbook_DumpMem_checktf(int user_data, int reason); +* extern int PLIbook_DumpMem_calltf(int user_data, int reason); +* extern int PLIbook_DumpMem_misctf(int user_data, int reason, int pvc); +* /* table entries -/ +* {usertask, /* type of PLI routine -/ +* 0, /* user_data value -/ +* PLIbook_DumpMem_checktf, /* checktf routine -/ +* 0, /* sizetf routine -/ +* PLIbook_DumpMem_calltf, /* calltf routine -/ +* PLIbook_DumpMem_misctf, /* misctf routine -/ +* "$dump_mem_hex", /* system task/function name -/ +* 1 /* forward reference = true -/ +* }, +* {usertask, /* type of PLI routine -/ +* 1, /* user_data value -/ +* PLIbook_DumpMem_checktf, /* checktf routine -/ +* 0, /* sizetf routine -/ +* PLIbook_DumpMem_calltf, /* calltf routine -/ +* PLIbook_DumpMem_misctf, /* misctf routine -/ +* "$dump_mem_bin", /* system task/function name -/ +* 1 /* forward reference = true -/ +* }, +* {usertask, /* type of PLI routine -/ +* 2, /* user_data value -/ +* PLIbook_DumpMem_checktf, /* checktf routine -/ +* 0, /* sizetf routine -/ +* PLIbook_DumpMem_calltf, /* calltf routine -/ +* PLIbook_DumpMem_misctf, /* misctf routine -/ +* "$dump_mem_ascii", /* system task/function name -/ +* 1 /* forward reference = true -/ +* }, +**********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +#define HEX 0 /* values of user_data for system task names */ +#define BIN 1 +#define ASCII 2 + +/********************************************************************** +* checktf routine +**********************************************************************/ +int PLIbook_DumpMem_checktf(int user_data, int reason) +{ + if (tf_nump() != 1) + if (user_data == HEX) + tf_error("Usage error: $dump_mem_hex();"); + else if (user_data == BIN) + tf_error("Usage error: $dump_mem_bin();"); + else + tf_error("Usage error: $dump_mem_ascii();"); + return(0); +} + +/********************************************************************** +* misctf routine +* +* The misctf routine is used to call tf_nodeinfo() at the +* beginning of simulation, so that the memory allocated by +* tf_nodeinfo() is only allocated one time for each instance of +* $dump_mem_??. +**********************************************************************/ +int PLIbook_DumpMem_misctf(int user_data, int reason, int paramvc) +{ + p_tfnodeinfo node_info; /* pointer to structure for tf_nodeinfo() */ + + if (reason != REASON_ENDOFCOMPILE) + return(0); /* exit now if this is not the start of simulation */ + + /* allocate memory for an s_tfexprinfo structure */ + node_info = (p_tfnodeinfo)malloc(sizeof(s_tfnodeinfo)); + + /* Get the nodeinfo structure for tfarg 1 */ + if (!tf_nodeinfo(1, node_info)) { + tf_error("Err: $dump_mem_?? could not get tf_nodeinfo for tfarg 1"); + tf_dofinish(); /* about simulation */ + return(0); + } + else if (node_info->node_type != TF_MEMORY_NODE) { + tf_error("Err: $dump_mem_?? arg is not a memory word -- aborting"); + tf_dofinish(); /* about simulation */ + return(0); + } + else + tf_setworkarea((PLI_BYTE8 *)node_info); /* save info pointer */ + + return(0); +} + +/********************************************************************** +* calltf routine +**********************************************************************/ +/* prototypes of functions invoked by the calltf routine */ +void PLIbook_DumpMemHex(); +void PLIbook_DumpMemBin(); +void PLIbook_DumpMemAscii(); + + +int PLIbook_DumpMem_calltf(int user_data, int reason) +{ + p_tfnodeinfo node_info; + + node_info = (p_tfnodeinfo)tf_getworkarea(); + + io_printf("\nWithin PLI:\n"); + io_printf(" Memory array width=%d depth=%d ngroups=%d\n", + node_info->node_vec_size, + node_info->node_mem_size, + node_info->node_ngroups); + + +io_printf("\n\nnode_ms_index = %d node_ls_index = %d\n\n", + node_info->node_ms_index, node_info->node_ls_index); + + if (user_data == HEX) /* application called by $dump_mem_hex */ + PLIbook_DumpMemHex(node_info); + else if (user_data == BIN) /* application called by $dump_mem_bin */ + PLIbook_DumpMemBin(node_info); + else /* application called by $dump_mem_ascii */ + PLIbook_DumpMemAscii(node_info); + + return(0); +} + +/********************************************************************** +* Function to dump each word of a Verilog array in hexadecimal +**********************************************************************/ +void PLIbook_DumpMemHex(p_tfnodeinfo node_info) +{ + PLI_BYTE8 *aval_ptr, *bval_ptr; + int word_increment, mem_address, group_num; + + io_printf(" Current memory contents of aval/bval groups in hex:\n"); + + word_increment = node_info->node_ngroups * 2; + for (mem_address = 0; + mem_address < node_info->node_mem_size; + mem_address++) { + + io_printf(" address %d:\t ", mem_address); + + /* set pointers to aval and bval words for the address */ + aval_ptr = node_info->node_value.memoryval_p + + (mem_address * word_increment); + bval_ptr = aval_ptr + node_info->node_ngroups; + + /* print groups in word in reverse order so will match Verilog: + the highest group number represents the left-most byte of a + Verilog word, the lowest group represents the right-most byte */ + for (group_num = node_info->node_ngroups - 1; + group_num >= 0; + group_num--) { + io_printf(" group %d: %x/%x", + group_num, aval_ptr[group_num], bval_ptr[group_num]); + } + io_printf("\n"); + } + io_printf("\n\n"); + return; +} + +/********************************************************************** +* Function to dump each word of a Verilog array in ASCII +**********************************************************************/ +void PLIbook_DumpMemAscii(p_tfnodeinfo node_info) +{ + PLI_BYTE8 *aval_ptr; + int word_increment, mem_address, group_num; + + /* Read current memory values as a string using only aval bits */ + io_printf(" Current memory contents in ASCII are:\n"); + io_printf(" "); + + word_increment = node_info->node_ngroups * 2; + for (mem_address = 0; + mem_address < node_info->node_mem_size; + mem_address++) { + /* set pointer to aval word for the address */ + aval_ptr = node_info->node_value.memoryval_p + + (mem_address * word_increment); + + /* print groups in word in reverse order so will match Verilog: + the highest group number represents the left-most byte of a + Verilog word, the lowest group represents the right-most byte */ + for (group_num = node_info->node_ngroups - 1; + group_num >= 0; + group_num--) { + io_printf("%c", aval_ptr[group_num]); + } + } + io_printf("\n\n"); + return; +} + + + #define OBVIOUS /* compile more obvious, less efficient version */ +/*#define EFFICIENT /* compile Drew's more efficient version */ + +#if defined EFFICIENT +/********************************************************************** +* Function to dump each word of a Verilog array in binary. +* This example of the function uses a more efficient C coding style to +* select one bit from a word. +**********************************************************************/ +void PLIbook_DumpMemBin(p_tfnodeinfo node_info) +{ + PLI_BYTE8 *aval_ptr, *bval_ptr; + int word_increment, mem_address, word_bit; + PLI_BYTE8 aval_val, bval_val; + + io_printf(" Current memory contents in binary are:\n"); + + word_increment = node_info->node_ngroups * 2; /* 1 word = aval/bval pair */ + for (mem_address = 0; + mem_address < node_info->node_mem_size; + mem_address++) { + /* set pointers to aval and bval words for the address */ + aval_ptr = node_info->node_value.memoryval_p + + (mem_address * word_increment); + bval_ptr = aval_ptr + node_info->node_ngroups; + io_printf(" address %d:\t ", mem_address); + + /* print groups in word in reverse order so will match Verilog: + the highest group number represents the left-most byte of a + Verilog word, the lowest group represents the right-most byte */ + for (word_bit = node_info->node_vec_size - 1; + word_bit >= 0; + word_bit--) { + aval_val = (aval_ptr[word_bit >> 3]) & (1 << (word_bit & 0x7)); + bval_val = (bval_ptr[word_bit >> 3]) & (1 << (word_bit & 0x7)); + + /* translate aval/bval pair to 4-state logic value */ + if (!bval_val) { + if (!aval_val) io_printf("0"); /* aval/bval == 0/0 */ + else io_printf("1"); /* aval/bval == 1/0 */ + } + else { + if (!aval_val) io_printf("z"); /* aval/bval == 0/1 */ + else io_printf("x"); /* aval/bval == 1/1 */ + } + } + io_printf("\n"); + } + return; +} + +#elif defined OBVIOUS +/********************************************************************** +* Function to dump each word of a Verilog array in binary. +* This example of the function uses a more obvious but less efficient +* C coding style to select one bit from a word. +**********************************************************************/ +void PLIbook_DumpMemBin(p_tfnodeinfo node_info) +{ + PLI_BYTE8 *aval_ptr, *bval_ptr; + int word_increment, mem_address, word_bit, group_num, group_bit; + PLI_BYTE8 aval_val, bval_val, bit_mask; + + io_printf(" Current memory contents in binary are:\n"); + + word_increment = node_info->node_ngroups * 2; + + for (mem_address = 0; + mem_address < node_info->node_mem_size; + mem_address++) { + + io_printf(" address %d:\t ", mem_address); + + /* step 1: set pointers to aval and bval words for the address */ + aval_ptr = node_info->node_value.memoryval_p + + (mem_address * word_increment); + bval_ptr = aval_ptr + node_info->node_ngroups; + for (word_bit = node_info->node_vec_size - 1; + word_bit >= 0; + word_bit--) { + + /* step 2: determine the group which contains the bit number */ + group_num = word_bit / 8; + + /* step 3: determine which bit in the group contains the bit */ + group_bit = word_bit % 8; + + /* step 4: set an 8-bit mask to block all unwanted bits in group */ + bit_mask = 0x01; /* Set mask to most-signif. bit of 8-bit group */ + bit_mask = bit_mask << group_bit; /* Shift to bit to be modified */ + + /* step 5: select desired aval and bval bits from the groups */ + aval_val = aval_ptr[group_num] & bit_mask; + bval_val = bval_ptr[group_num] & bit_mask; + + /* translate aval/bval pair to 4-state logic value */ + if (!bval_val) { + if (!aval_val) io_printf("0"); /* aval/bval == 0/0 */ + else io_printf("1"); /* aval/bval == 1/0 */ + } + else { + if (!aval_val) io_printf("z"); /* aval/bval == 0/1 */ + else io_printf("x"); /* aval/bval == 1/1 */ + } + } + io_printf("\n"); + } + io_printf("\n"); + return; +} + +#endif + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test.v b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test.v new file mode 100644 index 0000000..64bfb8d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $evaluatep_test example -- Verilog HDL test bench. + * + * Verilog test bench to test the $evaluatep_test 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 reg1; + reg [31:0] reg2; + reg [0:51] reg3; + real r1; + + initial + begin + reg1 = 1'b0; + reg2 = 32'hF0F0F0F0; + reg3 = {13{4'b01zx}}; + r1 = 3.1415; + + #1 $evaluatep_test("Hello world"); + #1 $evaluatep_test(r1); + #1 $evaluatep_test(reg1); + #1 $evaluatep_test(reg2); + #1 $evaluatep_test(reg3); + #1 $evaluatep_test(reg3[1]); + #1 $evaluatep_test(reg3[4:48]); + + #1 $finish; + end + +endmodule + +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_NC.log b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_NC.log new file mode 100644 index 0000000..f749d13 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_NC.log @@ -0,0 +1,117 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Expression info: + type = TF_STRING + ngroups = 0 + vector size = 0 + sign = 775041902 + LHS select = 0 + RHS select = 0 + string value = Hello world + + +Expression info: + type = TF_READWRITEREAL + ngroups = 0 + vector size = 0 + sign = 0 + LHS select = 0 + RHS select = 0 + real value = 0.000000 + + +Expression info: + type = TF_READWRITE + ngroups = 1 + vector size = 1 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 1 + + +Expression info: + type = TF_READWRITE + ngroups = 1 + vector size = 32 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = ffffffff + bvalbits[0] = ffffffff + + +Expression info: + type = TF_READWRITE + ngroups = 2 + vector size = 52 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = ffffffff + bvalbits[0] = ffffffff + avalbits[1] = fffff + bvalbits[1] = fffff + + +Expression info: + type = TF_RWBITSELECT + ngroups = 1 + vector size = 1 + sign = 0 + LHS select = 1 + RHS select = 1 + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 1 + + +Expression info: + type = TF_RWPARTSELECT + ngroups = 2 + vector size = 45 + sign = 0 + LHS select = 4 + RHS select = 48 + vector value (in hex): + avalbits[0] = ffffffff + bvalbits[0] = ffffffff + avalbits[1] = 1fff + bvalbits[1] = 1fff + + +ncsim> source "C:/Program Files/CDS/tools/inca/files/ncsimrc" +ncsim> run + string value = Hello world + + real value = 0.000000 + + vector value (in hex): + avalbits[0] = 0 + bvalbits[0] = 0 + + vector value (in hex): + avalbits[0] = f0f0f0f0 + bvalbits[0] = 0 + + vector value (in hex): + avalbits[0] = 55555555 + bvalbits[0] = 33333333 + avalbits[1] = 55555 + bvalbits[1] = 33333 + + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 0 + + vector value (in hex): + avalbits[0] = aaaaaaaa + bvalbits[0] = 66666666 + avalbits[1] = aaa + bvalbits[1] = 666 + +Simulation complete via $finish(1) at time 8 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_XL.log b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_XL.log new file mode 100644 index 0000000..d29cbd8 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_XL.log @@ -0,0 +1,115 @@ +VERILOG-XL 3.0.p001 log file created Nov 4, 2001 22:38:29 + +Expression info: + type=TF_STRING + ngroups = 0 + vector size = 0 + sign = 0 + LHS select = 0 + RHS select = 0 + string value = Hello world + + +Expression info: + type=TF_READWRITEREAL + ngroups = 0 + vector size = 0 + sign = 1 + LHS select = 0 + RHS select = 0 + real value = 0.000000 + + +Expression info: + type=TF_READWRITE + ngroups = 1 + vector size = 1 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 1 + + +Expression info: + type=TF_READWRITE + ngroups = 1 + vector size = 32 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = ffffffff + bvalbits[0] = ffffffff + + +Expression info: + type=TF_READWRITE + ngroups = 2 + vector size = 52 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = ffffffff + bvalbits[0] = ffffffff + avalbits[1] = fffff + bvalbits[1] = fffff + + +Expression info: + type=TF_RWBITSELECT + ngroups = 1 + vector size = 1 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 1 + + +Expression info: + type=TF_RWPARTSELECT + ngroups = 2 + vector size = 45 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = ffffffff + bvalbits[0] = ffffffff + avalbits[1] = 1fff + bvalbits[1] = 1fff + + + string value = Hello world + + real value = 0.000000 + + vector value (in hex): + avalbits[0] = 0 + bvalbits[0] = 0 + + vector value (in hex): + avalbits[0] = f0f0f0f0 + bvalbits[0] = 0 + + vector value (in hex): + avalbits[0] = 55555555 + bvalbits[0] = 33333333 + avalbits[1] = 55555 + bvalbits[1] = 33333 + + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 0 + + vector value (in hex): + avalbits[0] = aaaaaaaa + bvalbits[0] = 66666666 + avalbits[1] = aaa + bvalbits[1] = 666 + +L34 "evaluatep_test.v": $finish at simulation time 8 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_tf.c b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_tf.c new file mode 100644 index 0000000..c9a4f89 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/evaluatep_test_tf.c @@ -0,0 +1,150 @@ +/********************************************************************** + * $evaluatep_test example -- C source code using TF/ACC PLI routines + * + * C source to illustrate reading 4-state logic values into C integers. + * The signals in Verilog to be read can be a vector of any bit size + * (including scalar). + * + * 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 + * + * Usage: + * ------ + * + * Syntax: $evaluatep_test(); + * + * Example: + * reg [0:39] data; + * initial $evaluatep_test(data); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_evaluatepTest_checktf(int user_data, int reason); + * extern int PLIbook_evaluatepTest_calltf(int user_data, int reason); + * extern int PLIbook_evaluatepTest_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_evaluatepTest_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_evaluatepTtest_calltf, /* calltf routine -/ + * PLIbook_evaluatepTest_misctf, /* misctf routine -/ + * "$evaluatep_test", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_evaluatepTest_checktf(int user_data, int reason) +{ + if (tf_nump() != 1) + tf_error("Usage error: $evaluatep_test();"); + return(0); +} + +/********************************************************************** + * misctf routine + * + * The misctf routine is used to call tf_exprinfo() at the + * beginning of simulation, so that the memory allocated by + * tf_exprinfo() is only allocated one time for each instance of + * $evaluatep_test. + *********************************************************************/ +int PLIbook_evaluatepTest_misctf(int user_data, int reason, int pvc) +{ + p_tfexprinfo info_p; /* pointer to structure for tf_exprinfo() */ + p_vecval val_array; /* pointer to value array in info struct */ + int i; + if (reason != REASON_ENDOFCOMPILE) + return(0); /* exit now if this is not the start of simulation */ + + /* allocate memory for an s_tfexprinfo structure */ + info_p = (p_tfexprinfo)malloc(sizeof(s_tfexprinfo)); + tf_exprinfo(1, info_p); /* read expression info for arg 1 */ + tf_setworkarea((PLI_BYTE8 *)info_p); /* save info pointer */ + + io_printf("Expression info:\n"); + switch (info_p->expr_type) { + case TF_NULLPARAM: io_printf(" type=TF_NULLPARAM\n"); break; + case TF_STRING: io_printf(" type=TF_STRING\n"); break; + case TF_READONLY: io_printf(" type=TF_READONLY\n"); break; + case TF_READONLYREAL: io_printf(" type=TF_READONLYREAL\n"); break; + case TF_READWRITE: io_printf(" type=TF_READWRITE\n"); break; + case TF_READWRITEREAL:io_printf(" type=TF_READWRITEREAL\n"); break; + case TF_RWBITSELECT: io_printf(" type=TF_RWBITSELECT\n"); break; + case TF_RWPARTSELECT: io_printf(" type=TF_RWPARTSELECT\n"); break; + case TF_RWMEMSELECT: io_printf(" type=TF_RWMEMSELECT\n"); break; + default: io_printf(" type is unknown (%d)\n", info_p->expr_type); + } + io_printf(" ngroups = %d\n", info_p->expr_ngroups); + io_printf(" vector size = %d\n", info_p->expr_vec_size); + io_printf(" sign = %d\n", info_p->expr_sign); + io_printf(" LHS select = %d\n", info_p->expr_lhs_select); + io_printf(" RHS select = %d\n", info_p->expr_rhs_select); + + switch (info_p->expr_type) { + case TF_STRING: + io_printf(" string value = %s\n", info_p->expr_string); break; + case TF_READONLYREAL: + case TF_READWRITEREAL: + io_printf(" real value = %f\n", info_p->real_value); break; + case TF_READONLY: + case TF_READWRITE: + case TF_RWBITSELECT: + case TF_RWPARTSELECT: + case TF_RWMEMSELECT: + val_array = info_p->expr_value_p; + io_printf(" vector value (in hex):\n"); + for (i=0; iexpr_ngroups; i++) { + io_printf(" avalbits[%d] = %x\n", i, val_array[i].avalbits); + io_printf(" bvalbits[%d] = %x\n", i, val_array[i].bvalbits); + } + break; + } + io_printf("\n\n"); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_evaluatepTest_calltf(int user_data, int reason) +{ + p_tfexprinfo info_p; /* pointer to structure for tf_exprinfo() */ + p_vecval val_array; /* pointer to value array in info struct */ + int i; + + info_p = (p_tfexprinfo)tf_getworkarea(); /* retrieve info pointer */ + tf_evaluatep(1); /* re-read value of arg 1 */ + switch (info_p->expr_type) { + case TF_STRING: + io_printf(" string value = %s\n", info_p->expr_string); break; + case TF_READONLYREAL: + case TF_READWRITEREAL: + io_printf(" real value = %f\n", info_p->real_value); break; + case TF_READONLY: + case TF_READWRITE: + case TF_RWBITSELECT: + case TF_RWPARTSELECT: + case TF_RWMEMSELECT: + val_array = info_p->expr_value_p; + io_printf(" vector value (in hex):\n"); + for (i=0; iexpr_ngroups; i++) { + io_printf(" avalbits[%d] = %x\n", i, val_array[i].avalbits); + io_printf(" bvalbits[%d] = %x\n", i, val_array[i].bvalbits); + } + break; + } + io_printf("\n"); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test.v b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test.v new file mode 100644 index 0000000..d8b29e4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $exprinfo_test example -- Verilog HDL test bench. + * + * Verilog test bench to test the $exprinfo_test 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 reg1; + reg [31:0] reg2; + reg [0:51] reg3; + real r1; + + initial + begin + reg1 = 1'b0; + reg2 = 32'hF0F0F0F0; + reg3 = {13{4'b01zx}}; + r1 = 3.1415; + + #1 $exprinfo_test("Hello world"); + #1 $exprinfo_test(r1); + #1 $exprinfo_test(reg1); + #1 $exprinfo_test(reg2); + #1 $exprinfo_test(reg3); + #1 $exprinfo_test(reg3[1]); + #1 $exprinfo_test(reg3[4:48]); + + #1 $finish; + end + +endmodule + +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_NC.log b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_NC.log new file mode 100644 index 0000000..ea165a3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_NC.log @@ -0,0 +1,87 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Expression info: + type = TF_STRING + ngroups = 0 + vector size = 0 + sign = 28274128 + LHS select = 0 + RHS select = 0 + string value = Hello world + + +Expression info: + type = TF_READWRITEREAL + ngroups = 0 + vector size = 0 + sign = 28274128 + LHS select = 0 + RHS select = 0 + real value = 3.141500 + + +Expression info: + type = TF_READWRITE + ngroups = 1 + vector size = 1 + sign = 28274128 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 0 + bvalbits[0] = 0 + + +Expression info: + type = TF_READWRITE + ngroups = 1 + vector size = 32 + sign = 28274128 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = f0f0f0f0 + bvalbits[0] = 0 + + +Expression info: + type = TF_READWRITE + ngroups = 2 + vector size = 52 + sign = 28274128 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 55555555 + bvalbits[0] = 33333333 + avalbits[1] = 55555 + bvalbits[1] = 33333 + + +Expression info: + type = TF_RWBITSELECT + ngroups = 1 + vector size = 1 + sign = 28274128 + LHS select = 1 + RHS select = 1 + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 0 + + +Expression info: + type = TF_RWPARTSELECT + ngroups = 2 + vector size = 45 + sign = 28274128 + LHS select = 4 + RHS select = 48 + vector value (in hex): + avalbits[0] = aaaaaaaa + bvalbits[0] = 66666666 + avalbits[1] = aaa + bvalbits[1] = 666 + + +Simulation complete via $finish(1) at time 8 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_XL.log b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_XL.log new file mode 100644 index 0000000..fb27550 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_XL.log @@ -0,0 +1,87 @@ +VERILOG-XL 3.0.p001 log file created Nov 4, 2001 22:40:54 + +Expression info: + type = TF_STRING + ngroups = 0 + vector size = 0 + sign = 0 + LHS select = 0 + RHS select = 0 + string value = Hello world + + +Expression info: + type = TF_READWRITEREAL + ngroups = 0 + vector size = 0 + sign = 1 + LHS select = 0 + RHS select = 0 + real value = 3.141500 + + +Expression info: + type = TF_READWRITE + ngroups = 1 + vector size = 1 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 0 + bvalbits[0] = 0 + + +Expression info: + type = TF_READWRITE + ngroups = 1 + vector size = 32 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = f0f0f0f0 + bvalbits[0] = 0 + + +Expression info: + type = TF_READWRITE + ngroups = 2 + vector size = 52 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 55555555 + bvalbits[0] = 33333333 + avalbits[1] = 55555 + bvalbits[1] = 33333 + + +Expression info: + type = TF_RWBITSELECT + ngroups = 1 + vector size = 1 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = 1 + bvalbits[0] = 0 + + +Expression info: + type = TF_RWPARTSELECT + ngroups = 2 + vector size = 45 + sign = 0 + LHS select = 0 + RHS select = 0 + vector value (in hex): + avalbits[0] = aaaaaaaa + bvalbits[0] = 66666666 + avalbits[1] = aaa + bvalbits[1] = 666 + + +L34 "exprinfo_test.v": $finish at simulation time 8 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_tf.c b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_tf.c new file mode 100644 index 0000000..5d7a219 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/exprinfo_test_tf.c @@ -0,0 +1,106 @@ +/********************************************************************** + * $exprinfo_test example -- C source code using TF/ACC PLI routines + * + * C source to illustrate reading 4-state logic values into C integers. + * The signals in Verilog to be read can be a vector of any bit size + * (including scalar). + * + * 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 + * + * Usage: + * ------ + * + * Syntax: $exprinfo_test(); + * + * Example: + * reg [0:39] data; + * initial $exprinfo_test(data); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_exprinfoTest_checktf(int user_data, int reason); + * extern int PLIbook_exprinfoTest_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_exprinfoTest_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_exprinfoTest_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$exprinfo_test", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_exprinfoTest_checktf(int user_data, int reason) +{ + if (tf_nump() != 1) + tf_error("Usage error: $exprinfo_test();"); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_exprinfoTest_calltf(int user_data, int reason) +{ + s_tfexprinfo info_s; /* structure for tf_exprinfo() */ + p_vecval val_array; /* pointer to value array in info struct */ + int i; + + tf_exprinfo(1, &info_s); /* read expression info for arg 1 */ + + io_printf("Expression info:\n"); + switch (info_s.expr_type) { + case TF_NULLPARAM: io_printf(" type = TF_NULLPARAM\n"); break; + case TF_STRING: io_printf(" type = TF_STRING\n"); break; + case TF_READONLY: io_printf(" type = TF_READONLY\n"); break; + case TF_READONLYREAL: io_printf(" type = TF_READONLYREAL\n"); break; + case TF_READWRITE: io_printf(" type = TF_READWRITE\n"); break; + case TF_READWRITEREAL:io_printf(" type = TF_READWRITEREAL\n");break; + case TF_RWBITSELECT: io_printf(" type = TF_RWBITSELECT\n"); break; + case TF_RWPARTSELECT: io_printf(" type = TF_RWPARTSELECT\n"); break; + case TF_RWMEMSELECT: io_printf(" type = TF_RWMEMSELECT\n"); break; + default: io_printf(" type is unknown (%d)\n", info_s.expr_type); + } + io_printf(" ngroups = %d\n", info_s.expr_ngroups); + io_printf(" vector size = %d\n", info_s.expr_vec_size); + io_printf(" sign = %d\n", info_s.expr_sign); + io_printf(" LHS select = %d\n", info_s.expr_lhs_select); + io_printf(" RHS select = %d\n", info_s.expr_rhs_select); + + switch (info_s.expr_type) { + case TF_STRING: + io_printf(" string value = %s\n", info_s.expr_string); break; + case TF_READONLYREAL: + case TF_READWRITEREAL: + io_printf(" real value = %f\n", info_s.real_value); break; + case TF_READONLY: + case TF_READWRITE: + case TF_RWBITSELECT: + case TF_RWPARTSELECT: + case TF_RWMEMSELECT: + val_array = info_s.expr_value_p; + io_printf(" vector value (in hex):\n"); + for (i=0; i, ); + * + * Example: + * reg [23:0] RAM [0:3]; + * initial $fill_mem(RAM[2], 2); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_FillMem_checktf(int user_data, int reason); + * extern int PLIbook_FillMem_calltf(int user_data, int reason); + * extern int PLIbook_FillMem_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_FillMem_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_FillMem_calltf, /* calltf routine -/ + * PLIbook_FillMem_misctf, /* misctf routine -/ + * "$fill_mem", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_FillMem_checktf(int user_data, int reason) +{ + if (tf_nump() != 2) + tf_error("Usage: $fill_mem(mem_word_select, word_select_address);"); + return(0); +} + +/********************************************************************** + * misctf routine + * + * The misctf routine is used to call tf_nodeinfo() at the + * beginning of simulation, so that the memory allocated by + * tf_nodeinfo() and tf_exprinfo() is only allocated one time for each + * instance of $fill_mem. + *********************************************************************/ +typedef struct PLIbook_my_data { + p_tfnodeinfo node_info; /* pointer to structure for tf_nodeinfo() */ + p_tfexprinfo expr_info; /* pointer to structure for tf_exprinfo() */ +} PLIbook_my_data_s, *PLIbook_my_data_p; + +int PLIbook_FillMem_misctf(int user_data, int reason, int paramvc) +{ + PLIbook_my_data_p info; /* pointer to info structures */ + + if (reason != REASON_ENDOFCOMPILE) + return(0); /* exit now if this is not the start of simulation */ + + /* allocate memory for structure to store info structure */ + info = (PLIbook_my_data_p)malloc(sizeof(PLIbook_my_data_s)); + + /* allocate memory for an s_nodeinfo and an s_tfexprinfo structure */ + info->node_info = (p_tfnodeinfo)malloc(sizeof(s_tfnodeinfo)); + info->expr_info = (p_tfexprinfo)malloc(sizeof(s_tfexprinfo)); + + /* Get the nodeinfo structure for tfarg 1 */ + if (!tf_nodeinfo(1, info->node_info)) { + tf_error("Error: $fill_mem could not get tf_nodeinfo for tfarg 1"); + tf_dofinish(); /* about simulation */ + return(0); + } + else if (info->node_info->node_type != TF_MEMORY_NODE) { + tf_error("Error: $fill_mem arg is not a memory word -- aborting"); + tf_dofinish(); /* about simulation */ + return(0); + } + + /* Get the exprinfo structure for tfarg 1 */ + if (!tf_exprinfo(1, info->expr_info)) { + tf_error("Error: $fill_mem could not get tf_exprinfo for tfarg 1"); + tf_dofinish(); /* about simulation */ + return(0); + } + + tf_setworkarea((PLI_BYTE8 *)info); /* save info pointer */ + + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_FillMem_calltf(int user_data, int reason) +{ + int depth, width, ngroups, word_increment, mem_address, i; + PLI_BYTE8 *mem_ptr, *aval_ptr, *bval_ptr; + PLIbook_my_data_p info; /* pointer to info structures */ + + info = (PLIbook_my_data_p)tf_getworkarea(); + + mem_ptr = info->node_info->node_value.memoryval_p; + width = (int)info->node_info->node_vec_size; + depth = (int)info->node_info->node_mem_size; + ngroups = (int)info->node_info->node_ngroups; + + /* Modify current memory values: set aval bits to memory address, + set bval bits to 0 (2-state logic) */ + word_increment = ngroups * 2; /* 1 word = aval/bval group set */ + for (mem_address = 0; + mem_address < 4; /* node_info->node_mem_size; */ + mem_address++) { + aval_ptr = mem_ptr + (mem_address * word_increment); + bval_ptr = aval_ptr + ngroups; + aval_ptr[0] = mem_address; + bval_ptr[0] = 0x0; + for (i=1; i); + * + * Example: + * reg [0:39] data; + * initial $propagatep_test(data); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_propagatepTest_checktf(int user_data, int reason); + * extern int PLIbook_propagatepTest_calltf(int user_data, int reason); + * extern int PLIbook_propagatepTest_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_propagatepTest_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_propagatepTest_calltf, /* calltf routine -/ + * PLIbook_propagatepTest_misctf, /* misctf routine -/ + * "$propagatep_test", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_propagatepTest_checktf(int user_data, int reason) +{ + if (tf_nump() != 1) + tf_error("Usage error: $propagatep_test();"); + return(0); +} + +/********************************************************************** + * misctf routine + * + * The misctf routine is used to call tf_exprinfo() at the + * beginning of simulation, so that the memory allocated by + * tf_exprinfo() is only allocated one time for each instance of + * $read_4state_value. + *********************************************************************/ +int PLIbook_propagatepTest_misctf(int user_data, int reason, int pvc) +{ + p_tfexprinfo info_p; /* pointer to structure for tf_exprinfo() */ + + if (reason != REASON_ENDOFCOMPILE) + return(0); /* exit now if this is not the start of simulation */ + + /* allocate memory for an s_tfexprinfo structure */ + info_p = (p_tfexprinfo)malloc(sizeof(s_tfexprinfo)); + + tf_exprinfo(1, info_p); /* read expression info for arg 1 */ + if ( (info_p->expr_type != TF_READWRITE) + && (info_p->expr_type != TF_READWRITEREAL) + && (info_p->expr_type != TF_RWBITSELECT) + && (info_p->expr_type != TF_RWPARTSELECT) + && (info_p->expr_type != TF_RWMEMSELECT) ) { + io_printf("ERROR: Signal type not supported by $propagatep_test\n"); + tf_dofinish(); + } + else + tf_setworkarea((PLI_BYTE8 *)info_p); /* save info pointer */ + + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +/* prototype for subroutine used by calltf routine */ +void PLIbook_Print4stateValue(); + +int PLIbook_propagatepTest_calltf(int user_data, int reason) +{ + p_tfexprinfo info_p; /* pointer to structure for tf_exprinfo() */ + + info_p = (p_tfexprinfo)tf_getworkarea(); /* retrieve info pointer */ + + io_printf("$propagatep_test called at time %d\n", tf_gettime()); + /* read current value of argument 1 */ + io_printf(" current value:\n"); + tf_evaluatep(1); + PLIbook_Print4stateValue(info_p); + + /* modify value of argument 1 */ + switch (info_p->expr_type) { + case TF_READWRITE: + case TF_RWBITSELECT: + case TF_RWPARTSELECT: + case TF_RWMEMSELECT: + info_p->expr_value_p[0].avalbits++; + info_p->expr_value_p[0].bvalbits = 0; + break; + case TF_READWRITEREAL: + info_p->real_value++; + break; + } + tf_propagatep(1); + + /* read new value of argument 1 */ + io_printf(" new value:\n"); + tf_evaluatep(1); + PLIbook_Print4stateValue(info_p); + + return(0); +} + +void PLIbook_Print4stateValue(p_tfexprinfo info_p) +{ + int i; + + switch (info_p->expr_type) { + case TF_READWRITEREAL: + io_printf(" real value = %0.1f\n", info_p->real_value); break; + case TF_READWRITE: + case TF_RWBITSELECT: + case TF_RWPARTSELECT: + case TF_RWMEMSELECT: + io_printf(" vector value (in hex):\n"); + for (i=0; iexpr_ngroups; i++) { + io_printf(" avalbits[%d] = %x\n", + i, info_p->expr_value_p[i].avalbits); + io_printf(" bvalbits[%d] = %x\n", + i, info_p->expr_value_p[i].bvalbits); + } + break; + } + return; +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.11/realpow_test.log b/me250300_pli/plibook_examples_unix/chapter.11/realpow_test.log new file mode 100644 index 0000000..8b7f7fb --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/realpow_test.log @@ -0,0 +1,6 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +$realpow(2.5, 3) returns 15.625000 +$realpow(r1,r2) returns 36.029181 (r1=5.1 r2=2.2) + +Simulation complete via $finish(1) at time 4 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/realpow_test.v b/me250300_pli/plibook_examples_unix/chapter.11/realpow_test.v new file mode 100644 index 0000000..34ea80f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/realpow_test.v @@ -0,0 +1,30 @@ +/********************************************************************** + * $realpow example -- Verilog HDL test bench. + * + * Verilog test bench to test the $realpow 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; + real result, r1, r2; + + initial + begin + r1 = 5.1; + r2 = 2.2; + + #1 $display("\n$realpow(2.5, 3) returns %f", $realpow(2.5, 3)); + #1 result = $realpow(r1, r2); + #1 $display("$realpow(r1,r2) returns %f (r1=%2.1f r2=%2.1f)\n", + result, r1, r2); + #1 $finish; + end + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.11/realpow_tf.c b/me250300_pli/plibook_examples_unix/chapter.11/realpow_tf.c new file mode 100644 index 0000000..67d1776 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/realpow_tf.c @@ -0,0 +1,104 @@ +/********************************************************************** + * $realpow example -- C source code using TF/ACC PLI routines + * + * C source to calculate the result of a number to the power of an + * exponent. The value is returned to simulation as a system function. + * + * 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 + * + * Usage: result = $realpow(,); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_realpow_checktf(int user_data, int reason); + * extern int PLIbook_realpow_calltf(int user_data, int reason); + * /* table entries -/ + * {userrealfunction, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_realpow_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_realpow_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$realpow", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * Sizetf application -- not used to userrealfunction type + *********************************************************************/ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_realpow_checktf(int user_data, int reason) +{ + PLI_INT32 arg_type; + + if (tf_nump() != 2) { + tf_error("$pow must have 2 arguments.\n"); + return(0); + } + arg_type = tf_typep(1); + if (arg_type == TF_NULLPARAM) + tf_error("$pow arg 1 cannot be null.\n"); + else + if ( (arg_type != TF_READONLY) + && (arg_type != TF_READONLYREAL) + && (arg_type != TF_READWRITE) + && (arg_type != TF_READWRITEREAL) ) { + tf_error("$pow arg 1 must be number, variable or net.\n"); + } + arg_type = tf_typep(2); + if (arg_type == TF_NULLPARAM) + tf_error("$pow arg 2 cannot be null.\n"); + else + if ( (arg_type != TF_READONLY) + && (arg_type != TF_READONLYREAL) + && (arg_type != TF_READWRITE) + && (arg_type != TF_READWRITEREAL) ) { + tf_error("$pow arg 2 must be number, variable or net.\n"); + } + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +#include +int PLIbook_realpow_calltf(int user_data, int reason) +{ + double base, exp, result; + PLI_INT32 arg_type; + + arg_type = tf_typep(1); + if ( (arg_type == TF_READONLYREAL) + || (arg_type == TF_READWRITEREAL) ) + base = tf_getrealp(1); /* read double value from tfarg 1 */ + else + base = (double)tf_getp(1); /* read int value from tfarg 1 */ + + arg_type = tf_typep(2); + if ( (arg_type == TF_READONLYREAL) + || (arg_type == TF_READWRITEREAL) ) + exp = tf_getrealp(2); /* read double value from tfarg 2 */ + else + exp = (double)tf_getp(2); /* read int value from tfarg 2 */ + + result = pow(base, exp); + + tf_putrealp(0,result); /* return result */ + + return(0); +} + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test.log b/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test.log new file mode 100644 index 0000000..f984acf --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test.log @@ -0,0 +1,57 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +In Verilog, reg1 is 0 +$strgetp_test arg value is 0 (decimal) +$strgetp_test arg value is 0 (binary) +$strgetp_test arg value is 0 (hex) + +In Verilog, reg2 is 4294967295 +$strgetp_test arg value is 4294967295 (decimal) +$strgetp_test arg value is 11111111111111111111111111111111 (binary) +$strgetp_test arg value is ffffffff (hex) + +In Verilog, reg3 is -2 +$strgetp_test arg value is 8589934590 (decimal) +$strgetp_test arg value is 111111111111111111111111111111110 (binary) +$strgetp_test arg value is 1fffffffe (hex) + +In Verilog, i1 is 3 +$strgetp_test arg value is 3 (decimal) +$strgetp_test arg value is 00000000000000000000000000000011 (binary) +$strgetp_test arg value is 00000003 (hex) + +In Verilog, i2 is -4 +$strgetp_test arg value is -4 (decimal) +$strgetp_test arg value is 11111111111111111111111111111100 (binary) +$strgetp_test arg value is fffffffc (hex) + +In Verilog, r1 is 0.000000 +$strgetp_test arg value is 6 (decimal) +$strgetp_test arg value is 00000000000000000000000000000110 (binary) +$strgetp_test arg value is 00000006 (hex) + +In Verilog, r2 is 0.000000 +$strgetp_test arg value is 4294967289 (decimal) +$strgetp_test arg value is 11111111111111111111111111111001 (binary) +$strgetp_test arg value is fffffff9 (hex) + +In Verilog, 7 is 7 +$strgetp_test arg value is 7 (decimal) +$strgetp_test arg value is 00000000000000000000000000000111 (binary) +$strgetp_test arg value is 00000007 (hex) + +In Verilog, -8 is -8 +$strgetp_test arg value is 4294967288 (decimal) +$strgetp_test arg value is 11111111111111111111111111111000 (binary) +$strgetp_test arg value is fffffff8 (hex) + +In Verilog, 9.9 is 9.900000 +$strgetp_test arg value is 10 (decimal) +$strgetp_test arg value is 00000000000000000000000000001010 (binary) +$strgetp_test arg value is 0000000a (hex) + +In Verilog, -10.1 is -10.100000 +$strgetp_test arg value is 4294967286 (decimal) +$strgetp_test arg value is 11111111111111111111111111110110 (binary) +$strgetp_test arg value is fffffff6 (hex) +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test.v b/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test.v new file mode 100644 index 0000000..659a49a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test.v @@ -0,0 +1,50 @@ +/********************************************************************** + * $strgetp_test example -- Verilog HDL test bench. + * + * Verilog test bench to test the $strgetp_test 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 reg1; + reg [31:0] reg2; + reg signed [32:0] reg3; + integer i1, i2; + real r1, r2; + + initial + begin + reg1 = 1'b0; + reg2 = -32'd1; + reg3 = -32'd2; + i1 = 3; + i2 = -4; + r1 = 5.5; + r2 = -6.6; + + #1 + $display("\nIn Verilog, reg1 is %d", reg1); $strgetp_test(reg1); + $display("\nIn Verilog, reg2 is %d", reg2); $strgetp_test(reg2); + $display("\nIn Verilog, reg3 is %d", reg3); $strgetp_test(reg3); + $display("\nIn Verilog, i1 is %d", i1 ); $strgetp_test(i1); + $display("\nIn Verilog, i2 is %d", i2 ); $strgetp_test(i2); + $display("\nIn Verilog, r1 is %f", reg1); $strgetp_test(r1); + $display("\nIn Verilog, r2 is %f", reg1); $strgetp_test(r2); + + $display("\nIn Verilog, 7 is %d", 7); $strgetp_test(7); + $display("\nIn Verilog, -8 is %d", -8); $strgetp_test(-8); + $display("\nIn Verilog, 9.9 is %f", 9.9); $strgetp_test(9.9); + $display("\nIn Verilog, -10.1 is %f", -10.1); $strgetp_test(-10.1); + + #1 $finish; + end + +endmodule + +/**********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test_tf.c b/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test_tf.c new file mode 100644 index 0000000..6c4e118 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/strgetp_test_tf.c @@ -0,0 +1,74 @@ +/********************************************************************** + * $strgetp_test example -- C source code using TF/ACC PLI routines + * + * C source to illustrate reading 4-state logic values into C strings. + * The signals in Verilog to be read can be a vector of any bit size + * (including scalar) or a real number, and can be negative or positive. + * + * 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 + * + * Usage: + * ------ + * + * Syntax: $strgetp_test(); + * + * Example: + * reg [0:39] data; + * initial $strgetp_test(data); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_strgetpTest_checktf(int user_data, int reason); + * extern int PLIbook_strgetpTest_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_strgetpTest_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_strgetpTest_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$strgetp_test", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_strgetpTest_checktf(int user_data, int reason) +{ + if (tf_nump() != 1) + tf_error("Usage error: $strgetp_test();"); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_strgetpTest_calltf(int user_data, int reason) +{ + PLI_BYTE8 *dec, *bin, *hex; + + dec = tf_strgetp(1, 'd'); + bin = tf_strgetp(1, 'b'); + hex = tf_strgetp(1, 'h'); + if (dec != null) { + io_printf("$strgetp_test arg value is %s (decimal)\n", dec); + io_printf("$strgetp_test arg value is %s (binary)\n", bin); + io_printf("$strgetp_test arg value is %s (hex)\n", hex); + } + else + io_printf("ERROR: $strgetp_test could not read arg value\n"); + + return(0); +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.11/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.11/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.11/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.11/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.11/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.11/veriuser_VCS.tab new file mode 100644 index 0000000..ff03763 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/veriuser_VCS.tab @@ -0,0 +1,13 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$realpow data=0 check=PLIbook_realpow_checktf call=PLIbook_realpow_calltf size=r +$strgetp_test data=0 check=PLIbook_strgetpTest_checktf call=PLIbook_strgetpTest_calltf +$exprinfo_test data=0 check=PLIbook_exprinfoTest_checktf call=PLIbook_exprinfoTest_calltf +$evaluatep_test data=0 check=PLIbook_evaluatepTest_checktf call=PLIbook_evaluatepTest_calltf misc=PLIbook_evaluatepTest_misctf +$propagatep_test data=0 check=PLIbook_propagatepTest_checktf call=PLIbook_propagatepTest_calltf misc=PLIbook_propagatepTest_misctf +$nodeinfo_test data=0 check=PLIbook_nodeinfoTest_checktf call=PLIbook_nodeinfoTest_calltf +$dump_mem_hex data=0 check=PLIbook_DumpMem_checktf call=PLIbook_DumpMem_calltf misc=PLIbook_DumpMem_misctf +$dump_mem_bin data=1 check=PLIbook_DumpMem_checktf call=PLIbook_DumpMem_calltf misc=PLIbook_DumpMem_misctf +$dump_mem_ascii data=2 check=PLIbook_DumpMem_checktf call=PLIbook_DumpMem_calltf misc=PLIbook_DumpMem_misctf +$fill_mem data=0 check=PLIbook_FillMem_checktf call=PLIbook_FillMem_calltf misc=PLIbook_FillMem_misctf diff --git a/me250300_pli/plibook_examples_unix/chapter.11/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.11/veriusertfs_table.h new file mode 100644 index 0000000..3e64f07 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.11/veriusertfs_table.h @@ -0,0 +1,147 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_realpow_checktf(int user_data, int reason); +extern int PLIbook_realpow_calltf(int user_data, int reason); + +extern int PLIbook_strgetpTest_checktf(int user_data, int reason); +extern int PLIbook_strgetpTest_calltf(int user_data, int reason); + +extern int PLIbook_exprinfoTest_checktf(int user_data, int reason); +extern int PLIbook_exprinfoTest_calltf(int user_data, int reason); + +extern int PLIbook_evaluatepTest_checktf(int user_data, int reason); +extern int PLIbook_evaluatepTest_misctf(int user_data, int reason, int pvc); +extern int PLIbook_evaluatepTest_calltf(int user_data, int reason); + +extern int PLIbook_propagatepTest_checktf(int user_data, int reason); +extern int PLIbook_propagatepTest_calltf(int user_data, int reason); +extern int PLIbook_propagatepTest_misctf(int user_data, int reason, int pvc); + +extern int PLIbook_nodeinfoTest_checktf(int user_data, int reason); +extern int PLIbook_nodeinfoTest_calltf(int user_data, int reason); + +extern int PLIbook_DumpMem_checktf(int user_data, int reason); +extern int PLIbook_DumpMem_calltf(int user_data, int reason); +extern int PLIbook_DumpMem_misctf(int user_data, int reason, int pvc); + +extern int PLIbook_FillMem_checktf(int user_data, int reason); +extern int PLIbook_FillMem_calltf(int user_data, int reason); +extern int PLIbook_FillMem_misctf(int user_data, int reason, int pvc); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {userrealfunction, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_realpow_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_realpow_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$realpow", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_strgetpTest_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_strgetpTest_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$strgetp_test", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_exprinfoTest_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_exprinfoTest_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$exprinfo_test", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_evaluatepTest_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_evaluatepTest_calltf, /* calltf routine */ + PLIbook_evaluatepTest_misctf, /* misctf routine */ + "$evaluatep_test", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_propagatepTest_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_propagatepTest_calltf, /* calltf routine */ + PLIbook_propagatepTest_misctf, /* misctf routine */ + "$propagatep_test", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_nodeinfoTest_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_nodeinfoTest_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$nodeinfo_test", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_DumpMem_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_DumpMem_calltf, /* calltf routine */ + PLIbook_DumpMem_misctf, /* misctf routine */ + "$dump_mem_hex", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 1, /* user_data value */ + PLIbook_DumpMem_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_DumpMem_calltf, /* calltf routine */ + PLIbook_DumpMem_misctf, /* misctf routine */ + "$dump_mem_bin", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 2, /* user_data value */ + PLIbook_DumpMem_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_DumpMem_calltf, /* calltf routine */ + PLIbook_DumpMem_misctf, /* misctf routine */ + "$dump_mem_ascii", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_FillMem_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_FillMem_calltf, /* calltf routine */ + PLIbook_FillMem_misctf, /* misctf routine */ + "$fill_mem", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.12/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.12/build_MTI.mak new file mode 100644 index 0000000..292c56c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/build_MTI.mak @@ -0,0 +1,22 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = \ + my_strobe_tf.c \ + read_stimulus_short_tf.c \ + my_monitor1_tf.c \ + my_monitor2_tf.c \ + read_stimulus_tf.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.12/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.12/build_NC.mak new file mode 100644 index 0000000..d8abaaf --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/build_NC.mak @@ -0,0 +1,22 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = \ + my_strobe_tf.c \ + read_stimulus_short_tf.c \ + my_monitor1_tf.c \ + my_monitor2_tf.c \ + read_stimulus_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.12/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.12/build_XL.mak new file mode 100644 index 0000000..2dc99ac --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/build_XL.mak @@ -0,0 +1,22 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + my_strobe_tf.c \ + read_stimulus_short_tf.c \ + my_monitor1_tf.c \ + my_monitor2_tf.c \ + read_stimulus_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_test.log b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_test.log new file mode 100644 index 0000000..efb993a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_test.log @@ -0,0 +1,16 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0: tfarg 1 changed, new value is 0: +At 0: tfarg 3 changed, new value is 0000: +At 5: tfarg 1 changed, new value is 1: +At 6: tfarg 2 changed, new value is 0000: +At 10: tfarg 1 changed, new value is 0: +At 10: tfarg 3 changed, new value is 0001: +At 15: tfarg 1 changed, new value is 1: +At 16: tfarg 2 changed, new value is 0001: +At 20: tfarg 1 changed, new value is 0: +At 20: tfarg 3 changed, new value is 1111: +At 25: tfarg 1 changed, new value is 1: +At 26: tfarg 2 changed, new value is 1111: +At 30: tfarg 1 changed, new value is 0: +Simulation complete via $finish(1) at time 30 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_test.v b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_test.v new file mode 100644 index 0000000..69d53e5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_test.v @@ -0,0 +1,38 @@ +/********************************************************************** + * $my_monitor1 example -- Verilog test bench source code + * + * Verilog test bench to test the $my_monitor1 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 [3:0] q, d; + reg clock; + + initial + $my_monitor1(clock, q, d); + + always @(posedge clock) + q <= #1 d; + + initial + begin + clock = 0; + forever #5 clock = ~ clock; + end + + initial + begin + d = 4'h0; + @(negedge clock) d = 4'h1; + @(negedge clock) d = 4'hF; + @(negedge clock) $finish; + end +endmodule + \ No newline at end of file diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_tf.c b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_tf.c new file mode 100644 index 0000000..ec125eb --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor1_tf.c @@ -0,0 +1,57 @@ +/********************************************************************** + * $my_monitor1 example -- C source code using TF PLI routines + * + * C source to call the misctf routine asynchronously whenever an + * argument to a system task/function changes value. + * + * 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 + * + * Usage: + * ------ + * $my_monitor1(,,...); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_MyMonitor1_calltf(int user_data, int reason); + * extern int PLIbook_MyMonitor1_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_MyMonitor1_calltf, /* calltf routine -/ + * PLIbook_MyMonitor1_misctf, /* misctf routine -/ + * "$my_monitor1", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_MyMonitor1_calltf(int user_data, int reason) +{ + tf_asynchon(); /* enable asynchronous misctf callbacks */ + return(0); +} + +/********************************************************************** + * misctf routine + *********************************************************************/ +int PLIbook_MyMonitor1_misctf(int user_data, int reason, int paramvc) +{ + if (reason == REASON_PARAMVC) { + io_printf("At %s: tfarg %d changed, new value is %s:\n", + tf_strgettime(), paramvc, tf_strgetp(paramvc,'b')); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_test.log b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_test.log new file mode 100644 index 0000000..660ad0c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_test.log @@ -0,0 +1,33 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Reached end of time step 0: + tfarg 1 changed to 0 + tfarg 3 changed to 0000 + +Reached end of time step 5: + tfarg 1 changed to 1 + +Reached end of time step 6: + tfarg 2 changed to 0000 + +Reached end of time step 10: + tfarg 1 changed to 0 + tfarg 3 changed to 0001 + +Reached end of time step 15: + tfarg 1 changed to 1 + +Reached end of time step 16: + tfarg 2 changed to 0001 + +Reached end of time step 20: + tfarg 1 changed to 0 + tfarg 3 changed to 1111 + +Reached end of time step 25: + tfarg 1 changed to 1 + +Reached end of time step 26: + tfarg 2 changed to 1111 + +Simulation complete via $finish(1) at time 30 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_test.v b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_test.v new file mode 100644 index 0000000..9681e85 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_test.v @@ -0,0 +1,38 @@ +/********************************************************************** + * $my_monitor2 example -- Verilog test bench source code + * + * Verilog test bench to test the $my_monitor1 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 [3:0] q, d; + reg clock; + + initial + $my_monitor2(clock, q, d); + + always @(posedge clock) + q <= #1 d; + + initial + begin + clock = 0; + forever #5 clock = ~ clock; + end + + initial + begin + d = 4'h0; + @(negedge clock) d = 4'h1; + @(negedge clock) d = 4'hF; + @(negedge clock) $finish; + end +endmodule + \ No newline at end of file diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_tf.c b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_tf.c new file mode 100644 index 0000000..7688f49 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_monitor2_tf.c @@ -0,0 +1,75 @@ +/********************************************************************** + * $my_monitor2 example -- C source code using TF PLI routines + * + * C source to call the misctf routine asynchronously whenever an + * argument to a system task/function changes value, and then call the + * misctf synchronously at the end of the simulation time step to + * process all arguments that changed during that time step. + * + * 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 + * + * Usage: + * ------ + * $my_monitor1(,,...); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_MyMonitor2_calltf(int user_data, int reason); + * extern int PLIbook_MyMonitor2_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_MyMonitor2_calltf, /* calltf routine -/ + * PLIbook_MyMonitor2_misctf, /* misctf routine -/ + * "$my_monitor2", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_MyMonitor2_calltf(int user_data, int reason) +{ + tf_asynchon(); /* enable asynchronous misctf callbacks */ + return(0); +} + +/********************************************************************** + * misctf routine + *********************************************************************/ +int PLIbook_MyMonitor2_misctf(int user_data, int reason, int paramvc) +{ + PLI_INT32 arg_num; + + if (reason == REASON_PARAMVC) { + /* io_printf("At %s: change detected on tfarg %d\n", + tf_strgettime(), paramvc); */ + tf_copypvc_flag(paramvc); + tf_rosynchronize(); /* schedule a callback at end of time step */ + } + + if (reason == REASON_ROSYNCH) { + io_printf("Reached end of time step %s:\n", tf_strgettime()); + if (tf_movepvc_flag(-1)) { /* only print if something changed */ + arg_num = 0; + while (arg_num = tf_getpchange(arg_num) ) { + io_printf(" tfarg %d changed to %s\n", + arg_num, tf_strgetp(arg_num,'b')); + } + io_printf("\n"); + } + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_test.log b/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_test.log new file mode 100644 index 0000000..06f5f74 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_test.log @@ -0,0 +1,7 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Status of tfarg 1 is 0000: +Status of tfarg 1 is 0001: +Status of tfarg 1 is 0010: +Status of tfarg 1 is 0000: +Simulation complete via $finish(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_test.v b/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_test.v new file mode 100644 index 0000000..6e7375d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_test.v @@ -0,0 +1,41 @@ +/********************************************************************** + * $my_strobe example -- Verilog test bench source code + * + * Verilog test bench to test the $my_strobe 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 [3:0] sum, a, b; + reg clock; + + always @(posedge clock) + $my_strobe(sum); + + always @(posedge clock) + sum = a + b; + + initial + begin + clock = 0; + forever #5 clock = ~ clock; + end + + initial + begin + //$monitor("At %0d sum=%b",$stime, sum); + a = 4'h0; + b = 4'h0; + @(negedge clock) a = 4'h1; + @(negedge clock) b = 4'h1; + @(negedge clock) a = 4'hF; + @(negedge clock) $finish; + end +endmodule + \ No newline at end of file diff --git a/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_tf.c b/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_tf.c new file mode 100644 index 0000000..82a73c7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/my_strobe_tf.c @@ -0,0 +1,70 @@ +/********************************************************************** + * $my_strobe example -- C source code using TF PLI routines + * + * C source to synchronize to the end of a simulation time step before + * printing the current logic value of a task/function argument. + * + * 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 + * + * Usage: + * ------ + * $my_strobe(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_MyStrobe_checktf(int user_data, int reason); + * extern int PLIbook_MyStrobe_calltf(int user_data, int reason); + * extern int PLIbook_MyStrobe_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_MyStrobe_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_MyStrobe_calltf, /* calltf routine -/ + * PLIbook_MyStrobe_misctf, /* misctf routine -/ + * "$my_strobe", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_MyStrobe_checktf(int user_data, int reason) +{ + if (tf_nump() != 1) + tf_error("Usage: $my_strobe();"); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("Usage: $my_strobe();"); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_MyStrobe_calltf(int user_data, int reason) +{ + tf_rosynchronize(); + return(0); +} + +/********************************************************************** + * misctf routine + *********************************************************************/ +int PLIbook_MyStrobe_misctf(int user_data, int reason, int paramvc) +{ + if (reason == REASON_ROSYNCH) { + io_printf("Status of tfarg 1 is %s:\n", tf_strgetp(1,'b')); + } + return(0); +} + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus.pat b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus.pat new file mode 100644 index 0000000..a3fc53d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus.pat @@ -0,0 +1,7 @@ + 10 0_0000_0000 + 30 0_0000_0001 + 50 0_0001_0001 + 70 0_0001_1111 + 90 0_0000_1111 +110 1_1111_0000 +130 0_0000_0000 \ No newline at end of file diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_test.log b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_test.log new file mode 100644 index 0000000..8a06120 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_test.log @@ -0,0 +1,28 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + + 0 ns: a=xxxx b=xxxx ci=x sum=xxxx co=x + 10 ns: a=0000 b=0000 ci=0 sum=xxxx co=x + 12 ns: a=0000 b=0000 ci=0 sum=xxx0 co=0 + 14 ns: a=0000 b=0000 ci=0 sum=0000 co=0 + 40 ns: a=0000 b=0001 ci=0 sum=0000 co=0 + 42 ns: a=0000 b=0001 ci=0 sum=0001 co=0 + 90 ns: a=0001 b=0001 ci=0 sum=0001 co=0 + 92 ns: a=0001 b=0001 ci=0 sum=0000 co=0 + 94 ns: a=0001 b=0001 ci=0 sum=0010 co=0 + 160 ns: a=0001 b=1111 ci=0 sum=0010 co=0 + 162 ns: a=0001 b=1111 ci=0 sum=1000 co=0 + 166 ns: a=0001 b=1111 ci=0 sum=0000 co=1 + 250 ns: a=0000 b=1111 ci=0 sum=0000 co=1 + 252 ns: a=0000 b=1111 ci=0 sum=0001 co=1 + 254 ns: a=0000 b=1111 ci=0 sum=0011 co=1 + 256 ns: a=0000 b=1111 ci=0 sum=0111 co=1 + 258 ns: a=0000 b=1111 ci=0 sum=1111 co=0 + 360 ns: a=1111 b=0000 ci=1 sum=1111 co=0 + 362 ns: a=1111 b=0000 ci=1 sum=1110 co=0 + 364 ns: a=1111 b=0000 ci=1 sum=1100 co=0 + 366 ns: a=1111 b=0000 ci=1 sum=1000 co=0 + 368 ns: a=1111 b=0000 ci=1 sum=0000 co=1 +$read_stimuulus reached end-of-file + 490 ns: a=0000 b=0000 ci=0 sum=0000 co=1 + 492 ns: a=0000 b=0000 ci=0 sum=0000 co=0 +Simulation complete via $finish(1) at time 500 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_test.v b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_test.v new file mode 100644 index 0000000..797e6c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_test.v @@ -0,0 +1,65 @@ +/********************************************************************** + * $read_stimulus_short example -- Verilog test bench source code + * + * Verilog test bench to test the $read_stimulus_short 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 [8:0] input_vector; + wire [3:0] a, b, sum; + wire ci, co; + + add4 i1 (a, b, ci, sum, co); + + assign {ci, a, b} = input_vector; + + initial + begin + $timeformat(-9,0," ns",10); + $monitor("%t: a=%b b=%b ci=%b sum=%b co=%b", + $time, a, b, ci, sum, co); + $read_stimulus_short("read_stimulus.pat", input_vector); + #500 $finish; + end +endmodule + +/*** A netlist level 4-bit adder model ***/ +`timescale 1ns / 1ns +module add4 (a, b, ci, sum, co); + input [3:0] a, b; + input ci; + output [3:0] sum; + output co; + + wire [3:0] a, b, sum; + wire ci, c0, c1, c2, co; + + addbit u0 (a[0], b[0], ci, sum[0], c0); + addbit u1 (a[1], b[1], c0, sum[1], c1); + addbit u2 (a[2], b[2], c1, sum[2], c2); + addbit u3 (a[3], b[3], c2, sum[3], co); + +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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_tf.c b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_tf.c new file mode 100644 index 0000000..1635374 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_short_tf.c @@ -0,0 +1,106 @@ +/********************************************************************** + * $read_stimulus_short example -- C source code using TF PLI routines + * + * For the book, "The Verilog PLI Handbook", Chapter 11 + * Copyright 1998, Sutherland HDL Inc, Portland, Oregon. + * + * C source to read test vectors from a file and apply them to + * simulation. Once called, this application will call itself back + * until it reaches End-of-File. NOTE: A more versatile version of + * this application is presented in the $read_stimulus_ba example. + * + * Each line in the test vector file contains a delay time and a vector + * value, separated by white space. Delay values define when the + * vector is to be applied to simulation. Delays must be relative to + * the previous time. The test vector value must be in binary. + * An example file is: + * + * 10 00000000 + * 20 10111001 + * ... + * + * 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 + * + * Usage: + * + * initial + * $read_stimulus_short("file_name", verilog_reg); + * + * where: + * "file_name" is the name of the file to be read, in quotes. + * verilog_reg is a verilog register data type of the same bit + * width as the patterns to be read. + * + * NOTES: + * 1. There is no error checking on the data read from the file. + * 2. Delay times are limited to 32-bit integers. + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ReadStimulusShort_calltf(int user_data, int reason); + * extern int PLIbook_ReadStimulusShort_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadStimulusShort_calltf, /* calltf routine -/ + * PLIbook_ReadStimulusShort_misctf, /* misctf routine -/ + * "$read_stimulus_short", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/*********************************************************************/ +/* calltf routine */ +/*********************************************************************/ +int PLIbook_ReadStimulusShort_calltf(int user_data, int reason) +{ /* call the misctf routine at the end of current */ + tf_setdelay(0); /* time step, with REASON_REACTIVATE; the misctf */ + /* routine reads the stimulus file. */ + return(0); +} + +/*********************************************************************/ +/* misctf routine */ +/*********************************************************************/ +int PLIbook_ReadStimulusShort_misctf(int user_data, int reason, + int paramvc) +{ + PLI_INT32 delay; + FILE *file_p; /* pointer to the test vector file */ + PLI_BYTE8 vector[1024]; /* stimulus vector -- hard coded limit */ + + switch(reason) { + case REASON_ENDOFCOMPILE: /* misctf called at start of simulation*/ + file_p = fopen(tf_getcstringp(1), "r"); + /* store a pointer to the file in the work area */ + tf_setworkarea((char *)file_p); + break; + + case REASON_REACTIVATE: /* misctf called by tf_setdelay */ + /* get the file pointer from the work area */ + file_p = (FILE *)tf_getworkarea(); + /* read next line from the file */ + if ( (fscanf(file_p,"%d %s\n", &delay, (char *)vector)) == EOF) { + io_printf("$read_stimuulus reached end-of-file\n"); + return(0); /* exit without scheduling another callback */ + break; + } + /* schedule the vector to be applied after the delay period */ + tf_strdelputp(2, tf_sizep(2), 'b', vector, delay, 2); + /* call this routine back after delay time */ + tf_setdelay(delay); + break; + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_test.log b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_test.log new file mode 100644 index 0000000..83c6315 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_test.log @@ -0,0 +1,32 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + + 0 ns: a=xxxx b=xxxx ci=x sum=xxxx co=x + 10 ns: a=0000 b=0000 ci=0 sum=xxxx co=x + 12 ns: a=0000 b=0000 ci=0 sum=xxx0 co=0 + 14 ns: a=0000 b=0000 ci=0 sum=0000 co=0 + 30 ns: a=0000 b=0001 ci=0 sum=0000 co=0 + 32 ns: a=0000 b=0001 ci=0 sum=0001 co=0 + 50 ns: a=0001 b=0001 ci=0 sum=0001 co=0 + 52 ns: a=0001 b=0001 ci=0 sum=0000 co=0 + 54 ns: a=0001 b=0001 ci=0 sum=0010 co=0 + 70 ns: a=0001 b=1111 ci=0 sum=0010 co=0 + 72 ns: a=0001 b=1111 ci=0 sum=1000 co=0 + 76 ns: a=0001 b=1111 ci=0 sum=0000 co=1 + 90 ns: a=0000 b=1111 ci=0 sum=0000 co=1 + 92 ns: a=0000 b=1111 ci=0 sum=0001 co=1 + 94 ns: a=0000 b=1111 ci=0 sum=0011 co=1 + 96 ns: a=0000 b=1111 ci=0 sum=0111 co=1 + 98 ns: a=0000 b=1111 ci=0 sum=1111 co=0 + 110 ns: a=1111 b=0000 ci=1 sum=1111 co=0 + 112 ns: a=1111 b=0000 ci=1 sum=1110 co=0 + 114 ns: a=1111 b=0000 ci=1 sum=1100 co=0 + 116 ns: a=1111 b=0000 ci=1 sum=1000 co=0 + 118 ns: a=1111 b=0000 ci=1 sum=0000 co=1 + +$read_stimulus_?? has encountered end-of-file. + 130 ns: a=0000 b=0000 ci=0 sum=0000 co=1 + 132 ns: a=0000 b=0000 ci=0 sum=0000 co=0 +ncsim: *W,RNQUIE: Simulation is complete. +ncsim> exit + +PLI is processing finish at simulation time 134 diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_test.v b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_test.v new file mode 100644 index 0000000..36dd15b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_test.v @@ -0,0 +1,65 @@ +/********************************************************************** + * $read_stimulus_ba example -- Verilog test bench source code + * + * Verilog test bench to test the $read_stimulus_ba 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 [8:0] input_vector; + wire [3:0] a, b, sum; + wire ci, co; + + add4 i1 (a, b, ci, sum, co); + + assign {ci, a, b} = input_vector; + + initial + begin + $timeformat(-9,0," ns",10); + $monitor("%t: a=%b b=%b ci=%b sum=%b co=%b", + $time, a, b, ci, sum, co); + $read_stimulus_ba("read_stimulus.pat", input_vector); + #80 $save("read_stimulus.sav"); + end +endmodule + +/*** A netlist level 4-bit adder model ***/ +`timescale 1ns / 1ns +module add4 (a, b, ci, sum, co); + input [3:0] a, b; + input ci; + output [3:0] sum; + output co; + + wire [3:0] a, b, sum; + wire ci, c0, c1, c2, co; + + addbit u0 (a[0], b[0], ci, sum[0], c0); + addbit u1 (a[1], b[1], c0, sum[1], c1); + addbit u2 (a[2], b[2], c1, sum[2], c2); + addbit u3 (a[3], b[3], c2, sum[3], co); + +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 +/**********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_tf.c b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_tf.c new file mode 100644 index 0000000..f01df32 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/read_stimulus_tf.c @@ -0,0 +1,332 @@ +/********************************************************************** + * $read_stimulus_ba example -- C source code using TF PLI routines + * + * For the book, "The Verilog PLI Handbook", Chapter 11 + * Copyright 1998, Sutherland HDL Inc, Portland, Oregon. + * + * C source to read test vectors from a file and apply them to + * simulation. Once called, this application will call itself back + * until it reaches End-of-File. + * + * Each line in the test vector file contains a delay time and a vector + * value, separated by white space. Delay values define when the + * vector is to be applied to simulation. Delays may be relative to + * the previous time, or absolute to time 0. The test vector value + * may be in binary or hex. An example file is: + * + * 100 00000000 + * 70 10111001 + * ... + * + * 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 + * + * Usage: + * + * initial + * $read_stimulus("file_name", verilog_reg); + * + * where: + * is b or h (for binary or hex vectors). + * is r or a for relative or absolute times. + * "file_name" is the name of the file to be read, in quotes. + * verilog_reg is a verilog register data type of the same bit + * width as the patterns to be read. + * + * Output: + * + * Verbose debugging output is enabled with a +read_stimulus_debug + * invocation option to the simulation + * + * NOTES: + * 1. There is no error checking on the data read from the file. + * 2. Delay times are limited to 32-bit integers. + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ReadStimulus_checktf(int user_data, int reason); + * extern int PLIbook_ReadStimulus_calltf(int user_data, int reason); + * extern int PLIbook_ReadStimulus_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ReadStimulus_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadStimulus_calltf, /* calltf routine -/ + * PLIbook_ReadStimulus_misctf, /* misctf routine -/ + * "$read_stimulus", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ReadStimulus_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadStimulus_calltf, /* calltf routine -/ + * PLIbook_ReadStimulus_misctf, /* misctf routine -/ + * "$read_stimulus_ba", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + * {usertask, /* type of PLI routine -/ + * 1, /* user_data value -/ + * PLIbook_ReadStimulus_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadStimulus_calltf, /* calltf routine -/ + * PLIbook_ReadStimulus_misctf, /* misctf routine -/ + * "$read_stimulus_br", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + * {usertask, /* type of PLI routine -/ + * 2, /* user_data value -/ + * PLIbook_ReadStimulus_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadStimulus_calltf, /* calltf routine -/ + * PLIbook_ReadStimulus_misctf, /* misctf routine -/ + * "$read_stimulus_ha", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + * {usertask, /* type of PLI routine -/ + * 3, /* user_data value -/ + * PLIbook_ReadStimulus_checktf, /* checktf routine -/ + * 3, /* sizetf routine -/ + * PLIbook_ReadStimulus_calltf, /* calltf routine -/ + * PLIbook_ReadStimulus_misctf, /* misctf routine -/ + * "$read_stimulus_hr", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/* prototypes of sub-functions */ +char *PLIbook_reason_name(PLI_INT32 reason); + +/*********************************************************************/ +/* structure definition for data used by the misctf routine */ +/*********************************************************************/ +typedef struct PLIbook_stim_data { + FILE *file_ptr; /* pointer to the test vector file */ + long file_position; /* position within file of next byte to read */ + char *vector; /* pointer to stimulus vector */ + char dummy_msg[20]; /* dummy message field to show save/restart */ +} PLIbook_stim_data_s, *PLIbook_stim_data_p; + +/*********************************************************************/ +/* checktf routine */ +/*********************************************************************/ +int PLIbook_ReadStimulus_checktf(int user_data, int reason) +{ + bool err = FALSE; + + if (tf_nump() != 2) { + tf_text("$read_stimulus_?? requires 2 arguments\n"); + err = TRUE; + } + if (tf_typep(1) != tf_string) { + tf_text("$read_stimulus_?? arg 1 must be a string\n"); + err = TRUE; + } + if (tf_typep(2) != tf_readwrite) { + tf_text("$read_stimulus_?? arg 2 must be a register data type"); + err = TRUE; + } + if (err) + tf_message(ERR_ERROR, "", "", ""); /* print stored messages */ + return(0); +} + +/*********************************************************************/ +/* calltf routine */ +/*********************************************************************/ +int PLIbook_ReadStimulus_calltf(int user_data, int reason) +{ /* call the misctf routine at the end of current */ + tf_setdelay(0); /* time step, with REASON_REACTIVATE; the misctf */ + /* routine reads the stimulus file. */ + return(0); +} + +/*********************************************************************/ +/* misctf routine */ +/*********************************************************************/ +int PLIbook_ReadStimulus_misctf(int user_data, int reason, int paramvc) +{ + PLI_INT32 delay; + PLI_BYTE8 base; + PLIbook_stim_data_p data_p; + + bool debug = FALSE; + if(mc_scan_plusargs("read_stimulus_debug")) debug = TRUE; + + if (debug) + io_printf("** read_stimulus misctf called for %s at time %s **\n", + PLIbook_reason_name(reason), tf_strgettime()); + + switch(reason) { + case REASON_ENDOFCOMPILE: /* misctf called at start of simulation */ + + /* Check work area to see if application data is already + /* allocated and the vector file opened. This check is necessary + /* because REASON_RESTART can occur before REASON_ENDOFCOMPILE */ + data_p = (PLIbook_stim_data_p)tf_getworkarea(); + if (data_p) + return(0); /* abort if work area already contains data */ + + /* allocate a memory block for data storage */ + data_p=(PLIbook_stim_data_p)malloc(sizeof(PLIbook_stim_data_s)); + + /* store a pointer to the application data in the work area */ + tf_setworkarea((PLI_BYTE8 *)data_p); + + /* fill in the application data fields */ + data_p->file_ptr = fopen((char *)tf_getcstringp(1), "r"); + if ( !data_p->file_ptr ) { + tf_error("$read_stimulus_?? could not open file %s", + (char *)tf_getcstringp(1)); + tf_dofinish(); /* exit simulation if cannot open file */ + break; + } + data_p->file_position = ftell(data_p->file_ptr); + data_p->vector = (char *)malloc(((int)tf_sizep(2) * 8) + 1); + strcpy(data_p->dummy_msg, "Hello world"); + break; + + + case REASON_REACTIVATE: /* misctf called by tf_setdelay */ + + /* get the pointer to the data structure from the work area */ + data_p = (PLIbook_stim_data_p)tf_getworkarea(); + + /* read next line from the file */ + if ( (fscanf(data_p->file_ptr,"%d %s\n", + &delay, data_p->vector)) == EOF) { + tf_rosynchronize(); /* if end of file, schedule a callback */ + break; /* at the end of the current time step */ + } + if (debug) + io_printf("** values read from file: delay = %d vector = %s\n", + delay, data_p->vector); + + /* set flag for test vector radix */ + switch(user_data) { + case 0: + case 1: base = 'b'; break; /* vectors are in binary format */ + case 2: + case 3: base = 'h'; break; /* vectors are in hex format */ + } + + /* convert absolute delays to relative to current time */ + switch(user_data) { + case 0: + case 2: /* using absolute delays; convert to relative */ + delay = delay - tf_gettime(); + } + + /* schedule the vector to be applied after the delay period */ + tf_strdelputp(2, tf_sizep(2), base, (PLI_BYTE8 *)data_p->vector, + delay, 0); + + /* schedule reactive callback to this routine after delay time */ + tf_setdelay(delay); + break; + + + case REASON_ROSYNCH: /* misctf called at end of time step */ + io_printf("\n$read_stimulus_?? has encountered end-of-file.\n"); + tf_dofinish; + break; + + + case REASON_FINISH: /* misctf called at end of simulation */ + io_printf("\nPLI is processing finish at simulation time %s\n\n", + tf_strgettime()); + /* get the pointer to the application data from the work area */ + data_p = (PLIbook_stim_data_p)tf_getworkarea(); + /* close file */ + if (data_p->file_ptr) fclose(data_p->file_ptr); + /* de-allocate storage */ + free(data_p); + break; + + + case REASON_SAVE: /* misctf called for $save */ + + /* get the pointer to the application data from the work area */ + data_p = (PLIbook_stim_data_p)tf_getworkarea(); + + /* save current file position in the application data */ + data_p->file_position = ftell(data_p->file_ptr); + + /* add application data to simulation save file */ + tf_write_save((PLI_BYTE8 *)data_p, sizeof(PLIbook_stim_data_s)); + if (debug) + io_printf("\nPLI data saved (last file position was %ld)\n\n", + data_p->file_position); + break; + + + case REASON_RESTART: /* misctf called end of simulation */ + + /* re-allocate memory for PLI application data */ + data_p=(PLIbook_stim_data_p)malloc(sizeof(PLIbook_stim_data_s)); + + /* save new application data pointer in work area */ + tf_setworkarea((PLI_BYTE8 *)data_p); + + /* retrieve old application data from save file */ + if (!tf_read_restart((PLI_BYTE8 *)data_p, + sizeof(PLIbook_stim_data_s)) ) { + tf_error("\nError retrieving PLI data from save file!\n"); + return(0); + } + if (debug) { + io_printf("\nPLI data retrieved from save file.\n"); + /* test to see if old application data was restored */ + io_printf(" dummy message = %s, file position = %ld\n\n", + data_p->dummy_msg, data_p->file_position); + } + /* re-open test vector file */ + data_p->file_ptr = fopen((char *)tf_getcstringp(1), "r"); + if ( !data_p->file_ptr ) { + tf_error("$read_stimulus_?? could not re-open file %s", + (char *)tf_getcstringp(1)); + tf_dofinish(); /* exit simulation if cannot open file */ + } + + /* re-position file to next test vector to be read */ + if ( fseek(data_p->file_ptr, data_p->file_position, SEEK_SET)) { + tf_error("$read_stimulus_?? could not reposition file"); + tf_dofinish(); /* exit simulation if reposition open file */ + } + break; + } + return(0); +} + +/*********************************************************************/ +/* Function to convert reason integer to reason name */ +/*********************************************************************/ +char *PLIbook_reason_name(PLI_INT32 reason) +{ + char str[25]; + switch (reason) { + case REASON_ENDOFCOMPILE : return("REASON_ENDOFCOMPILE"); break; + case REASON_FINISH : return("REASON_FINISH"); break; + case REASON_INTERACTIVE : return("REASON_INTERACTIVE"); break; + case REASON_SYNCH : return("REASON_SYNCH"); break; + case REASON_ROSYNCH : return("REASON_ROSYNCH"); break; + case REASON_REACTIVATE : return("REASON_REACTIVATE"); break; + case REASON_PARAMVC : return("REASON_PARAMVC"); break; + case REASON_PARAMDRC : return("REASON_PARAMDRC"); break; + case REASON_SAVE : return("REASON_SAVE"); break; + case REASON_RESTART : return("REASON_RESTART"); break; + case REASON_RESET : return("REASON_RESET"); break; + case REASON_ENDOFRESET : return("REASON_ENDOFRESET"); break; + case REASON_FORCE : return("REASON_FORCE"); break; + case REASON_RELEASE : return("REASON_RELEASE"); break; + } + return("Non-standard or Unknown Reason"); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.12/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.12/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.12/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.12/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.12/veriuser_VCS.tab new file mode 100644 index 0000000..be9a11c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/veriuser_VCS.tab @@ -0,0 +1,12 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$my_strobe data=0 check=PLIbook_MyStrobe_checktf call=PLIbook_MyStrobe_calltf misc=PLIbook_MyStrobe_misctf +$read_stimulus_short data=0 call=PLIbook_ReadStimulusShort_calltf misc=PLIbook_ReadStimulusShort_misctf +$my_monitor1 data=0 call=PLIbook_MyMonitor1_calltf misc=PLIbook_MyMonitor1_misctf +$my_monitor2 data=0 call=PLIbook_MyMonitor2_calltf misc=PLIbook_MyMonitor2_misctf +$read_stimulus data=0 check=PLIbook_ReadStimulus_checktf call=PLIbook_ReadStimulus_calltf misc=PLIbook_ReadStimulus_misctf +$read_stimulus_ba data=0 check=PLIbook_ReadStimulus_checktf call=PLIbook_ReadStimulus_calltf misc=PLIbook_ReadStimulus_misctf +$read_stimulus_br data=1 check=PLIbook_ReadStimulus_checktf call=PLIbook_ReadStimulus_calltf misc=PLIbook_ReadStimulus_misctf +$read_stimulus_ha data=2 check=PLIbook_ReadStimulus_checktf call=PLIbook_ReadStimulus_calltf misc=PLIbook_ReadStimulus_misctf +$read_stimulus_hr data=3 check=PLIbook_ReadStimulus_checktf call=PLIbook_ReadStimulus_calltf misc=PLIbook_ReadStimulus_misctf diff --git a/me250300_pli/plibook_examples_unix/chapter.12/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.12/veriusertfs_table.h new file mode 100644 index 0000000..29f8830 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.12/veriusertfs_table.h @@ -0,0 +1,122 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_MyStrobe_checktf(int user_data, int reason); +extern int PLIbook_MyStrobe_calltf(int user_data, int reason); +extern int PLIbook_MyStrobe_misctf(int user_data, int reason, int pvc); + +extern int PLIbook_ReadStimulusShort_calltf(int user_data, int reason); +extern int PLIbook_ReadStimulusShort_misctf(int user_data, int reason, int pvc); + +extern int PLIbook_MyMonitor1_calltf(int user_data, int reason); +extern int PLIbook_MyMonitor1_misctf(int user_data, int reason, int pvc); + +extern int PLIbook_MyMonitor2_calltf(int user_data, int reason); +extern int PLIbook_MyMonitor2_misctf(int user_data, int reason, int pvc); + +extern int PLIbook_ReadStimulus_checktf(int user_data, int reason); +extern int PLIbook_ReadStimulus_calltf(int user_data, int reason); +extern int PLIbook_ReadStimulus_misctf(int user_data, int reason, int pvc); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_MyStrobe_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_MyStrobe_calltf, /* calltf routine */ + PLIbook_MyStrobe_misctf, /* misctf routine */ + "$my_strobe", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadStimulusShort_calltf, /* calltf routine */ + PLIbook_ReadStimulusShort_misctf, /* misctf routine */ + "$read_stimulus_short", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_MyMonitor1_calltf, /* calltf routine */ + PLIbook_MyMonitor1_misctf, /* misctf routine */ + "$my_monitor1", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_MyMonitor2_calltf, /* calltf routine */ + PLIbook_MyMonitor2_misctf, /* misctf routine */ + "$my_monitor2", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ReadStimulus_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadStimulus_calltf, /* calltf routine */ + PLIbook_ReadStimulus_misctf, /* misctf routine */ + "$read_stimulus", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ReadStimulus_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadStimulus_calltf, /* calltf routine */ + PLIbook_ReadStimulus_misctf, /* misctf routine */ + "$read_stimulus_ba", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + {usertask, /* type of PLI routine */ + 1, /* user_data value */ + PLIbook_ReadStimulus_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadStimulus_calltf, /* calltf routine */ + PLIbook_ReadStimulus_misctf, /* misctf routine */ + "$read_stimulus_br", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + {usertask, /* type of PLI routine */ + 2, /* user_data value */ + PLIbook_ReadStimulus_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadStimulus_calltf, /* calltf routine */ + PLIbook_ReadStimulus_misctf, /* misctf routine */ + "$read_stimulus_ha", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + {usertask, /* type of PLI routine */ + 3, /* user_data value */ + PLIbook_ReadStimulus_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadStimulus_calltf, /* calltf routine */ + PLIbook_ReadStimulus_misctf, /* misctf routine */ + "$read_stimulus_hr", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.13/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.13/build_MTI.mak new file mode 100644 index 0000000..e903135 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/build_MTI.mak @@ -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 = \ + sci_alu_comb_calltf_tf.c \ +# sci_alu_comb_misctf_tf.c \ +# sci_alu_sequential_tf.c \ +# sci_alu_synchronized_tf.c \ +# sci_alu_latched_tf.c \ +# sci_alu_with_delays_tf.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.13/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.13/build_NC.mak new file mode 100644 index 0000000..279ef6e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/build_NC.mak @@ -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 = \ + sci_alu_comb_calltf_tf.c \ +# sci_alu_comb_misctf_tf.c \ +# sci_alu_sequential_tf.c \ +# sci_alu_synchronized_tf.c \ +# sci_alu_latched_tf.c \ +# sci_alu_with_delays_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.13/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.13/build_XL.mak new file mode 100644 index 0000000..471a044 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/build_XL.mak @@ -0,0 +1,23 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + sci_alu_comb_calltf_tf.c \ +# sci_alu_comb_misctf_tf.c \ +# sci_alu_sequential_tf.c \ +# sci_alu_synchronized_tf.c \ +# sci_alu_latched_tf.c \ +# sci_alu_with_delays_tf.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_shell.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_shell.v new file mode 100644 index 0000000..caae654 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + //using combinational logic input sensitivity + always @(a or b or opcode) + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_test.log b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_test.log new file mode 100644 index 0000000..f87e89a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 2 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 3 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_test.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_test.v new file mode 100644 index 0000000..3fee9c4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_comb_calltf_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out, excep, err); + + initial + begin + $timeformat(-9,0," ns",7); + $monitor("At %t: result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display("\n"); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_tf.c b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_tf.c new file mode 100644 index 0000000..abba947 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_calltf_tf.c @@ -0,0 +1,154 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (outputs change on an input change). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine: Serves as an interface between Verilog simulation + * and the C model. Called whenever the C model inputs change value, + * reads the input values, and passes the values to the C model, and + * writes the C model outputs into simulation. + * NOTE: the Verilog shell module must invoke the $scientific_alu + * system task on each C model input change that can affect the + * C model outputs. That is: + * For combinational logic: + * always @(a or b or opcode) $scientific_alu(...); + * For sequential logic: + * always @(posedge clock) $scientific_alu(...); + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + #define ALU_A 1 /* system task arg 1 is ALU A input */ + #define ALU_B 2 /* system task arg 2 is ALU B input */ + #define ALU_OP 3 /* system task arg 3 is ALU opcode input */ + #define ALU_RESULT 4 /* system task arg 4 is ALU result output */ + #define ALU_EXCEPT 5 /* system task arg 5 is ALU exception output */ + #define ALU_ERROR 6 /* system task arg 6 is ALU error output */ + + double a, b, result; + int opcode, excep, err; + + /* Read current values of C model inputs from Verilog simulation */ + a = tf_getrealp(ALU_A); + b = tf_getrealp(ALU_B); + opcode = (int)tf_getp(ALU_OP); + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err); + + /* Write the C model outputs onto the Verilog signals */ + tf_putrealp(ALU_RESULT, result); + tf_putp (ALU_EXCEPT, (PLI_INT32)excep); + tf_putp (ALU_ERROR, (PLI_INT32)err); + + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + if (tf_nump() != 6) + tf_error("$scientific_alu requires 6 arguments"); + else { + if (tf_typep(ALU_A) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 1 must be a real variable\n"); + if (tf_typep(ALU_B) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + if (tf_typep(ALU_OP) != TF_READONLY) + tf_error("$scientific_alu arg 3 must be a net\n"); + else if (tf_sizep(ALU_OP) != 4) + tf_error("$scientific_alu arg 3 must be a 4-bit vector\n"); + if (tf_typep(ALU_RESULT) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 4 must be a real variable\n"); + if (tf_typep(ALU_EXCEPT) != TF_READWRITE) + tf_error("$scientific_alu arg 5 must be a reg\n"); + else if (tf_sizep(ALU_EXCEPT) != 1) + tf_error("$scientific_alu arg 5 must be scalar\n"); + if (tf_typep(ALU_ERROR) != TF_READWRITE) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (tf_sizep(ALU_ERROR) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_shell.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_shell.v new file mode 100644 index 0000000..cb7ccee --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_shell.v @@ -0,0 +1,39 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_test.log b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_test.log new file mode 100644 index 0000000..f87e89a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 2 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 3 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_test.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_test.v new file mode 100644 index 0000000..d220460 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_comb_misctf_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out, excep, err); + + initial + begin + $timeformat(-9,0," ns",7); + $monitor("At %t: result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display("\n"); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_tf.c b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_tf.c new file mode 100644 index 0000000..f833962 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_comb_misctf_tf.c @@ -0,0 +1,166 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * PLIbook_ScientificALU_misctf, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (outputs change on an input change). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine: turns on asynchronous callbacks to the misctf + * routine whenever an argument to the system task changes value. + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + tf_asynchon(); + return(0); +} + +/********************************************************************** + * misctf routine: Serves as an interface between Verilog simulation + * and the C model. Called whenever the C model inputs change value, + * reads the input values, and passes the values to the C model, and + * writes the C model outputs into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc) +{ + #define ALU_A 1 /* system task arg 1 is ALU A input */ + #define ALU_B 2 /* system task arg 2 is ALU B input */ + #define ALU_OP 3 /* system task arg 3 is ALU opcode input */ + #define ALU_RESULT 4 /* system task arg 4 is ALU result output */ + #define ALU_EXCEPT 5 /* system task arg 5 is ALU exception output */ + #define ALU_ERROR 6 /* system task arg 6 is ALU error output */ + + double a, b, result; + int opcode, excep, err; + + /* abort if misctf was not called for a task argument value change */ + if (reason != REASON_PARAMVC) + return(0); + + /* abort if task argument that changed was a model output */ + if (paramvc > ALU_OP) /* model outputs are after model inputs */ + return(0); + + /* Read current values of C model inputs from Verilog simulation */ + a = tf_getrealp(ALU_A); + b = tf_getrealp(ALU_B); + opcode = (int)tf_getp(ALU_OP); + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err); + + /* Write the C model outputs onto the Verilog signals */ + tf_putrealp(ALU_RESULT, result); + tf_putp (ALU_EXCEPT, (PLI_INT32)excep); + tf_putp (ALU_ERROR, (PLI_INT32)err); + + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + if (tf_nump() != 6) + tf_error("$scientific_alu requires 6 arguments"); + else { + if (tf_typep(ALU_A) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 1 must be a real variable\n"); + if (tf_typep(ALU_B) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + if (tf_typep(ALU_OP) != TF_READONLY) + tf_error("$scientific_alu arg 3 must be a net\n"); + else if (tf_sizep(ALU_OP) != 4) + tf_error("$scientific_alu arg 3 must be a 4-bit vector\n"); + if (tf_typep(ALU_RESULT) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 4 must be a real variable\n"); + if (tf_typep(ALU_EXCEPT) != TF_READWRITE) + tf_error("$scientific_alu arg 5 must be a reg\n"); + else if (tf_sizep(ALU_EXCEPT) != 1) + tf_error("$scientific_alu arg 5 must be scalar\n"); + if (tf_typep(ALU_ERROR) != TF_READWRITE) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (tf_sizep(ALU_ERROR) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_shell.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_shell.v new file mode 100644 index 0000000..a3366fd --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, latched logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(enable, a_in, b_in, opcode, + result_out, exception, error); + input enable; + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(enable, a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_test.log b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_test.log new file mode 100644 index 0000000..9fd1692 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_test.log @@ -0,0 +1,39 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: en=1 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: en=1 result1=4.00 result2=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=1 +At 2 ns: en=1 result1=8886110.52 result2=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=2 +At 3 ns: en=1 result1=64.00 result2=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: en=1 result1=16.00 result2=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: en=1 result1=0.00 result2=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: en=1 result1=16.00 result2=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: en=1 result1=16.00 result2=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: en=1 result1=2.77 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: en=1 result1=1.20 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: en=1 result1=-0.29 result2=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: en=1 result1=-0.96 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: en=1 result1=0.30 result2=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: en=1 result1=0.00 result2=8886110.52 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: en=1 result1=0.00 result2=4.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: en=1 result1=1.51 result2=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: en=1 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +At 26 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 27 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 28 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 29 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 30 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 31 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 32 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 33 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 34 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 35 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 36 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 37 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 38 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 39 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 40 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=e +At 41 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 42 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 52 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_test.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_test.v new file mode 100644 index 0000000..b954812 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_test.v @@ -0,0 +1,61 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a latched + * logic device. + * + * 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 "sci_alu_latched_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + reg enable; + wire excep, err, excep1, err1, excep2, err2; + real a, b, result1, result2; + wire [63:0] a_in, b_in, result_out1, result_out2; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out1) result1 = $bitstoreal(result_out1); + always @(result_out2) result2 = $bitstoreal(result_out2); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (enable, a_in, b_in, opcode[3:0], result_out1, excep1, err1); + scientific_alu i2 (enable, a_in, b_in, ~opcode[3:0], result_out2, excep2, err2); + + assign err = err1 | err2; + assign excep = excep1 | excep2; + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: en=%b result1=%.2f \tresult2=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, enable, result1, result2, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + enable = 1; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + enable = 0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_tf.c b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_tf.c new file mode 100644 index 0000000..4ff2685 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_latched_tf.c @@ -0,0 +1,226 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * latched logic version (output values are stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * PLIbook_ScientificALU_misctf, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * Definition for a structure to store output values when the ALU is + * latched. When enable is 1, the ALU returns the currently calculated + * outputs, and when 0, the ALU returns the latched previous results. + *********************************************************************/ +#include +#include + typedef struct PLIbook_SciALUoutputs *PLIbook_SciALUoutputs_p; + typedef struct PLIbook_SciALUoutputs { + char *instance_p; /* shows which task instance owns this space */ + double result; /* stored result of previous operation */ + int excep; + int err; + PLIbook_SciALUoutputs_p next_ALU_outputs; /* next stack location */ + } PLIbook_SciALUoutputs_s; + + /* declare global stack pointer */ + static PLIbook_SciALUoutputs_p ALU_outputs_stack = NULL; + + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Latched outputs version. + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + int enable, /* input; 0 = latched */ + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err, /* output; set if input is out of range */ + char *instance_p) /* input; pointer to system task instance */ +{ + PLIbook_SciALUoutputs_p ALU_outputs; + + /* Locate the output storage in the stack for this model instance */ + /* If no storage is found, then allocate a storage block and add */ + /* the storage to the stack. */ + ALU_outputs = ALU_outputs_stack; /* top-of-stack is in global var. */ + while (ALU_outputs && (ALU_outputs->instance_p != instance_p)) + ALU_outputs = ALU_outputs->next_ALU_outputs; + + /* If no storage area found for this model instance, create one */ + if (ALU_outputs == NULL) { + ALU_outputs = + (PLIbook_SciALUoutputs_p)malloc(sizeof(PLIbook_SciALUoutputs_s)); + ALU_outputs->instance_p = instance_p; /* set owner of this space */ + ALU_outputs->next_ALU_outputs = ALU_outputs_stack; + ALU_outputs_stack = ALU_outputs; /* save new top-of-stack */ + } + + if (enable) { /* ALU is not latched, calculate outputs and store */ + switch (opcode) { + case 0x0: ALU_outputs->result = pow (a, b); break; + case 0x1: ALU_outputs->result = sqrt (a); break; + case 0x2: ALU_outputs->result = exp (a); break; + case 0x3: ALU_outputs->result = ldexp (a, (int)b); break; + case 0x4: ALU_outputs->result = fabs (a); break; + case 0x5: ALU_outputs->result = fmod (a, b); break; + case 0x6: ALU_outputs->result = ceil (a); break; + case 0x7: ALU_outputs->result = floor (a); break; + case 0x8: ALU_outputs->result = log (a); break; + case 0x9: ALU_outputs->result = log10 (a); break; + case 0xA: ALU_outputs->result = sin (a); break; + case 0xB: ALU_outputs->result = cos (a); break; + case 0xC: ALU_outputs->result = tan (a); break; + case 0xD: ALU_outputs->result = asin (a); break; + case 0xE: ALU_outputs->result = acos (a); break; + case 0xF: ALU_outputs->result = atan (a); break; + } + ALU_outputs->excep = (errno == ERANGE);/* result out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + ALU_outputs->err = (_isnan(*result) || /* not-a-number, or */ + errno == EDOM); /* arg out-of-range */ + #else + ALU_outputs->err = (isnan(*result) || /* not-a-number, or */ + errno == EDOM); /* arg out-of-range */ + #endif + if (ALU_outputs->err) ALU_outputs->result = 0.0; + errno = 0; /* clear error flag */ + } + + /* return the values stored in the C model */ + *result = ALU_outputs->result; + *err = ALU_outputs->err; + *excep = ALU_outputs->excep; + + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine: turns on asynchronous callbacks to the misctf + * routine whenever an argument to the system task changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + tf_asynchon(); + return(0); +} + +/********************************************************************** + * misctf routine: Serves as an interface between Verilog simulation + * and the C model. Called whenever the C model inputs change value, + * reads the input values, and passes the values to the C model, and + * puts the C model outputs into simulation. Passes the instance + * pointer of the Verilog system task which represents the C model + * to serve as a unique flag within the C model. + *********************************************************************/ +int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc) +{ + #define ALU_ENABLE 1 /* system task arg 1 is ALU enable input */ + #define ALU_A 2 /* system task arg 2 is ALU A input */ + #define ALU_B 3 /* system task arg 3 is ALU B input */ + #define ALU_OP 4 /* system task arg 4 is ALU opcode input */ + #define ALU_RESULT 5 /* system task arg 5 is ALU result output */ + #define ALU_EXCEPT 6 /* system task arg 6 is ALU exception output */ + #define ALU_ERROR 7 /* system task arg 7 is ALU error output */ + + double a, b, result; + int opcode, excep, err, enable; + char *instance_p; + + /* abort if misctf was not called for a task argument value change */ + if (reason != REASON_PARAMVC) + return(0); + + /* abort if task argument that changed was a model output */ + if (paramvc > ALU_OP) /* model outputs are after model inputs */ + return(0); + + enable = (int)tf_getp(ALU_ENABLE); + a = tf_getrealp(ALU_A); + b = tf_getrealp(ALU_B); + opcode = (int)tf_getp(ALU_OP); + + /* Obtain the instance pointer for this system task instance */ + instance_p = (char *)tf_getinstance(); + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(enable, a, b, opcode, + &result, &excep, &err, instance_p); + + /* Write the C model outputs onto the Verilog signals */ + tf_putrealp(ALU_RESULT, result); + tf_putp (ALU_EXCEPT, (PLI_INT32)excep); + tf_putp (ALU_ERROR, (PLI_INT32)err); + + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + if (tf_nump() != 7) + tf_error("$scientific_alu requires 7 arguments"); + else { + if (tf_typep(ALU_ENABLE) != TF_READONLY) + tf_error("$scientific_alu arg 1 must be a net\n"); + else if (tf_sizep(ALU_ENABLE) != 1) + tf_error("$scientific_alu arg 1 must be scalar\n"); + if (tf_typep(ALU_A) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + if (tf_typep(ALU_B) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 3 must be a real variable\n"); + if (tf_typep(ALU_OP) != TF_READONLY) + tf_error("$scientific_alu arg 4 must be a net\n"); + else if (tf_sizep(ALU_OP) != 4) + tf_error("$scientific_alu arg 4 must be a 4-bit vector\n"); + if (tf_typep(ALU_RESULT) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 5 must be a real variable\n"); + if (tf_typep(ALU_EXCEPT) != TF_READWRITE) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (tf_sizep(ALU_EXCEPT) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + if (tf_typep(ALU_ERROR) != TF_READWRITE) + tf_error("$scientific_alu arg 7 must be a reg\n"); + else if (tf_sizep(ALU_ERROR) != 1) + tf_error("$scientific_alu arg 7 must be scalar\n"); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_shell.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_shell.v new file mode 100644 index 0000000..8d04a16 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, sequential logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(clock, a_in, b_in, opcode, + result_out, exception, error); + input clock; + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(clock, a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_test.log b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_test.log new file mode 100644 index 0000000..e2ab21f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_test.log @@ -0,0 +1,36 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: clk=0 result=0.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 5 ns: clk=1 result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 10 ns: clk=0 result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 15 ns: clk=1 result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 20 ns: clk=0 result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 25 ns: clk=1 result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 30 ns: clk=0 result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 35 ns: clk=1 result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 40 ns: clk=0 result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 45 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 50 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 55 ns: clk=1 result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 60 ns: clk=0 result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 65 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 70 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 75 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 80 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 85 ns: clk=1 result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 90 ns: clk=0 result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 95 ns: clk=1 result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 100 ns: clk=0 result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 105 ns: clk=1 result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 110 ns: clk=0 result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 115 ns: clk=1 result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 120 ns: clk=0 result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 125 ns: clk=1 result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 130 ns: clk=0 result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 135 ns: clk=1 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 140 ns: clk=0 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 145 ns: clk=1 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 150 ns: clk=0 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 155 ns: clk=1 result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f + +Simulation complete via $finish(1) at time 160 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_test.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_test.v new file mode 100644 index 0000000..a54de6d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_test.v @@ -0,0 +1,56 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a sequential + * logic device. + * + * 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 "sci_alu_sequential_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [3:0] opcode; + reg clk; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + integer i; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (clk, a_in, b_in, opcode, result_out, excep, err); + + always #5 clk = ~clk; + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + opcode = 0; + a = 16.0; + b = 2.0; + #0 clk = 0; + for (i=1; i<=15; i=i+1) + @(negedge clk) opcode = i; + #10 $display(""); + $finish; + end + + always @(clk) + $strobe("At %t: clk=%b result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, clk, result, excep, err, a, b, opcode); + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_tf.c b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_tf.c new file mode 100644 index 0000000..57f240b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_sequential_tf.c @@ -0,0 +1,177 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * PLIbook_ScientificALU_misctf, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Sequential logic version (outputs change on a clock edge). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + int clock, /* input */ + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine: turns on asynchronous callbacks to the misctf + * routine whenever an argument to the system task changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + tf_asynchon(); + return(0); +} + +/********************************************************************** + * misctf routine: Serves as an interface between Verilog simulation + * and the C model. Called whenever the C model inputs change value, + * ignores all changes except a positive edge of clock, on the positive + * edge of clock, reads the input values, and passes the values to the + * C model, and writes the C model outputs into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc) +{ + #define ALU_CLOCK 1 /* system task arg 1 is ALU clock input */ + #define ALU_A 2 /* system task arg 2 is ALU A input */ + #define ALU_B 3 /* system task arg 3 is ALU B input */ + #define ALU_OP 4 /* system task arg 4 is ALU opcode input */ + #define ALU_RESULT 5 /* system task arg 5 is ALU result output */ + #define ALU_EXCEPT 6 /* system task arg 6 is ALU exception output */ + #define ALU_ERROR 7 /* system task arg 7 is ALU error output */ + + double a, b, result; + int opcode, excep, err, clock; + + /* abort if misctf was not called for a task argument value change */ + if (reason != REASON_PARAMVC) + return(0); + + /* abort if task argument that changed was not the clock input */ + if (paramvc != ALU_CLOCK) + return(0); + + /* Read current values of C model inputs from Verilog simulation */ + clock = (int)tf_getp(ALU_CLOCK); + if (clock != 1) /* abort if not a positive edge of the clock input */ + return(0); + a = tf_getrealp(ALU_A); + b = tf_getrealp(ALU_B); + opcode = (int)tf_getp(ALU_OP); + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(clock, a, b, opcode, + &result, &excep, &err); + + /* Write the C model outputs onto the Verilog signals */ + tf_putrealp(ALU_RESULT, result); + tf_putp (ALU_EXCEPT, (PLI_INT32)excep); + tf_putp (ALU_ERROR, (PLI_INT32)err); + + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + if (tf_nump() != 7) + tf_error("$scientific_alu requires 7 arguments"); + else { + if (tf_typep(ALU_CLOCK) != TF_READONLY) + tf_error("$scientific_alu arg 1 must be a net\n"); + else if (tf_sizep(ALU_CLOCK) != 1) + tf_error("$scientific_alu arg 1 must be scalar\n"); + if (tf_typep(ALU_A) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + if (tf_typep(ALU_B) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 3 must be a real variable\n"); + if (tf_typep(ALU_OP) != TF_READONLY) + tf_error("$scientific_alu arg 4 must be a net\n"); + else if (tf_sizep(ALU_OP) != 4) + tf_error("$scientific_alu arg 4 must be a 4-bit vector\n"); + if (tf_typep(ALU_RESULT) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 5 must be a real variable\n"); + if (tf_typep(ALU_EXCEPT) != TF_READWRITE) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (tf_sizep(ALU_EXCEPT) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + if (tf_typep(ALU_ERROR) != TF_READWRITE) + tf_error("$scientific_alu arg 7 must be a reg\n"); + else if (tf_sizep(ALU_ERROR) != 1) + tf_error("$scientific_alu arg 7 must be scalar\n"); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_shell.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_shell.v new file mode 100644 index 0000000..cb7ccee --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_shell.v @@ -0,0 +1,39 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_test.log b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_test.log new file mode 100644 index 0000000..6a8d32d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result1=4.00 result2=0.00 excep=0 err=x a=16.0 b=2.0 opcode=1 +At 2 ns: result1=8886110.52 result2=0.00 excep=0 err=x a=16.0 b=2.0 opcode=2 +At 3 ns: result1=64.00 result2=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result1=16.00 result2=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result1=0.00 result2=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result1=16.00 result2=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result1=16.00 result2=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result1=2.77 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result1=1.20 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result1=-0.29 result2=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result1=-0.96 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result1=0.30 result2=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result1=0.00 result2=8886110.52 excep=0 err=x a=16.0 b=2.0 opcode=d +At 14 ns: result1=0.00 result2=4.00 excep=0 err=x a=16.0 b=2.0 opcode=e +At 15 ns: result1=1.51 result2=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_test.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_test.v new file mode 100644 index 0000000..183b1b9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_test.v @@ -0,0 +1,51 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_synchronized_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result1, result2; + wire [63:0] a_in, b_in, result_out1, result_out2; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out1) result1 = $bitstoreal(result_out1); + always @(result_out2) result2 = $bitstoreal(result_out2); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out1, excep, err); + scientific_alu i2 (a_in, b_in, ~opcode[3:0], result_out2, excep, err); + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: result1=%.2f \tresult2=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result1, result2, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_tf.c b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_tf.c new file mode 100644 index 0000000..95eaf42 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_synchronized_tf.c @@ -0,0 +1,185 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * PLIbook_ScientificALU_misctf, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (outputs change on an input change). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine: turns on asynchronous callbacks to the misctf + * routine whenever an argument to the system task changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + tf_asynchon(); + tf_setworkarea(NULL); /* set work area to null */ + return(0); +} + +/********************************************************************** + * misctf routine: Serves as an interface between Verilog simulation + * and the C model. The misctf routine performs different operations + * depending on the reason it is called: + * - For a value change callback: schedules a callback to the misctf + * application synchronized to the end of a time step. Only schedules + * one callback for a time step. + * - For a synchronize callback: reads the input values, and passes + * the values to the C model, and writes the C model outputs into + * simulation. + *********************************************************************/ +int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc) +{ + #define ALU_A 1 /* system task arg 1 is ALU A input */ + #define ALU_B 2 /* system task arg 2 is ALU B input */ + #define ALU_OP 3 /* system task arg 3 is ALU opcode input */ + #define ALU_RESULT 4 /* system task arg 4 is ALU result output */ + #define ALU_EXCEPT 5 /* system task arg 5 is ALU exception output */ + #define ALU_ERROR 6 /* system task arg 6 is ALU error output */ + + double a, b, result; + int opcode, excep, err; + + /* check if misctf was called for a task argument value change */ + if (reason == REASON_PARAMVC) { + /* abort if task argument that changed was a model output */ + if (paramvc > ALU_OP) /* model outputs are after model inputs */ + return(0); + + /* If the TF work area is null, then no misctf synchronize */ + /* callback has been scheduled for this time step (the work area */ + /* is set to non-null by this routine, and is set to null by the */ + /* misctf after a synchronize callback is processed. */ + if (tf_getworkarea() == NULL) { + /* Schedule a synchronize callback to misctf for this instance */ + tf_synchronize(); + tf_setworkarea("1"); /* set work area to non-null */ + } + return(0); + } + + /* check if misctf was called for end-of-time step synchronize */ + if (reason == REASON_SYNCH) { + /* Read current values of C model inputs from Verilog simulation */ + a = tf_getrealp(ALU_A); + b = tf_getrealp(ALU_B); + opcode = (int)tf_getp(ALU_OP); + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err); + + /* Write the C model outputs onto the Verilog signals */ + tf_putrealp(ALU_RESULT, result); + tf_putp (ALU_EXCEPT, (PLI_INT32)excep); + tf_putp (ALU_ERROR, (PLI_INT32)err); + tf_setworkarea(NULL); /* set work area to null */ + } + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + if (tf_nump() != 6) + tf_error("$scientific_alu requires 6 arguments"); + else { + if (tf_typep(ALU_A) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 1 must be a real variable\n"); + if (tf_typep(ALU_B) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + if (tf_typep(ALU_OP) != TF_READONLY) + tf_error("$scientific_alu arg 3 must be a net\n"); + else if (tf_sizep(ALU_OP) != 4) + tf_error("$scientific_alu arg 3 must be a 4-bit vector\n"); + if (tf_typep(ALU_RESULT) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 4 must be a real variable\n"); + if (tf_typep(ALU_EXCEPT) != TF_READWRITE) + tf_error("$scientific_alu arg 5 must be a reg\n"); + else if (tf_sizep(ALU_EXCEPT) != 1) + tf_error("$scientific_alu arg 5 must be scalar\n"); + if (tf_typep(ALU_ERROR) != TF_READWRITE) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (tf_sizep(ALU_ERROR) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_shell.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_shell.v new file mode 100644 index 0000000..865fb71 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_shell.v @@ -0,0 +1,76 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version with pin-to-pin + * path delays. The path delays are represented using a Verilog + * specify block. + * + * NOTES: + * - Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * - Some Verilog simulators require that path delays to be used with + * models where all ports are connected to uni-directional + * primitives with nets data types connected to the inputs an outputs + * of the primitives. This model satisfies this restriction by + * adding buffers to all input and output ports. + * + * - This shell module uses the array of instances from the IEEE 1364 + * Verilog standard. Some simulators do not support this construct, + * and may require using a separate instance statement for each bit + * of a vector. + * + * 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 / 100ps +module scientific_alu(a_in, b_in, opcode_in, + result_out, exception, error); + output [63:0] result_out; + output exception, error; + input [63:0] a_in, b_in; + input [3:0] opcode_in; + + wire [63:0] result_out, result_vector; + wire [63:0] a_in, a_vector; + wire [63:0] b_in, b_vector; + wire [3:0] opcode_in, opcode_vector; + wire exception, error; + + reg exception_reg, error_reg; + real a, b, result; // real variables used in this module + + // convert real numbers to/from 64-bit vector port connections + assign result_vector = $realtobits(result); + always @(a_vector) a = $bitstoreal(a_vector); + always @(b_vector) b = $bitstoreal(b_vector); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode_vector, + result, exception_reg, error_reg); + + specify + (a_in, b_in *> result_out, exception, error) = (5.6, 4.7); + (opcode_in *> result_out, exception, error) = (3.4, 3.8); + endspecify + + // add buffers to all ports, with nets connected to each buffer + // (this example uses the array of instance syntax in the + // from the IEEE 1364-1995 Verilog standard + buf result_buf[63:0] (result_out, result_vector); + buf excep_buf (exception, exception_reg); + buf error_buf (error, error_reg); + + buf a_buf[63:0] (a_vector, a_in); + buf b_buf[63:0] (b_vector, b_in); + buf opcode_buf[3:0] (opcode_vector, opcode_in); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_test.log new file mode 100644 index 0000000..f490720 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_test.log @@ -0,0 +1,46 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result=0.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 3 ns: result=256.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 4 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 10 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 14 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 20 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 23 ns: result=17772221.04 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 24 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 30 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 33 ns: result=17772221.04 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 34 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 40 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 43 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 44 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 50 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 54 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 60 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 63 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 70 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 80 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 83 ns: result=22.18 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 84 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 90 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 94 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 100 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 103 ns: result=-1.21 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 104 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 110 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 113 ns: result=-1.93 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 114 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 120 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 123 ns: result=-1.98 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 124 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 130 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 133 ns: result=0.30 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 134 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 140 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 150 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 153 ns: result=1.51 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 154 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 160 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 164 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 170 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_test.v new file mode 100644 index 0000000..0ef709e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_with_delays_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out, excep, err); + + initial + begin + $timeformat(-9,0," ns",7); + $monitor("At %t: result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #10 ; + + #10 $display("\n"); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_tf.c b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_tf.c new file mode 100644 index 0000000..f833962 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/sci_alu_with_delays_tf.c @@ -0,0 +1,166 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * PLIbook_ScientificALU_misctf, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (outputs change on an input change). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +/********************************************************************** + * calltf routine: turns on asynchronous callbacks to the misctf + * routine whenever an argument to the system task changes value. + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + tf_asynchon(); + return(0); +} + +/********************************************************************** + * misctf routine: Serves as an interface between Verilog simulation + * and the C model. Called whenever the C model inputs change value, + * reads the input values, and passes the values to the C model, and + * writes the C model outputs into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc) +{ + #define ALU_A 1 /* system task arg 1 is ALU A input */ + #define ALU_B 2 /* system task arg 2 is ALU B input */ + #define ALU_OP 3 /* system task arg 3 is ALU opcode input */ + #define ALU_RESULT 4 /* system task arg 4 is ALU result output */ + #define ALU_EXCEPT 5 /* system task arg 5 is ALU exception output */ + #define ALU_ERROR 6 /* system task arg 6 is ALU error output */ + + double a, b, result; + int opcode, excep, err; + + /* abort if misctf was not called for a task argument value change */ + if (reason != REASON_PARAMVC) + return(0); + + /* abort if task argument that changed was a model output */ + if (paramvc > ALU_OP) /* model outputs are after model inputs */ + return(0); + + /* Read current values of C model inputs from Verilog simulation */ + a = tf_getrealp(ALU_A); + b = tf_getrealp(ALU_B); + opcode = (int)tf_getp(ALU_OP); + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err); + + /* Write the C model outputs onto the Verilog signals */ + tf_putrealp(ALU_RESULT, result); + tf_putp (ALU_EXCEPT, (PLI_INT32)excep); + tf_putp (ALU_ERROR, (PLI_INT32)err); + + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + if (tf_nump() != 6) + tf_error("$scientific_alu requires 6 arguments"); + else { + if (tf_typep(ALU_A) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 1 must be a real variable\n"); + if (tf_typep(ALU_B) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + if (tf_typep(ALU_OP) != TF_READONLY) + tf_error("$scientific_alu arg 3 must be a net\n"); + else if (tf_sizep(ALU_OP) != 4) + tf_error("$scientific_alu arg 3 must be a 4-bit vector\n"); + if (tf_typep(ALU_RESULT) != TF_READWRITEREAL) + tf_error("$scientific_alu arg 4 must be a real variable\n"); + if (tf_typep(ALU_EXCEPT) != TF_READWRITE) + tf_error("$scientific_alu arg 5 must be a reg\n"); + else if (tf_sizep(ALU_EXCEPT) != 1) + tf_error("$scientific_alu arg 5 must be scalar\n"); + if (tf_typep(ALU_ERROR) != TF_READWRITE) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (tf_sizep(ALU_ERROR) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + } + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.13/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.13/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.13/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.13/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.13/veriuser_VCS.tab new file mode 100644 index 0000000..7e4a3b6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/veriuser_VCS.tab @@ -0,0 +1,5 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$scientific_alu data=0 check=PLIbook_ScientificALU_checktf call=PLIbook_ScientificALU_calltf +//$scientific_alu data=0 check=PLIbook_ScientificALU_checktf call=PLIbook_ScientificALU_calltf misc=PLIbook_ScientificALU_misctf diff --git a/me250300_pli/plibook_examples_unix/chapter.13/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.13/veriusertfs_table.h new file mode 100644 index 0000000..71e6877 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.13/veriusertfs_table.h @@ -0,0 +1,34 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_ScientificALU_checktf(int user_data, int reason); +extern int PLIbook_ScientificALU_calltf(int user_data, int reason); +/* extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int pvc); /* */ + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ScientificALU_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ScientificALU_calltf, /* calltf routine */ +/* PLIbook_ScientificALU_misctf, /* misctf routine */ + 0, /* NO misctf routine */ + "$scientific_alu", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.14/build_MTI.mak new file mode 100644 index 0000000..4ff7c8a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/build_MTI.mak @@ -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_acc.c \ + show_all_signals1_acc.c \ + show_all_signals2_acc.c \ + show_all_signals3_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.14/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.14/build_NC.mak new file mode 100644 index 0000000..b425f97 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/build_NC.mak @@ -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_acc.c \ + show_all_signals1_acc.c \ + show_all_signals2_acc.c \ + show_all_signals3_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.14/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.14/build_XL.mak new file mode 100644 index 0000000..7138d70 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/build_XL.mak @@ -0,0 +1,21 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + show_all_nets_acc.c \ + show_all_signals1_acc.c \ + show_all_signals2_acc.c \ + show_all_signals3_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_acc.c b/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_acc.c new file mode 100644 index 0000000..e237662 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_acc.c @@ -0,0 +1,74 @@ +/********************************************************************** + * $show_all_nets example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the names of all nets in + * the module with the current logic value. + * + * 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 + * + * Usage: $show_all_nets(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ShowNets_checktf(int user_data, int reason); + * extern int PLIbook_ShowNets_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ShowNets_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ShowNets_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$show_all_nets", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ShowNets_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$show_all_nets must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$show_all_nets arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$show_all_nets arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ShowNets_calltf(int user_data, int reason) +{ + handle module_handle, net_handle; + acc_initialize(); + module_handle = acc_handle_tfarg(1); + io_printf("\nAt time %s, nets in module %s (%s):\n", + tf_strgettime(), + acc_fetch_fullname(module_handle), + acc_fetch_defname(module_handle)); + net_handle = null; /* start with known value for target handle */ + while (net_handle=acc_next_net(module_handle,net_handle)) { + io_printf(" %-13s %-13s value is %s (hex)\n", + acc_fetch_type_str(acc_fetch_fulltype(net_handle)), + acc_fetch_name(net_handle), + acc_fetch_value(net_handle, "%h", null)); + } + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_test.log b/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_test.log new file mode 100644 index 0000000..840a5e4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_test.log @@ -0,0 +1,15 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At time 20, nets in module top (top): + accTri results value is 1 (hex) + +At time 30, nets in module top.i1 (addbit): + accWire a value is 1 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accWire sum value is 1 (hex) + accWire co value is 0 (hex) + accWire n1 value is 1 (hex) + accWire n2 value is 0 (hex) + accWire n3 value is 0 (hex) +Simulation stopped via $stop(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_test.v b/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_test.v new file mode 100644 index 0000000..2f37709 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_nets_test.v @@ -0,0 +1,49 @@ +/********************************************************************** + * $show_all_nets example -- Verilog test bench source code + * + * Verilog test bench to test the $show_all_nets 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 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'b001; + + #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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_acc.c b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_acc.c new file mode 100644 index 0000000..a1cebdc --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_acc.c @@ -0,0 +1,76 @@ +/********************************************************************** + * $show_all_signals example -- C source code using TF/ACC PLI routines + * + * C source to scan through a module and list the names of all nets, + * regs and variables in the module with the current logic value. + * + * 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 + * + * Usage: $show_all_nets(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ShowSignals1_checktf(int user_data, int reason); + * extern int PLIbook_ShowSignals1_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ShowSignals1_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ShowSignals1_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$show_all_signals1", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ShowSignals1_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$show_all_signals must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$show_all_signals arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$show_all_signals arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ShowSignals1_calltf(int user_data, int reason) +{ + handle module_h, signal_h; + static PLI_INT32 signal_types[6] = {accNet, accReg, accIntegerVar, + accTimeVar, accRealVar, 0 }; + acc_initialize(); + module_h = acc_handle_tfarg(1); + io_printf("\nAt time %s, signals in module %s (%s):\n", + tf_strgettime(), + acc_fetch_fullname(module_h), + acc_fetch_defname(module_h)); + signal_h = null; /* start with known value for target handle */ + while (signal_h = acc_next(signal_types, module_h, signal_h)) { + io_printf(" %-13s %-13s value is %s (hex)\n", + acc_fetch_type_str(acc_fetch_fulltype(signal_h)), + acc_fetch_name(signal_h), + acc_fetch_value(signal_h, "%h", null)); + } + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_test.log b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_test.log new file mode 100644 index 0000000..5041582 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_test.log @@ -0,0 +1,13 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At time 20, signals in module top (top): + accTri results value is 1 (hex) + accIntegerVar test value is 00000001 (hex) + +At time 30, signals in module top.i1 (addbit): + accWire a value is 1 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 1 (hex) + accRegister co value is 0 (hex) +Simulation stopped via $stop(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_test.v b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_test.v new file mode 100644 index 0000000..413b4ef --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals1_test.v @@ -0,0 +1,47 @@ +/********************************************************************** + * $show_all_signals example -- Verilog test bench source code + * + * Verilog test bench to test the $show_all_signals PLI application on + * a 1-bit adder modeled using RTL code. + * + * 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_signals1(top); + #10 $show_all_signals1(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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_acc.c b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_acc.c new file mode 100644 index 0000000..85c429d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_acc.c @@ -0,0 +1,85 @@ +/********************************************************************** + * $show_all_signals example -- C source code using TF/ACC PLI routines + * + * C source to scan through a module and list the names of all nets, + * regs and variables in the module with the current logic value. A + * null argument or no argument is interpreted as the current module. + * + * 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 + * + * Usage: $show_all_nets(?); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ShowSignals2_checktf(int user_data, int reason); + * extern int PLIbook_ShowSignals2_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ShowSignals2_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ShowSignals2_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$show_all_signals2", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ShowSignals2_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() == 0) + return(0); /* no arguments is OK, skip remaining checks */ + if (tf_nump() > 1) + tf_error("$show_all_signals must have 0 or 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + return(0); /* null argument is OK, skip remaining checks */ + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$show_all_signals arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ShowSignals2_calltf(int user_data, int reason) +{ + handle module_h, signal_h; + static PLI_INT32 signal_types[6] = {accNet, accReg, accIntegerVar, + accTimeVar, accRealVar, 0 }; + acc_initialize(); + if (tf_nump() == 0) + module_h = acc_handle_scope(acc_handle_tfinst()); + + else if (tf_typep(1) == tf_nullparam) + module_h = acc_handle_scope(acc_handle_tfinst()); + else + module_h = acc_handle_tfarg(1); + io_printf("\nAt time %s, signals in module %s (%s):\n", + tf_strgettime(), + acc_fetch_fullname(module_h), + acc_fetch_defname(module_h)); + signal_h = null; /* start with known value for target handle */ + while (signal_h = acc_next(signal_types, module_h, signal_h)) { + io_printf(" %-13s %-13s value is %s (hex)\n", + acc_fetch_type_str(acc_fetch_fulltype(signal_h)), + acc_fetch_name(signal_h), + acc_fetch_value(signal_h, "%h", null)); + } + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_test.log b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_test.log new file mode 100644 index 0000000..2679a45 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_test.log @@ -0,0 +1,27 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At time 0, signals in module top.i1 (addbit): + accWire a value is 0 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 0 (hex) + accRegister co value is 0 (hex) + +At time 10, signals in module top.i1 (addbit): + accWire a value is 1 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 1 (hex) + accRegister co value is 0 (hex) + +At time 20, signals in module top (top): + accTri results value is 1 (hex) + accIntegerVar test value is 00000001 (hex) + +At time 30, signals in module top.i1 (addbit): + accWire a value is 1 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 1 (hex) + accRegister co value is 0 (hex) +Simulation complete via $finish(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_test.v b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_test.v new file mode 100644 index 0000000..530cfb0 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals2_test.v @@ -0,0 +1,49 @@ +/********************************************************************** + * $show_all_signals example -- Verilog test bench source code + * + * Verilog test bench to test the $show_all_signals PLI application on + * a 1-bit adder modeled using RTL code. + * + * 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_signals2(); + #10 $show_all_signals2(top.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; + + always @(sum) + $show_all_signals2; + +endmodule +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_acc.c b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_acc.c new file mode 100644 index 0000000..fae1f3f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_acc.c @@ -0,0 +1,104 @@ +/********************************************************************** + * $show_all_signals example -- C source code using TF/ACC PLI routines + * + * C source to scan through a module and list the names of all nets, + * regs and variables in the module with the current logic value. A + * null argument or no argument is interpreted as the current module. + * Multiple hierarchy levels can be listed as system task 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 + * + * Usage: $show_all_nets(?, ?, ...); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ShowSignals3_checktf(int user_data, int reason), + * extern int PLIbook_ShowSignals3_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ShowSignals3_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ShowSignals3_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$show_all_signals3", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ShowSignals3_checktf(int user_data, int reason) +{ + int i, numargs; + + acc_initialize(); + numargs = (int)tf_nump(); + if (numargs == 0) + return(0); /* no arguments is OK, skip remaining checks */ + for (i = 1; i <= numargs; i++) { + if (tf_typep(i) == TF_NULLPARAM) + break; /* null argument is OK, skip other checks for this arg */ + else if (acc_fetch_type(acc_handle_tfarg(i)) != accModule) + tf_error("$show_all_signals arg must be a module instance."); + } + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +void PLIbook_GetAllSignals(); /* prototype function used by calltf */ + +int PLIbook_ShowSignals3_calltf(int user_data, int reason) +{ + handle module_h; + int i, numargs; + acc_initialize(); + numargs = (int)tf_nump(); + if (numargs == 0) { + module_h = acc_handle_scope(acc_handle_tfinst()); + PLIbook_GetAllSignals(module_h); + } + else + for (i = 1; i <= numargs; i++) { + if (tf_typep(i) == tf_nullparam) + module_h = acc_handle_scope(acc_handle_tfinst()); + else + module_h = acc_handle_tfarg(i); + PLIbook_GetAllSignals(module_h); + } + acc_close(); + return(0); +} + +void PLIbook_GetAllSignals(handle module_h) +{ + handle signal_h; + static PLI_INT32 signal_types[6] = {accNet, accReg, accIntegerVar, + accTimeVar, accRealVar, 0 }; + io_printf("\nAt time %s, signals in module %s (%s):\n", + tf_strgettime(), + acc_fetch_fullname(module_h), + acc_fetch_defname(module_h)); + signal_h = null; /* start with known value for target handle */ + while (signal_h = acc_next(signal_types, module_h, signal_h)) { + io_printf(" %-13s %-13s value is %s (hex)\n", + acc_fetch_type_str(acc_fetch_fulltype(signal_h)), + acc_fetch_name(signal_h), + acc_fetch_value(signal_h, "%h", null)); + } + return; +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_test.log b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_test.log new file mode 100644 index 0000000..af8bb40 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_test.log @@ -0,0 +1,27 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At time 0, signals in module top.i1 (addbit): + accWire a value is 0 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 0 (hex) + accRegister co value is 0 (hex) + +At time 10, signals in module top.i1 (addbit): + accWire a value is 1 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 1 (hex) + accRegister co value is 0 (hex) + +At time 20, signals in module top.i1 (addbit): + accWire a value is 1 (hex) + accWire b value is 0 (hex) + accWire ci value is 0 (hex) + accRegister sum value is 1 (hex) + accRegister co value is 0 (hex) + +At time 20, signals in module top (top): + accTri results value is 1 (hex) + accIntegerVar test value is 00000001 (hex) +Simulation complete via $finish(1) at time 30 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_test.v b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_test.v new file mode 100644 index 0000000..3ef6ea4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/show_all_signals3_test.v @@ -0,0 +1,49 @@ +/********************************************************************** + * $show_all_signals example -- Verilog test bench source code + * + * Verilog test bench to test the $show_all_signals PLI application on + * a 1-bit adder modeled using RTL code. + * + * 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_signals3(top.i1, ); /* 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_signals3; + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.14/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.14/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.14/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.14/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.14/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.14/veriuser_VCS.tab new file mode 100644 index 0000000..db31bf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/veriuser_VCS.tab @@ -0,0 +1,7 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$show_all_nets data=0 check=PLIbook_ShowNets_checktf call=PLIbook_ShowNets_calltf acc+=read:* +$show_all_signals1 data=0 check=PLIbook_ShowSignals1_checktf call=PLIbook_ShowSignals1_calltf acc+=read:* +$show_all_signals2 data=0 check=PLIbook_ShowSignals2_checktf call=PLIbook_ShowSignals2_calltf acc+=read:* +$show_all_signals3 data=0 check=PLIbook_ShowSignals3_checktf call=PLIbook_ShowSignals3_calltf acc+=read:* diff --git a/me250300_pli/plibook_examples_unix/chapter.14/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.14/veriusertfs_table.h new file mode 100644 index 0000000..429d558 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.14/veriusertfs_table.h @@ -0,0 +1,71 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_ShowNets_checktf(int user_data, int reason); +extern int PLIbook_ShowNets_calltf(int user_data, int reason); + +extern int PLIbook_ShowSignals1_checktf(int user_data, int reason); +extern int PLIbook_ShowSignals1_calltf(int user_data, int reason); + +extern int PLIbook_ShowSignals2_checktf(int user_data, int reason); +extern int PLIbook_ShowSignals2_calltf(int user_data, int reason); + +extern int PLIbook_ShowSignals3_checktf(int user_data, int reason); +extern int PLIbook_ShowSignals3_calltf(int user_data, int reason); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ShowNets_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ShowNets_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$show_all_nets", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ShowSignals1_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ShowSignals1_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$show_all_signals1", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ShowSignals2_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ShowSignals2_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$show_all_signals2", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ShowSignals3_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ShowSignals3_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$show_all_signals3", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.15/build_MTI.mak new file mode 100644 index 0000000..6b41d92 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/build_MTI.mak @@ -0,0 +1,22 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = \ + list_pathout_ports_acc.c \ + port_info_acc.c \ + list_cells_acc.c \ + count_loads_acc.c \ + display_all_nets_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.15/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.15/build_NC.mak new file mode 100644 index 0000000..0bc5c6a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/build_NC.mak @@ -0,0 +1,22 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = \ + list_pathout_ports_acc.c \ + port_info_acc.c \ + list_cells_acc.c \ + count_loads_acc.c \ + display_all_nets_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.15/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.15/build_XL.mak new file mode 100644 index 0000000..d83cca9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/build_XL.mak @@ -0,0 +1,22 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + list_pathout_ports_acc.c \ + port_info_acc.c \ + list_cells_acc.c \ + count_loads_acc.c \ + display_all_nets_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.15/count_loads_acc.c b/me250300_pli/plibook_examples_unix/chapter.15/count_loads_acc.c new file mode 100644 index 0000000..4e8ea5d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/count_loads_acc.c @@ -0,0 +1,104 @@ +/********************************************************************** + * $count_loads example -- C source code using ACC PLI routines + * + * C source to count the number of loads on an output port and return + * the count back to simulation. + * + * 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 + * + * Usage: count = $count_loads(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_CountLoads_checktf(int user_data, int reason); + * extern int PLIbook_CountLoads_sizetf(int user_data, int reason); + * extern int PLIbook_CountLoads_calltf(int user_data, int reason, int pvc); + * /* table entries -/ + * {userfunction, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_CountLoads_checktf, /* checktf routine -/ + * PLIbook_CountLoads_sizetf, /* sizetf routine -/ + * PLIbook_CountLoads_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$count_loads", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * Sizetf application + *********************************************************************/ +int PLIbook_CountLoads_sizetf(int user_data, int reason) +{ + return(32); /* $count_loads returns a 32-bit integer value */ +} + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_CountLoads_checktf(int user_data, int reason) +{ + static PLI_INT32 valid_args[4] = {accNet, accReg, accRegBit, 0}; + PLI_INT32 direction; + handle tfarg_h, port_h; + + acc_initialize(); + if (tf_nump() != 1) + tf_error("$count_loads must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$count_loads arg cannot be null."); + /* acc_handle_tfarg() returns a loconn handle, not a port handle */ + else if (tf_sizep(1) != 1) + tf_error("$count_loads arg must be scalar or a bit-select."); + else { + tfarg_h = acc_handle_tfarg(1); + if (!acc_object_in_typelist(tfarg_h, valid_args)) { + tf_error("$count_loads arg must be a net or reg signal"); + return(0); + } + port_h = acc_next_port(tfarg_h, null); + if (port_h == null) { + tf_error("$count_loads arg is not connected to a module port."); + return(0); + } + direction = acc_fetch_direction(port_h); + if ( direction != accOutput + && direction != accInout) + tf_error("$count_loads arg must be an output or inout port."); + } + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_CountLoads_calltf(int user_data, int reason) +{ + handle loconn_h, port_h, hiconn_h; + int load_count; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + /* acc_handle_tfarg() may return loconn handle, not port handle */ + loconn_h = acc_handle_tfarg(1); + if (acc_fetch_type(loconn_h) == accPort) + port_h = loconn_h; + else + port_h = acc_next_port(loconn_h, null); + hiconn_h = acc_handle_hiconn(port_h); + load_count = acc_count(acc_next_cell_load, hiconn_h); + tf_putp(0, load_count); + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.15/count_loads_test.log b/me250300_pli/plibook_examples_unix/chapter.15/count_loads_test.log new file mode 100644 index 0000000..74bf9c8 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/count_loads_test.log @@ -0,0 +1,7 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +loads on i1.a1.sum = 2 + +loads on i1.a2.r1 = 1 + +Simulation complete via $finish(1) at time 1 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.15/count_loads_test.v b/me250300_pli/plibook_examples_unix/chapter.15/count_loads_test.v new file mode 100644 index 0000000..c010da4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/count_loads_test.v @@ -0,0 +1,148 @@ +/********************************************************************** + * $count_loads example -- Verilog test bench source code + * + * Verilog test bench to test the $count_loads 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 + *********************************************************************/ + +/********************************************************************** + * Top-level test bench module for a 4-bit adder model. + *********************************************************************/ +`timescale 1ns / 1ns +module test; + reg [3:0] a, b; + wire [3:0] sum; + reg ci; + wire co; + + add4 i1 (a, b, ci, sum, co); + + initial + begin + $display("loads on i1.a1.sum = %d\n", $count_loads(i1.a1.sum)); + $display("loads on i1.a2.r1 = %d\n", $count_loads(i1.a2.r1)); + #1 $finish; + end +endmodule + +/********************************************************************** + * 4-bit adder model, using a 1-bit adder model. + *********************************************************************/ +`timescale 1ns / 1ns +module add4 (a, b, ci, sum, co); + input [3:0] a, b; + input ci; + output [3:0] sum; + output co; + + wire [3:0] a, b, sum; + wire ci, co, co1, co2, co3; + wire n1, n2, n3, n4, n5, n6, n7, n8, n9; + + addbit a1 (a[0], b[0], ci, sum[0], co1, n1); + addbit a2 (a[1], b[1], co1, sum[1], co2, n2); + addbit a3 (a[2], b[2], co2, sum[2], co3, n3); + addbit a4 (a[3], b[3], co3, sum[3], co , n4); + + and2 a5 (n5, sum[0], sum[1]); + xor2 a6 (n6, sum[0], co); + or2 a7 (n7, n1, n2); + or2 a8 (n8, n3, n4); + and2 a9 (n9, n7, n8); +endmodule + +/********************************************************************** + * 1-bit adder model, using cells from a library. + *********************************************************************/ +`timescale 1ns / 1ns +module addbit (a, b, ci, sum, co, r1); + input a, b, ci; + output sum, co; + output r1; + + wire a, b, ci, sum, co, n1, n2, n3; + reg r1; + + xor2 u1 (n1, a, b); + xor2 u2 (sum, n1, ci); + and2 u3 (n2, a, b); + and2 u4 (n3, n1, ci); + or2 u5 (co, n2, n3); + +endmodule +/********************************************************************** +* Cell library + *********************************************************************/ +`resetall +`celldefine +`timescale 1ns / 10ps +module or2 (y, a, b); + output y; + input a, b; + wire y, a, b; //wire data type for cmos + or (y, a, b); + specify + (a *> y) = 1.0; + (b *> y) = 1.0; + specparam BaseDelay$ = 2.5; + specparam InputLoad$a = 0.3; + specparam InputLoad$b = 0.3; + specparam InputLoad$c = 0.3; + specparam in_cap_pf$a = 0.02; + specparam in_cap_pf$b = 0.02; + specparam in_cap_pf$c = 0.02; + specparam out_cap_pf$ = 0.05; + endspecify +endmodule +`endcelldefine +/*********************************************************************/ +`resetall +`celldefine +`timescale 1ns / 10ps +module xor2 (y, a, b); + output y; + input a, b; + wire y, a, b; //wire data type for cmos + xor (y, a, b); + specify + (a *> y) = 1.0; + (b *> y) = 1.0; + specparam BaseDelay$ = 2.5; + specparam InputLoad$a = 0.3; + specparam InputLoad$b = 0.3; + specparam InputLoad$c = 0.3; + specparam in_cap_pf$a = 0.02; + specparam in_cap_pf$b = 0.02; + specparam in_cap_pf$c = 0.02; + specparam out_cap_pf$ = 0.05; + endspecify +endmodule +`endcelldefine +/*********************************************************************/ +`resetall +`celldefine +`timescale 1 ns / 10 ps +module and2 (y, a, b); + output y; + input a, b; + wire y, a, b; //wire data type for cmos + and (y, a, b); + specify + (a *> y) = 1.0; + (b *> y) = 1.0; + specparam BaseDelay$ = 2.5; + specparam InputLoad$a = 0.2; + specparam InputLoad$b = 0.2; + specparam in_cap_pf$a = 0.02; + specparam in_cap_pf$b = 0.02; + specparam out_cap_pf$ = 0.05; + endspecify +endmodule +`endcelldefine +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_acc.c b/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_acc.c new file mode 100644 index 0000000..e1c3066 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_acc.c @@ -0,0 +1,123 @@ +/********************************************************************** + * $display_all_nets example -- C source code using TF/ACC PLI routines + * + * C source to scan through a module and list the names of all nets in + * the module with the current logic value. For run-time performance, + * the handles for all nets are collected once at the start of + * simulation, and the list of handles used in each call to the + * 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 + * + * Usage: $display_all_nets(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_DisplayNets_checktf(int user_data, int reason); + * extern int PLIbook_DisplayNets_calltf(int user_data, int reason); + * extern int PLIbook_DisplayNets_misctf(int user_data, int reason, int pvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_DisplayNets_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_DisplayNets_calltf, /* calltf routine -/ + * PLIbook_DisplayNets_misctf, /* misctf routine -/ + * "$display_all_nets", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * structure definition for data to be passed from misctf to calltf + *********************************************************************/ +typedef struct PLIbook_NetData { + handle module_h; + handle *net_array; + int net_count; +} PLIbook_NetData_s, *PLIbook_NetData_p; + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_DisplayNets_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$display_all_nets must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$display_all_nets arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$display_all_nets arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * misctf routine + *********************************************************************/ +int PLIbook_DisplayNets_misctf(int user_data, int reason, int paramvc) +{ + PLIbook_NetData_p net_data; + handle mod_h; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + switch (reason) { + case REASON_ENDOFCOMPILE: + acc_initialize(); + net_data = (PLIbook_NetData_p)malloc(sizeof(PLIbook_NetData_s)); + net_data->module_h = acc_handle_tfarg(1); + net_data->net_array = acc_collect(acc_next_net, + net_data->module_h, + &net_data->net_count); + io_printf("Total nets collected in misctf routine = %d\n", + net_data->net_count); + tf_setworkarea((PLI_BYTE8 *)net_data); + break; + case REASON_FINISH: + net_data = (PLIbook_NetData_p)tf_getworkarea(); + acc_free(net_data->net_array); + break; + } + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_DisplayNets_calltf(int user_data, int reason) +{ + PLIbook_NetData_p net_data; + int i; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + net_data = (PLIbook_NetData_p)tf_getworkarea(); + + io_printf("\nAt time %s, nets in module %s (%s):\n", + tf_strgettime(), + acc_fetch_fullname(net_data->module_h), + acc_fetch_defname(net_data->module_h)); + for (i=0; inet_count; i++) { + io_printf(" %-13s value is %s (hex)\n", + acc_fetch_name(net_data->net_array[i]), + acc_fetch_value(net_data->net_array[i], "%h", null)); + } + + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_test.log b/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_test.log new file mode 100644 index 0000000..3e3bbef --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_test.log @@ -0,0 +1,32 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At time 5, nets in module top.i1 (addbit): + a value is 0 (hex) + b value is 0 (hex) + ci value is 0 (hex) + sum value is 0 (hex) + co value is 0 (hex) + n1 value is 0 (hex) + n2 value is 0 (hex) + n3 value is 0 (hex) + +At time 15, nets in module top.i1 (addbit): + a value is 1 (hex) + b value is 0 (hex) + ci value is 0 (hex) + sum value is 1 (hex) + co value is 0 (hex) + n1 value is 1 (hex) + n2 value is 0 (hex) + n3 value is 0 (hex) + +At time 25, nets in module top.i1 (addbit): + a value is 1 (hex) + b value is 1 (hex) + ci value is 0 (hex) + sum value is 0 (hex) + co value is 1 (hex) + n1 value is 0 (hex) + n2 value is 1 (hex) + n3 value is 0 (hex) +Simulation complete via $finish(1) at time 30 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_test.v b/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_test.v new file mode 100644 index 0000000..08a5d1d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/display_all_nets_test.v @@ -0,0 +1,55 @@ +/********************************************************************** + * $display_all_nets example -- Verilog test bench source code + * + * Verilog test bench to test the $display_all_nets 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 top; + reg [2:0] test; + reg clock; + wire [1:0] results; + + addbit i1 (test[0], test[1], test[2], results[0], results[1]); + + always @(negedge clock) + $display_all_nets(i1); + + initial + begin + clock = 1; + forever #5 clock = ~clock; + end + + initial + begin + test = 3'b000; + @(posedge clock) test = 3'b001; + @(posedge clock) test = 3'b011; + @(posedge clock) $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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/list_cells_acc.c b/me250300_pli/plibook_examples_unix/chapter.15/list_cells_acc.c new file mode 100644 index 0000000..427a9f7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/list_cells_acc.c @@ -0,0 +1,76 @@ +/********************************************************************** + * $list_cells example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the names of all cells + * in the module. + * + * 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 + * + * Usage: $list_cells(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ListCells_checktf(int user_data, int reason); + * extern int PLIbook_ListCells_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ListCells_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ListCells_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$list_cells", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ListCells_checktf() +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$list_cells must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_cells arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_cells arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ListCells_calltf() +{ + handle mod_h, cell_h; + int cell_cnt = 0; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + mod_h = acc_handle_tfarg(1); + io_printf("\nCells in Module %s, instance %s:\n", + acc_fetch_defname(mod_h), acc_fetch_fullname(mod_h)); + cell_h = null; /* start with null (no cells found yet) */ + while (cell_h = acc_next_cell(mod_h,cell_h)) { + io_printf(" %s (%s)\n", + acc_fetch_fullname(cell_h), acc_fetch_defname(cell_h)); + cell_cnt++; + } + io_printf("Total cells in this hierarchy tree = %d\n\n", cell_cnt); + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/list_cells_test.log b/me250300_pli/plibook_examples_unix/chapter.15/list_cells_test.log new file mode 100644 index 0000000..d43696b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/list_cells_test.log @@ -0,0 +1,26 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Cells in Module add4, instance test.i1: + test.i1.a1.u1 (xor2) + test.i1.a1.u2 (xor2) + test.i1.a1.u3 (and2) + test.i1.a1.u4 (and2) + test.i1.a1.u5 (or2) + test.i1.a2.u1 (xor2) + test.i1.a2.u2 (xor2) + test.i1.a2.u3 (and2) + test.i1.a2.u4 (and2) + test.i1.a2.u5 (or2) + test.i1.a3.u1 (xor2) + test.i1.a3.u2 (xor2) + test.i1.a3.u3 (and2) + test.i1.a3.u4 (and2) + test.i1.a3.u5 (or2) + test.i1.a4.u1 (xor2) + test.i1.a4.u2 (xor2) + test.i1.a4.u3 (and2) + test.i1.a4.u4 (and2) + test.i1.a4.u5 (or2) +Total cells in this hierarchy tree = 20 + +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.15/list_cells_test.v b/me250300_pli/plibook_examples_unix/chapter.15/list_cells_test.v new file mode 100644 index 0000000..642ced4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/list_cells_test.v @@ -0,0 +1,140 @@ +/********************************************************************** + * $list_cells example -- Verilog test bench source code + * + * Verilog test bench to test the $list_cells 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 + *********************************************************************/ + +/********************************************************************** + * Top-level test bench module for a 4-bit adder model. + *********************************************************************/ +`timescale 1ns / 1ns +module test; + reg [3:0] a, b; + wire [3:0] sum; + reg ci; + wire co; + + add4 i1 (a, b, ci, sum, co); + + initial + begin + #1 $list_cells(i1); + #1 $finish; + end +endmodule + +/********************************************************************** + * 4-bit adder model, using a 1-bit adder model. + *********************************************************************/ +`timescale 1ns / 1ns +module add4 (a, b, ci, sum, co); + input [3:0] a, b; + input ci; + output [3:0] sum; + output co; + + wire [3:0] a, b, sum; + wire ci, co, co1, co2, co3; + + addbit a1 (a[0], b[0], ci, sum[0], co1); + addbit a2 (a[1], b[1], co1, sum[1], co2); + addbit a3 (a[2], b[2], co2, sum[2], co3); + addbit a4 (a[3], b[3], co3, sum[3], co ); + +endmodule + +/********************************************************************** + * 1-bit adder model, using cells from a library. + *********************************************************************/ +`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; + + xor2 u1 (n1, a, b); + xor2 u2 (sum, n1, ci); + and2 u3 (n2, a, b); + and2 u4 (n3, n1, ci); + or2 u5 (co, n2, n3); + +endmodule +/********************************************************************** +* Cell library + *********************************************************************/ +`resetall +`celldefine +`timescale 1ns / 10ps +module or2 (y, a, b); + output y; + input a, b; + wire y, a, b; //wire data type for cmos + or (y, a, b); + specify + (a *> y) = 1.0; + (b *> y) = 1.0; + specparam BaseDelay$ = 2.5; + specparam InputLoad$a = 0.3; + specparam InputLoad$b = 0.3; + specparam InputLoad$c = 0.3; + specparam in_cap_pf$a = 0.02; + specparam in_cap_pf$b = 0.02; + specparam in_cap_pf$c = 0.02; + specparam out_cap_pf$ = 0.05; + endspecify +endmodule +`endcelldefine +/*********************************************************************/ +`resetall +`celldefine +`timescale 1ns / 10ps +module xor2 (y, a, b); + output y; + input a, b; + wire y, a, b; //wire data type for cmos + xor (y, a, b); + specify + (a *> y) = 1.0; + (b *> y) = 1.0; + specparam BaseDelay$ = 2.5; + specparam InputLoad$a = 0.3; + specparam InputLoad$b = 0.3; + specparam InputLoad$c = 0.3; + specparam in_cap_pf$a = 0.02; + specparam in_cap_pf$b = 0.02; + specparam in_cap_pf$c = 0.02; + specparam out_cap_pf$ = 0.05; + endspecify +endmodule +`endcelldefine +/*********************************************************************/ +`resetall +`celldefine +`timescale 1 ns / 10 ps +module and2 (y, a, b); + output y; + input a, b; + wire y, a, b; //wire data type for cmos + and (y, a, b); + specify + (a *> y) = 1.0; + (b *> y) = 1.0; + specparam BaseDelay$ = 2.5; + specparam InputLoad$a = 0.2; + specparam InputLoad$b = 0.2; + specparam in_cap_pf$a = 0.02; + specparam in_cap_pf$b = 0.02; + specparam out_cap_pf$ = 0.05; + endspecify +endmodule +`endcelldefine +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_acc.c b/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_acc.c new file mode 100644 index 0000000..66b0c46 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_acc.c @@ -0,0 +1,78 @@ +/********************************************************************** + * $list_pathout_ports example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the names of all output + * ports which are also connected to a pin-to-pin path delay within + * the module. + * + * 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 + * + * Usage: $list_pathout_ports(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ListPorts_checktf(int user_data, int reason); + * extern int PLIbook_ListPorts_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ListPorts_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ListPorts_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$list_pathout_ports", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ListPorts_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$list_pathout_ports must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_pathout_ports arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_pathout_ports arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ListPorts_calltf(int user_data, int reason) +{ + handle module_h, modpath_h, pathterm_h, net_h, port_h; + + acc_initialize(); + + module_h = acc_handle_tfarg(1); + io_printf("\nOutput ports with path delays in module %s:\n", + acc_fetch_defname(module_h)); + + modpath_h = pathterm_h = net_h = port_h = null; + while (modpath_h = acc_next_modpath(module_h, modpath_h)) { + while (pathterm_h = acc_next_output(modpath_h, pathterm_h)) { + net_h = acc_handle_conn(pathterm_h); + while (port_h = acc_next_port(net_h, port_h)) { + io_printf(" Port %s\n", acc_fetch_name(port_h)); + } + } + } + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_test.log b/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_test.log new file mode 100644 index 0000000..328e4a1 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_test.log @@ -0,0 +1,15 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0: a=0 b=0 ci=0 sum=x co=x +At 2: a=0 b=0 ci=0 sum=0 co=x +At 3: a=0 b=0 ci=0 sum=0 co=0 +At 10: a=1 b=0 ci=0 sum=0 co=0 +At 12: a=1 b=0 ci=0 sum=1 co=0 +At 20: a=1 b=1 ci=0 sum=1 co=0 +At 22: a=1 b=1 ci=0 sum=0 co=0 +At 23: a=1 b=1 ci=0 sum=0 co=1 + +Output ports with path delays in module addbit: + Port sum + Port co +Simulation complete via $finish(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_test.v b/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_test.v new file mode 100644 index 0000000..e19d1ff --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/list_pathout_ports_test.v @@ -0,0 +1,58 @@ +/********************************************************************** + * $list_pathout_ports example -- Verilog test bench source code + * + * Verilog test bench to test the $list_pathout_ports 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 a, b, ci, clk; + wire sum, co, foo; + + addbit i1 (a, b, ci, sum, co, foo); + + 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; + + #10 $list_pathout_ports(i1); + + #10 $finish; + end +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 1ns +module addbit (a, b, ci, sum, co, foo); + input a, b, ci; + output sum, co, foo; + + wire a, b, ci, sum, co, foo, + n1, n2, n3; + + xor (n1, a, b); + xor (sum, n1, ci); + and (n2, a, b); + and (n3, n1, ci); + or (co, n2, n3); + + specify + (a,b,ci => sum) = 2; + (a,b,ci => co) = 3; + endspecify + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/port_info_acc.c b/me250300_pli/plibook_examples_unix/chapter.15/port_info_acc.c new file mode 100644 index 0000000..53a0520 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/port_info_acc.c @@ -0,0 +1,127 @@ +/********************************************************************** + * $port_info example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the names of all ports, + * along with the vector size of the port and the type of signals + * connected internally and externally to the port. + * + * 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 + * + * Usage: $port_info(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_PortInfo_checktf(int user_data, int reason); + * extern int PLIbook_PortInfo_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_PortInfo_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_PortInfo_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$port_info", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_PortInfo_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$port_info requires 1 argument"); + if (tf_typep(1) == TF_NULLPARAM) + tf_error("$port_info arg cannot be null"); + if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$port_info arg must be a module instance"); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_PortInfo_calltf(int user_data, int reason) +{ + handle mod_h, port_h, loconn_h, hiconn_h; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + mod_h = acc_handle_tfarg(1); + + io_printf("\nModule %s:\n", acc_fetch_defname(mod_h)); + io_printf(" Instance name: %s\n", acc_fetch_fullname(mod_h)); + + switch ( acc_fetch_fulltype(mod_h) ) { + case accTopModule: + io_printf(" Module type: top-level\n"); + break; + case accModuleInstance: + io_printf(" Module type: module instance\n"); + break; + case accCellInstance: + io_printf(" Module type: cell module\n"); + break; + default: + io_printf(" Module type: unknown\n"); + } + + io_printf(" Ports:\n"); + port_h = null; + while (port_h = acc_next_port(mod_h, port_h)) { + io_printf(" %-8s", acc_fetch_name(port_h) ); + io_printf("%2d-bit ", acc_fetch_size(port_h) ); + switch ( acc_fetch_direction(port_h) ) { + case accInput: + io_printf("input "); + break; + case accOutput: + io_printf("output "); + break; + case accInout: + io_printf("inout "); + break; + case accMixedIo: + io_printf("mixed input/output "); + break; + default: + io_printf("unknown direction "); + } + + if (acc_object_of_type(port_h, accExpandedVector)) + io_printf(" Expanded=true "); + else + io_printf(" Expanded=false "); + if (acc_object_of_type(port_h, accUnExpandedVector)) + io_printf(" Unexpanded=true\n"); + else + io_printf(" Unexpanded=false\n"); + + loconn_h = acc_handle_loconn(port_h); + io_printf(" Loconn type = %s\n", + acc_fetch_type_str(acc_fetch_fulltype(loconn_h))); + + hiconn_h = acc_handle_hiconn(port_h); + if (hiconn_h) + io_printf(" Hiconn type = %s\n\n", + acc_fetch_type_str(acc_fetch_fulltype(hiconn_h))); + else + io_printf(" Hiconn type = none\n\n"); + } /* end of next port_h loop */ + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/port_info_test.log b/me250300_pli/plibook_examples_unix/chapter.15/port_info_test.log new file mode 100644 index 0000000..af4e3ed --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/port_info_test.log @@ -0,0 +1,31 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Module addbit: + Instance name: test.i1 + Module type: module instance + Ports: + a 1-bit input Expanded=false Unexpanded=false + Loconn type = accWire + Hiconn type = accRegister + + b 1-bit input Expanded=false Unexpanded=false + Loconn type = accWire + Hiconn type = accRegister + + ci 1-bit input Expanded=false Unexpanded=false + Loconn type = accWire + Hiconn type = accRegister + + sum 1-bit output Expanded=false Unexpanded=false + Loconn type = accRegister + Hiconn type = accWire + + co 1-bit output Expanded=false Unexpanded=false + Loconn type = accRegister + Hiconn type = accWire + + foo 4-bit output Expanded=true Unexpanded=false + Loconn type = accWand + Hiconn type = none + +Simulation complete via $finish(1) at time 20 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.15/port_info_test.v b/me250300_pli/plibook_examples_unix/chapter.15/port_info_test.v new file mode 100644 index 0000000..cd36264 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/port_info_test.v @@ -0,0 +1,42 @@ +/********************************************************************** + * $port_info example -- Verilog test bench source code + * + * Verilog test bench to test the $port_info 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 a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + begin + #10 $port_info(i1); + #10 $finish; + end +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 1ns +module addbit (a, b, ci, sum, co, foo); + input a, b, ci; + output sum, co; + output [3:0] foo; + + wire a, b, ci; + reg sum, co; + wand scalared [3:0] foo; + + always @(a or b or ci) + {co,sum} = a + b + ci; + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.15/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.15/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.15/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.15/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.15/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.15/veriuser_VCS.tab new file mode 100644 index 0000000..018c72b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/veriuser_VCS.tab @@ -0,0 +1,8 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$list_pathout_ports data=0 check=PLIbook_ListPorts_checktf call=PLIbook_ListPorts_calltf acc+=read:* acc+=mp:* +$port_info data=0 check=PLIbook_PortInfo_checktf call=PLIbook_PortInfo_calltf acc+=read:* +$list_cells data=0 check=PLIbook_ListCells_checktf call=PLIbook_ListCells_calltf acc+=read:* +$count_loads data=0 check=PLIbook_CountLoads_checktf call=PLIbook_CountLoads_calltf size=32 acc+=read:* +$display_all_nets data=0 check=PLIbook_DisplayNets_checktf call=PLIbook_DisplayNets_calltf misc=PLIbook_DisplayNets_misctf acc+=read:* diff --git a/me250300_pli/plibook_examples_unix/chapter.15/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.15/veriusertfs_table.h new file mode 100644 index 0000000..2c95bdd --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.15/veriusertfs_table.h @@ -0,0 +1,85 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_ListPorts_checktf(int user_data, int reason); +extern int PLIbook_ListPorts_calltf(int user_data, int reason); + +extern int PLIbook_PortInfo_checktf(int user_data, int reason); +extern int PLIbook_PortInfo_calltf(int user_data, int reason); + +extern int PLIbook_ListCells_checktf(int user_data, int reason); +extern int PLIbook_ListCells_calltf(int user_data, int reason); + +extern int PLIbook_CountLoads_checktf(int user_data, int reason); +extern int PLIbook_CountLoads_sizetf(int user_data, int reason); +extern int PLIbook_CountLoads_calltf(int user_data, int reason, int pvc); + +extern int PLIbook_DisplayNets_checktf(int user_data, int reason); +extern int PLIbook_DisplayNets_calltf(int user_data, int reason); +extern int PLIbook_DisplayNets_misctf(int user_data, int reason, int pvc); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ListPorts_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ListPorts_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$list_pathout_ports", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_PortInfo_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_PortInfo_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$port_info", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ListCells_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ListCells_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$list_cells", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {userfunction, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_CountLoads_checktf, /* checktf routine */ + PLIbook_CountLoads_sizetf, /* sizetf routine */ + PLIbook_CountLoads_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$count_loads", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_DisplayNets_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_DisplayNets_calltf, /* calltf routine */ + PLIbook_DisplayNets_misctf, /* misctf routine */ + "$display_all_nets", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {0} /*** final entry must be 0 ***/ +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.16/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.16/build_MTI.mak new file mode 100644 index 0000000..0632a0e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/build_MTI.mak @@ -0,0 +1,28 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = \ + invoke_commands_acc.c \ + list_nets_acc.c \ + fetch_values_acc.c \ + read_vecval_acc.c \ + func_72bit_acc.c \ + timescale_info_acc.c \ + list_prim_delays_acc.c \ + list_path_delays_acc.c \ + mipd_delays_acc.c \ + change_path_delays_acc.c \ + list_parameters_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.16/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.16/build_NC.mak new file mode 100644 index 0000000..c66e8dd --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/build_NC.mak @@ -0,0 +1,28 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = \ + invoke_commands_acc.c \ + list_nets_acc.c \ + fetch_values_acc.c \ + read_vecval_acc.c \ + func_72bit_acc.c \ + timescale_info_acc.c \ + list_prim_delays_acc.c \ + list_path_delays_acc.c \ + mipd_delays_acc.c \ + change_path_delays_acc.c \ + list_parameters_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.16/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.16/build_XL.mak new file mode 100644 index 0000000..8a43562 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/build_XL.mak @@ -0,0 +1,28 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds/LDV_2.2 + +SOURCES = \ + invoke_commands_acc.c \ + list_nets_acc.c \ + fetch_values_acc.c \ + read_vecval_acc.c \ + func_72bit_acc.c \ + timescale_info_acc.c \ + list_prim_delays_acc.c \ + list_path_delays_acc.c \ + mipd_delays_acc.c \ + change_path_delays_acc.c \ + list_parameters_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_acc.c new file mode 100644 index 0000000..c74231f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_acc.c @@ -0,0 +1,94 @@ +/********************************************************************** + * $change_path_delays example -- C source code using ACC PLI routines + * + * C source to scale the pin-to-pin path delays of a module. The module + * instance and scale factor are passed as system task 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 + * + * Usage: $change_path_delays(, ); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_AddDelays_checktf(int user_data, int reason); + * extern int PLIbook_AddDelays_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ChangeDelays_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ChangeDelays_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$change_path_delays", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ChangeDelays_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 2) + tf_error("$list_path_delays must have 2 arguments."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_path_delays arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_path_delays arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ChangeDelays_calltf(int user_data, int reason) +{ + double rise, fall, toZ; + double scale_factor; + handle module_h, path_h; + int path_count = 0; + + acc_initialize(); + acc_configure(accMinTypMaxDelays, "false"); + acc_configure(accPathDelayCount, "3"); + + module_h = acc_handle_tfarg(1); + io_printf("\nIn module: %s\n", acc_fetch_fullname(module_h)); + + scale_factor = acc_fetch_tfarg(2); + + path_h = null; /* start with known value for target handle */ + while (path_h = acc_next_modpath(module_h, path_h)) { + path_count++; + acc_fetch_delays(path_h, &rise, &fall, &toZ); + io_printf(" Path %s:\n", acc_fetch_name(path_h)); + io_printf(" Original delay values are (%2.2f,%2.2f,%2.2f):\n", + rise, fall, toZ); + rise *= scale_factor; + fall *= scale_factor; + toZ *= scale_factor; + +// acc_replace_delays(path_h, rise, fall, toZ); + + acc_fetch_delays(path_h, &rise, &fall, &toZ); + io_printf(" After scaling, values are (%2.2f,%2.2f,%2.2f):\n", + rise, fall, toZ); + io_printf("\n"); + } + if (!path_count) { + io_printf(" no module paths found\n"); + } + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_test.log new file mode 100644 index 0000000..1d5bef7 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_test.log @@ -0,0 +1,16 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +In module: top.u1 + Path r1$out: + Original delay values are (1.10,1.20,1.10): + After scaling, values are (1.87,2.04,1.87): + + Path r2$out: + Original delay values are (1.50,1.60,1.50): + After scaling, values are (2.55,2.72,2.55): + + Path ci$out: + Original delay values are (1.80,1.90,1.80): + After scaling, values are (3.06,3.23,3.06): + +Simulation complete via $finish(1) at time 1 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_test.v new file mode 100644 index 0000000..b6a5dea --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/change_path_delays_test.v @@ -0,0 +1,67 @@ +/********************************************************************** + * $change_path_delays example -- Verilog test bench source code + * + * Verilog test bench to test the $change_path_delays 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 / 100ps +module top; + wire [3:0] in1, in2; + wire carry_in; + wire [3:0] result; + wire carry_out; + + add4 u1 (in1, in2, carry_in, result, carry_out); + + initial + begin + $change_path_delays(top.u1, 1.7); + #1 $finish; + end +endmodule + +/*** A 4-bit adder model, made of 1-bit adders ***/ +`timescale 1ns / 10ps +module add4 (r1, r2, ci, out, co); + input [3:0] r1, r2; + input ci; + output [3:0] out; + output co; + wire [3:0] r1, r2, out; + wire ci, c1, c2, c3, co; + + addbit i1 (r1[0],r2[0],ci,out[0],c1); + addbit i2 (r1[1],r2[1],c1,out[1],c2); + addbit i3 (r1[2],r2[2],c2,out[2],c3); + addbit i4 (r1[3],r2[3],c3,out[3],co); + + specify + (r1 *> out) = (1.1, 1.2); + (r2 *> out) = (1.5, 1.6); + (ci *> out) = (1.8, 1.9); + endspecify +endmodule + +/*** A gate level 1 bit adder model ***/ +`celldefine +`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, n4; + + xor p1 (n1, a, b); + xor p2 (sum, n1, ci); + and p3 (n2, a, b); + and p4 (n3, n1, ci); + or p5 (co, n2, n3); +endmodule +`endcelldefine +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_acc.c new file mode 100644 index 0000000..8c9a612 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_acc.c @@ -0,0 +1,62 @@ +/********************************************************************** + * $test_acc_fetch_value example -- C source code using ACC PLI routines + * + * C source to various formats of acc_fetch_value(). + * + * 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 + * + * Usage: $test_acc_fetch_value(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ListNets_checktf(int user_data, int reason); + * extern int PLIbook_ListNets_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_TestFetchVal_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$test_acc_fetch_value", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_TestFetchVal_calltf(int user_data, int reason) +{ + handle tfarg_h; + s_acc_value val_s; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + tfarg_h = acc_handle_tfarg(1); + + val_s.format = accBinStrVal; /* */ +/* val_s.format = accIntVal; /* */ +/* val_s.format = accRealVal; /* */ + + if (acc_error_flag) + io_printf("acc_fecth_value() error\n"); + + acc_fetch_value(tfarg_h, "%%", &val_s); + + io_printf("%s = %s\n", acc_fetch_name(tfarg_h), val_s.value.str); /* */ +/* io_printf("%s = %d\n", acc_fetch_name(tfarg_h), val_s.value.integer); /* */ +/* io_printf("%s = %f\n", acc_fetch_name(tfarg_h), val_s.value.real); /* */ + + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_test.log b/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_test.log new file mode 100644 index 0000000..d517ff9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_test.log @@ -0,0 +1,4 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +reg1 = 0100100001101001 +Simulation complete via $finish(1) at time 11 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_test.v b/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_test.v new file mode 100644 index 0000000..06fa3da --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/fetch_values_test.v @@ -0,0 +1,30 @@ +/********************************************************************** + * $test_acc_fetch_value example -- Verilog test bench source code + * + * Verilog test bench to test the $test_acc_fetch_value 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 top; + reg [15:0] reg1; + real real1; + + initial + begin + reg1 = "Hi"; + real1 = 3.1415; + + #1 $test_acc_fetch_value(reg1); +// #1 $test_acc_fetch_value(real1); + + #10 $finish; + end +endmodule + +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/func_72bit_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/func_72bit_acc.c new file mode 100644 index 0000000..6d04f22 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/func_72bit_acc.c @@ -0,0 +1,72 @@ +/********************************************************************** + * $func_72bit example -- PLI application using ACC routines + * + * C source to return an 72-bit vector value to a system function. + * + * Usage: result = $func_72bit(); + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_Func72bit_sizetf(int user_data, int reason); + * extern int PLIbook_Func72bit_calltf(int user_data, int reason); + * /* table entries -/ + * {userfunction, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * PLIbook_Func72bit_sizetf, /* sizetf routine -/ + * PLIbook_Func72bit_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$func_72bit", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * Sizetf application + *********************************************************************/ +int PLIbook_Func72bit_sizetf(int user_data, int reason) +{ + return(72); /* $pow returns 32-bit values */ +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_Func72bit_calltf(int user_data, int reason) +{ + handle systf_handle; + s_setval_value value; + s_setval_delay delay; + p_acc_vecval val_array; + int array_size, i; + + /* declare an array of aval/bval pairs for the vector size */ + #define VEC_SIZE 72 /* hard coded 72-bit vector for this example */ + array_size = ((VEC_SIZE-1)/32)+1; + val_array = (p_acc_vecval)malloc(sizeof(s_acc_vecval) * array_size); + + /* set value of vector aval/bval pairs */ + for (i=0; i"); + * Where /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * calltf routine + *********************************************************************/ +/* prototypes of subroutines used by calltf routine */ +void PLIbook_ScanCommandFile(PLI_BYTE8 **arg); + +int PLIbook_InvokeCommands_calltf(int user_data, int reason) +{ + int argc, i; + PLI_BYTE8 **argv; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + argc = acc_fetch_argc(); + argv = acc_fetch_argv(); + + io_printf("\nSimulation invocation commands:\n"); + for (i=0; i invoke_commands_test.v + * +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; + + initial + begin + $print_invoke_commands; + #1 $finish; + end + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.16/invoke_commands_test1.f b/me250300_pli/plibook_examples_unix/chapter.16/invoke_commands_test1.f new file mode 100644 index 0000000..bbffd79 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/invoke_commands_test1.f @@ -0,0 +1,6 @@ +//command file ++a1 ++b1 +//+test1 +-f invoke_commands_test2.f ++c1 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/invoke_commands_test2.f b/me250300_pli/plibook_examples_unix/chapter.16/invoke_commands_test2.f new file mode 100644 index 0000000..0bddd3e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/invoke_commands_test2.f @@ -0,0 +1,5 @@ +//command file ++a2 ++b2 ++test2 ++c2 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_nets_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/list_nets_acc.c new file mode 100644 index 0000000..017ba6d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_nets_acc.c @@ -0,0 +1,71 @@ +/********************************************************************** + * $list_nets example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the names of all nets in + * the module with the current logic value. + * + * 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 + * + * Usage: $list_nets(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ListNets_checktf(int user_data, int reason); + * extern int PLIbook_ListNets_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ListNets_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ListNets_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$list_nets", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ListNets_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$list_nets must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_nets arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_nets arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ListNets_calltf(int user_data, int reason) +{ + handle module_h, net_h; + acc_initialize(); + module_h = acc_handle_tfarg(1); + io_printf("\nNet values in module %s:\n", + acc_fetch_fullname(module_h)); + net_h = null; /* start with known value for target handle */ + while (net_h = acc_next_net(module_h, net_h)) { + io_printf(" %-10s: %s\n", + acc_fetch_name(net_h), + acc_fetch_value(net_h, "%b", null)); + } + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_nets_test.log b/me250300_pli/plibook_examples_unix/chapter.16/list_nets_test.log new file mode 100644 index 0000000..c6effd9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_nets_test.log @@ -0,0 +1,16 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Net values in module top: + results : z01 + +Net values in module top.i1: + a : 1 + b : 0 + ci : 0 + sum : 1 + co : 0 + n1 : 1 + n2 : 0 + n3 : 0 + foo : xz10 +Simulation complete via $finish(1) at time 40 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_nets_test.v b/me250300_pli/plibook_examples_unix/chapter.16/list_nets_test.v new file mode 100644 index 0000000..63e016f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_nets_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $list_nets example -- Verilog test bench source code + * + * Verilog test bench to test the $list_nets 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 top; + reg [2:0] test; + wire [2:0] results; + + addbit i1 (test[0], test[1], test[2], results[0], results[1]); + + initial + begin + test = 3'b000; + #10 test = 3'b001; + + #10 $list_nets(top); + #10 $list_nets(i1); + + #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; + wire [3:0] foo = 4'bXZ10; + + xor (n1, a, b); + xor #2 (sum, n1, ci); + and (n2, a, b); + and (n3, n1, ci); + or #2 (co, n2, n3); + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_acc.c new file mode 100644 index 0000000..68ee447 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_acc.c @@ -0,0 +1,81 @@ +/********************************************************************** + * $list_parameters example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the typical rise, fall + * and turn-off delays of all primitives in a module. + * + * 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 + * + * Usage: $list_prim_delays(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ListParams_checktf(int user_data, int reason); + * extern int PLIbook_ListParams_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ListParams_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ListParams_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$list_parameters", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ListParams_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$list_parameters must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_parameters arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_parameters arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ListParams_calltf(int user_data, int reason) +{ + handle module_h, param_h; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + module_h = acc_handle_tfarg(1); + io_printf("\nConstants in module %s:\n", + acc_fetch_fullname(module_h)); + param_h = null; + while(param_h = acc_next_parameter(module_h, param_h)) { + io_printf(" Parameter %s is: ", acc_fetch_fullname(param_h)); + switch(acc_fetch_paramtype(param_h) ) { + case accRealParam: + io_printf("%f\n", acc_fetch_paramval(param_h)); + break; + case accIntegerParam: + io_printf("%d\n", (int)acc_fetch_paramval(param_h)); + break; + case accStringParam: + io_printf("%s\n", (char*)(int)acc_fetch_paramval(param_h)); + } + } + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_test.log b/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_test.log new file mode 100644 index 0000000..e7ff24a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_test.log @@ -0,0 +1,8 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Constants in module top.i1: + Parameter top.i1.int_param is: 1 + Parameter top.i1.real_param is: 2.000000 + Parameter top.i1.string_param is: 3.0 + Parameter top.i1.vector_param is: 4 +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_test.v b/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_test.v new file mode 100644 index 0000000..5dc37b5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_parameters_test.v @@ -0,0 +1,48 @@ +/********************************************************************** + * $list_parameters example -- Verilog test bench source code + * + * Verilog test bench to test the $list_parameters 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 top; + reg [2:0] test; + wire [1:0] results; + + addbit i1 (test[0], test[1], test[2], results[0], results[1]); + + initial + begin + #1 $list_parameters(i1); + #1 $finish; + end +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 10ps +module addbit (a, b, ci, sum, co); + input a, b, ci; + output sum, co; + + parameter int_param = 1; + parameter real_param = 2.0; + parameter string_param = "3.0"; + parameter [3:0] vector_param = 4'b01zx; + + wire a, b, ci, sum, co, n1, n2, n3, n4; + wire [3:0] foo = 4'bXZ10; + + xor #1.87 p1 (n1, a, b); // all transitions have same delay + xor #(1.8, 2.2) p2 (sum, n1, ci); //rise, fall delays + and p3 (n2, a, b); + and p4 (n3, n1, ci); + or #4 p5 (co, n2, n3); //integer delay + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_acc.c new file mode 100644 index 0000000..3e95cfb --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_acc.c @@ -0,0 +1,88 @@ +/********************************************************************** + * $list_path_delays example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the min:typ:max rise, + * fall and turn-off delays of all module paths in a module. + * + * 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 + * + * Usage: $list_path_delays(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_PathDelays_checktf(int user_data, int reason); + * extern int PLIbook_PathDelays_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_PathDelays_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_PathDelays_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$list_path_delays", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_PathDelays_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$list_path_delays must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_path_delays arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_path_delays arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_PathDelays_calltf(int user_data, int reason) +{ + handle module_h, path_h; + double delay_set[18]; + int i; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + acc_configure(accMinTypMaxDelays, "true"); + acc_configure(accPathDelayCount, "6"); + + module_h = acc_handle_tfarg(1); + io_printf("\nPath delays in module %s:\n", + acc_fetch_fullname(module_h)); + path_h = null; /* start with known value for target handle */ + while (path_h = acc_next_modpath(module_h, path_h)) { + io_printf(" %-12s : ", + acc_fetch_name(path_h)); + acc_fetch_delays(path_h, delay_set); + for (i=0; i<18; i++) { + if ( i == 0 ) /* format output like Verilog syntax */ + io_printf("("); + else if ( (i % 3) ) + io_printf(":"); + else + io_printf(", "); + io_printf("%1.1f", delay_set[i]); + } + io_printf(")\n\n"); + } + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_test.log new file mode 100644 index 0000000..41b9c4e --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_test.log @@ -0,0 +1,13 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. +ncverilog + +ncanno_simtime + list_path_delays_test.v + +Path delays in module top.i1: + a$sum : (3.1:3.1:3.1, 3.1:3.1:3.1, 3.1:3.1:3.1, 3.1:3.1:3.1, 3.1:3.1:3.1, 3.1:3.1:3.1) + + b$sum : (2.0:2.0:2.0, 5.0:5.0:5.0, 8.0:8.0:8.0, 2.0:2.0:2.0, 8.0:8.0:8.0, 5.0:5.0:5.0) + + ci$sum : (1.0:1.0:1.0, 2.0:2.0:2.0, 3.0:3.0:3.0, 4.0:4.0:4.0, 5.0:5.0:5.0, 6.0:6.0:6.0) + +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_test.v new file mode 100644 index 0000000..da287ff --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_path_delays_test.v @@ -0,0 +1,50 @@ +/********************************************************************** + * $list_path_delays example -- Verilog test bench source code + * + * Verilog test bench to test the $list_path_delays 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 top; + reg [2:0] test; + wire [1:0] results; + + addbit i1 (test[0], test[1], test[2], results[0], results[1]); + + initial + begin + #1 $list_path_delays(i1); + #1 $finish; + end +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 10ps +module addbit (a, b, ci, sum, co); + input a, b, ci; + output sum, co; + + wire a, b, ci, sum, co, n1, n2, n3, n4; + wire [3:0] foo = 4'bXZ10; + + xor p1 (n1, a, b); // all transitions have same delay + xor p2 (sum, n1, ci); //rise, fall delays + and p3 (n2, a, b); + and p4 (n3, n1, ci); +// or p5 (co, n2, n3); //integer delay + bufif1 p6 (co, n2, 1'b0); //all delay values + + specify + (a *> sum) = 3.1415; + (b *> sum) = (1:2:3, 4:5:6, 7:8:9); + (ci *> sum, co) = (1, 2, 3, 4, 5, 6); + endspecify + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_acc.c new file mode 100644 index 0000000..cbc47b2 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_acc.c @@ -0,0 +1,88 @@ +/********************************************************************** + * $list_prim_delays example -- C source code using ACC PLI routines + * + * C source to scan through a module and list the typical rise, fall + * and turn-off delays of all primitives in a module. + * + * 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 + * + * Usage: $list_prim_delays(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_PrimDelays_checktf(int user_data, int reason); + * extern int PLIbook_PrimDelays_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_PrimDelays_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_PrimDelays_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$list_prim_delays", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_PrimDelays_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$list_prim_delays must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$list_prim_delays arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$list_prim_delays arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_PrimDelays_calltf(int user_data, int reason) +{ + handle module_h, prim_h; + double rise, fall, toZ; + static PLI_INT32 three_state[7] = {accBufif0Gate, accBufif1Gate, + accNotif0Gate, accNotif1Gate, + accTranif0Gate, accTranif1Gate, + 0}; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + acc_configure(accMinTypMaxDelays, "false"); + + module_h = acc_handle_tfarg(1); + io_printf("\nPrimitives in module %s:\n", + acc_fetch_fullname(module_h)); + prim_h = null; /* start with known value for target handle */ + while (prim_h = acc_next_primitive(module_h, prim_h)) { + io_printf(" %-8s instance %-4s: ", + acc_fetch_defname(prim_h), + acc_fetch_name(prim_h)); + if (acc_object_in_typelist(prim_h, three_state)) { + acc_fetch_delays(prim_h, &rise, &fall, &toZ); + io_printf("rise=%2.2f, fall=%2.2f, toZ=%2.2f\n", rise, fall, toZ); + } + else { + acc_fetch_delays(prim_h, &rise, &fall); + io_printf("rise=%2.2f, fall=%2.2f\n", rise, fall); + } + } + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_test.log new file mode 100644 index 0000000..15c448f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_test.log @@ -0,0 +1,10 @@ +VERILOG-XL 3.0.p001 log file created Nov 4, 2001 23:07:23 + +Primitives in module top.i1: + xor instance p1 : rise=1.87, fall=1.87 + xor instance p2 : rise=1.80, fall=2.20 + and instance p3 : rise=0.00, fall=0.00 + and instance p4 : rise=0.00, fall=0.00 + or instance p5 : rise=4.00, fall=4.00 + bufif1 instance p6 : rise=2.00, fall=5.00, toZ=8.00 +L22 "list_prim_delays_test.v": $finish at simulation time 200 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_test.v new file mode 100644 index 0000000..3fc0938 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/list_prim_delays_test.v @@ -0,0 +1,45 @@ +/********************************************************************** + * $list_prim_delays example -- Verilog test bench source code + * + * Verilog test bench to test the $list_prim_delays 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 top; + reg [2:0] test; + wire [1:0] results; + + addbit i1 (test[0], test[1], test[2], results[0], results[1]); + + initial + begin + #1 $list_prim_delays(i1); + #1 $finish; + end +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 10ps +module addbit (a, b, ci, sum, co); + input a, b, ci; + output sum, co; + + wire a, b, ci, sum, co, n1, n2, n3, n4; + wire [3:0] foo = 4'bXZ10; + + xor #1.87 p1 (n1, a, b); // all transitions have same delay + xor #(1.8, 2.2) p2 (sum, n1, ci); //rise, fall delays + and p3 (n2, a, b); + and p4 (n3, n1, ci); + or #4 p5 (co, n2, n3); //integer delay + + bufif1 #(1:2:3, 4:5:6, 7:8:9) p6 (n4, n2, n3); //all delay values + +endmodule +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_acc.c new file mode 100644 index 0000000..22f4a30 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_acc.c @@ -0,0 +1,116 @@ +/********************************************************************** + * $mipd_delays example -- C source code using ACC PLI routines + * + * C source to modify the delays of a verilog gate primitive. the + * gate instance and delay values to be added to the existing gate + * delays are passed as system task 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 + * + * Usage: $mipd_delays(, , , ... ); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_AddDelays_checktf(int user_data, int reason); + * extern int PLIbook_AddDelays_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * 0, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_MipdDelays_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$mipd_delays", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +#define DEBUG 0 /* set to non-zero for debug messages */ + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_MipdDelays_calltf(int user_data, int reason) +{ + double delay_array[9]; + double rise, fall, toZ; + handle port_h; + int i; + PLI_INT32 arg_type; + + acc_initialize(); + acc_configure(accDisplayWarnings, "true"); + + acc_configure(accMinTypMaxDelays, "true"); + port_h = acc_handle_tfarg(1); + + arg_type = acc_fetch_type(port_h); + + #if DEBUG + io_printf("\nDEBUG: acc_handle_tfarg(1) object type is %s / %s\n", + acc_fetch_type_str(arg_type), + acc_fetch_type_str(arg_type)); + #endif + + /* most simulators return loconn handle, not port handle */ + switch (arg_type) { + case accPort: + case accScalarPort: break; /* arg type is the right type */ + case accPortBit: port_h = acc_handle_parent(port_h); break; + case accNet: + case accNetBit: port_h = acc_next_port(port_h, null); break; + default: io_printf("\nERROR in $mipd_delays: acc_handle_tfarg(1) returned illegal type of %s\n\n", acc_fetch_type_str(arg_type)); return(0); + } + + /* see if now have a port handle */ + arg_type = acc_fetch_type(port_h); + switch (arg_type) { + case accPort: + case accScalarPort: break; /* arg type is the right type */ + case accPortBit: port_h = acc_handle_parent(port_h); break; + default: io_printf("\nERROR in $mipd_delays: could not obtain port handle; ended up with type of %s\n\n", acc_fetch_type_str(arg_type)); return(0); + } + + #if DEBUG + arg_type = acc_fetch_type(port_h); + io_printf("DEBUG: after type checks, port_h type is %s / %s\n", + acc_fetch_type_str(arg_type), + acc_fetch_type_str(arg_type)); + io_printf("DEBUG: the port handle is to %s\n\n", + acc_fetch_fullname(port_h)); + #endif + + for (i = 0; i <= 8; i++) { + delay_array[i] = acc_fetch_tfarg(i+2); + } + + #if DEBUG + for (i = 0; i <= 8; i++) { + io_printf("DEBUG: delay_array[%d] has value %f\n", + i, delay_array[i]); + io_printf("\n"); + } + #endif + + acc_replace_delays(port_h, delay_array); + + /* verify new delays took affect */ + acc_configure(accMinTypMaxDelays, "false"); + rise = fall = toZ = 0.0; + acc_fetch_delays(port_h, &rise, &fall, &toZ); + io_printf("Port %s new delays: (%1.2f, %1.2f, %1.2f)\n\n", + acc_fetch_name(port_h), + rise, fall, toZ); + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.log b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.log new file mode 100644 index 0000000..022ce0b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.log @@ -0,0 +1,5 @@ +Verilog_XL_Turbo_NT 2.6.9 log file created Jan 11, 1999 01:33:50 + +Port ci new delays: (1.60, 1.30, 0.80) + +L22 "mipd_delays_test.v": $finish at simulation time 100 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.sdf b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.sdf new file mode 100644 index 0000000..ccf0887 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.sdf @@ -0,0 +1,25 @@ +(DELAYFILE + (DESIGN "MIPD Delays PLI Test") + (DATE ) + (VENDOR "Sutherland HDL") + (PROGRAM ) + (VERSION ) + (DIVIDER .) + (VOLTAGE ) + (PROCESS ) + (TEMPERATURE ) + (TIMESCALE 1ns) + + (CELL + (CELLTYPE "addbit") + (INSTANCE top.u1.i1) + (DELAY + (ABSOLUTE + (PORT ci + (0.1:0.1:0.1) (0.1:0.1:0.1) + ) + ) + ) + ) +) + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.v b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.v new file mode 100644 index 0000000..5416576 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/mipd_delays_test.v @@ -0,0 +1,63 @@ +/********************************************************************** + * $append_gate_delays example -- Verilog test bench source code + * + * Verilog test bench to test the $append_gate_delays 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 / 100ps +module top; + wire [3:0] in1, in2; + wire carry_in; + wire [3:0] result; + wire carry_out; + + add4 u1 (in1, in2, carry_in, result, carry_out); + + initial + begin + /*** some simulators cannot annotate port delays until after SDF has annotated that port ***/ + $sdf_annotate("mipd_delays_test.sdf"); + $mipd_delays(top.u1.i1.ci, 1.4, 1.6, 1.9, 1.1, 1.3, 1.5, 0.6, 0.8, 0.9); + #1 $finish; + end +endmodule + +/*** A 4-bit adder model, made of 1-bit adders ***/ +`timescale 1ns / 10ps +module add4 (r1, r2, ci, out, co); + input [3:0] r1, r2; + input ci; + output [3:0] out; + output co; + wire [3:0] r1, r2, out; + wire ci, c1, c2, c3, co; + + addbit i1 (r1[0],r2[0],ci,out[0],c1); + addbit i2 (r1[1],r2[1],c1,out[1],c2); + addbit i3 (r1[2],r2[2],c2,out[2],c3); + addbit i4 (r1[3],r2[3],c3,out[3],co); +endmodule + +/*** A gate level 1 bit adder model ***/ +`celldefine +`timescale 1ns / 10ps +module addbit (a, b, ci, sum, co); + input a, b, ci; + output sum, co; + + wire a, b, ci, sum, co, n1, n2, n3, n4; + + xor #1.87 p1 (n1, a, b); // all transitions have same delay + xor #(1.8, 2.2) p2 (sum, n1, ci); //rise, fall delays + and p3 (n2, a, b); + and p4 (n3, n1, ci); + or #4 p5 (co, n2, n3); //integer delay +endmodule +`endcelldefine +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/read_vecval_acc.c b/me250300_pli/plibook_examples_unix/chapter.16/read_vecval_acc.c new file mode 100644 index 0000000..7fb594b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/read_vecval_acc.c @@ -0,0 +1,124 @@ +/********************************************************************** + * $read_vecval example -- PLI application using ACC routines + * + * C source to read logic values of a net and print the net name and + * current logic value. + * + * Usage: $read_vecval(); + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ReadVecVal_checktf(int user_data, int reason), + * extern int PLIbook_ReadVecVal_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ReadVecVal_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ReadVecVal_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$read_vecval", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +/* prototypes of subroutines used by the calltf routine */ +char PLIbook_get_4state_val(); +int PLIbook_getbit() ; + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_ReadVecVal_checktf(int user_data, int reason) +{ + PLI_INT32 arg_type; + acc_initialize(); + if (tf_nump() != 1) + tf_error("$timescale_info must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$time_info arg cannot be null."); + else { + arg_type = acc_fetch_type(acc_handle_tfarg(1)); + if ( (arg_type != accNet) + && (arg_type != accReg) ) + tf_error("$read_vecval arg must be a net or reg."); + } + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_ReadVecVal_calltf(int user_data, int reason) +{ + handle vector_h; + s_acc_value vector_val; /* structure to receive vector value */ + int i, vector_size, array_size, avalbit, bvalbit, bit_num; + char vlogval; + + vector_h = acc_handle_tfarg(1); + + vector_size = acc_fetch_size(vector_h); /* determine number of...*/ + array_size = ((vector_size-1) / 32 + 1); /* ...elements in array */ + + vector_val.value.vector = + (p_acc_vecval)malloc(array_size * sizeof(s_acc_vecval)); + + vector_val.format = accVectorVal; /* set value format field */ + + acc_fetch_value(vector_h,"%%",&vector_val); /* read vector's value */ + + io_printf("\nVector %s encoded value:\n", + acc_fetch_name(vector_h)); + for (i=0; i); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_TimeInfo_checktf(int user_data, int reason); + * extern int PLIbook_TimeInfo_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_TimeInfo_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_TimeInfo_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$timescale_info", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_TimeInfo_checktf(int user_data, int reason) +{ + acc_initialize(); + if (tf_nump() != 1) + tf_error("$timescale_info must have 1 argument."); + else if (tf_typep(1) == TF_NULLPARAM) + tf_error("$time_info arg cannot be null."); + else if (acc_fetch_type(acc_handle_tfarg(1)) != accModule) + tf_error("$timescale_info arg must be a module instance."); + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +int PLIbook_TimeInfo_calltf(int user_data, int reason) +{ + handle module_h, tfinst_h; + s_timescale_info ts_info; + + acc_initialize(); + + module_h = acc_handle_tfarg(1); + tfinst_h = acc_handle_tfinst(); + + acc_fetch_timescale_info(module_h, &ts_info); + io_printf("\nModule %s: time_units = %d time_precision = %d\n", + acc_fetch_fullname(module_h), + ts_info.unit, ts_info.precision); + + acc_fetch_timescale_info(tfinst_h, &ts_info); + io_printf("\nSystem task: time_units = %d time_precision = %d\n", + ts_info.unit, ts_info.precision); + + acc_fetch_timescale_info(null, &ts_info); + io_printf("\n$timeformat time_units = %d time_precision = %d\n\n", + ts_info.unit, ts_info.precision); + + acc_close(); + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/timescale_info_test.log b/me250300_pli/plibook_examples_unix/chapter.16/timescale_info_test.log new file mode 100644 index 0000000..71cea5f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/timescale_info_test.log @@ -0,0 +1,9 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +Module test.i1: time_units = -9 time_precision = -12 + +System task: time_units = -9 time_precision = -9 + +$timeformat time_units = -6 time_precision = 1 + +Simulation complete via $finish(1) at time 2 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.16/timescale_info_test.v b/me250300_pli/plibook_examples_unix/chapter.16/timescale_info_test.v new file mode 100644 index 0000000..14677ed --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/timescale_info_test.v @@ -0,0 +1,44 @@ +/********************************************************************** + * $timescale_info example -- Verilog test bench source code + * + * Verilog test bench to test the $timescale_info 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 a, b, ci, clk; + wire sum, co; + + addbit i1 (a, b, ci, sum, co); + + initial + begin + $timeformat(-6,1," ms",10); + #1 $timescale_info(i1); + #1 $finish; + end +endmodule + +/*** A gate level 1 bit adder model ***/ +`timescale 1ns / 1ps +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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.16/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.16/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.16/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.16/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.16/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.16/veriuser_VCS.tab new file mode 100644 index 0000000..c25ec1a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/veriuser_VCS.tab @@ -0,0 +1,13 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$print_invoke_commands data=0 call=PLIbook_InvokeCommands_calltf acc+=read:* +$list_nets data=0 check=PLIbook_ListNets_checktf call=PLIbook_ListNets_calltf acc+=read:* +$test_acc_fetch_value data=0 call=PLIbook_TestFetchVal_calltf acc+=read:* +$read_vecval data=0 check=PLIbook_ReadVecVal_checktf call=PLIbook_ReadVecVal_calltf acc+=read:* +$func_72bit data=0 call=PLIbook_Func72bit_calltf size=72 acc+=read:* +$timescale_info data=0 check=PLIbook_TimeInfo_checktf call=PLIbook_TimeInfo_calltf acc+=read:* +$list_prim_delays data=0 check=PLIbook_PrimDelays_checktf call=PLIbook_PrimDelays_calltf acc+=read_write:* acc+=gate_backannotation:* +$list_path_delays data=0 check=PLIbook_PathDelays_checktf call=PLIbook_PathDelays_calltf acc+=read_write:* acc+=module_path_backannotation:* +$mipd_delays data=0 call=PLIbook_MipdDelays_calltf acc+=read_write:* acc+=module_input_port_backannotation:addbit acc+=module_input_port_bit_backannotation:addbit +$list_parameters data=0 check=PLIbook_ListParams_checktf call=PLIbook_ListParams_calltf acc+=read_write:* diff --git a/me250300_pli/plibook_examples_unix/chapter.16/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.16/veriusertfs_table.h new file mode 100644 index 0000000..60397c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.16/veriusertfs_table.h @@ -0,0 +1,159 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ + +extern int PLIbook_ListNets_checktf(int user_data, int reason); +extern int PLIbook_ListNets_calltf(int user_data, int reason); + +extern int PLIbook_TestFetchVal_calltf(int user_data, int reason); + +extern int PLIbook_ReadVecVal_checktf(int user_data, int reason); +extern int PLIbook_ReadVecVal_calltf(int user_data, int reason); + +extern int PLIbook_Func72bit_sizetf(int user_data, int reason); +extern int PLIbook_Func72bit_calltf(int user_data, int reason); + +extern int PLIbook_TimeInfo_checktf(int user_data, int reason); +extern int PLIbook_TimeInfo_calltf(int user_data, int reason); + +extern int PLIbook_PrimDelays_checktf(int user_data, int reason); +extern int PLIbook_PrimDelays_calltf(int user_data, int reason); + +extern int PLIbook_PathDelays_checktf(int user_data, int reason); +extern int PLIbook_PathDelays_calltf(int user_data, int reason); + +extern int PLIbook_MipdDelays_calltf(int user_data, int reason); + +extern int PLIbook_ChangeDelays_checktf(int user_data, int reason); +extern int PLIbook_ChangeDelays_calltf(int user_data, int reason); + +extern int PLIbook_ListParams_checktf(int user_data, int reason); +extern int PLIbook_ListParams_calltf(int user_data, int reason); + +extern int PLIbook_InvokeCommands_calltf(int user_data, int reason); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_InvokeCommands_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$print_invoke_commands", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ListNets_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ListNets_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$list_nets", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_TestFetchVal_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$test_acc_fetch_value", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ReadVecVal_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ReadVecVal_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$read_vecval", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {userfunction, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + PLIbook_Func72bit_sizetf, /* sizetf routine */ + PLIbook_Func72bit_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$func_72bit", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_TimeInfo_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_TimeInfo_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$timescale_info", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_PrimDelays_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_PrimDelays_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$list_prim_delays", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_PathDelays_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_PathDelays_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$list_path_delays", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + 0, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_MipdDelays_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$mipd_delays", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ChangeDelays_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ChangeDelays_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$change_path_delays", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ListParams_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ListParams_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$list_parameters", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {0} /*** final entry must be 0 ***/ +}; diff --git a/me250300_pli/plibook_examples_unix/chapter.17/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.17/build_MTI.mak new file mode 100644 index 0000000..fe42f84 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/build_MTI.mak @@ -0,0 +1,18 @@ +# +# NMAKE makefile to make my_pli.dll for MTI Modelsim, using VisualC++ on Windows +# + +MTI_INSTALL_DIR=c:\progra~1\ModelTech + +SOURCES = \ + my_monitor_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.17/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.17/build_NC.mak new file mode 100644 index 0000000..62e255b --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/build_NC.mak @@ -0,0 +1,18 @@ +# +# sample NMAKE makefile to make libvpi.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=C:/progra~1/cds/ + +SOURCES = \ + my_monitor_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.17/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.17/build_XL.mak new file mode 100644 index 0000000..63c8287 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/build_XL.mak @@ -0,0 +1,18 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + my_monitor_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_acc.c b/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_acc.c new file mode 100644 index 0000000..d6c3b4f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_acc.c @@ -0,0 +1,119 @@ +/********************************************************************** + * $my_monitor example -- C source code using TF/ACC PLI routines + * + * C source to: + * 1. Add VCL flags to signals listed in the system task arguments. + * 2. Whenever a signal changes value, print the current simulation + * time, old logic value and new logic value. + * + * 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 + * + * Usage: $show_all_nets(); + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_MyMonitor_checktf(int user_data, int reason); + * extern int PLIbook_MyMonitor_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_MyMonitor_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_MyMonitor_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$my_monitor", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +/* prototype of consumer routine */ +int PLIbook_MyMonitor_consumer(p_vc_record vc_record); + +/********************************************************************** + * checktf routine + *********************************************************************/ +int PLIbook_MyMonitor_checktf(int user_data, int reason) +{ + int i; + static PLI_INT32 validTypes[5] = {accNet, accNetBit, + accReg, accRegBit, 0}; + + acc_initialize(); + for (i=1; i<=tf_nump(); i++) { + if ( !(acc_object_in_typelist(acc_handle_tfarg(i), validTypes)) ) + tf_error("$my_monitor argument %d must be a net or reg", i); + else if ( tf_sizep(i) != 1) + tf_error("$my_monitor argument %d must be scalar", i); + } + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine + *********************************************************************/ +typedef struct PLIbook_MyMon_t { + PLI_BYTE8 signalName[256]; /* signal names--up to 255 characters */ + PLI_BYTE8 lastValue[2]; /* scalar logic value stored as a string */ +} PLIbook_MyMon_s, *PLIbook_MyMon_p; + +PLIbook_MyMonitor_calltf(int user_data, int reason) { + handle signal_h; + int i, numargs; + + /* allocate memory for an array of p_monitor structures */ + PLIbook_MyMon_p monArray; /* starting address for the array */ + numargs = (int)tf_nump(); + monArray = (PLIbook_MyMon_p)malloc(numargs*(sizeof(PLIbook_MyMon_s))); + + acc_initialize(); + /* save name and current logic value of each signal */ + for (i=0; iuser_data; + switch (vc_record->vc_reason) { /* check reason call-back occurred */ + case logic_value_change: /* scalar net changed */ + case sregister_value_change : { /* scalar register changed */ + switch (vc_record->out_value.logic_value) { /* convert value */ + case vcl0: strcpy(newValue, "0"); break; /* to string */ + case vcl1: strcpy(newValue, "1"); break; + case vclX: strcpy(newValue, "x"); break; + case vclZ: strcpy(newValue, "z"); break; + } + io_printf("At time %4d: %-20s last value=%s new value=%s\n", + vc_record->vc_lowtime, ArrayElem_p->signalName, + ArrayElem_p->lastValue, newValue); + strcpy(ArrayElem_p->lastValue, newValue); /* save the new value */ + } + } + return(0); +} +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_test.log b/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_test.log new file mode 100644 index 0000000..8cb104f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_test.log @@ -0,0 +1,11 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At time 0: top.i1.sum last value=x new value=0 +At time 0: top.i1.co last value=x new value=0 +At time 0: top.results[0] last value=x new value=0 +At time 10: top.i1.sum last value=0 new value=1 +At time 10: top.results[0] last value=0 new value=1 +At time 20: top.i1.sum last value=1 new value=0 +At time 20: top.i1.co last value=0 new value=1 +At time 20: top.results[0] last value=1 new value=0 +Simulation complete via $finish(1) at time 30 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_test.v b/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_test.v new file mode 100644 index 0000000..44125f3 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/my_monitor_test.v @@ -0,0 +1,45 @@ +/********************************************************************** + * $my_monitor example -- Verilog test bench source code + * + * Verilog test bench to test the $my_monitor PLI application on + * a 1-bit adder modeled using RTL code. + * + * 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 + $my_monitor(results[0]); + $my_monitor(i1.sum, i1.co); + test = 3'b000; + #10 test = 3'b001; + #10 test = 3'b011; + #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 +/*********************************************************************/ + diff --git a/me250300_pli/plibook_examples_unix/chapter.17/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.17/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.17/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.17/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.17/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.17/veriuser_VCS.tab new file mode 100644 index 0000000..89e097c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/veriuser_VCS.tab @@ -0,0 +1,4 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$my_monitor data=0 check=PLIbook_MyMonitor_checktf call=PLIbook_MyMonitor_calltf acc+=read:* acc+=callback:* diff --git a/me250300_pli/plibook_examples_unix/chapter.17/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.17/veriusertfs_table.h new file mode 100644 index 0000000..47ac79a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.17/veriusertfs_table.h @@ -0,0 +1,32 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_MyMonitor_checktf(int user_data, int reason); +extern int PLIbook_MyMonitor_calltf(int user_data, int reason); + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_MyMonitor_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_MyMonitor_calltf, /* calltf routine */ + 0, /* misctf routine */ + "$my_monitor", /* system task/function name */ + 1 /* forward reference = true */ + }, + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/chapter.18/build_MTI.mak b/me250300_pli/plibook_examples_unix/chapter.18/build_MTI.mak new file mode 100644 index 0000000..0ca9266 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/build_MTI.mak @@ -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 = \ + sci_alu_combinational_acc.c \ +# sci_alu_sequential_acc.c \ +# sci_alu_synchronized_acc.c \ +# sci_alu_latched_acc.c \ + veriuser_MTI.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:init_usertfs $(MTI_INSTALL_DIR)/win32/mtipli.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.18/build_NC.mak b/me250300_pli/plibook_examples_unix/chapter.18/build_NC.mak new file mode 100644 index 0000000..4973f1a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/build_NC.mak @@ -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 = \ + sci_alu_combinational_acc.c \ +# sci_alu_sequential_acc.c \ +# sci_alu_synchronized_acc.c \ +# sci_alu_latched_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.18/build_XL.mak b/me250300_pli/plibook_examples_unix/chapter.18/build_XL.mak new file mode 100644 index 0000000..67af9f1 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/build_XL.mak @@ -0,0 +1,21 @@ +# +# sample NMAKE makefile to make libpli.dll for Cadence Verilog-XL, using VisualC++ on Windows +# + +CDS_INST_DIR=c:/progra~1/cds + +SOURCES = \ + sci_alu_combinational_acc.c \ +# sci_alu_sequential_acc.c \ +# sci_alu_synchronized_acc.c \ +# sci_alu_latched_acc.c \ + veriuser_CDS.c + +OBJS = $(SOURCES:.c=.obj) +CFLAGS = -DMSC -DWIN32 -I$(CDS_INST_DIR)/tools/verilog/include -MD -O2 + +.c.obj: + $(CC) $(CFLAGS) -c $< + +libpli.dll: $(OBJS) + link -dll /out:$@ $(OBJS) $(CDS_INST_DIR)/tools/verilog/lib/pliinterface.lib diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_acc.c b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_acc.c new file mode 100644 index 0000000..86ab0e6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_acc.c @@ -0,0 +1,230 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using ACC routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +#define ALU_A 1 /* system task arg 1 is ALU A input */ +#define ALU_B 2 /* system task arg 2 is ALU B input */ +#define ALU_OP 3 /* system task arg 3 is ALU opcode input */ +#define ALU_RESULT 4 /* system task arg 4 is ALU result output */ +#define ALU_EXCEPT 5 /* system task arg 5 is ALU exception output */ +#define ALU_ERROR 6 /* system task arg 6 is ALU error output */ + +/********************************************************************** + * VCL simulation callback routine: Serves as an interface between + * Verilog simulation and the C model. Called whenever the C model + * inputs change value, passes the values to the C model, and puts + * the C model outputs into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_interface(p_vc_record vc_record) +{ + + double a, b, result; + int opcode, excep, err; + handle instance_h, result_h, excep_h, err_h, + a_h, b_h, opcode_h; + s_setval_value value_s; + s_setval_delay delay_s; + s_acc_time time_s; + + acc_initialize(); + + /* Retrieve instance handle from VCL user_data field */ + instance_h = (handle)vc_record->user_data; + + /* Obtain handles to all task arguments */ + a_h = acc_handle_itfarg(ALU_A, instance_h); + b_h = acc_handle_itfarg(ALU_B, instance_h); + opcode_h = acc_handle_itfarg(ALU_OP, instance_h); + result_h = acc_handle_itfarg(ALU_RESULT, instance_h); + excep_h = acc_handle_itfarg(ALU_EXCEPT, instance_h); + err_h = acc_handle_itfarg(ALU_ERROR, instance_h); + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = accRealVal; + acc_fetch_value(a_h, "%%", &value_s); + a = value_s.value.real; + + acc_fetch_value(b_h, "%%", &value_s); + b = value_s.value.real; + + value_s.format = accIntVal; + acc_fetch_value(opcode_h, "%%", &value_s); + opcode = (int)value_s.value.integer; + + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err); + + + /* Write the C model outputs onto the Verilog signals */ + delay_s.model = accNoDelay; + delay_s.time = time_s; + delay_s.time.type = accRealTime; + delay_s.time.real = 0.0; + + value_s.format = accRealVal; + value_s.value.real = result; + acc_set_value(result_h, &value_s, &delay_s); + + value_s.format = accIntVal; + value_s.value.integer = (PLI_INT32)excep; + acc_set_value(excep_h, &value_s, &delay_s); + + value_s.value.integer = (PLI_INT32)err; + acc_set_value(err_h, &value_s, &delay_s); + + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + handle instance_h, a_h, b_h, opcode_h; + + acc_initialize(); + + /* get handles for signals in task args which are C model inputs */ + a_h = acc_handle_tfarg(ALU_A); + b_h = acc_handle_tfarg(ALU_B); + opcode_h = acc_handle_tfarg(ALU_OP); + + /* get handles for this system task instance to pass to VCL app. */ + instance_h = acc_handle_tfinst(); + + /* add VCL flags to all signals which are inputs to the C model */ + /* pass handle for task instance as the user_data value */ + acc_vcl_add(a_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + acc_vcl_add(b_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + acc_vcl_add(opcode_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + + acc_close(); + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + acc_initialize(); + + if (tf_nump() != 6) + tf_error("$scientific_alu requires 6 arguments"); + + else { + if (!(acc_object_of_type(acc_handle_tfarg(ALU_A), accRealVar))) + tf_error("$scientific_alu arg 4 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_B), accRealVar))) + tf_error("$scientific_alu arg 5 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_OP), accWire))) + tf_error("$scientific_alu arg 6 must be a net\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_OP)) != 4) + tf_error("$scientific_alu arg 6 must be a 4-bit vector\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_RESULT),accRealVar))) + tf_error("$scientific_alu arg 1 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_EXCEPT), accReg))) + tf_error("$scientific_alu arg 2 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_EXCEPT)) != 1) + tf_error("$scientific_alu arg 2 must be scalar\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_ERROR), accReg))) + tf_error("$scientific_alu arg 3 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_ERROR)) != 1) + tf_error("$scientific_alu arg 3 must be scalar\n"); + } + + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_shell.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_shell.v new file mode 100644 index 0000000..4eb1fac --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_shell.v @@ -0,0 +1,39 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_test.log b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_test.log new file mode 100644 index 0000000..f87e89a --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 2 ns: result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 3 ns: result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_test.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_test.v new file mode 100644 index 0000000..5b4200c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_combinational_test.v @@ -0,0 +1,49 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_combinational_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out, excep, err); + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_acc.c b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_acc.c new file mode 100644 index 0000000..f47141c --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_acc.c @@ -0,0 +1,287 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * latched logic version (output values are stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * Definition for a structure to store output values when the ALU is + * latched. When enable is 1, the ALU returns the currently calculated + * outputs, and when 0, the ALU returns the latched previous results. + *********************************************************************/ +#include +#include +#include +#include +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + + typedef struct PLIbook_SciALUoutputs *PLIbook_SciALUoutputs_p; + typedef struct PLIbook_SciALUoutputs { + PLI_BYTE8 *instance_p; /* shows which task instance owns this space*/ + double result; /* stored result of previous operation */ + int excep; + int err; + PLIbook_SciALUoutputs_p next_ALU_outputs; /* next stack location */ + } PLIbook_SciALUoutputs_s; + + /* declare global stack pointer */ + static PLIbook_SciALUoutputs_p ALU_outputs_stack = NULL; + + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Latched outputs version. + *********************************************************************/ +void PLIbook_ScientificALU_C_model( + int enable, /* input; 0 = latched */ + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err, /* output; set if input is out of range */ + PLI_BYTE8 *instance_p) /* input; pointer to sys task instance */ +{ + PLIbook_SciALUoutputs_p ALU_outputs; + + /* Locate the output storage in the stack for this model instance */ + /* If no storage is found, then allocate a storage block and add */ + /* the storage to the stack. */ + ALU_outputs = ALU_outputs_stack; /* top-of-stack is in global var. */ + while (ALU_outputs && (ALU_outputs->instance_p != instance_p)) + ALU_outputs = ALU_outputs->next_ALU_outputs; + + /* If no storage area found for this model instance, create one */ + if (ALU_outputs == NULL) { + ALU_outputs = + (PLIbook_SciALUoutputs_p)malloc(sizeof(PLIbook_SciALUoutputs_s)); + ALU_outputs->instance_p = instance_p; /* set owner of this space */ + ALU_outputs->next_ALU_outputs = ALU_outputs_stack; + ALU_outputs_stack = ALU_outputs; /* save new top-of-stack */ + } + + if (enable) { /* ALU is not latched, calculate outputs and store */ + switch (opcode) { + case 0x0: ALU_outputs->result = pow (a, b); break; + case 0x1: ALU_outputs->result = sqrt (a); break; + case 0x2: ALU_outputs->result = exp (a); break; + case 0x3: ALU_outputs->result = ldexp (a, (int)b); break; + case 0x4: ALU_outputs->result = fabs (a); break; + case 0x5: ALU_outputs->result = fmod (a, b); break; + case 0x6: ALU_outputs->result = ceil (a); break; + case 0x7: ALU_outputs->result = floor (a); break; + case 0x8: ALU_outputs->result = log (a); break; + case 0x9: ALU_outputs->result = log10 (a); break; + case 0xA: ALU_outputs->result = sin (a); break; + case 0xB: ALU_outputs->result = cos (a); break; + case 0xC: ALU_outputs->result = tan (a); break; + case 0xD: ALU_outputs->result = asin (a); break; + case 0xE: ALU_outputs->result = acos (a); break; + case 0xF: ALU_outputs->result = atan (a); break; + } + ALU_outputs->excep = (errno == ERANGE);/* result out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + ALU_outputs->err = (_isnan(*result) || /* not-a-number, or */ + errno == EDOM); /* arg out-of-range */ + #else + ALU_outputs->err = (isnan(*result) || /* not-a-number, or */ + errno == EDOM); /* arg out-of-range */ + #endif + if (ALU_outputs->err) ALU_outputs->result = 0.0; + errno = 0; /* clear error flag */ + } + + /* return the values stored in the C model */ + *result = ALU_outputs->result; + *err = ALU_outputs->err; + *excep = ALU_outputs->excep; + + return; +} +/*********************************************************************/ + + +#define ALU_ENABLE 1 /* system task arg 1 is ALU enable input */ +#define ALU_A 2 /* system task arg 2 is ALU A input */ +#define ALU_B 3 /* system task arg 3 is ALU B input */ +#define ALU_OP 4 /* system task arg 4 is ALU opcode input */ +#define ALU_RESULT 5 /* system task arg 5 is ALU result output */ +#define ALU_EXCEPT 6 /* system task arg 6 is ALU exception output */ +#define ALU_ERROR 7 /* system task arg 7 is ALU error output */ + +/********************************************************************** + * VCL simulation callback routine: Serves as an interface between + * Verilog simulation and the C model. Called whenever the C model + * inputs change value, passes the values to the C model, and puts + * the C model outputs into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_interface(p_vc_record vc_record) +{ + + double a, b, result; + int opcode, excep, err, enable; + handle instance_h, result_h, excep_h, err_h, + a_h, b_h, opcode_h, enable_h; + s_setval_value value_s; + s_setval_delay delay_s; + s_acc_time time_s; + + acc_initialize(); + + /* Retrieve instance handle from VCL user_data field */ + instance_h = (handle)vc_record->user_data; + + /* Obtain handles to all task arguments */ + enable_h = acc_handle_itfarg(ALU_ENABLE, instance_h); + a_h = acc_handle_itfarg(ALU_A, instance_h); + b_h = acc_handle_itfarg(ALU_B, instance_h); + opcode_h = acc_handle_itfarg(ALU_OP, instance_h); + result_h = acc_handle_itfarg(ALU_RESULT, instance_h); + excep_h = acc_handle_itfarg(ALU_EXCEPT, instance_h); + err_h = acc_handle_itfarg(ALU_ERROR, instance_h); + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = accRealVal; + acc_fetch_value(a_h, "%%", &value_s); + a = value_s.value.real; + + acc_fetch_value(b_h, "%%", &value_s); + b = value_s.value.real; + + value_s.format = accIntVal; + acc_fetch_value(opcode_h, "%%", &value_s); + opcode = (int)value_s.value.integer; + + acc_fetch_value(enable_h, "%%", &value_s); + enable = (int)value_s.value.integer; + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(enable, a, b, opcode, + &result, &excep, &err, + (PLI_BYTE8 *)instance_h); + + /* Write the C model outputs onto the Verilog signals */ + delay_s.model = accNoDelay; + delay_s.time = time_s; + delay_s.time.type = accRealTime; + delay_s.time.real = 0.0; + + value_s.format = accRealVal; + value_s.value.real = result; + acc_set_value(result_h, &value_s, &delay_s); + + value_s.format = accIntVal; + value_s.value.integer = (PLI_INT32)excep; + acc_set_value(excep_h, &value_s, &delay_s); + + value_s.value.integer = (PLI_INT32)err; + acc_set_value(err_h, &value_s, &delay_s); + + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + handle instance_h, enable_h, a_h, b_h, opcode_h; + + acc_initialize(); + + /* get handles for signals in task args which are C model inputs */ + enable_h = acc_handle_tfarg(ALU_ENABLE); + a_h = acc_handle_tfarg(ALU_A); + b_h = acc_handle_tfarg(ALU_B); + opcode_h = acc_handle_tfarg(ALU_OP); + + /* get handles for this system task instance to pass to VCL app. */ + instance_h = acc_handle_tfinst(); + + /* add VCL flags to all signals which are inputs to the C model */ + /* pass handle for task instance as the user_data value */ + acc_vcl_add(enable_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + acc_vcl_add(a_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + acc_vcl_add(b_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + acc_vcl_add(opcode_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)instance_h, vcl_verilog_logic); + + acc_close(); + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + acc_initialize(); + + if (tf_nump() != 7) + tf_error("$scientific_alu requires 7 arguments"); + + else { + if (!(acc_object_of_type(acc_handle_tfarg(ALU_ENABLE), accWire))) + tf_error("$scientific_alu arg 1 must be a net\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_ENABLE)) != 1) + tf_error("$scientific_alu arg 1 must be scalar\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_A), accRealVar))) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_B), accRealVar))) + tf_error("$scientific_alu arg 3 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_OP), accWire))) + tf_error("$scientific_alu arg 4 must be a net\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_OP)) != 4) + tf_error("$scientific_alu arg 4 must be a 4-bit vector\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_RESULT),accRealVar))) + tf_error("$scientific_alu arg 5 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_EXCEPT), accReg))) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_EXCEPT)) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_ERROR), accReg))) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_ERROR)) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + } + + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_shell.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_shell.v new file mode 100644 index 0000000..a3366fd --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, latched logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(enable, a_in, b_in, opcode, + result_out, exception, error); + input enable; + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(enable, a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_test.log b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_test.log new file mode 100644 index 0000000..9fd1692 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_test.log @@ -0,0 +1,39 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: en=1 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: en=1 result1=4.00 result2=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=1 +At 2 ns: en=1 result1=8886110.52 result2=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=2 +At 3 ns: en=1 result1=64.00 result2=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: en=1 result1=16.00 result2=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: en=1 result1=0.00 result2=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: en=1 result1=16.00 result2=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: en=1 result1=16.00 result2=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: en=1 result1=2.77 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: en=1 result1=1.20 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: en=1 result1=-0.29 result2=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: en=1 result1=-0.96 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: en=1 result1=0.30 result2=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: en=1 result1=0.00 result2=8886110.52 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 14 ns: en=1 result1=0.00 result2=4.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 15 ns: en=1 result1=1.51 result2=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: en=1 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +At 26 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 27 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 28 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 29 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 30 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 31 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 32 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 33 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 34 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 35 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 36 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 37 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 38 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 39 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 40 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=e +At 41 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 42 ns: en=0 result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 52 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_test.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_test.v new file mode 100644 index 0000000..b954812 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_latched_test.v @@ -0,0 +1,61 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a latched + * logic device. + * + * 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 "sci_alu_latched_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + reg enable; + wire excep, err, excep1, err1, excep2, err2; + real a, b, result1, result2; + wire [63:0] a_in, b_in, result_out1, result_out2; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out1) result1 = $bitstoreal(result_out1); + always @(result_out2) result2 = $bitstoreal(result_out2); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (enable, a_in, b_in, opcode[3:0], result_out1, excep1, err1); + scientific_alu i2 (enable, a_in, b_in, ~opcode[3:0], result_out2, excep2, err2); + + assign err = err1 | err2; + assign excep = excep1 | excep2; + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: en=%b result1=%.2f \tresult2=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, enable, result1, result2, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + enable = 1; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + enable = 0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_acc.c b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_acc.c new file mode 100644 index 0000000..6c82ef8 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_acc.c @@ -0,0 +1,241 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Sequential logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason), + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * 0, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Sequential logic version (outputs change on a clock edge). + *********************************************************************/ +#include +#include +#include +#include +void PLIbook_ScientificALU_C_model( + int clock, /* input */ + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +#define ALU_CLOCK 1 /* system task arg 1 is ALU clock input */ +#define ALU_A 2 /* system task arg 2 is ALU A input */ +#define ALU_B 3 /* system task arg 3 is ALU B input */ +#define ALU_OP 4 /* system task arg 4 is ALU opcode input */ +#define ALU_RESULT 5 /* system task arg 5 is ALU result output */ +#define ALU_EXCEPT 6 /* system task arg 6 is ALU exception output */ +#define ALU_ERROR 7 /* system task arg 7 is ALU error output */ + +/********************************************************************** + * Definition for a structure to hold the data to be passed from + * calltf routine to the ALU interface (a VCL consumer routine). + *********************************************************************/ +typedef struct PLIbook_SciALU_data { + handle clock_h, a_h, b_h, opcode_h, result_h, excep_h, err_h; +} PLIbook_SciALU_data_s, *PLIbook_SciALU_data_p; + +/********************************************************************** + * VCL simulation callback routine: Serves as an interface between + * Verilog simulation and the C model. Called whenever the C model + * clock input changes value, reads the values of all model inputs, + * passes the values to the C model, and writes the C model outputs + * into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_interface(p_vc_record vc_record) +{ + double a, b, result; + int clock, opcode, excep, err; + s_setval_value value_s; + s_setval_delay delay_s; + s_acc_time time_s; + + PLIbook_SciALU_data_p ALUdata; + + acc_initialize(); + + /* Retrieve pointer to ALU data structure from VCL user_data field */ + ALUdata = (PLIbook_SciALU_data_p)vc_record->user_data; + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = accIntVal; + acc_fetch_value(ALUdata->clock_h, "%%", &value_s); + clock = (int)value_s.value.integer; + if (clock != 1) /* abort if not a positive edge of the clock input */ + return(0); + + value_s.format = accRealVal; + acc_fetch_value(ALUdata->a_h, "%%", &value_s); + a = value_s.value.real; + + acc_fetch_value(ALUdata->b_h, "%%", &value_s); + b = value_s.value.real; + + value_s.format = accIntVal; + acc_fetch_value(ALUdata->opcode_h, "%%", &value_s); + opcode = (int)value_s.value.integer; + + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(0, a, b, opcode, &result, &excep, &err); + + + /* Write the C model outputs onto the Verilog signals */ + delay_s.model = accNoDelay; + delay_s.time = time_s; + delay_s.time.type = accRealTime; + delay_s.time.real = 0.0; + + value_s.format = accRealVal; + value_s.value.real = result; + acc_set_value(ALUdata->result_h, &value_s, &delay_s); + + value_s.format = accIntVal; + value_s.value.integer = (PLI_INT32)excep; + acc_set_value(ALUdata->excep_h, &value_s, &delay_s); + + value_s.value.integer = (PLI_INT32)err; + acc_set_value(ALUdata->err_h, &value_s, &delay_s); + + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever the clock input to the C model changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + PLIbook_SciALU_data_p ALUdata; + + acc_initialize(); + + ALUdata=(PLIbook_SciALU_data_p)malloc(sizeof(PLIbook_SciALU_data_s)); + + /* get handles for all signals in Verilog which connect to C model */ + ALUdata->clock_h = acc_handle_tfarg(ALU_CLOCK); + ALUdata->a_h = acc_handle_tfarg(ALU_A); + ALUdata->b_h = acc_handle_tfarg(ALU_B); + ALUdata->opcode_h = acc_handle_tfarg(ALU_OP); + ALUdata->result_h = acc_handle_tfarg(ALU_RESULT); + ALUdata->excep_h = acc_handle_tfarg(ALU_EXCEPT); + ALUdata->err_h = acc_handle_tfarg(ALU_ERROR); + + /* add VCL flag to the clock input to the C model */ + /* pass pointer to storage for handles as user_data value */ + acc_vcl_add(ALUdata->clock_h, PLIbook_ScientificALU_interface, + (PLI_BYTE8 *)ALUdata, vcl_verilog_logic); + + acc_close(); + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + acc_initialize(); + + if (tf_nump() != 7) + tf_error("$scientific_alu requires 7 arguments"); + + else { + if (!(acc_object_of_type(acc_handle_tfarg(ALU_CLOCK), accWire))) + tf_error("$scientific_alu arg 1 must be a net\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_CLOCK)) != 1) + tf_error("$scientific_alu arg 1 must be scalar\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_A), accRealVar))) + tf_error("$scientific_alu arg 2 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_B), accRealVar))) + tf_error("$scientific_alu arg 3 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_OP), accWire))) + tf_error("$scientific_alu arg 4 must be a net\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_OP)) != 4) + tf_error("$scientific_alu arg 4 must be a 4-bit vector\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_RESULT),accRealVar))) + tf_error("$scientific_alu arg 5 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_EXCEPT), accReg))) + tf_error("$scientific_alu arg 6 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_EXCEPT)) != 1) + tf_error("$scientific_alu arg 6 must be scalar\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_ERROR), accReg))) + tf_error("$scientific_alu arg 7 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_ERROR)) != 1) + tf_error("$scientific_alu arg 7 must be scalar\n"); + } + + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_shell.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_shell.v new file mode 100644 index 0000000..8d04a16 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_shell.v @@ -0,0 +1,40 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, sequential logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(clock, a_in, b_in, opcode, + result_out, exception, error); + input clock; + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(clock, a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_test.log b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_test.log new file mode 100644 index 0000000..e2ab21f --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_test.log @@ -0,0 +1,36 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: clk=0 result=0.00 excep=x err=x a=16.0 b=2.0 opcode=0 +At 5 ns: clk=1 result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 10 ns: clk=0 result=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 15 ns: clk=1 result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=1 +At 20 ns: clk=0 result=4.00 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 25 ns: clk=1 result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=2 +At 30 ns: clk=0 result=8886110.52 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 35 ns: clk=1 result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 40 ns: clk=0 result=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 45 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 50 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 55 ns: clk=1 result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 60 ns: clk=0 result=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 65 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 70 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 75 ns: clk=1 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 80 ns: clk=0 result=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 85 ns: clk=1 result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 90 ns: clk=0 result=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 95 ns: clk=1 result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 100 ns: clk=0 result=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 105 ns: clk=1 result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 110 ns: clk=0 result=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 115 ns: clk=1 result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 120 ns: clk=0 result=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 125 ns: clk=1 result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 130 ns: clk=0 result=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=d +At 135 ns: clk=1 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=d +At 140 ns: clk=0 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 145 ns: clk=1 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=e +At 150 ns: clk=0 result=0.00 excep=0 err=1 a=16.0 b=2.0 opcode=f +At 155 ns: clk=1 result=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=f + +Simulation complete via $finish(1) at time 160 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_test.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_test.v new file mode 100644 index 0000000..a54de6d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_sequential_test.v @@ -0,0 +1,56 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a sequential + * logic device. + * + * 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 "sci_alu_sequential_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [3:0] opcode; + reg clk; + wire excep, err; + real a, b, result; + wire [63:0] a_in, b_in, result_out; + integer i; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out) result = $bitstoreal(result_out); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (clk, a_in, b_in, opcode, result_out, excep, err); + + always #5 clk = ~clk; + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + opcode = 0; + a = 16.0; + b = 2.0; + #0 clk = 0; + for (i=1; i<=15; i=i+1) + @(negedge clk) opcode = i; + #10 $display(""); + $finish; + end + + always @(clk) + $strobe("At %t: clk=%b result=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, clk, result, excep, err, a, b, opcode); + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_acc.c b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_acc.c new file mode 100644 index 0000000..b592905 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_acc.c @@ -0,0 +1,264 @@ +/********************************************************************** + * $scientific_alu example -- PLI application using TF routines + * + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (output values are not stored). + * + * 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 + * + * Routine definitions for a veriusertfs array: + * /* routine prototypes -/ + * extern int PLIbook_ScientificALU_checktf(int user_data, int reason); + * extern int PLIbook_ScientificALU_calltf(int user_data, int reason); + * extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc); + * /* table entries -/ + * {usertask, /* type of PLI routine -/ + * 0, /* user_data value -/ + * PLIbook_ScientificALU_checktf, /* checktf routine -/ + * 0, /* sizetf routine -/ + * PLIbook_ScientificALU_calltf, /* calltf routine -/ + * PLIbook_ScientificALU_misctf, /* misctf routine -/ + * "$scientific_alu", /* system task/function name -/ + * 1 /* forward reference = true -/ + * }, + *********************************************************************/ + +/********************************************************************** + * C model of a Scientific Arithmetic Logic Unit. + * Combinational logic version (outputs change on an input change). + *********************************************************************/ +#include +#include +#include +void PLIbook_ScientificALU_C_model( + double a, /* input */ + double b, /* input */ + int opcode, /* input */ + double *result, /* output from ALU */ + int *excep, /* output; set if result is out of range */ + int *err) /* output; set if input is out of range */ +{ + switch (opcode) { + case 0x0: *result = pow (a, b); break; + case 0x1: *result = sqrt (a); break; + case 0x2: *result = exp (a); break; + case 0x3: *result = ldexp (a, (int)b); break; + case 0x4: *result = fabs (a); break; + case 0x5: *result = fmod (a, b); break; + case 0x6: *result = ceil (a); break; + case 0x7: *result = floor (a); break; + case 0x8: *result = log (a); break; + case 0x9: *result = log10 (a); break; + case 0xA: *result = sin (a); break; + case 0xB: *result = cos (a); break; + case 0xC: *result = tan (a); break; + case 0xD: *result = asin (a); break; + case 0xE: *result = acos (a); break; + case 0xF: *result = atan (a); break; + } + *excep = (errno == ERANGE); /* result of math func. out-of-range */ + #ifdef WIN32 /* for Microsoft Windows compatibility */ + *err = (_isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #else + *err = (isnan(*result) || /* result is not-a-number, or */ + errno == EDOM); /* arg to math func. is out-of-range */ + #endif + if (*err) *result = 0.0; /* set result to 0 if error occurred */ + errno = 0; /* clear the error flag */ + return; +} +/*********************************************************************/ + + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ +#include "acc_user.h" /* IEEE 1364 PLI ACC routine library */ + +#define ALU_A 1 /* system task arg 1 is ALU A input */ +#define ALU_B 2 /* system task arg 2 is ALU B input */ +#define ALU_OP 3 /* system task arg 3 is ALU opcode input */ +#define ALU_RESULT 4 /* system task arg 4 is ALU result output */ +#define ALU_EXCEPT 5 /* system task arg 5 is ALU exception output */ +#define ALU_ERROR 6 /* system task arg 6 is ALU error output */ + +/********************************************************************** + * VCL simulation callback routine: Schedules a callback to the misctf + * application synchronized to the end of a time step. Only schedules + * one callback for a time step + *********************************************************************/ +int PLIbook_ScientificALU_interface(p_vc_record vc_record) +{ + PLI_BYTE8 *instance_p; + + /* Retrieve instance handle from VCL user_data field */ + instance_p = vc_record->user_data; + + /* If the TF work area for this instance is NULL, then no misctf */ + /* synchronize callback has been scheduled for this time step (the */ + /* work area is set to non-null by this routine, and is set to */ + /* NULL by the misctf after a callback is processed. */ + + if (tf_igetworkarea(instance_p) == NULL) { + /* Schedule a synchronize callback to misctf for this instance */ + tf_isynchronize(instance_p); + tf_isetworkarea("1", instance_p); /* set work area to non-null */ + } + + return(0); +} + +/********************************************************************** + * misctf routine: Serves as an interface between Verilog simulation + * and the C model. Called by the VCL consumer application whenever + * the C model inputs change value, reads the values of all inputs, + * passes the values to the C model, and writes the C model outputs + * into simulation. + *********************************************************************/ +int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc) +{ + double a, b, result; + int opcode, excep, err; + handle instance_h, result_h, excep_h, err_h, + a_h, b_h, opcode_h; + s_setval_value value_s; + s_setval_delay delay_s; + s_acc_time time_s; + + if (reason != REASON_SYNCH) + return(0); /* abort misctf if not called for synchronize reason */ + + acc_initialize(); + + /* Set the TF work area for this instance to null (a flag that */ + /* this callback has been processed) */ + tf_setworkarea(null); + + /* Obtain handles to all task arguments */ + a_h = acc_handle_tfarg(ALU_A); + b_h = acc_handle_tfarg(ALU_B); + opcode_h = acc_handle_tfarg(ALU_OP); + result_h = acc_handle_tfarg(ALU_RESULT); + excep_h = acc_handle_tfarg(ALU_EXCEPT); + err_h = acc_handle_tfarg(ALU_ERROR); + + /* Read current values of C model inputs from Verilog simulation */ + value_s.format = accRealVal; + acc_fetch_value(a_h, "%%", &value_s); + a = value_s.value.real; + + acc_fetch_value(b_h, "%%", &value_s); + b = value_s.value.real; + + value_s.format = accIntVal; + acc_fetch_value(opcode_h, "%%", &value_s); + opcode = (int)value_s.value.integer; + + + /****** Call C model ******/ + PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err); + + + /* Write the C model outputs onto the Verilog signals */ + delay_s.model = accNoDelay; + delay_s.time = time_s; + delay_s.time.type = accRealTime; + delay_s.time.real = 0.0; + + value_s.format = accRealVal; + value_s.value.real = result; + acc_set_value(result_h, &value_s, &delay_s); + + value_s.format = accIntVal; + value_s.value.integer = (PLI_INT32)excep; + acc_set_value(excep_h, &value_s, &delay_s); + + value_s.value.integer = (PLI_INT32)err; + acc_set_value(err_h, &value_s, &delay_s); + + acc_close(); + return(0); +} + +/********************************************************************** + * calltf routine: Registers a callback to the C model interface + * whenever any input to the C model changes value + *********************************************************************/ +int PLIbook_ScientificALU_calltf(int user_data, int reason) +{ + handle a_h, b_h, opcode_h; + PLI_BYTE8 *instance_p; + + acc_initialize(); + + /* get handles for signals in task args which are C model inputs */ + a_h = acc_handle_tfarg(ALU_A); + b_h = acc_handle_tfarg(ALU_B); + opcode_h = acc_handle_tfarg(ALU_OP); + + /* get pointer for this system task instance to pass to VCL app. */ + instance_p = tf_getinstance(); + + /* set the TF work area for this instance to null */ + tf_setworkarea(NULL); + + /* add VCL flags to all signals which are inputs to the C model */ + /* pass handle for task instance as the user_data value */ + acc_vcl_add(a_h, PLIbook_ScientificALU_interface, + instance_p, vcl_verilog_logic); + acc_vcl_add(b_h, PLIbook_ScientificALU_interface, + instance_p, vcl_verilog_logic); + acc_vcl_add(opcode_h, PLIbook_ScientificALU_interface, + instance_p, vcl_verilog_logic); + + acc_close(); + return(0); +} + +/********************************************************************** + * checktf routine: Verifies that $scientific_alu() is used correctly. + * Note: For simplicity, only limited data types are allowed for + * task arguments. Could add checks to allow other data types. + *********************************************************************/ +int PLIbook_ScientificALU_checktf(int user_data, int reason) +{ + acc_initialize(); + + if (tf_nump() != 6) + tf_error("$scientific_alu requires 6 arguments"); + + else { + if (!(acc_object_of_type(acc_handle_tfarg(ALU_A), accRealVar))) + tf_error("$scientific_alu arg 4 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_B), accRealVar))) + tf_error("$scientific_alu arg 5 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_OP), accWire))) + tf_error("$scientific_alu arg 6 must be a net\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_OP)) != 4) + tf_error("$scientific_alu arg 6 must be a 4-bit vector\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_RESULT),accRealVar))) + tf_error("$scientific_alu arg 1 must be a real variable\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_EXCEPT), accReg))) + tf_error("$scientific_alu arg 2 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_EXCEPT)) != 1) + tf_error("$scientific_alu arg 2 must be scalar\n"); + + if (!(acc_object_of_type(acc_handle_tfarg(ALU_ERROR), accReg))) + tf_error("$scientific_alu arg 3 must be a reg\n"); + else if (acc_fetch_size(acc_handle_tfarg(ALU_ERROR)) != 1) + tf_error("$scientific_alu arg 3 must be scalar\n"); + } + + acc_close(); + return(0); +} +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_shell.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_shell.v new file mode 100644 index 0000000..cb7ccee --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_shell.v @@ -0,0 +1,39 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL shell module + * + * Scientific ALU C model, combinational logic version. + * + * Note: The Verilog language does not permit floating point numbers + * to be connected to module ports. However, the language provides + * built-in system functions which convert real numbers to 64-bit + * vectors, and vice-versa, so the real values can be passed through + * a module the port connection. These built-in system functions are + * $realtobits() and $bitstoreal(). + * + * 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 scientific_alu(a_in, b_in, opcode, + result_out, exception, error); + input [63:0] a_in, b_in; + input [3:0] opcode; + output [63:0] result_out; + output exception, error; + + real a, b, result; // real variables used in this module + reg exception, error; + + // convert real numbers to/from 64-bit vector port connections + assign result_out = $realtobits(result); + always @(a_in) a = $bitstoreal(a_in); + always @(b_in) b = $bitstoreal(b_in); + + //call the PLI application which interfaces to the C model + initial + $scientific_alu(a, b, opcode, result, exception, error); + +endmodule diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_test.log b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_test.log new file mode 100644 index 0000000..6a8d32d --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_test.log @@ -0,0 +1,21 @@ +ncverilog: v3.20.(p1): (c) Copyright 1995 - 2000 Cadence Design Systems, Inc. + +At 0 ns: result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 +At 1 ns: result1=4.00 result2=0.00 excep=0 err=x a=16.0 b=2.0 opcode=1 +At 2 ns: result1=8886110.52 result2=0.00 excep=0 err=x a=16.0 b=2.0 opcode=2 +At 3 ns: result1=64.00 result2=0.30 excep=0 err=0 a=16.0 b=2.0 opcode=3 +At 4 ns: result1=16.00 result2=-0.96 excep=0 err=0 a=16.0 b=2.0 opcode=4 +At 5 ns: result1=0.00 result2=-0.29 excep=0 err=0 a=16.0 b=2.0 opcode=5 +At 6 ns: result1=16.00 result2=1.20 excep=0 err=0 a=16.0 b=2.0 opcode=6 +At 7 ns: result1=16.00 result2=2.77 excep=0 err=0 a=16.0 b=2.0 opcode=7 +At 8 ns: result1=2.77 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=8 +At 9 ns: result1=1.20 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=9 +At 10 ns: result1=-0.29 result2=0.00 excep=0 err=0 a=16.0 b=2.0 opcode=a +At 11 ns: result1=-0.96 result2=16.00 excep=0 err=0 a=16.0 b=2.0 opcode=b +At 12 ns: result1=0.30 result2=64.00 excep=0 err=0 a=16.0 b=2.0 opcode=c +At 13 ns: result1=0.00 result2=8886110.52 excep=0 err=x a=16.0 b=2.0 opcode=d +At 14 ns: result1=0.00 result2=4.00 excep=0 err=x a=16.0 b=2.0 opcode=e +At 15 ns: result1=1.51 result2=256.00 excep=0 err=0 a=16.0 b=2.0 opcode=f +At 16 ns: result1=256.00 result2=1.51 excep=0 err=0 a=16.0 b=2.0 opcode=0 + +Simulation complete via $finish(1) at time 26 NS + 0 diff --git a/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_test.v b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_test.v new file mode 100644 index 0000000..183b1b9 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/sci_alu_synchronized_test.v @@ -0,0 +1,51 @@ +/********************************************************************** + * $scientific_alu example -- Verilog HDL test bench. + * + * Verilog test bench to test the $scientific_alu C model PLI + * application. This test uses the Scientific Alu as a combinational + * logic device. + * + * 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 "sci_alu_synchronized_shell.v" + +`timescale 1ns / 1ns +module test; + + reg [4:0] opcode; + wire excep, err; + real a, b, result1, result2; + wire [63:0] a_in, b_in, result_out1, result_out2; + + // convert real numbers to/from 64-bit vector port connections + always @(result_out1) result1 = $bitstoreal(result_out1); + always @(result_out2) result2 = $bitstoreal(result_out2); + assign a_in = $realtobits(a); + assign b_in = $realtobits(b); + + scientific_alu i1 (a_in, b_in, opcode[3:0], result_out1, excep, err); + scientific_alu i2 (a_in, b_in, ~opcode[3:0], result_out2, excep, err); + + initial + begin + $display(""); //add some white space to output + $timeformat(-9,0," ns",7); + $monitor("At %t: result1=%.2f \tresult2=%.2f \t excep=%b err=%b a=%.1f b=%.1f opcode=%h", + $time, result1, result2, excep, err, a, b, opcode[3:0]); + a = 16.0; + b = 2.0; + for (opcode=0; opcode<=15; opcode=opcode+1) + #1 ; + + #10 $display(""); + $finish; + end + +endmodule + +/*********************************************************************/ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/veriuser_CDS.c b/me250300_pli/plibook_examples_unix/chapter.18/veriuser_CDS.c new file mode 100644 index 0000000..de9e3c5 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/veriuser_CDS.c @@ -0,0 +1,65 @@ +/* $Author: chas $ */ +/* $Date: 1995/01/11 00:51:12 $ */ +/* $Source: /net/thanatos/home/verilog/VDH/Repository/source/veriuser.c,v $ */ +/* $Revision: 46.5 $ */ +/* $State: Exp $ */ +/* $Locker: $ */ + +/* + * |-----------------------------------------------------------------------| + * | | + * | Copyright Cadence Design Systems, Inc. 1985, 1988. | + * | All Rights Reserved. Licensed Software. | + * | | + * | | + * | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CADENCE DESIGN SYSTEMS | + * | The copyright notice above does not evidence any actual or intended | + * | publication of such source code. | + * | | + * |-----------------------------------------------------------------------| + */ + +/* + * |-------------------------------------------------------------| + * | | + * | PROPRIETARY INFORMATION, PROPERTY OF CADENCE DESIGN SYSTEMS | + * | | + * |-------------------------------------------------------------| + */ +/***************************************************************************** +* This is the `veriuser.c' file. For more information about the contents +* of this file, please see `veriuser.doc'. +*****************************************************************************/ + +#include "veriuser.h" +#include "vxl_veriuser.h" + +char *veriuser_version_str = ""; + +int (*endofcompile_routines[])() = +{ + /*** my_eoc_routine, ***/ + 0 /*** final entry must be 0 ***/ +}; + +bool err_intercept(level,facility,code) +int level; char *facility; char *code; +{ return(true); } + +/**************** +s_tfcell veriusertfs[] = +{ + /*** Template for an entry: + { usertask|userfunction, data, + checktf(), sizetf(), calltf(), misctf(), + "$tfname", forwref?, Vtool?, ErrMsg? }, + Example: + { usertask, 0, my_check, 0, my_func, my_misctf, "$my_task" }, + ---/ + + /*** add user entries here ---/ + {0} /*** final entry must be 0 ---/ +}; +****************/ + +#include "veriusertfs_table.h" /* Use the example veriusertfs table from the PLI book */ diff --git a/me250300_pli/plibook_examples_unix/chapter.18/veriuser_MTI.c b/me250300_pli/plibook_examples_unix/chapter.18/veriuser_MTI.c new file mode 100644 index 0000000..3ceedf4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/veriuser_MTI.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Example file to register PLI applications with the Model Technology + * ModelSim simulator. + * + * For the book, "The Verilog PLI Handbook". + *********************************************************************/ + +#include "veriuser.h" + +typedef int (*p_tffn)(); + +typedef struct t_tfcell +{ + short type; /* USERTASK, USERFUNCTION, or USERREALFUNCTION */ + short data; /* passed as data argument of callback function */ + p_tffn checktf; /* argument checking callback function */ + p_tffn sizetf; /* function return size callback function */ + p_tffn calltf; /* task or function call callback function */ + p_tffn misctf; /* miscellaneous reason callback function */ + char *tfname; /* name of system task or function */ + + /* The following fields are ignored by ModelSim Verilog */ + int forwref; + char *tfveritool; + char *tferrmessage; + int hash; + struct t_tfcell *left_p; + struct t_tfcell *right_p; + char *namecell_p; + int warning_printed; +} s_tfcell, *p_tfcell; +/* values for 'type' field in tfcell structure */ +#define usertask 1 +#define USERTASK 1 +#define userfunction 2 +#define USERFUNCTION 2 +#define userrealfunction 3 +#define USERREALFUNCTION 3 + + +#include "veriusertfs_table.h" + + +void init_usertfs() +{ + p_tfcell usertf; + + for (usertf = veriusertfs; usertf; usertf++) { + if (usertf->type == 0) + return; + mti_RegisterUserTF(usertf); + } +} diff --git a/me250300_pli/plibook_examples_unix/chapter.18/veriuser_VCS.tab b/me250300_pli/plibook_examples_unix/chapter.18/veriuser_VCS.tab new file mode 100644 index 0000000..dd632d6 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/veriuser_VCS.tab @@ -0,0 +1,5 @@ +// Example Synopsys VCS PLI table to register PLI applications +// For the book, "The Verilog PLI Handbook" + +$scientific_alu data=0 check=PLIbook_ScientificALU_checktf call=PLIbook_ScientificALU_calltf acc+=read_write:* acc+=callback:* +//$scientific_alu data=0 check=PLIbook_ScientificALU_checktf call=PLIbook_ScientificALU_calltf misc=PLIbook_ScientificALU_misctf acc+=read_write:* acc+=callback:* diff --git a/me250300_pli/plibook_examples_unix/chapter.18/veriusertfs_table.h b/me250300_pli/plibook_examples_unix/chapter.18/veriusertfs_table.h new file mode 100644 index 0000000..7b29044 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/chapter.18/veriusertfs_table.h @@ -0,0 +1,34 @@ +/********************************************************************** + * Example veriusertfs table that is used by many Verilog simulators + * to register PLI applications that use the TF and ACC libraries of + * the IEEE 1364 PLI. + * + * 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 + *********************************************************************/ + +/* prototypes of the PLI application routines */ +extern int PLIbook_ScientificALU_checktf(int user_data, int reason); +extern int PLIbook_ScientificALU_calltf(int user_data, int reason); +/* extern int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc); /* */ + +/* the veriusertfs table */ +s_tfcell veriusertfs[] = +{ + {usertask, /* type of PLI routine */ + 0, /* user_data value */ + PLIbook_ScientificALU_checktf, /* checktf routine */ + 0, /* sizetf routine */ + PLIbook_ScientificALU_calltf, /* calltf routine */ +/* PLIbook_ScientificALU_misctf, /* misctf routine */ + 0, /* NO misctf routine */ + "$scientific_alu", /* system task/function name */ + 1 /* forward reference = true */ + }, /* */ + + {0} /*** final entry must be 0 ***/ +}; + diff --git a/me250300_pli/plibook_examples_unix/vpi_1995_compat.h b/me250300_pli/plibook_examples_unix/vpi_1995_compat.h new file mode 100644 index 0000000..bb15ff4 --- /dev/null +++ b/me250300_pli/plibook_examples_unix/vpi_1995_compat.h @@ -0,0 +1,185 @@ +/********************************************************************** + * VPI 1995 Compatibilty Kludges -- PLI application using VPI routines + * + * C source for functions to implement a few Verilog-2001 VPI routines + * that did not exist in the Verilog-1995 standard. + * + * NOTE: THESE ROUTINES ARE INTENDED AS A TEMPORARY WORK AROUND FOR + * TESTING PURPOSES ONLY. THEY ARE KLUDGES FOR SIMULATORS THAT HAVE + * NOT YET IMPLEMENTED THE FULL IEEE 1364-2001 STANDARD. THE ROUTINES + * USE THE SAME NAME AS THE IEEE STANDARD, AND THEREFORE WILL CONFLICT + * WITH SIMULATORS THAT HAVE IMPLEMENTED THE STARDARD ROUTINES. + * + * Usage: + * vpi_control(operation_constant, ...); + * Controls certain simulation functions. The only operation + * constants implemented are vpiStop and vpiFinish. Other + * constants are ignored. + * + * vpi_put_userdata(systf_handle, value); + * Stores a value in a work area that is unique to each instance + * of a system task/function. + * + * value = vpi_get_userdata(systf_handle); + * Retreives the value stored in the work area for a specific + * instance of a system task/function. + * + * 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 2001, Sutherland HDL Inc, Portland, Oregon, USA + * Contact: www.sutherland-hdl.com + *********************************************************************/ + +#include /* ANSI C standard library */ +#include /* ANSI C standard input/output library */ +#include /* ANSI C standard arguments library */ +#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */ +#include "veriuser.h" /* IEEE 1364 PLI TF routine library */ + +#define PLIbookDebug 1 /* set to non-zero for verbose debug messages */ + +#define CONTROL 1 /* set to non-zero for vpi_control() kludge */ +#define USERDATA 0 /* set to non-zero for vpi_put/get_userdata() kludge */ + +#if CONTROL +PLI_INT32 vpi_control(PLI_INT32 operation, ...); + +/********************************************************************** + * vpi_control() + * Allows a PLI application to control certain aspects of simulation. + * - vpi_control(vpiStop, n) is mapped to tf_dostop(); + * - vpi_control(vpiFinish, n) is mapped to tf_dofinish(); + * + * This routine does not implement the all the features of the + * vpi_control() defined in the Verilog-2001 standard. It only + * implements two of the control constants, does not implement the + * arguments to the controls, and always returns a 1, without + * checking to see if the functionality was successful. + *********************************************************************/ + +PLI_INT32 vpi_control(PLI_INT32 operation, ...) { + #define vpiStop 66 /* execute simulator's $stop */ + #define vpiFinish 67 /* execute simulator's $finish */ + #define vpiReset 68 /* execute simulator's $reset */ + #define vpiSetInteractiveScope 69 /* set simulator's interactive scope */ + + switch(operation) { + case vpiStop: tf_dostop(); /* halt simulation */ + break; + case vpiFinish: tf_dofinish(); /* abort simulation */ + break; + } + return(1); +} +#endif /* conditional compilation for vpi_control() */ + + +#if USERDATA + +void *vpi_get_userdata(vpiHandle obj); +PLI_INT32 vpi_put_userdata (vpiHandle systf_h, void *userdata); + +/********************************************************************** + * vpi_put_userdata() + * Stores a data value in the work area for a specific system + * task/function instance. Emulates the vpi_put_userdata() added in + * the Verilog-2001 standard. Similar to tf_setworkarea(). + * + * This routine automatically allocates a work area that is specific + * to an instance of a system task or system function. The work area + * is created using a simple LIFO stack so that a work area can be + * allocated for any number of system task/function instances. Only + * one work area per task/function instance will be allocated. + * + * The work area stores a void* pointer in its data field. The data + * can be retrieved using vpi_get_userdata(). + * + * NOTE: no thought or effort was put into memory efficiency or + * simulation performance. This function is only provided as a + * kludge for simulators that have not yet implented the full + * Verilog-2001 standard. + *********************************************************************/ + +/* Work area structure definition */ +typedef struct PLIbook_userdata *PLIbook_userdata_p; +typedef struct PLIbook_userdata { + vpiHandle systf_h; /* shows which systf instance owns this space */ + void *data; /* data to be stored in userdata */ + PLIbook_userdata_p next_PLIbook_userdata; +} PLIbook_userdata_s; + +/* allocate a global stack pointer for all task/function instances */ +static PLIbook_userdata_p PLIbook_userdata_stack = NULL; + + +PLI_INT32 vpi_put_userdata (vpiHandle systf_h, void *userdata) +{ + PLIbook_userdata_p tfinst_userdata; + + /* get top-of-stack pointer from global stack pointer */ + tfinst_userdata = PLIbook_userdata_stack; + + /* locate the userdata in the stack for this task instance */ + if (tfinst_userdata != NULL) { + while (tfinst_userdata && + !vpi_compare_objects(tfinst_userdata->systf_h, systf_h) ) { + tfinst_userdata = tfinst_userdata->next_PLIbook_userdata; + } + } + + /* if no work area found for this task instance, create one */ + if (tfinst_userdata == NULL) { + tfinst_userdata = (PLIbook_userdata_p)malloc(sizeof(PLIbook_userdata_s)); + tfinst_userdata->systf_h = systf_h; /* set owner of this userdata */ + if (PLIbook_userdata_stack == NULL) { + /* work area stack doesn't exist yet, create first location */ + tfinst_userdata->next_PLIbook_userdata = NULL; + PLIbook_userdata_stack = tfinst_userdata; + } + else { + tfinst_userdata->next_PLIbook_userdata = PLIbook_userdata_stack; + PLIbook_userdata_stack = tfinst_userdata; /* set new top-of-stack */ + } + } + if (tfinst_userdata == NULL) { + #ifdef PLIbookDebug /* generate verbose debug message */ + vpi_printf("ERROR: failed to allocate userdata for this task instance\n"); + #endif + return(0); /* return 0 for error */ + } + + /* store user's data in the userdata area */ + tfinst_userdata->data = userdata; + return(1); /* return 1 for successful */ +} + +/********************************************************************** + * vpi_get_userdata() + * Returns the data stored in the work area for a specific system + * task/function instance. Similar to tf_getworkarea(). A NULL is + * returned if unsuccessful. + *********************************************************************/ +void *vpi_get_userdata(vpiHandle systf_h) +{ + PLIbook_userdata_p tfinst_userdata; + + /* locate the userdata in the stack for this task instance */ + tfinst_userdata = PLIbook_userdata_stack; /* top-of-stack pointer */ + if (tfinst_userdata != NULL) { + while (tfinst_userdata && + !vpi_compare_objects(tfinst_userdata->systf_h, systf_h) ) { + tfinst_userdata = tfinst_userdata->next_PLIbook_userdata; + } + } + if (tfinst_userdata == NULL) { + #ifdef PLIbookDebug /* generate verbose debug message */ + vpi_printf("Warning: no userdata storage found for this task instance\n"); + #endif + return(NULL); + } + return(tfinst_userdata->data); +} +#endif /* end of conditional compilation for vpi_put/get_userdata() */ + +/*********************************************************************/