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;
93 map
<string
,const char*> flags
;
94 char*vpi_module_list
= 0;
96 map
<perm_string
,unsigned> missing_modules
;
97 map
<string
,bool> library_file_map
;
99 list
<const char*> library_suff
;
101 list
<perm_string
> roots
;
103 char*ivlpp_string
= 0;
105 char* depfile_name
= NULL
;
106 FILE *depend_file
= NULL
;
109 * These are the warning enable flags.
111 bool warn_implicit
= false;
112 bool warn_timescale
= false;
113 bool warn_portbinding
= false;
115 bool error_implicit
= false;
118 * Debug message class flags.
120 bool debug_scopes
= false;
121 bool debug_eval_tree
= false;
122 bool debug_elaborate
= false;
123 bool debug_synth2
= false;
125 * Verbose messages enabled.
127 bool verbose_flag
= false;
129 unsigned integer_width
= 32;
132 * Keep a heap of identifier strings that I encounter. This is a more
133 * efficient way to allocate those strings.
135 StringHeapLex lex_strings
;
138 * In library searches, Windows file names are never case sensitive.
140 #if defined(__MINGW32__)
141 const bool CASE_SENSITIVE
= false;
143 const bool CASE_SENSITIVE
= true;
146 extern void cprop(Design
*des
);
147 extern void synth(Design
*des
);
148 extern void synth2(Design
*des
);
149 extern void syn_rules(Design
*des
);
150 extern void nodangle(Design
*des
);
152 extern void xnfio(Design
*des
);
155 typedef void (*net_func
)(Design
*);
156 static struct net_func_map
{
158 void (*func
)(Design
*);
161 { "nodangle",&nodangle
},
163 { "synth2", &synth2
},
164 { "syn-rules", &syn_rules
},
171 queue
<net_func
> net_func_queue
;
173 net_func
name_to_net_func(const string
&name
)
175 for (unsigned idx
= 0 ; func_table
[idx
].name
; idx
+= 1)
176 if (name
== func_table
[idx
].name
)
177 return func_table
[idx
].func
;
182 const char *net_func_to_name(const net_func func
)
184 for (unsigned idx
= 0 ; func_table
[idx
].name
; idx
+= 1)
185 if (func
== func_table
[idx
].func
)
186 return func_table
[idx
].name
;
188 return "This cannot happen";
191 static void process_generation_flag(const char*gen
)
193 if (strcmp(gen
,"1") == 0) {
194 generation_flag
= GN_VER1995
;
196 } else if (strcmp(gen
,"2") == 0) {
197 generation_flag
= GN_VER2001
;
199 } else if (strcmp(gen
,"2x") == 0) {
200 generation_flag
= GN_VER2001X
;
202 } else if (strcmp(gen
,"xtypes") == 0) {
203 gn_cadence_types_flag
= true;
205 } else if (strcmp(gen
,"no-xtypes") == 0) {
206 gn_cadence_types_flag
= false;
208 } else if (strcmp(gen
,"specify") == 0) {
209 gn_specify_blocks_flag
= true;
211 } else if (strcmp(gen
,"no-specify") == 0) {
212 gn_specify_blocks_flag
= false;
218 static void parm_to_flagmap(const string
&flag
)
222 unsigned off
= flag
.find('=');
223 if (off
> flag
.size()) {
228 key
= flag
.substr(0, off
);
229 value
= strdup(flag
.substr(off
+1).c_str());
236 * Read the contents of a config file. This file is a temporary
237 * configuration file made by the compiler driver to carry the bulky
238 * flags generated from the user. This reduces the size of the command
239 * line needed to invoke ivl.
241 * Each line of the iconfig file has the format:
245 * The <value> is all the text after the ':' and up to but not
246 * including the end of the line. Thus, white spaces and ':'
247 * characters may appear here.
249 * The valid keys are:
256 * Select which expression to use.
262 * Location to look for installed sub-components
265 * Activate a class of debug messages.
268 * Give the path to an output dependency file.
270 * flag:<name>=<string>
271 * Generic compiler flag strings.
274 * Append a named functor to the processing path.
276 * generation:<1|2|2x|xtypes|no-xtypes|specify|no-specify>
277 * This is the generation flag
279 * ivlpp:<preprocessor command>
280 * This specifies the ivlpp command line used to process
281 * library modules as I read them in.
284 * This specifies the width of integer variables. (that is,
285 * variables declared using the "integer" keyword.)
287 * library_file:<path>
288 * This marks that a source file with the given path is a
289 * library. Any modules in that file are marked as library
296 * Path to the output file.
299 * Path to a system functions descriptor table
302 * Specify a root module. There may be multiple of this.
305 * Warning flag letters.
307 static void read_iconfig_file(const char*ipath
)
311 FILE*ifile
= fopen(ipath
, "r");
313 cerr
<< "ERROR: Unable to read config file: " << ipath
<< endl
;
317 while (fgets(buf
, sizeof buf
, ifile
) != 0) {
320 char*cp
= strchr(buf
, ':');
325 char*ep
= cp
+ strlen(cp
);
340 if (strcmp(buf
, "basedir") == 0) {
341 basedir
= strdup(cp
);
343 } else if (strcmp(buf
, "debug") == 0) {
344 if (strcmp(cp
, "scope") == 0) {
346 cerr
<< "debug: Enable scope debug" << endl
;
347 } else if (strcmp(cp
,"eval_tree") == 0) {
348 debug_eval_tree
= true;
349 cerr
<< "debug: Enable eval_tree debug" << endl
;
350 } else if (strcmp(cp
,"elaborate") == 0) {
351 debug_elaborate
= true;
352 cerr
<< "debug: Enable elaborate debug" << endl
;
353 } else if (strcmp(cp
,"synth2") == 0) {
355 cerr
<< "debug: Enable synth2 debug" << endl
;
359 } else if (strcmp(buf
, "depfile") == 0) {
360 depfile_name
= strdup(cp
);
362 } else if (strcmp(buf
, "flag") == 0) {
364 parm_to_flagmap(parm
);
366 } else if (strcmp(buf
,"functor") == 0) {
367 net_func tmp
= name_to_net_func(cp
);
369 cerr
<< "No such design transform function ``"
370 << cp
<< "''." << endl
;
374 net_func_queue
.push(tmp
);
376 } else if (strcmp(buf
, "generation") == 0) {
377 process_generation_flag(cp
);
379 } else if (strcmp(buf
, "ivlpp") == 0) {
380 ivlpp_string
= strdup(cp
);
382 } else if (strcmp(buf
, "iwidth") == 0) {
383 integer_width
= strtoul(cp
,0,10);
385 } else if (strcmp(buf
, "library_file") == 0) {
386 const char* path
= strdup(cp
);
387 library_file_map
[path
] = true;
389 } else if (strcmp(buf
,"module") == 0) {
390 if (vpi_module_list
== 0) {
391 vpi_module_list
= strdup(cp
);
394 char*tmp
= (char*)realloc(vpi_module_list
,
395 strlen(vpi_module_list
)
400 vpi_module_list
= tmp
;
402 flags
["VPI_MODULE_LIST"] = vpi_module_list
;
404 } else if (strcmp(buf
, "out") == 0) {
405 flags
["-o"] = strdup(cp
);
407 } else if (strcmp(buf
, "sys_func") == 0) {
408 load_sys_func_table(cp
);
410 } else if (strcmp(buf
, "root") == 0) {
411 roots
.push_back(lex_strings
.make(cp
));
413 } else if (strcmp(buf
,"warnings") == 0) {
414 /* Scan the warnings enable string for warning flags. */
415 for ( ; *cp
; cp
+= 1) switch (*cp
) {
417 warn_implicit
= true;
420 warn_portbinding
= true;
423 warn_timescale
= true;
429 } else if (strcmp(buf
, "-y") == 0) {
430 build_library_index(cp
, CASE_SENSITIVE
);
432 } else if (strcmp(buf
, "-yl") == 0) {
433 build_library_index(cp
, false);
435 } else if (strcmp(buf
, "-Y") == 0) {
436 library_suff
.push_back(strdup(cp
));
438 } else if (strcmp(buf
,"-t") == 0) {
441 } else if (strcmp(buf
,"-T") == 0) {
442 if (strcmp(cp
,"min") == 0) {
443 min_typ_max_flag
= MIN
;
444 min_typ_max_warn
= 0;
445 } else if (strcmp(cp
,"typ") == 0) {
446 min_typ_max_flag
= TYP
;
447 min_typ_max_warn
= 0;
448 } else if (strcmp(cp
,"max") == 0) {
449 min_typ_max_flag
= MAX
;
450 min_typ_max_warn
= 0;
452 cerr
<< "Invalid argument (" << optarg
<< ") to -T flag."
461 extern Design
* elaborate(list
<perm_string
> root
);
463 #if defined(HAVE_TIMES)
464 static double cycles_diff(struct tms
*a
, struct tms
*b
)
466 clock_t aa
= a
->tms_utime
471 clock_t bb
= b
->tms_utime
476 return (aa
-bb
)/(double)sysconf(_SC_CLK_TCK
);
478 #else // ! defined(HAVE_TIMES)
480 struct tms
{ int x
; };
481 inline static void times(struct tms
*) { }
482 inline static double cycles_diff(struct tms
*a
, struct tms
*b
) { return 0; }
483 #endif // ! defined(HAVE_TIMES)
485 int main(int argc
, char*argv
[])
487 bool help_flag
= false;
488 bool times_flag
= false;
490 const char* net_path
= 0;
491 const char* pf_path
= 0;
494 struct tms cycles
[5];
496 library_suff
.push_back(".v");
498 vpi_module_list
= strdup("system");
499 flags
["VPI_MODULE_LIST"] = vpi_module_list
;
500 flags
["-o"] = "a.out";
501 min_typ_max_flag
= TYP
;
502 min_typ_max_warn
= 10;
504 while ((opt
= getopt(argc
, argv
, "C:f:hN:P:p:Vv")) != EOF
) switch (opt
) {
507 read_iconfig_file(optarg
);
511 parm_to_flagmap(optarg
);
523 parm_to_flagmap(optarg
);
527 # if defined(HAVE_TIMES)
532 cout
<< "Icarus Verilog version " << VERSION
<< endl
;
533 cout
<< COPYRIGHT
<< endl
;
534 cout
<< endl
<< NOTICE
<< endl
;
545 cout
<< "Icarus Verilog version " << VERSION
<< endl
<<
546 "usage: ivl <options> <file>\n"
548 "\t-C <name> Config file from driver.\n"
549 "\t-h Print usage information, and exit.\n"
550 "\t-N <file> Dump the elaborated netlist to <file>.\n"
551 "\t-P <file> Write the parsed input to <file>.\n"
552 "\t-p <assign> Set a parameter value.\n"
553 "\t-v Print progress indications"
554 #if defined(HAVE_TIMES)
555 " and execution times"
558 "\t-V Print version and copyright information, and exit.\n"
564 if (optind
== argc
) {
565 cerr
<< "No input files." << endl
;
570 depend_file
= fopen(depfile_name
, "a");
572 perror(depfile_name
);
581 cout
<< "Using language generation: ";
582 switch (generation_flag
) {
584 cout
<< "IEEE1364-1995";
587 cout
<< "IEEE1364-2001";
590 cout
<< "IEEE1364-2001+Extensions";
594 if (gn_specify_blocks_flag
)
597 cout
<< ",no-specify";
599 if (gn_cadence_types_flag
)
602 cout
<< ",no-xtypes";
604 cout
<< endl
<< "PARSING INPUT" << endl
;
607 /* Parse the input. Make the pform. */
608 int rc
= pform_parse(argv
[optind
]);
611 ofstream
out (pf_path
);
612 out
<< "PFORM DUMP MODULES:" << endl
;
613 for (map
<perm_string
,Module
*>::iterator mod
= pform_modules
.begin()
614 ; mod
!= pform_modules
.end()
616 pform_dump(out
, (*mod
).second
);
618 out
<< "PFORM DUMP PRIMITIVES:" << endl
;
619 for (map
<perm_string
,PUdp
*>::iterator idx
= pform_primitives
.begin()
620 ; idx
!= pform_primitives
.end()
622 (*idx
).second
->dump(out
);
631 /* If the user did not give specific module(s) to start with,
632 then look for modules that are not instantiated anywhere. */
635 map
<perm_string
,bool> mentioned_p
;
636 map
<perm_string
,Module
*>::iterator mod
;
638 cout
<< "LOCATING TOP-LEVEL MODULES" << endl
<< " ";
639 for (mod
= pform_modules
.begin()
640 ; mod
!= pform_modules
.end()
642 list
<PGate
*> gates
= (*mod
).second
->get_gates();
643 list
<PGate
*>::const_iterator gate
;
644 for (gate
= gates
.begin(); gate
!= gates
.end(); gate
++) {
645 PGModule
*mod
= dynamic_cast<PGModule
*>(*gate
);
647 // Note that this module has been instantiated
648 mentioned_p
[mod
->get_type()] = true;
653 for (mod
= pform_modules
.begin()
654 ; mod
!= pform_modules
.end()
657 /* Don't choose library modules. */
658 if ((*mod
).second
->library_flag
)
661 /* Don't choose modules instantiated in other
663 if (mentioned_p
[(*mod
).second
->mod_name()])
666 /* What's left might as well be chosen as a root. */
668 cout
<< " " << (*mod
).second
->mod_name();
669 roots
.push_back((*mod
).second
->mod_name());
675 /* If there is *still* no guess for the root module, then give
676 up completely, and complain. */
679 cerr
<< "No top level modules, and no -s option." << endl
;
688 <<cycles_diff(cycles
+1, cycles
+0)<<" seconds."<<endl
;
690 cout
<< "ELABORATING DESIGN" << endl
;
693 /* On with the process of elaborating the module. */
694 Design
*des
= elaborate(roots
);
696 if ((des
== 0) || (des
->errors
> 0)) {
699 << " error(s) during elaboration." << endl
;
701 ofstream
out (net_path
);
705 cerr
<< "Elaboration failed" << endl
;
711 des
->set_flags(flags
);
713 /* Done iwth all the pform data. Delete the modules. */
714 for (map
<perm_string
,Module
*>::iterator idx
= pform_modules
.begin()
715 ; idx
!= pform_modules
.end() ; idx
++) {
717 delete (*idx
).second
;
725 <<cycles_diff(cycles
+2, cycles
+1)<<" seconds."<<endl
;
727 cout
<< "RUNNING FUNCTORS" << endl
;
730 while (!net_func_queue
.empty()) {
731 net_func func
= net_func_queue
.front();
732 net_func_queue
.pop();
734 cerr
<<" -F "<<net_func_to_name(func
)<< " ..." <<endl
;
740 cerr
<<" dumping netlist to " <<net_path
<< "..." <<endl
;
742 ofstream
out (net_path
);
748 << " error(s) in post-elaboration processing." <<
757 <<cycles_diff(cycles
+3, cycles
+2)<<" seconds."<<endl
;
762 cout
<< "CODE GENERATION -t "<<target
<< endl
;
766 emit_rc
= emit(des
, target
);
768 cerr
<< "error: Code generation had "
769 << emit_rc
<< " errors."
774 cerr
<< "error: Code generator failure: " << emit_rc
<< endl
;
782 <<cycles_diff(cycles
+4, cycles
+3)<<" seconds."<<endl
;
784 cout
<< "DONE." << endl
;
789 cout
<< "STATISTICS" << endl
;
790 cout
<< "lex_string:"
791 << " add_count=" << lex_strings
.add_count()
792 << " hit_count=" << lex_strings
.add_hit_count()
799 if (missing_modules
.size() > 0) {
800 cerr
<< "*** These modules were missing:" << endl
;
802 map
<perm_string
,unsigned>::const_iterator idx
;
803 for (idx
= missing_modules
.begin()
804 ; idx
!= missing_modules
.end()
806 cerr
<< " " << (*idx
).first
807 << " referenced " << (*idx
).second
810 cerr
<< "***" << endl
;
813 return des
? des
->errors
: 1;
818 * Revision 1.95 2007/04/19 02:52:53 steve
819 * Add support for -v flag in command file.
821 * Revision 1.94 2007/03/07 04:24:59 steve
822 * Make integer width controllable.
824 * Revision 1.93 2006/09/28 04:35:18 steve
825 * Support selective control of specify and xtypes features.
827 * Revision 1.92 2005/07/14 23:38:43 steve
828 * Display as version 0.9.devel
830 * Revision 1.91 2005/07/07 16:22:49 steve
831 * Generalize signals to carry types.
833 * Revision 1.90 2005/06/28 04:25:55 steve
834 * Remove reference to SystemVerilog.
836 * Revision 1.89 2005/04/24 23:44:02 steve
837 * Update DFF support to new data flow.
839 * Revision 1.88 2005/01/22 01:06:55 steve
840 * Change case compare from logic to an LPM node.
842 * Revision 1.87 2004/12/11 02:31:26 steve
843 * Rework of internals to carry vectors through nexus instead
844 * of single bits. Make the ivl, tgt-vvp and vvp initial changes
847 * Revision 1.86 2004/10/04 01:10:53 steve
848 * Clean up spurious trailing white space.
850 * Revision 1.85 2004/09/25 01:58:44 steve
851 * Add a debug_elaborate flag
853 * Revision 1.84 2004/09/10 23:51:42 steve
854 * Fix the evaluation of constant ternary expressions.
856 * Revision 1.83 2004/09/05 17:44:42 steve
857 * Add support for module instance arrays.
859 * Revision 1.82 2004/03/10 04:51:24 steve
860 * Add support for system function table files.
862 * Revision 1.81 2004/02/18 17:11:56 steve
863 * Use perm_strings for named langiage items.
865 * Revision 1.80 2004/02/15 00:19:29 steve
866 * Report elaboration errors without crashing.
868 * Revision 1.79 2003/11/26 01:37:14 steve
869 * Properly initialize vpi_module_list with system.
871 * Revision 1.78 2003/11/13 05:55:33 steve
872 * Move the DLL= flag to target config files.
874 * Revision 1.77 2003/11/13 04:09:49 steve
875 * Pass flags through the temporary config file.
877 * Revision 1.76 2003/11/13 03:10:38 steve
878 * ivl -F and -t flags are onpassed throught the -C file.
880 * Revision 1.75 2003/11/10 20:59:03 steve
881 * Design::get_flag returns const char* instead of string.
883 * Revision 1.74 2003/11/01 04:22:30 steve
884 * Accept functors in the config file.
886 * Revision 1.73 2003/10/26 22:43:42 steve
887 * Improve -V messages,
889 * Revision 1.72 2003/09/26 02:17:14 steve
890 * Delete pform when done with it.
892 * Revision 1.71 2003/09/25 00:25:14 steve
893 * Summary list of missing modules.
895 * Revision 1.70 2003/09/23 05:57:36 steve
896 * Pass -m flag from driver via iconfig file.
898 * Revision 1.69 2003/09/22 01:12:08 steve
899 * Pass more ivl arguments through the iconfig file.
901 * Revision 1.68 2003/06/20 00:53:19 steve
902 * Module attributes from the parser
903 * through to elaborated form.
905 * Revision 1.67 2003/04/24 05:25:27 steve
906 * Dump design even on errors.
908 * Revision 1.66 2003/03/01 06:25:30 steve
909 * Add the lex_strings string handler, and put
910 * scope names and system task/function names
911 * into this table. Also, permallocate event
912 * names from the beginning.