2 const char COPYRIGHT
[] =
3 "Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)";
6 * This source code is free software; you can redistribute it
7 * and/or modify it in source code form under the terms of the GNU
8 * General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 #ident "$Id: main.cc,v 1.95 2007/04/19 02:52:53 steve Exp $"
28 " This program is free software; you can redistribute it and/or modify\n"
29 " it under the terms of the GNU General Public License as published by\n"
30 " the Free Software Foundation; either version 2 of the License, or\n"
31 " (at your option) any later version.\n"
33 " This program is distributed in the hope that it will be useful,\n"
34 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
35 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
36 " GNU General Public License for more details.\n"
38 " You should have received a copy of the GNU General Public License\n"
39 " along with this program; if not, write to the Free Software\n"
40 " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
51 #if defined(HAVE_TIMES)
52 # include <sys/times.h>
54 #if defined(HAVE_GETOPT_H)
58 # include "parse_api.h"
61 # include "compiler.h"
63 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
64 extern "C" int getopt(int argc
, char*argv
[], const char*fmt
);
65 extern "C" int optind
;
66 extern "C" const char*optarg
;
69 #if defined(__CYGWIN32__) && !defined(HAVE_GETOPT_H)
70 extern "C" int getopt(int argc
, char*argv
[], const char*fmt
);
71 extern "C" int optind
;
72 extern "C" const char*optarg
;
75 /* Count errors detected in flag processing. */
76 unsigned flag_errors
= 0;
78 const char VERSION
[] = "$Name: $";
80 const char*basedir
= ".";
82 const char*target
= "null";
85 * These are the language support control flags. These support which
86 * language features (the generation) to support. The generation_flag
87 * is a major moce, and the gn_* flags control specifc sub-features.
89 generation_t generation_flag
= GN_DEFAULT
;
90 bool gn_cadence_types_flag
= true;
91 bool gn_specify_blocks_flag
= true;
92 bool gn_io_range_error_flag
= true;
94 map
<string
,const char*> flags
;
95 char*vpi_module_list
= 0;
97 map
<perm_string
,unsigned> missing_modules
;
98 map
<string
,bool> library_file_map
;
100 list
<const char*> library_suff
;
102 list
<perm_string
> roots
;
104 char*ivlpp_string
= 0;
106 char* depfile_name
= NULL
;
107 FILE *depend_file
= NULL
;
110 * These are the warning enable flags.
112 bool warn_implicit
= false;
113 bool warn_timescale
= false;
114 bool warn_portbinding
= false;
116 bool error_implicit
= false;
119 * Debug message class flags.
121 bool debug_scopes
= false;
122 bool debug_eval_tree
= false;
123 bool debug_elaborate
= false;
124 bool debug_synth2
= false;
126 * Verbose messages enabled.
128 bool verbose_flag
= false;
130 unsigned integer_width
= 32;
133 * Keep a heap of identifier strings that I encounter. This is a more
134 * efficient way to allocate those strings.
136 StringHeapLex lex_strings
;
139 * In library searches, Windows file names are never case sensitive.
141 #if defined(__MINGW32__)
142 const bool CASE_SENSITIVE
= false;
144 const bool CASE_SENSITIVE
= true;
147 extern void cprop(Design
*des
);
148 extern void synth(Design
*des
);
149 extern void synth2(Design
*des
);
150 extern void syn_rules(Design
*des
);
151 extern void nodangle(Design
*des
);
153 extern void xnfio(Design
*des
);
156 typedef void (*net_func
)(Design
*);
157 static struct net_func_map
{
159 void (*func
)(Design
*);
162 { "nodangle",&nodangle
},
164 { "synth2", &synth2
},
165 { "syn-rules", &syn_rules
},
172 queue
<net_func
> net_func_queue
;
174 net_func
name_to_net_func(const string
&name
)
176 for (unsigned idx
= 0 ; func_table
[idx
].name
; idx
+= 1)
177 if (name
== func_table
[idx
].name
)
178 return func_table
[idx
].func
;
183 const char *net_func_to_name(const net_func func
)
185 for (unsigned idx
= 0 ; func_table
[idx
].name
; idx
+= 1)
186 if (func
== func_table
[idx
].func
)
187 return func_table
[idx
].name
;
189 return "This cannot happen";
192 static void process_generation_flag(const char*gen
)
194 if (strcmp(gen
,"1") == 0) {
195 generation_flag
= GN_VER1995
;
197 } else if (strcmp(gen
,"2") == 0) {
198 generation_flag
= GN_VER2001
;
200 } else if (strcmp(gen
,"2x") == 0) {
201 generation_flag
= GN_VER2001X
;
203 } else if (strcmp(gen
,"xtypes") == 0) {
204 gn_cadence_types_flag
= true;
206 } else if (strcmp(gen
,"no-xtypes") == 0) {
207 gn_cadence_types_flag
= false;
209 } else if (strcmp(gen
,"specify") == 0) {
210 gn_specify_blocks_flag
= true;
212 } else if (strcmp(gen
,"no-specify") == 0) {
213 gn_specify_blocks_flag
= false;
215 } else if (strcmp(gen
,"io-range-error") == 0) {
216 gn_io_range_error_flag
= true;
218 } else if (strcmp(gen
,"no-io-range-error") == 0) {
219 gn_io_range_error_flag
= false;
225 static void parm_to_flagmap(const string
&flag
)
229 unsigned off
= flag
.find('=');
230 if (off
> flag
.size()) {
235 key
= flag
.substr(0, off
);
236 value
= strdup(flag
.substr(off
+1).c_str());
243 * Read the contents of a config file. This file is a temporary
244 * configuration file made by the compiler driver to carry the bulky
245 * flags generated from the user. This reduces the size of the command
246 * line needed to invoke ivl.
248 * Each line of the iconfig file has the format:
252 * The <value> is all the text after the ':' and up to but not
253 * including the end of the line. Thus, white spaces and ':'
254 * characters may appear here.
256 * The valid keys are:
263 * Select which expression to use.
269 * Location to look for installed sub-components
272 * Activate a class of debug messages.
275 * Give the path to an output dependency file.
277 * flag:<name>=<string>
278 * Generic compiler flag strings.
281 * Append a named functor to the processing path.
283 * generation:<1|2|2x|xtypes|no-xtypes|specify|no-specify>
284 * This is the generation flag
286 * ivlpp:<preprocessor command>
287 * This specifies the ivlpp command line used to process
288 * library modules as I read them in.
291 * This specifies the width of integer variables. (that is,
292 * variables declared using the "integer" keyword.)
294 * library_file:<path>
295 * This marks that a source file with the given path is a
296 * library. Any modules in that file are marked as library
303 * Path to the output file.
306 * Path to a system functions descriptor table
309 * Specify a root module. There may be multiple of this.
312 * Warning flag letters.
314 static void read_iconfig_file(const char*ipath
)
318 FILE*ifile
= fopen(ipath
, "r");
320 cerr
<< "ERROR: Unable to read config file: " << ipath
<< endl
;
324 while (fgets(buf
, sizeof buf
, ifile
) != 0) {
327 char*cp
= strchr(buf
, ':');
332 char*ep
= cp
+ strlen(cp
);
347 if (strcmp(buf
, "basedir") == 0) {
348 basedir
= strdup(cp
);
350 } else if (strcmp(buf
, "debug") == 0) {
351 if (strcmp(cp
, "scope") == 0) {
353 cerr
<< "debug: Enable scope debug" << endl
;
354 } else if (strcmp(cp
,"eval_tree") == 0) {
355 debug_eval_tree
= true;
356 cerr
<< "debug: Enable eval_tree debug" << endl
;
357 } else if (strcmp(cp
,"elaborate") == 0) {
358 debug_elaborate
= true;
359 cerr
<< "debug: Enable elaborate debug" << endl
;
360 } else if (strcmp(cp
,"synth2") == 0) {
362 cerr
<< "debug: Enable synth2 debug" << endl
;
366 } else if (strcmp(buf
, "depfile") == 0) {
367 depfile_name
= strdup(cp
);
369 } else if (strcmp(buf
, "flag") == 0) {
371 parm_to_flagmap(parm
);
373 } else if (strcmp(buf
,"functor") == 0) {
374 net_func tmp
= name_to_net_func(cp
);
376 cerr
<< "No such design transform function ``"
377 << cp
<< "''." << endl
;
381 net_func_queue
.push(tmp
);
383 } else if (strcmp(buf
, "generation") == 0) {
384 process_generation_flag(cp
);
386 } else if (strcmp(buf
, "ivlpp") == 0) {
387 ivlpp_string
= strdup(cp
);
389 } else if (strcmp(buf
, "iwidth") == 0) {
390 integer_width
= strtoul(cp
,0,10);
392 } else if (strcmp(buf
, "library_file") == 0) {
393 const char* path
= strdup(cp
);
394 library_file_map
[path
] = true;
396 } else if (strcmp(buf
,"module") == 0) {
397 if (vpi_module_list
== 0) {
398 vpi_module_list
= strdup(cp
);
401 char*tmp
= (char*)realloc(vpi_module_list
,
402 strlen(vpi_module_list
)
407 vpi_module_list
= tmp
;
409 flags
["VPI_MODULE_LIST"] = vpi_module_list
;
411 } else if (strcmp(buf
, "out") == 0) {
412 flags
["-o"] = strdup(cp
);
414 } else if (strcmp(buf
, "sys_func") == 0) {
415 load_sys_func_table(cp
);
417 } else if (strcmp(buf
, "root") == 0) {
418 roots
.push_back(lex_strings
.make(cp
));
420 } else if (strcmp(buf
,"warnings") == 0) {
421 /* Scan the warnings enable string for warning flags. */
422 for ( ; *cp
; cp
+= 1) switch (*cp
) {
424 warn_implicit
= true;
427 warn_portbinding
= true;
430 warn_timescale
= true;
436 } else if (strcmp(buf
, "-y") == 0) {
437 build_library_index(cp
, CASE_SENSITIVE
);
439 } else if (strcmp(buf
, "-yl") == 0) {
440 build_library_index(cp
, false);
442 } else if (strcmp(buf
, "-Y") == 0) {
443 library_suff
.push_back(strdup(cp
));
445 } else if (strcmp(buf
,"-t") == 0) {
448 } else if (strcmp(buf
,"-T") == 0) {
449 if (strcmp(cp
,"min") == 0) {
450 min_typ_max_flag
= MIN
;
451 min_typ_max_warn
= 0;
452 } else if (strcmp(cp
,"typ") == 0) {
453 min_typ_max_flag
= TYP
;
454 min_typ_max_warn
= 0;
455 } else if (strcmp(cp
,"max") == 0) {
456 min_typ_max_flag
= MAX
;
457 min_typ_max_warn
= 0;
459 cerr
<< "Invalid argument (" << optarg
<< ") to -T flag."
468 extern Design
* elaborate(list
<perm_string
> root
);
470 #if defined(HAVE_TIMES)
471 static double cycles_diff(struct tms
*a
, struct tms
*b
)
473 clock_t aa
= a
->tms_utime
478 clock_t bb
= b
->tms_utime
483 return (aa
-bb
)/(double)sysconf(_SC_CLK_TCK
);
485 #else // ! defined(HAVE_TIMES)
487 struct tms
{ int x
; };
488 inline static void times(struct tms
*) { }
489 inline static double cycles_diff(struct tms
*a
, struct tms
*b
) { return 0; }
490 #endif // ! defined(HAVE_TIMES)
492 int main(int argc
, char*argv
[])
494 bool help_flag
= false;
495 bool times_flag
= false;
497 const char* net_path
= 0;
498 const char* pf_path
= 0;
501 struct tms cycles
[5];
503 library_suff
.push_back(".v");
505 vpi_module_list
= strdup("system");
506 flags
["VPI_MODULE_LIST"] = vpi_module_list
;
507 flags
["-o"] = "a.out";
508 min_typ_max_flag
= TYP
;
509 min_typ_max_warn
= 10;
511 while ((opt
= getopt(argc
, argv
, "C:f:hN:P:p:Vv")) != EOF
) switch (opt
) {
514 read_iconfig_file(optarg
);
518 parm_to_flagmap(optarg
);
530 parm_to_flagmap(optarg
);
534 # if defined(HAVE_TIMES)
539 cout
<< "Icarus Verilog version " << VERSION
<< endl
;
540 cout
<< COPYRIGHT
<< endl
;
541 cout
<< endl
<< NOTICE
<< endl
;
552 cout
<< "Icarus Verilog version " << VERSION
<< endl
<<
553 "usage: ivl <options> <file>\n"
555 "\t-C <name> Config file from driver.\n"
556 "\t-h Print usage information, and exit.\n"
557 "\t-N <file> Dump the elaborated netlist to <file>.\n"
558 "\t-P <file> Write the parsed input to <file>.\n"
559 "\t-p <assign> Set a parameter value.\n"
560 "\t-v Print progress indications"
561 #if defined(HAVE_TIMES)
562 " and execution times"
565 "\t-V Print version and copyright information, and exit.\n"
571 if (optind
== argc
) {
572 cerr
<< "No input files." << endl
;
577 depend_file
= fopen(depfile_name
, "a");
579 perror(depfile_name
);
588 cout
<< "Using language generation: ";
589 switch (generation_flag
) {
591 cout
<< "IEEE1364-1995";
594 cout
<< "IEEE1364-2001";
597 cout
<< "IEEE1364-2001+Extensions";
601 if (gn_specify_blocks_flag
)
604 cout
<< ",no-specify";
606 if (gn_cadence_types_flag
)
609 cout
<< ",no-xtypes";
611 cout
<< endl
<< "PARSING INPUT" << endl
;
614 /* Parse the input. Make the pform. */
615 int rc
= pform_parse(argv
[optind
]);
618 ofstream
out (pf_path
);
619 out
<< "PFORM DUMP MODULES:" << endl
;
620 for (map
<perm_string
,Module
*>::iterator mod
= pform_modules
.begin()
621 ; mod
!= pform_modules
.end()
623 pform_dump(out
, (*mod
).second
);
625 out
<< "PFORM DUMP PRIMITIVES:" << endl
;
626 for (map
<perm_string
,PUdp
*>::iterator idx
= pform_primitives
.begin()
627 ; idx
!= pform_primitives
.end()
629 (*idx
).second
->dump(out
);
638 /* If the user did not give specific module(s) to start with,
639 then look for modules that are not instantiated anywhere. */
642 map
<perm_string
,bool> mentioned_p
;
643 map
<perm_string
,Module
*>::iterator mod
;
645 cout
<< "LOCATING TOP-LEVEL MODULES" << endl
<< " ";
646 for (mod
= pform_modules
.begin()
647 ; mod
!= pform_modules
.end()
649 list
<PGate
*> gates
= (*mod
).second
->get_gates();
650 list
<PGate
*>::const_iterator gate
;
651 for (gate
= gates
.begin(); gate
!= gates
.end(); gate
++) {
652 PGModule
*mod
= dynamic_cast<PGModule
*>(*gate
);
654 // Note that this module has been instantiated
655 mentioned_p
[mod
->get_type()] = true;
660 for (mod
= pform_modules
.begin()
661 ; mod
!= pform_modules
.end()
664 /* Don't choose library modules. */
665 if ((*mod
).second
->library_flag
)
668 /* Don't choose modules instantiated in other
670 if (mentioned_p
[(*mod
).second
->mod_name()])
673 /* What's left might as well be chosen as a root. */
675 cout
<< " " << (*mod
).second
->mod_name();
676 roots
.push_back((*mod
).second
->mod_name());
682 /* If there is *still* no guess for the root module, then give
683 up completely, and complain. */
686 cerr
<< "No top level modules, and no -s option." << endl
;
695 <<cycles_diff(cycles
+1, cycles
+0)<<" seconds."<<endl
;
697 cout
<< "ELABORATING DESIGN" << endl
;
700 /* On with the process of elaborating the module. */
701 Design
*des
= elaborate(roots
);
703 if ((des
== 0) || (des
->errors
> 0)) {
706 << " error(s) during elaboration." << endl
;
708 ofstream
out (net_path
);
712 cerr
<< "Elaboration failed" << endl
;
718 des
->set_flags(flags
);
720 /* Done iwth all the pform data. Delete the modules. */
721 for (map
<perm_string
,Module
*>::iterator idx
= pform_modules
.begin()
722 ; idx
!= pform_modules
.end() ; idx
++) {
724 delete (*idx
).second
;
732 <<cycles_diff(cycles
+2, cycles
+1)<<" seconds."<<endl
;
734 cout
<< "RUNNING FUNCTORS" << endl
;
737 while (!net_func_queue
.empty()) {
738 net_func func
= net_func_queue
.front();
739 net_func_queue
.pop();
741 cerr
<<" -F "<<net_func_to_name(func
)<< " ..." <<endl
;
747 cerr
<<" dumping netlist to " <<net_path
<< "..." <<endl
;
749 ofstream
out (net_path
);
755 << " error(s) in post-elaboration processing." <<
764 <<cycles_diff(cycles
+3, cycles
+2)<<" seconds."<<endl
;
769 cout
<< "CODE GENERATION -t "<<target
<< endl
;
773 emit_rc
= emit(des
, target
);
775 cerr
<< "error: Code generation had "
776 << emit_rc
<< " errors."
781 cerr
<< "error: Code generator failure: " << emit_rc
<< endl
;
789 <<cycles_diff(cycles
+4, cycles
+3)<<" seconds."<<endl
;
791 cout
<< "DONE." << endl
;
796 cout
<< "STATISTICS" << endl
;
797 cout
<< "lex_string:"
798 << " add_count=" << lex_strings
.add_count()
799 << " hit_count=" << lex_strings
.add_hit_count()
806 if (missing_modules
.size() > 0) {
807 cerr
<< "*** These modules were missing:" << endl
;
809 map
<perm_string
,unsigned>::const_iterator idx
;
810 for (idx
= missing_modules
.begin()
811 ; idx
!= missing_modules
.end()
813 cerr
<< " " << (*idx
).first
814 << " referenced " << (*idx
).second
817 cerr
<< "***" << endl
;
820 return des
? des
->errors
: 1;
825 * Revision 1.95 2007/04/19 02:52:53 steve
826 * Add support for -v flag in command file.
828 * Revision 1.94 2007/03/07 04:24:59 steve
829 * Make integer width controllable.
831 * Revision 1.93 2006/09/28 04:35:18 steve
832 * Support selective control of specify and xtypes features.
834 * Revision 1.92 2005/07/14 23:38:43 steve
835 * Display as version 0.9.devel
837 * Revision 1.91 2005/07/07 16:22:49 steve
838 * Generalize signals to carry types.
840 * Revision 1.90 2005/06/28 04:25:55 steve
841 * Remove reference to SystemVerilog.
843 * Revision 1.89 2005/04/24 23:44:02 steve
844 * Update DFF support to new data flow.
846 * Revision 1.88 2005/01/22 01:06:55 steve
847 * Change case compare from logic to an LPM node.
849 * Revision 1.87 2004/12/11 02:31:26 steve
850 * Rework of internals to carry vectors through nexus instead
851 * of single bits. Make the ivl, tgt-vvp and vvp initial changes
854 * Revision 1.86 2004/10/04 01:10:53 steve
855 * Clean up spurious trailing white space.
857 * Revision 1.85 2004/09/25 01:58:44 steve
858 * Add a debug_elaborate flag
860 * Revision 1.84 2004/09/10 23:51:42 steve
861 * Fix the evaluation of constant ternary expressions.
863 * Revision 1.83 2004/09/05 17:44:42 steve
864 * Add support for module instance arrays.
866 * Revision 1.82 2004/03/10 04:51:24 steve
867 * Add support for system function table files.
869 * Revision 1.81 2004/02/18 17:11:56 steve
870 * Use perm_strings for named langiage items.
872 * Revision 1.80 2004/02/15 00:19:29 steve
873 * Report elaboration errors without crashing.
875 * Revision 1.79 2003/11/26 01:37:14 steve
876 * Properly initialize vpi_module_list with system.
878 * Revision 1.78 2003/11/13 05:55:33 steve
879 * Move the DLL= flag to target config files.
881 * Revision 1.77 2003/11/13 04:09:49 steve
882 * Pass flags through the temporary config file.
884 * Revision 1.76 2003/11/13 03:10:38 steve
885 * ivl -F and -t flags are onpassed throught the -C file.
887 * Revision 1.75 2003/11/10 20:59:03 steve
888 * Design::get_flag returns const char* instead of string.
890 * Revision 1.74 2003/11/01 04:22:30 steve
891 * Accept functors in the config file.
893 * Revision 1.73 2003/10/26 22:43:42 steve
894 * Improve -V messages,
896 * Revision 1.72 2003/09/26 02:17:14 steve
897 * Delete pform when done with it.
899 * Revision 1.71 2003/09/25 00:25:14 steve
900 * Summary list of missing modules.
902 * Revision 1.70 2003/09/23 05:57:36 steve
903 * Pass -m flag from driver via iconfig file.
905 * Revision 1.69 2003/09/22 01:12:08 steve
906 * Pass more ivl arguments through the iconfig file.
908 * Revision 1.68 2003/06/20 00:53:19 steve
909 * Module attributes from the parser
910 * through to elaborated form.
912 * Revision 1.67 2003/04/24 05:25:27 steve
913 * Dump design even on errors.
915 * Revision 1.66 2003/03/01 06:25:30 steve
916 * Add the lex_strings string handler, and put
917 * scope names and system task/function names
918 * into this table. Also, permallocate event
919 * names from the beginning.