diff --git a/.cvsignore b/.cvsignore index eb555c269..5ff32a9eb 100644 --- a/.cvsignore +++ b/.cvsignore @@ -7,6 +7,7 @@ dep configure Makefile verilog +gverilog config.status config.log config.cache diff --git a/Makefile.in b/Makefile.in index 44289de00..866460b97 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,12 +18,12 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.30 1999/11/29 17:02:21 steve Exp $" +#ident "$Id: Makefile.in,v 1.31 1999/12/18 04:15:01 steve Exp $" # # SHELL = /bin/sh -VERSION = 0.0 +VERSION = 0.2PRE prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -47,7 +47,7 @@ CPPFLAGS = @CPPFLAGS@ @DEFS@ CXXFLAGS = @CXXFLAGS@ -I$(srcdir) LDFLAGS = @LDFLAGS@ -all: ivl verilog +all: ivl verilog gverilog cd vpi ; $(MAKE) all cd vvm ; $(MAKE) all cd ivlpp ; $(MAKE) all @@ -96,6 +96,9 @@ verilog: $(srcdir)/verilog.sh ivl: $O $(CXX) $(CXXFLAGS) -o ivl $O +gverilog: gverilog.c + $(CC) $(CPPFLAGS) -o gverilog -DLIBDIR='"@libdir@"' -DINCDIR='"@includedir@"' gverilog.c + %.o dep/%.d: %.cc @[ -d dep ] || mkdir dep $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o @@ -113,7 +116,7 @@ parse.h parse.cc: $(srcdir)/parse.y lexor.cc: $(srcdir)/lexor.lex flex -PVL -s -olexor.cc $(srcdir)/lexor.lex -install: all installdirs $(bindir)/verilog $(bindir)/ivl $(mandir)/man1/verilog.1 +install: all installdirs $(bindir)/verilog $(bindir)/gverilog $(bindir)/ivl $(mandir)/man1/verilog.1 cd vpi ; $(MAKE) install cd vvm ; $(MAKE) install cd ivlpp ; $(MAKE) install @@ -121,6 +124,9 @@ install: all installdirs $(bindir)/verilog $(bindir)/ivl $(mandir)/man1/verilog. $(bindir)/verilog: ./verilog $(INSTALL_PROGRAM) ./verilog $(bindir)/verilog +$(bindir)/gverilog: ./gverilog + $(INSTALL_PROGRAM) ./gverilog $(bindir)/gverilog + $(bindir)/ivl: ivl $(INSTALL_PROGRAM) ./ivl $(bindir)/ivl $(STRIP) $(bindir)/ivl diff --git a/gverilog.c b/gverilog.c new file mode 100644 index 000000000..882770e8c --- /dev/null +++ b/gverilog.c @@ -0,0 +1,390 @@ +/* + * gvlog.c - A driver for verilog compiler ivl + * Copyright (C) 1999 Stefan Petersen (spe@geda.seul.org) + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + + +#ifndef LIBDIR +# define LIBDIR "/usr/local/lib" +#endif +#ifndef INCLUDEDIR +# define INCLUDEDIR "/usr/local/include" +#endif + +#define REMOVE "rm -f" +#define MOVE "mv" + +#define P_IF_SET(var) var.set ? var.name : "" + +/* Div compiler settings */ +struct compset { + char compsw[5]; + char name[50]; + int set; +}; + +/* cpp include path */ +struct compset cppincdir = {"-I", INCLUDEDIR, 1}; + +/* cpp library path */ +struct compset cpplibdir ={"-L", LIBDIR, 1}; + +/* VPI module path */ +struct compset VPImodpath = {"-f", LIBDIR "/ivl", 1}; + +/* ivl include path */ +struct compset ivlppincdir = {"-I", "", 0}; + +/* ivl defines */ +struct compset ivlppdefines = {"-D", "", 0}; + +/* ivl target setup */ +/* Compilation target, default vvm */ +typedef enum {VVM, XNF, OTHER} targettype; +struct target { + targettype target; + struct compset targetinfo; +}; +struct target target = {VVM, {"-t", "vvm", 0}}; + +/* output file */ +struct compset outputfile = {"-o", "", 0}; + +/* topmodule name */ +struct compset topmodule = {"-s", "", 0}; + +/* verilog files */ +char verilogfiles[50] = ""; + + +/* Temp files for storage */ +char tmpPPfile[50]; +char tmpCCfile[50]; + +/* Compilation flag info */ +struct compileinfo { + int pform; + int execute; + int elabnetlist; +}; +struct compileinfo compileinfo = {0, 0, 0}; + + +void sorry(char optelem) +{ + printf("Sorry, switch -%c not implemented yet!\n", optelem); +} + + +targettype resolvtarget(char *target) +{ + if (strcmp(target, "vvm") == 0) + return VVM; + else if (strcmp(target, "xnf") == 0) + return XNF; + else + return OTHER; +} + + +void error_exit(void) +{ + fprintf(stderr, "verilog [-Dmacro[=defn]] [-Iincludepath] [-X] \n"); + fprintf(stderr, "[-x] [-o outputfilename] [-s topmodule] sourcefile[s]\n"); + exit(1); +} + + +void create_outputfilename(char *input, char *output) +{ + int dotpos=0; + int spacepos=0; + int i=0; + + dotpos = strlen(input); + for(i=dotpos; i!=0; i--){ + if ((dotpos == 0) && (input[i] == '.')) dotpos = i; + if ((spacepos == 0) && (input[i] == ' ')) spacepos = i; + } + + if ((dotpos != 0) && (dotpos > spacepos)) { + output = strncpy(output, &input[spacepos+1], dotpos-spacepos-3); + } + + return; +} + + +void preprocess(void) +{ + char *argument; + + argument = (char *)malloc(256); + + sprintf(argument, "ivlpp %s %s -L -o%s %s", + P_IF_SET(ivlppdefines), + P_IF_SET(ivlppincdir), + tmpPPfile, + verilogfiles); +#if DEBUG + printf("Executing command : \n%s\n", argument); +#else + if (system(argument)) { + fprintf(stderr, "Preprocessing failed. Terminating compilation\n"); + sprintf(argument, "%s %s", REMOVE, tmpPPfile); + system(argument); + free(argument); + exit(1); + } +#endif + + free(argument); + return; +} + + +void compile(void) +{ + char *argument; + + argument = (char *)malloc(256); + + sprintf(argument, "ivl %s %s %s -o %s %s", + P_IF_SET(topmodule), + target.targetinfo.compsw, + target.targetinfo.name, + /* compileinfo.pform ? "-P whatever_pform" : "", + compileinfo.elabnetlist ? "-E whatever_netlist" : "", */ + tmpCCfile, + tmpPPfile); +#if DEBUG + printf("Executing command : \n%s\n", argument); +#else + if (system(argument)) { + fprintf(stderr, "Compilation failed. Terminating compilation\n"); + sprintf(argument, "%s %s", REMOVE, tmpCCfile); + system(argument); + free(argument); + exit(1); + } +#endif + + + sprintf(argument, "%s %s", REMOVE, tmpPPfile); +#if DEBUG + printf("Executing command:\n %s\n", argument); +#else + system(argument); +#endif + + free(argument); + return; +} + + +void postprocess(void) +{ + char *argument; + + /* Hopefully not filling stack with large array */ + argument = malloc(256); + + switch (target.target) { + case VVM: /* Compile C++ source */ + + sprintf(argument, "g++ -rdynamic %s%s %s%s %s -o %s -lvvm -ldl", + cppincdir.compsw, cppincdir.name, /* Include dir */ + cpplibdir.compsw, cpplibdir.name, /* Library dir */ + tmpCCfile, + outputfile.name); +#if DEBUG + printf("Executing command :\n%s\n", argument); +#else + if (system(argument)) { + fprintf(stderr, "g++ compilation failed. Terminating compilation\n"); + sprintf(argument, "%s %s", REMOVE, tmpCCfile); + system(argument); + free(argument); + exit(1); + } +#endif + + sprintf(argument, "%s %s", REMOVE, tmpCCfile); +#if DEBUG + printf("Executing command :\n%s\n", argument); +#else + system(argument); +#endif + + break; + case XNF: /* Just move file as is */ + sprintf(argument, "%s %s %s.xnf", MOVE, tmpCCfile, outputfile.name); +#if DEBUG + printf("Executing command :\n%s\n", argument); +#else + system(argument); +#endif + break; + case OTHER: /* Just move file as is */ + sprintf(argument, "mv %s %s.%s", + tmpCCfile, + outputfile.name, + target.targetinfo.name); +#if DEBUG + printf("Executing command :\n%s\n", argument); +#else + system(argument); +#endif + break; + default: + fprintf(stderr, "Illegal target. This should never happen.\n"); + error_exit(); + } + + if (compileinfo.execute) { +#if DEBUG + printf("Executing command :\n%s\n", outputfile.name); +#else + system(outputfile.name); +#endif + } + + + free(argument); + return; +} + + + +void main(int argc, char **argv) +{ + const char optstring[] = "D:I:Xxf:o:s:t:EP"; + int optelem = 0; + + + while ((optelem = getopt(argc, argv, optstring)) != EOF) { + /*#if DEBUG + if (optarg == NULL) + printf("Option element %c\n", (char)optelem); + else + printf("Option element %c %s\n", (char)optelem, optarg); + #endif*/ + + switch ((char)optelem) { + case 'D': /* defines */ + sprintf(ivlppdefines.name, "%s %s%s", ivlppdefines.name, + ivlppdefines.compsw, optarg); + ivlppdefines.set =1; + break; + case 'I': /* includepath */ + sprintf(ivlppincdir.name, "%s %s %s", ivlppincdir.name, + ivlppincdir.compsw, optarg); + ivlppincdir.set = 1; + break; + case 'X': /* xnf target */ + if (target.targetinfo.set) + fprintf(stderr, "Target already set to %s\n", target.targetinfo.name); + else { + sprintf(target.targetinfo.name,"%s xnf", target.targetinfo.compsw); + target.targetinfo.set = 1; + target.target = XNF; + } + break; + case 'x': /* execute */ + compileinfo.execute = 1; + break; + case 'f': /* flags? */ + sorry((char)optelem); + break; + case 'o': /* output file */ + if (outputfile.set) + fprintf(stderr, "Output filename already set to %s\n", + outputfile.name); + else { + sprintf(outputfile.name, "%s", optarg); + outputfile.set = 1; + } + break; + case 's': /* top module */ + if (topmodule.set) + fprintf(stderr, "Topmodule name already set to %s\n", topmodule.name); + else { + sprintf(topmodule.name, "%s %s", topmodule.compsw, optarg); + topmodule.set = 1 ; + } + break; + case 't': /* code target */ + if (target.targetinfo.set) + fprintf(stderr, "Target already set to %s\n", target.targetinfo.name); + else { + sprintf(target.targetinfo.name, "%s", optarg); + target.targetinfo.set = 1; + target.target = resolvtarget(target.targetinfo.name); + } + break; + case 'E': /* elaborated netlist */ + compileinfo.elabnetlist = 1; + break; + case 'P': /* dump pform */ + compileinfo.pform = 1; + break; + case '?': + fprintf(stderr, "Not defined commandswitch\n", argv[optind]); + error_exit(); + default: + fprintf(stderr, "Not handled commandswitch %s\n", argv[optind]); + error_exit(); + } + + } + + if (optind == argc){ + fprintf(stderr, "Missing infile(s)\n"); + error_exit(); + } + + /* Resolve temporary file storage */ + sprintf(tmpPPfile, "/tmp/ivl%d.pp", (int)getpid()); + sprintf(tmpCCfile, "/tmp/ivl%d.cc", (int)getpid()); + /*#if DEBUG + printf("Temporary files are %s and %s\n", tmpPPfile, tmpCCfile); + #endif */ + + /* Build list of verilog files */ + for(; optind != argc; optind++) { + sprintf(verilogfiles, "%s %s", verilogfiles, argv[optind]); + } + + /* Determine output filename if not explicitly set */ + if (!outputfile.set) { + create_outputfilename(verilogfiles, outputfile.name); + } + + + preprocess(); + + compile(); + + postprocess(); + + return; +}