From 6466d02eda6cdc5710c67ebdd12d247ba5e535bc Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 20 Oct 2001 23:02:39 +0000 Subject: [PATCH] Add automatic module libraries. --- Makefile.in | 4 +- compiler.h | 13 +- driver/build_string.c | 12 +- driver/globals.h | 8 +- driver/iverilog.man | 25 +++- driver/main.c | 26 +++- elaborate.cc | 313 ++++++------------------------------------ iverilog.conf | 18 +-- lexor.lex | 10 +- load_module.cc | 61 ++++++++ main.cc | 46 ++++--- pform.cc | 152 +++++--------------- pform.h | 7 +- util.h | 13 +- 14 files changed, 278 insertions(+), 430 deletions(-) create mode 100644 load_module.cc diff --git a/Makefile.in b/Makefile.in index 2eb50c90b..a0ff4a712 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.106 2001/10/19 23:15:01 steve Exp $" +#ident "$Id: Makefile.in,v 1.107 2001/10/20 23:02:39 steve Exp $" # # SHELL = /bin/sh @@ -115,7 +115,7 @@ O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \ elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \ elab_sig.o emit.o eval.o eval_rconst.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ -mangle.o netlist.o netmisc.o net_assign.o \ +load_module.o mangle.o netlist.o netmisc.o net_assign.o \ net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \ net_scope.o net_udp.o pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ diff --git a/compiler.h b/compiler.h index f4193ec6f..f1b64990e 100644 --- a/compiler.h +++ b/compiler.h @@ -19,9 +19,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $" +#ident "$Id: compiler.h,v 1.6 2001/10/20 23:02:40 steve Exp $" #endif +# include + /* * This defines constants and defaults for the compiler in general. */ @@ -66,8 +68,17 @@ /* Implicit definitions of wires. */ extern bool warn_implicit; +/* This is true if verbose output is requested. */ +extern bool verbose_flag; + +/* This is an ordered list of libraries to search. */ +extern listlibrary_dirs; + /* * $Log: compiler.h,v $ + * Revision 1.6 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.5 2000/10/31 17:49:02 steve * Support time variables. * diff --git a/driver/build_string.c b/driver/build_string.c index f3a704256..3dca20a43 100644 --- a/driver/build_string.c +++ b/driver/build_string.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: build_string.c,v 1.4 2001/07/25 03:10:50 steve Exp $" +#ident "$Id: build_string.c,v 1.5 2001/10/20 23:02:40 steve Exp $" #endif # include "config.h" @@ -129,6 +129,13 @@ int build_string(char*output, size_t olen, const char*pattern) olen -= strlen(warning_flags); break; + case 'y': + if (library_flags) { + strcpy(output, library_flags); + output += strlen(library_flags); + olen -= strlen(library_flags); + } + break; } pattern += 1; @@ -144,6 +151,9 @@ int build_string(char*output, size_t olen, const char*pattern) /* * $Log: build_string.c,v $ + * Revision 1.5 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.4 2001/07/25 03:10:50 steve * Create a config.h.in file to hold all the config * junk, and support gcc 3.0. (Stephan Boettcher) diff --git a/driver/globals.h b/driver/globals.h index a09b0b135..9ad83fd2c 100644 --- a/driver/globals.h +++ b/driver/globals.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: globals.h,v 1.4 2001/07/03 04:09:25 steve Exp $" +#ident "$Id: globals.h,v 1.5 2001/10/20 23:02:40 steve Exp $" #endif # include @@ -56,12 +56,18 @@ extern int verbose_flag; extern char warning_flags[]; + /* -y flags from the command line. */ +extern char* library_flags; + extern const char*lookup_pattern(const char*key); extern int build_string(char*out, size_t olen, const char*pattern); /* * $Log: globals.h,v $ + * Revision 1.5 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.4 2001/07/03 04:09:25 steve * Generate verbuse status messages (Stephan Boettcher) * diff --git a/driver/iverilog.man b/driver/iverilog.man index 398fa9927..38a91d5f0 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -1,10 +1,12 @@ -.TH iverilog 1 "$Date: 2001/08/31 17:28:10 $" Version "$Date: 2001/08/31 17:28:10 $" +.TH iverilog 1 "$Date: 2001/10/20 23:02:40 $" Version "$Date: 2001/10/20 23:02:40 $" .SH NAME iverilog - Icarus Verilog compiler .SH SYNOPSIS .B iverilog -[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value] [-Iincludepath] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] sourcefile +[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value] +[-Iincludepath] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule] +[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile .SH DESCRIPTION .PP @@ -117,6 +119,25 @@ Turn on different classes of warnings. See the \fBWARNING TYPES\fP section below for desctriptions of the different warning groups. If multiple \fB-W\fP switches are used, the warning set is the union of all the requested classes. +.TP 8 +.B -y\fIlibdir\fp +Append the directory to the library module search path. When the +compiler finds an undefined module, it looks in these directories for +files with the right name. + +.SH MODULE LIBRARIES + +The Icarus Verilog compiler supports module libraries as directories +that contain Verilog source files. During elaboration, the compiler +notices the instantiation of undefined module types. If the user +specifies library search directories, the compiler will search the +directory for files with the name of the missing module type. If it +finds such a file, it loads it as a Verilog source file, they tries +again to elaborate the module. + +Library module files should contain only a single module, but this is +not a requirement. Library modules may reference other modules in the +library or in the main design. .SH TARGETS diff --git a/driver/main.c b/driver/main.c index 43cdc8350..818ba66fa 100644 --- a/driver/main.c +++ b/driver/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: main.c,v 1.23 2001/10/19 23:10:08 steve Exp $" +#ident "$Id: main.c,v 1.24 2001/10/20 23:02:40 steve Exp $" # include "config.h" @@ -25,7 +25,7 @@ const char HELP[] = " [-D macro[=defn]] [-I includedir] [-m module]\n" " [-N file] [-o filename] [-p flag=value]\n" " [-s topmodule] [-t target] [-T min|typ|max]\n" -" [-W class] source_file(s)\n" +" [-W class] [-y dur] source_file(s)\n" "See man page for details."; #define MAXSIZE 4096 @@ -87,6 +87,7 @@ const char*targ = "vvp"; const char*start = 0; char warning_flags[16] = ""; +char *library_flags = 0; char*inc_list = 0; char*def_list = 0; @@ -340,6 +341,19 @@ static void process_warning_switch(const char*name) } } +static void process_library_switch(const char *name) +{ + if (library_flags) { + library_flags = realloc(library_flags, + strlen(library_flags) + strlen(name) + 5); + strcat(library_flags, " -y "); + } else { + library_flags = malloc(strlen(name) + 4); + strcpy(library_flags, "-y "); + } + strcat(library_flags, name); +} + int main(int argc, char **argv) { const char*config_path = 0; @@ -386,7 +400,7 @@ int main(int argc, char **argv) base = ivl_root; #endif - while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:")) != EOF) { + while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:y:")) != EOF) { switch (opt) { case 'B': @@ -498,6 +512,9 @@ int main(int argc, char **argv) case 'W': process_warning_switch(optarg); break; + case 'y': + process_library_switch(optarg); + break; case '?': default: return 1; @@ -644,6 +661,9 @@ int main(int argc, char **argv) /* * $Log: main.c,v $ + * Revision 1.24 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.23 2001/10/19 23:10:08 steve * Fix memory fault with -c flag. * diff --git a/elaborate.cc b/elaborate.cc index e72d9cc49..e9df4a753 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.222 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: elaborate.cc,v 1.223 2001/10/20 23:02:40 steve Exp $" #endif # include "config.h" @@ -37,12 +37,7 @@ # include "netlist.h" # include "netmisc.h" # include "util.h" - - // Urff, I don't like this global variable. I *will* figure out a - // way to get rid of it. But, for now the PGModule::elaborate method - // needs it to find the module definition. -static const map* modlist = 0; -static const map* udplist = 0; +# include "parse_api.h" static Link::strength_t drive_type(PGate::strength_t drv) { @@ -705,8 +700,8 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const bool PGModule::elaborate_sig(Design*des, NetScope*scope) const { // Look for the module type - map::const_iterator mod = modlist->find(type_); - if (mod != modlist->end()) + map::const_iterator mod = pform_modules.find(type_); + if (mod != pform_modules.end()) return elaborate_sig_mod_(des, scope, (*mod).second); return true; @@ -716,15 +711,15 @@ bool PGModule::elaborate_sig(Design*des, NetScope*scope) const void PGModule::elaborate(Design*des, const string&path) const { // Look for the module type - map::const_iterator mod = modlist->find(type_); - if (mod != modlist->end()) { + map::const_iterator mod = pform_modules.find(type_); + if (mod != pform_modules.end()) { elaborate_mod_(des, (*mod).second, path); return; } // Try a primitive type - map::const_iterator udp = udplist->find(type_); - if (udp != udplist->end()) { + map::const_iterator udp = pform_primitives.find(type_); + if (udp != pform_primitives.end()) { elaborate_udp_(des, (*udp).second, path); return; } @@ -736,18 +731,38 @@ void PGModule::elaborate(Design*des, const string&path) const void PGModule::elaborate_scope(Design*des, NetScope*sc) const { // Look for the module type - map::const_iterator mod = modlist->find(type_); - if (mod != modlist->end()) { + map::const_iterator mod = pform_modules.find(type_); + if (mod != pform_modules.end()) { elaborate_scope_mod_(des, (*mod).second, sc); return; } // Try a primitive type - map::const_iterator udp = udplist->find(type_); - if (udp != udplist->end()) + map::const_iterator udp = pform_primitives.find(type_); + if (udp != pform_primitives.end()) return; + // Not a module or primitive that I know about yet, so try to + // load a library module file (which parses some new Verilog + // code) and try again. + if (load_module(type_.c_str())) { + // Try again to find the module type + mod = pform_modules.find(type_); + if (mod != pform_modules.end()) { + elaborate_scope_mod_(des, (*mod).second, sc); + return; + } + + // Try again to find a primitive type + udp = pform_primitives.find(type_); + if (udp != pform_primitives.end()) + return; + } + + + // Not a module or primitive that I know about or can find by + // any means, so give up. cerr << get_line() << ": error: Unknown module type: " << type_ << endl; des->errors += 1; } @@ -2283,9 +2298,7 @@ struct root_elem { NetScope *scope; }; -Design* elaborate(const map&modules, - const map&primitives, - listroots) +Design* elaborate(listroots) { svector root_elems(roots.size()); bool rc = true; @@ -2295,15 +2308,15 @@ Design* elaborate(const map&modules, // module and elaborate what I find. Design*des = new Design; - modlist = &modules; - udplist = &primitives; + for (list::const_iterator root = roots.begin() + ; root != roots.end() + ; root++) { - for (list::const_iterator root = roots.begin(); - root != roots.end(); root++) { - // Look for the root module in the list. - map::const_iterator mod = modules.find(*root); - if (mod == modules.end()) { - cerr << "Unable to find root module \"" << (*root) << "\"." << endl; + // Look for the root module in the list. + map::const_iterator mod = pform_modules.find(*root); + if (mod == pform_modules.end()) { + cerr << "Unable to find root module \"" + << (*root) << "\"." << endl; des->errors++; continue; } @@ -2358,9 +2371,6 @@ Design* elaborate(const map&modules, } - modlist = 0; - udplist = 0; - if (rc == false) { delete des; des = 0; @@ -2372,248 +2382,13 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.223 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.222 2001/10/20 05:21:51 steve * Scope/module names are char* instead of string. * * Revision 1.221 2001/10/19 21:53:24 steve * Support multiple root modules (Philip Blundell) - * - * Revision 1.220 2001/08/25 23:50:02 steve - * Change the NetAssign_ class to refer to the signal - * instead of link into the netlist. This is faster - * and uses less space. Make the NetAssignNB carry - * the delays instead of the NetAssign_ lval objects. - * - * Change the vvp code generator to support multiple - * l-values, i.e. concatenations of part selects. - * - * Revision 1.219 2001/08/01 05:17:31 steve - * Accept empty port lists to module instantiation. - * - * Revision 1.218 2001/07/28 22:13:11 steve - * Detect a missing task definition before it crashes me. - * - * Revision 1.217 2001/07/25 03:10:49 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.216 2001/07/19 03:43:15 steve - * Do not connect reg to module outputs. - * - * Revision 1.215 2001/06/27 18:34:43 steve - * Report line of unsupported cassign. - * - * Revision 1.214 2001/05/17 03:35:22 steve - * do not assert if memory reference is invalid. - * - * Revision 1.213 2001/04/29 20:19:10 steve - * Add pullup and pulldown devices. - * - * Revision 1.212 2001/04/28 23:18:08 steve - * UDP instances need not have user supplied names. - * - * Revision 1.211 2001/04/24 02:23:58 steve - * Support for UDP devices in VVP (Stephen Boettcher) - * - * Revision 1.210 2001/04/22 23:09:46 steve - * More UDP consolidation from Stephan Boettcher. - * - * Revision 1.209 2001/04/02 02:28:12 steve - * Generate code for task calls. - * - * Revision 1.208 2001/02/15 06:59:36 steve - * FreeBSD port has a maintainer now. - * - * Revision 1.207 2001/02/09 05:44:23 steve - * support evaluation of constant < in expressions. - * - * Revision 1.206 2001/02/07 21:47:13 steve - * Fix expression widths for rvalues and parameters (PR#131,132) - * - * Revision 1.205 2001/01/14 23:04:56 steve - * Generalize the evaluation of floating point delays, and - * get it working with delay assignment statements. - * - * Allow parameters to be referenced by hierarchical name. - * - * Revision 1.204 2001/01/10 03:13:23 steve - * Build task outputs as lval instead of nets. (PR#98) - * - * Revision 1.203 2001/01/09 05:58:47 steve - * Cope with width mismatches to module ports (PR#89) - * - * Revision 1.202 2000/12/15 01:24:17 steve - * Accept x in outputs of primitive. (PR#84) - * - * Revision 1.201 2000/12/10 22:01:36 steve - * Support decimal constants in behavioral delays. - * - * Revision 1.200 2000/12/10 06:41:59 steve - * Support delays on continuous assignment from idents. (PR#40) - * - * Revision 1.199 2000/12/06 06:31:09 steve - * Check lvalue of procedural continuous assign (PR#29) - * - * Revision 1.198 2000/12/01 23:52:49 steve - * Handle null statements inside a wait. (PR#60) - * - * Revision 1.197 2000/11/11 01:52:09 steve - * change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1 - * change set to correct behavior of bufif0 and bufif1 - * (Tim Leight) - * - * Also includes fix for PR#27 - * - * Revision 1.196 2000/11/05 06:05:59 steve - * Handle connectsion to internally unconnected modules (PR#38) - * - * Revision 1.195 2000/10/28 00:51:42 steve - * Add scope to threads in vvm, pass that scope - * to vpi sysTaskFunc objects, and add vpi calls - * to access that information. - * - * $display displays scope in %m (PR#1) - * - * Revision 1.194 2000/10/26 17:09:46 steve - * Fix handling of errors in behavioral lvalues. (PR#28) - * - * Revision 1.193 2000/10/07 19:45:42 steve - * Put logic devices into scopes. - * - * Revision 1.192 2000/09/29 22:58:57 steve - * Do not put noop statements into blocks. - * - * Revision 1.191 2000/09/24 17:41:13 steve - * fix null pointer when elaborating undefined task. - * - * Revision 1.190 2000/09/20 02:53:14 steve - * Correctly measure comples l-values of assignments. - * - * Revision 1.189 2000/09/09 15:21:26 steve - * move lval elaboration to PExpr virtual methods. - * - * Revision 1.188 2000/09/07 01:29:44 steve - * Fix bit padding of assign signal-to-signal - * - * Revision 1.187 2000/09/07 00:06:53 steve - * encapsulate access to the l-value expected width. - * - * Revision 1.186 2000/09/03 17:58:35 steve - * Change elaborate_lval to return NetAssign_ objects. - * - * Revision 1.185 2000/09/02 23:40:12 steve - * Pull NetAssign_ creation out of constructors. - * - * Revision 1.184 2000/09/02 20:54:20 steve - * Rearrange NetAssign to make NetAssign_ separate. - * - * Revision 1.183 2000/08/18 04:38:57 steve - * Proper error messages when port direction is missing. - * - * Revision 1.182 2000/07/30 18:25:43 steve - * Rearrange task and function elaboration so that the - * NetTaskDef and NetFuncDef functions are created during - * signal enaboration, and carry these objects in the - * NetScope class instead of the extra, useless map in - * the Design class. - * - * Revision 1.181 2000/07/27 05:13:44 steve - * Support elaboration of disable statements. - * - * Revision 1.180 2000/07/26 05:08:07 steve - * Parse disable statements to pform. - * - * Revision 1.179 2000/07/22 22:09:03 steve - * Parse and elaborate timescale to scopes. - * - * Revision 1.178 2000/07/14 06:12:57 steve - * Move inital value handling from NetNet to Nexus - * objects. This allows better propogation of inital - * values. - * - * Clean up constant propagation a bit to account - * for regs that are not really values. - * - * Revision 1.177 2000/07/07 04:53:54 steve - * Add support for non-constant delays in delay statements, - * Support evaluating ! in constant expressions, and - * move some code from netlist.cc to net_proc.cc. - * - * Revision 1.176 2000/06/13 03:24:48 steve - * Index in memory assign should be a NetExpr. - * - * Revision 1.175 2000/05/31 02:26:49 steve - * Globally merge redundant event objects. - * - * Revision 1.174 2000/05/27 19:33:23 steve - * Merge similar probes within a module. - * - * Revision 1.173 2000/05/16 04:05:16 steve - * Module ports are really special PEIdent - * expressions, because a name can be used - * many places in the port list. - * - * Revision 1.172 2000/05/11 23:37:27 steve - * Add support for procedural continuous assignment. - * - * Revision 1.171 2000/05/08 05:28:29 steve - * Use bufz to make assignments directional. - * - * Revision 1.170 2000/05/07 21:17:21 steve - * non-blocking assignment to a bit select. - * - * Revision 1.169 2000/05/07 04:37:56 steve - * Carry strength values from Verilog source to the - * pform and netlist for gates. - * - * Change vvm constants to use the driver_t to drive - * a constant value. This works better if there are - * multiple drivers on a signal. - * - * Revision 1.168 2000/05/02 16:27:38 steve - * Move signal elaboration to a seperate pass. - * - * Revision 1.167 2000/05/02 03:13:31 steve - * Move memories to the NetScope object. - * - * Revision 1.166 2000/05/02 00:58:11 steve - * Move signal tables to the NetScope class. - * - * Revision 1.165 2000/04/28 23:12:12 steve - * Overly aggressive eliding of task calls. - * - * Revision 1.164 2000/04/28 22:17:47 steve - * Skip empty tasks. - * - * Revision 1.163 2000/04/28 16:50:53 steve - * Catch memory word parameters to tasks. - * - * Revision 1.162 2000/04/23 03:45:24 steve - * Add support for the procedural release statement. - * - * Revision 1.161 2000/04/22 04:20:19 steve - * Add support for force assignment. - * - * Revision 1.160 2000/04/21 04:38:15 steve - * Bit padding in assignment to memory. - * - * Revision 1.159 2000/04/18 01:02:53 steve - * Minor cleanup of NetTaskDef. - * - * Revision 1.158 2000/04/12 04:23:58 steve - * Named events really should be expressed with PEIdent - * objects in the pform, - * - * Handle named events within the mix of net events - * and edges. As a unified lot they get caught together. - * wait statements are broken into more complex statements - * that include a conditional. - * - * Do not generate NetPEvent or NetNEvent objects in - * elaboration. NetEvent, NetEvWait and NetEvProbe - * take over those functions in the netlist. - * - * Revision 1.157 2000/04/10 05:26:06 steve - * All events now use the NetEvent class. */ diff --git a/iverilog.conf b/iverilog.conf index 2487db2ae..e30355e5e 100644 --- a/iverilog.conf +++ b/iverilog.conf @@ -43,6 +43,8 @@ # # %W Substitute the ivl warning flags. # +# %y Substitute all the -y flags here. +# # %[] # This substitution pattern is magical, and is the only # multicharacter pattern. This tests the code , and @@ -56,20 +58,20 @@ # be useful and interesting if the -N flag is included. [-tnull -S] -%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- - +%B/ivl %[v-v] %y %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- - [-tnull] -%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- - +%B/ivl %[v-v] %y %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- - # -- # The vvp target generates code that the vvp simulation engine can execute. # These rules support synthesized and non-synthesized variants. [-tvvp -S] -%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -o%o -- - +%B/ivl %[v-v] %y %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -o%o -- - [-tvvp] -%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- - +%B/ivl %[v-v] %y %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- - # -- # The vvm target uses the string to take the preprocessed code from @@ -78,20 +80,20 @@ # on the result. [-tvvm] -%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- - +%B/ivl %[v-v] %y %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- - # This is the XNF code generator. [-txnf] -%B/ivl %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- - +%B/ivl %y %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- - # And this is another XNF code generator, under development. [-tfpga] -%B/ivl %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/fpga.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- - +%B/ivl %y %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/fpga.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- - # -- # This is the pal code generator. The target module requires the -fpart= # flag to specify the part type. [-tpal] -%B/ivl %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- - +%B/ivl %y %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- - diff --git a/lexor.lex b/lexor.lex index 58c6c2076..de4e737a2 100644 --- a/lexor.lex +++ b/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: lexor.lex,v 1.63 2001/09/08 01:22:55 steve Exp $" +#ident "$Id: lexor.lex,v 1.64 2001/10/20 23:02:40 steve Exp $" #endif # include "config.h" @@ -29,13 +29,12 @@ # include # include "compiler.h" # include "parse_misc.h" +# include "parse_api.h" # include "parse.h" # include # include # include "lexor_keyword.h" -extern FILE*vl_input; -extern string vl_file; # define YY_USER_INIT reset_lexor(); # define yylval VLlval @@ -77,7 +76,7 @@ static const char* set_file_name(char*text) extern void pform_set_timescale(int, int); -static void reset_lexor(); +void reset_lexor(); static void line_directive(); static void line_directive2(); @@ -1066,7 +1065,8 @@ static void line_directive2() yylloc.text = set_file_name(buf); } -static void reset_lexor() +extern FILE*vl_input; +void reset_lexor() { yyrestart(vl_input); yylloc.first_line = 1; diff --git a/load_module.cc b/load_module.cc new file mode 100644 index 000000000..379402e27 --- /dev/null +++ b/load_module.cc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2001 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: load_module.cc,v 1.1 2001/10/20 23:02:40 steve Exp $" +#endif + +# include "util.h" +# include "parse_api.h" +# include "compiler.h" +# include + + +const char dir_character = '/'; + +bool load_module(const char*type) +{ + char path[4096]; + + for (list::iterator cur = library_dirs.begin() + ; cur != library_dirs.end() + ; cur ++ ) { + sprintf(path, "%s%c%s.v", *cur, dir_character, type); + + FILE*file = fopen(path, "r"); + if (file == 0) + continue; + + if (verbose_flag) { + cerr << "Loading library file " << path << "." << endl; + } + + pform_parse(path, file); + return true; + } + + return false; +} + +/* + * $Log: load_module.cc,v $ + * Revision 1.1 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * + */ + diff --git a/main.cc b/main.cc index 4ccd9e887..fb2fffbfc 100644 --- a/main.cc +++ b/main.cc @@ -19,7 +19,7 @@ const char COPYRIGHT[] = * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: main.cc,v 1.49 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: main.cc,v 1.50 2001/10/20 23:02:40 steve Exp $" #endif # include "config.h" @@ -55,6 +55,7 @@ const char NOTICE[] = # include #endif # include "pform.h" +# include "parse_api.h" # include "netlist.h" # include "target.h" # include "compiler.h" @@ -77,11 +78,18 @@ const char*target = "null"; map flags; +list library_dirs; + /* * These are the warning enable flags. */ bool warn_implicit = false; +/* + * Verbose messages enabled. + */ +bool verbose_flag = false; + static void parm_to_flagmap(const string&flag) { @@ -100,9 +108,7 @@ static void parm_to_flagmap(const string&flag) } -extern Design* elaborate(const map&modules, - const map&primitives, - list root); +extern Design* elaborate(list root); extern void cprop(Design*des); extern void synth(Design*des); @@ -166,7 +172,6 @@ inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; } int main(int argc, char*argv[]) { bool help_flag = false; - bool verbose_flag = false; bool times_flag = false; const char* net_path = 0; @@ -184,7 +189,7 @@ int main(int argc, char*argv[]) min_typ_max_flag = TYP; min_typ_max_warn = 10; - while ((opt = getopt(argc, argv, "F:f:hm:N:o:P:p:s:T:t:VvW:")) != EOF) switch (opt) { + while ((opt = getopt(argc, argv, "F:f:hm:N:o:P:p:s:T:t:VvW:y:")) != EOF) switch (opt) { case 'F': { net_func tmp = name_to_net_func(optarg); if (tmp == 0) { @@ -253,6 +258,9 @@ int main(int argc, char*argv[]) case 'W': warn_en = optarg; break; + case 'y': + library_dirs.push_back(optarg); + break; default: flag_errors += 1; break; @@ -281,6 +289,7 @@ int main(int argc, char*argv[]) #endif ".\n" "\t-V Print version and copyright information, and exit.\n" +"\t-y Add directory to library search path.\n" ; cout << "Netlist functions:" << endl; @@ -313,21 +322,19 @@ int main(int argc, char*argv[]) } /* Parse the input. Make the pform. */ - map modules; - map primitives; - int rc = pform_parse(argv[optind], modules, primitives); + int rc = pform_parse(argv[optind]); if (pf_path) { ofstream out (pf_path); out << "PFORM DUMP MODULES:" << endl; - for (map::iterator mod = modules.begin() - ; mod != modules.end() + for (map::iterator mod = pform_modules.begin() + ; mod != pform_modules.end() ; mod ++ ) { pform_dump(out, (*mod).second); } out << "PFORM DUMP PRIMITIVES:" << endl; - for (map::iterator idx = primitives.begin() - ; idx != primitives.end() + for (map::iterator idx = pform_primitives.begin() + ; idx != pform_primitives.end() ; idx ++ ) { (*idx).second->dump(out); } @@ -346,7 +353,9 @@ int main(int argc, char*argv[]) map::iterator mod; if (verbose_flag) cout << "LOCATING TOP-LEVEL MODULES..." << endl << " "; - for (mod = modules.begin(); mod != modules.end(); mod++) { + for (mod = pform_modules.begin() + ; mod != pform_modules.end() + ; mod++) { list gates = (*mod).second->get_gates(); list::const_iterator gate; for (gate = gates.begin(); gate != gates.end(); gate++) { @@ -358,7 +367,9 @@ int main(int argc, char*argv[]) } } - for (mod = modules.begin(); mod != modules.end(); mod++) { + for (mod = pform_modules.begin() + ; mod != pform_modules.end() + ; mod++) { if (mentioned_p[(*mod).second->mod_name()] == false) { if (verbose_flag) cout << " " << (*mod).second->mod_name(); @@ -388,7 +399,7 @@ int main(int argc, char*argv[]) } /* On with the process of elaborating the module. */ - Design*des = elaborate(modules, primitives, roots); + Design*des = elaborate(roots); if (des == 0) { cerr << "Elaboration failed" << endl; return 1; @@ -455,6 +466,9 @@ int main(int argc, char*argv[]) /* * $Log: main.cc,v $ + * Revision 1.50 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.49 2001/10/20 05:21:51 steve * Scope/module names are char* instead of string. * diff --git a/pform.cc b/pform.cc index 93e84a753..78d3f5fed 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.cc,v 1.79 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: pform.cc,v 1.80 2001/10/20 23:02:40 steve Exp $" #endif # include "config.h" @@ -25,6 +25,7 @@ # include "compiler.h" # include "pform.h" # include "parse_misc.h" +# include "parse_api.h" # include "PEvent.h" # include "PUdp.h" # include @@ -33,6 +34,9 @@ # include # include +map pform_modules; +map pform_primitives; + /* * The lexor accesses the vl_* variables. */ @@ -90,9 +94,6 @@ static string scoped_name(string name) return name; } -static map vl_modules; -static map vl_primitives; - /* * This function evaluates delay expressions. The result should be a * simple constant that I can interpret as an unsigned number. @@ -130,7 +131,7 @@ void pform_endmodule(const char*name) { assert(pform_cur_module); assert(strcmp(name, pform_cur_module->mod_name()) == 0); - vl_modules[name] = pform_cur_module; + pform_modules[name] = pform_cur_module; pform_cur_module = 0; } @@ -296,7 +297,7 @@ void pform_make_udp(const char*name, list*parms, } // Put the primitive into the primitives table - if (vl_primitives[name]) { + if (pform_primitives[name]) { VLerror("UDP primitive already exists."); } else { @@ -315,7 +316,7 @@ void pform_make_udp(const char*name, list*parms, udp->toutput = output; udp->initial = init; - vl_primitives[name] = udp; + pform_primitives[name] = udp; } /* Delete the excess tables and lists from the parser. */ @@ -839,8 +840,8 @@ void pform_set_attrib(const string&name, const string&key, const string&value) void pform_set_type_attrib(const string&name, const string&key, const string&value) { - map::const_iterator udp = vl_primitives.find(name); - if (udp == vl_primitives.end()) { + map::const_iterator udp = pform_primitives.find(name); + if (udp == pform_primitives.end()) { VLerror("type name is not (yet) defined."); return; } @@ -990,35 +991,48 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st) FILE*vl_input = 0; -int pform_parse(const char*path, map&modules, - map&prim) +extern void reset_lexor(); + +int pform_parse(const char*path, FILE*file) { vl_file = path; - if (strcmp(path, "-") == 0) - vl_input = stdin; - else - vl_input = fopen(path, "r"); - if (vl_input == 0) { - cerr << "Unable to open " <&modules, * * Revision 1.67 2000/11/30 17:31:42 steve * Change LineInfo to store const C strings. - * - * Revision 1.66 2000/10/31 17:49:02 steve - * Support time variables. - * - * Revision 1.65 2000/10/31 17:00:04 steve - * Remove C++ string from variable lists. - * - * Revision 1.64 2000/09/13 16:32:26 steve - * Error message for invalid variable list. - * - * Revision 1.63 2000/07/29 17:58:21 steve - * Introduce min:typ:max support. - * - * Revision 1.62 2000/07/22 22:09:04 steve - * Parse and elaborate timescale to scopes. - * - * Revision 1.61 2000/05/23 16:03:13 steve - * Better parsing of expressions lists will empty expressoins. - * - * Revision 1.60 2000/05/16 04:05:16 steve - * Module ports are really special PEIdent - * expressions, because a name can be used - * many places in the port list. - * - * Revision 1.59 2000/05/08 05:30:20 steve - * Deliver gate output strengths to the netlist. - * - * Revision 1.58 2000/05/06 15:41:57 steve - * Carry assignment strength to pform. - * - * Revision 1.57 2000/04/01 19:31:57 steve - * Named events as far as the pform. - * - * Revision 1.56 2000/03/12 17:09:41 steve - * Support localparam. - * - * Revision 1.55 2000/03/08 04:36:54 steve - * Redesign the implementation of scopes and parameters. - * I now generate the scopes and notice the parameters - * in a separate pass over the pform. Once the scopes - * are generated, I can process overrides and evalutate - * paremeters before elaboration begins. - * - * Revision 1.54 2000/02/23 02:56:55 steve - * Macintosh compilers do not support ident. - * - * Revision 1.53 2000/02/18 05:15:03 steve - * Catch module instantiation arrays. - * - * Revision 1.52 2000/01/09 05:50:49 steve - * Support named parameter override lists. - * - * Revision 1.51 2000/01/02 01:59:28 steve - * Forgot to handle no overrides at all. - * - * Revision 1.50 2000/01/01 23:47:58 steve - * Fix module parameter override syntax. - * - * Revision 1.49 1999/12/30 19:06:14 steve - * Support reg initial assignment syntax. - * - * Revision 1.48 1999/12/11 05:45:41 steve - * Fix support for attaching attributes to primitive gates. - * - * Revision 1.47 1999/11/23 01:04:57 steve - * A file name of - means standard input. - * - * Revision 1.46 1999/09/30 01:22:37 steve - * Handle declaration of integers (including scope) in functions. - * - * Revision 1.45 1999/09/21 00:58:33 steve - * Get scope right when setting the net range. - * - * Revision 1.44 1999/09/17 02:06:26 steve - * Handle unconnected module ports. - * - * Revision 1.43 1999/09/15 01:55:06 steve - * Elaborate non-blocking assignment to memories. - * - * Revision 1.42 1999/09/10 05:02:09 steve - * Handle integers at task parameters. - * - * Revision 1.41 1999/08/31 22:38:29 steve - * Elaborate and emit to vvm procedural functions. - * - * Revision 1.40 1999/08/27 15:08:37 steve - * continuous assignment lists. - * - * Revision 1.39 1999/08/25 22:22:41 steve - * elaborate some aspects of functions. - * - * Revision 1.38 1999/08/23 16:48:39 steve - * Parameter overrides support from Peter Monta - * AND and XOR support wide expressions. - * - * Revision 1.37 1999/08/03 04:14:49 steve - * Parse into pform arbitrarily complex module - * port declarations. */ diff --git a/pform.h b/pform.h index 9bbff87fb..6b1328391 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.h,v 1.46 2001/10/20 05:21:51 steve Exp $" +#ident "$Id: pform.h,v 1.47 2001/10/20 23:02:40 steve Exp $" #endif # include "netlist.h" @@ -196,12 +196,13 @@ extern svector*pform_make_task_ports(NetNet::PortType pt, * parses the source file and places all the modules it finds into the * mod list. The dump function dumps a module to the output stream. */ -extern int pform_parse(const char*path, map&mod, - map&prim); extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.47 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.46 2001/10/20 05:21:51 steve * Scope/module names are char* instead of string. * diff --git a/util.h b/util.h index 163a128d3..621b4d784 100644 --- a/util.h +++ b/util.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: util.h,v 1.2 2001/01/14 23:04:56 steve Exp $" +#ident "$Id: util.h,v 1.3 2001/10/20 23:02:40 steve Exp $" #endif # include @@ -33,8 +33,19 @@ extern string parse_first_name(string&path); extern string parse_last_name(string&path); +/* + * This file attempts to locate a module in a file. It operates by + * looking for a plausible Verilog file to hold the module, and + * invoking the parser to bring in that file's contents. + */ +extern bool load_module(const char*type); + + /* * $Log: util.h,v $ + * Revision 1.3 2001/10/20 23:02:40 steve + * Add automatic module libraries. + * * Revision 1.2 2001/01/14 23:04:56 steve * Generalize the evaluation of floating point delays, and * get it working with delay assignment statements.