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;
148 * Are we doing synthesis?
150 bool synthesis
= false;
152 extern void cprop(Design
*des
);
153 extern void synth(Design
*des
);
154 extern void synth2(Design
*des
);
155 extern void syn_rules(Design
*des
);
156 extern void nodangle(Design
*des
);
158 extern void xnfio(Design
*des
);
161 typedef void (*net_func
)(Design
*);
162 static struct net_func_map
{
164 void (*func
)(Design
*);
167 { "nodangle",&nodangle
},
169 { "synth2", &synth2
},
170 { "syn-rules", &syn_rules
},
177 queue
<net_func
> net_func_queue
;
179 net_func
name_to_net_func(const string
&name
)
181 for (unsigned idx
= 0 ; func_table
[idx
].name
; idx
+= 1)
182 if (name
== func_table
[idx
].name
)
183 return func_table
[idx
].func
;
188 const char *net_func_to_name(const net_func func
)
190 for (unsigned idx
= 0 ; func_table
[idx
].name
; idx
+= 1)
191 if (func
== func_table
[idx
].func
)
192 return func_table
[idx
].name
;
194 return "This cannot happen";
197 static void process_generation_flag(const char*gen
)
199 if (strcmp(gen
,"1") == 0) {
200 generation_flag
= GN_VER1995
;
202 } else if (strcmp(gen
,"2") == 0) {
203 generation_flag
= GN_VER2001
;
205 } else if (strcmp(gen
,"2x") == 0) {
206 generation_flag
= GN_VER2001X
;
208 } else if (strcmp(gen
,"xtypes") == 0) {
209 gn_cadence_types_flag
= true;
211 } else if (strcmp(gen
,"no-xtypes") == 0) {
212 gn_cadence_types_flag
= false;
214 } else if (strcmp(gen
,"specify") == 0) {
215 gn_specify_blocks_flag
= true;
217 } else if (strcmp(gen
,"no-specify") == 0) {
218 gn_specify_blocks_flag
= false;
220 } else if (strcmp(gen
,"io-range-error") == 0) {
221 gn_io_range_error_flag
= true;
223 } else if (strcmp(gen
,"no-io-range-error") == 0) {
224 gn_io_range_error_flag
= false;
230 static void parm_to_flagmap(const string
&flag
)
234 unsigned off
= flag
.find('=');
235 if (off
> flag
.size()) {
240 key
= flag
.substr(0, off
);
241 value
= strdup(flag
.substr(off
+1).c_str());
248 * Read the contents of a config file. This file is a temporary
249 * configuration file made by the compiler driver to carry the bulky
250 * flags generated from the user. This reduces the size of the command
251 * line needed to invoke ivl.
253 * Each line of the iconfig file has the format:
257 * The <value> is all the text after the ':' and up to but not
258 * including the end of the line. Thus, white spaces and ':'
259 * characters may appear here.
261 * The valid keys are:
268 * Select which expression to use.
274 * Location to look for installed sub-components
277 * Activate a class of debug messages.
280 * Give the path to an output dependency file.
282 * flag:<name>=<string>
283 * Generic compiler flag strings.
286 * Append a named functor to the processing path.
288 * generation:<1|2|2x|xtypes|no-xtypes|specify|no-specify>
289 * This is the generation flag
291 * ivlpp:<preprocessor command>
292 * This specifies the ivlpp command line used to process
293 * library modules as I read them in.
296 * This specifies the width of integer variables. (that is,
297 * variables declared using the "integer" keyword.)
299 * library_file:<path>
300 * This marks that a source file with the given path is a
301 * library. Any modules in that file are marked as library
308 * Path to the output file.
311 * Path to a system functions descriptor table
314 * Specify a root module. There may be multiple of this.
317 * Warning flag letters.
319 static void read_iconfig_file(const char*ipath
)
323 FILE*ifile
= fopen(ipath
, "r");
325 cerr
<< "ERROR: Unable to read config file: " << ipath
<< endl
;
329 while (fgets(buf
, sizeof buf
, ifile
) != 0) {
332 char*cp
= strchr(buf
, ':');
337 char*ep
= cp
+ strlen(cp
);
352 if (strcmp(buf
, "basedir") == 0) {
353 basedir
= strdup(cp
);
355 } else if (strcmp(buf
, "debug") == 0) {
356 if (strcmp(cp
, "scope") == 0) {
358 cerr
<< "debug: Enable scope debug" << endl
;
359 } else if (strcmp(cp
,"eval_tree") == 0) {
360 debug_eval_tree
= true;
361 cerr
<< "debug: Enable eval_tree debug" << endl
;
362 } else if (strcmp(cp
,"elaborate") == 0) {
363 debug_elaborate
= true;
364 cerr
<< "debug: Enable elaborate debug" << endl
;
365 } else if (strcmp(cp
,"synth2") == 0) {
367 cerr
<< "debug: Enable synth2 debug" << endl
;
371 } else if (strcmp(buf
, "depfile") == 0) {
372 depfile_name
= strdup(cp
);
374 } else if (strcmp(buf
, "flag") == 0) {
376 parm_to_flagmap(parm
);
378 } else if (strcmp(buf
,"functor") == 0) {
379 if (strncmp(cp
, "synth", 5) == 0) {
380 synthesis
= true; // We are doing synthesis.
382 net_func tmp
= name_to_net_func(cp
);
384 cerr
<< "No such design transform function ``"
385 << cp
<< "''." << endl
;
389 net_func_queue
.push(tmp
);
391 } else if (strcmp(buf
, "generation") == 0) {
392 process_generation_flag(cp
);
394 } else if (strcmp(buf
, "ivlpp") == 0) {
395 ivlpp_string
= strdup(cp
);
397 } else if (strcmp(buf
, "iwidth") == 0) {
398 integer_width
= strtoul(cp
,0,10);
400 } else if (strcmp(buf
, "library_file") == 0) {
401 const char* path
= strdup(cp
);
402 library_file_map
[path
] = true;
404 } else if (strcmp(buf
,"module") == 0) {
405 if (vpi_module_list
== 0) {
406 vpi_module_list
= strdup(cp
);
409 char*tmp
= (char*)realloc(vpi_module_list
,
410 strlen(vpi_module_list
)
415 vpi_module_list
= tmp
;
417 flags
["VPI_MODULE_LIST"] = vpi_module_list
;
419 } else if (strcmp(buf
, "out") == 0) {
420 flags
["-o"] = strdup(cp
);
422 } else if (strcmp(buf
, "sys_func") == 0) {
423 load_sys_func_table(cp
);
425 } else if (strcmp(buf
, "root") == 0) {
426 roots
.push_back(lex_strings
.make(cp
));
428 } else if (strcmp(buf
,"warnings") == 0) {
429 /* Scan the warnings enable string for warning flags. */
430 for ( ; *cp
; cp
+= 1) switch (*cp
) {
432 warn_implicit
= true;
435 warn_portbinding
= true;
438 warn_timescale
= true;
444 } else if (strcmp(buf
, "-y") == 0) {
445 build_library_index(cp
, CASE_SENSITIVE
);
447 } else if (strcmp(buf
, "-yl") == 0) {
448 build_library_index(cp
, false);
450 } else if (strcmp(buf
, "-Y") == 0) {
451 library_suff
.push_back(strdup(cp
));
453 } else if (strcmp(buf
,"-t") == 0) {
456 } else if (strcmp(buf
,"-T") == 0) {
457 if (strcmp(cp
,"min") == 0) {
458 min_typ_max_flag
= MIN
;
459 min_typ_max_warn
= 0;
460 } else if (strcmp(cp
,"typ") == 0) {
461 min_typ_max_flag
= TYP
;
462 min_typ_max_warn
= 0;
463 } else if (strcmp(cp
,"max") == 0) {
464 min_typ_max_flag
= MAX
;
465 min_typ_max_warn
= 0;
467 cerr
<< "Invalid argument (" << optarg
<< ") to -T flag."
476 extern Design
* elaborate(list
<perm_string
> root
);
478 #if defined(HAVE_TIMES)
479 static double cycles_diff(struct tms
*a
, struct tms
*b
)
481 clock_t aa
= a
->tms_utime
486 clock_t bb
= b
->tms_utime
491 return (aa
-bb
)/(double)sysconf(_SC_CLK_TCK
);
493 #else // ! defined(HAVE_TIMES)
495 struct tms
{ int x
; };
496 inline static void times(struct tms
*) { }
497 inline static double cycles_diff(struct tms
*a
, struct tms
*b
) { return 0; }
498 #endif // ! defined(HAVE_TIMES)
500 int main(int argc
, char*argv
[])
502 bool help_flag
= false;
503 bool times_flag
= false;
505 const char* net_path
= 0;
506 const char* pf_path
= 0;
509 struct tms cycles
[5];
511 library_suff
.push_back(".v");
513 vpi_module_list
= strdup("system");
514 flags
["VPI_MODULE_LIST"] = vpi_module_list
;
515 flags
["-o"] = "a.out";
516 min_typ_max_flag
= TYP
;
517 min_typ_max_warn
= 10;
519 while ((opt
= getopt(argc
, argv
, "C:f:hN:P:p:Vv")) != EOF
) switch (opt
) {
522 read_iconfig_file(optarg
);
526 parm_to_flagmap(optarg
);
538 parm_to_flagmap(optarg
);
542 # if defined(HAVE_TIMES)
547 cout
<< "Icarus Verilog version " << VERSION
<< endl
;
548 cout
<< COPYRIGHT
<< endl
;
549 cout
<< endl
<< NOTICE
<< endl
;
560 cout
<< "Icarus Verilog version " << VERSION
<< endl
<<
561 "usage: ivl <options> <file>\n"
563 "\t-C <name> Config file from driver.\n"
564 "\t-h Print usage information, and exit.\n"
565 "\t-N <file> Dump the elaborated netlist to <file>.\n"
566 "\t-P <file> Write the parsed input to <file>.\n"
567 "\t-p <assign> Set a parameter value.\n"
568 "\t-v Print progress indications"
569 #if defined(HAVE_TIMES)
570 " and execution times"
573 "\t-V Print version and copyright information, and exit.\n"
579 if (optind
== argc
) {
580 cerr
<< "No input files." << endl
;
585 depend_file
= fopen(depfile_name
, "a");
587 perror(depfile_name
);
596 cout
<< "Using language generation: ";
597 switch (generation_flag
) {
599 cout
<< "IEEE1364-1995";
602 cout
<< "IEEE1364-2001";
605 cout
<< "IEEE1364-2001+Extensions";
609 if (gn_specify_blocks_flag
)
612 cout
<< ",no-specify";
614 if (gn_cadence_types_flag
)
617 cout
<< ",no-xtypes";
619 cout
<< endl
<< "PARSING INPUT" << endl
;
622 /* Parse the input. Make the pform. */
623 int rc
= pform_parse(argv
[optind
]);
626 ofstream
out (pf_path
);
627 out
<< "PFORM DUMP MODULES:" << endl
;
628 for (map
<perm_string
,Module
*>::iterator mod
= pform_modules
.begin()
629 ; mod
!= pform_modules
.end()
631 pform_dump(out
, (*mod
).second
);
633 out
<< "PFORM DUMP PRIMITIVES:" << endl
;
634 for (map
<perm_string
,PUdp
*>::iterator idx
= pform_primitives
.begin()
635 ; idx
!= pform_primitives
.end()
637 (*idx
).second
->dump(out
);
646 /* If the user did not give specific module(s) to start with,
647 then look for modules that are not instantiated anywhere. */
650 map
<perm_string
,bool> mentioned_p
;
651 map
<perm_string
,Module
*>::iterator mod
;
653 cout
<< "LOCATING TOP-LEVEL MODULES" << endl
<< " ";
654 for (mod
= pform_modules
.begin()
655 ; mod
!= pform_modules
.end()
657 list
<PGate
*> gates
= (*mod
).second
->get_gates();
658 list
<PGate
*>::const_iterator gate
;
659 for (gate
= gates
.begin(); gate
!= gates
.end(); gate
++) {
660 PGModule
*mod
= dynamic_cast<PGModule
*>(*gate
);
662 // Note that this module has been instantiated
663 mentioned_p
[mod
->get_type()] = true;
668 for (mod
= pform_modules
.begin()
669 ; mod
!= pform_modules
.end()
672 /* Don't choose library modules. */
673 if ((*mod
).second
->library_flag
)
676 /* Don't choose modules instantiated in other
678 if (mentioned_p
[(*mod
).second
->mod_name()])
681 /* What's left might as well be chosen as a root. */
683 cout
<< " " << (*mod
).second
->mod_name();
684 roots
.push_back((*mod
).second
->mod_name());
690 /* If there is *still* no guess for the root module, then give
691 up completely, and complain. */
694 cerr
<< "No top level modules, and no -s option." << endl
;
703 <<cycles_diff(cycles
+1, cycles
+0)<<" seconds."<<endl
;
705 cout
<< "ELABORATING DESIGN" << endl
;
708 /* On with the process of elaborating the module. */
709 Design
*des
= elaborate(roots
);
711 if ((des
== 0) || (des
->errors
> 0)) {
714 << " error(s) during elaboration." << endl
;
716 ofstream
out (net_path
);
720 cerr
<< "Elaboration failed" << endl
;
726 des
->set_flags(flags
);
728 /* Done iwth all the pform data. Delete the modules. */
729 for (map
<perm_string
,Module
*>::iterator idx
= pform_modules
.begin()
730 ; idx
!= pform_modules
.end() ; idx
++) {
732 delete (*idx
).second
;
740 <<cycles_diff(cycles
+2, cycles
+1)<<" seconds."<<endl
;
742 cout
<< "RUNNING FUNCTORS" << endl
;
745 while (!net_func_queue
.empty()) {
746 net_func func
= net_func_queue
.front();
747 net_func_queue
.pop();
749 cerr
<<" -F "<<net_func_to_name(func
)<< " ..." <<endl
;
755 cerr
<<" dumping netlist to " <<net_path
<< "..." <<endl
;
757 ofstream
out (net_path
);
763 << " error(s) in post-elaboration processing." <<
772 <<cycles_diff(cycles
+3, cycles
+2)<<" seconds."<<endl
;
777 cout
<< "CODE GENERATION -t "<<target
<< endl
;
781 emit_rc
= emit(des
, target
);
783 cerr
<< "error: Code generation had "
784 << emit_rc
<< " errors."
789 cerr
<< "error: Code generator failure: " << emit_rc
<< endl
;
797 <<cycles_diff(cycles
+4, cycles
+3)<<" seconds."<<endl
;
799 cout
<< "DONE." << endl
;
804 cout
<< "STATISTICS" << endl
;
805 cout
<< "lex_string:"
806 << " add_count=" << lex_strings
.add_count()
807 << " hit_count=" << lex_strings
.add_hit_count()
814 if (missing_modules
.size() > 0) {
815 cerr
<< "*** These modules were missing:" << endl
;
817 map
<perm_string
,unsigned>::const_iterator idx
;
818 for (idx
= missing_modules
.begin()
819 ; idx
!= missing_modules
.end()
821 cerr
<< " " << (*idx
).first
822 << " referenced " << (*idx
).second
825 cerr
<< "***" << endl
;
828 return des
? des
->errors
: 1;
833 * Revision 1.95 2007/04/19 02:52:53 steve
834 * Add support for -v flag in command file.
836 * Revision 1.94 2007/03/07 04:24:59 steve
837 * Make integer width controllable.
839 * Revision 1.93 2006/09/28 04:35:18 steve
840 * Support selective control of specify and xtypes features.
842 * Revision 1.92 2005/07/14 23:38:43 steve
843 * Display as version 0.9.devel
845 * Revision 1.91 2005/07/07 16:22:49 steve
846 * Generalize signals to carry types.
848 * Revision 1.90 2005/06/28 04:25:55 steve
849 * Remove reference to SystemVerilog.
851 * Revision 1.89 2005/04/24 23:44:02 steve
852 * Update DFF support to new data flow.
854 * Revision 1.88 2005/01/22 01:06:55 steve
855 * Change case compare from logic to an LPM node.
857 * Revision 1.87 2004/12/11 02:31:26 steve
858 * Rework of internals to carry vectors through nexus instead
859 * of single bits. Make the ivl, tgt-vvp and vvp initial changes
862 * Revision 1.86 2004/10/04 01:10:53 steve
863 * Clean up spurious trailing white space.
865 * Revision 1.85 2004/09/25 01:58:44 steve
866 * Add a debug_elaborate flag
868 * Revision 1.84 2004/09/10 23:51:42 steve
869 * Fix the evaluation of constant ternary expressions.
871 * Revision 1.83 2004/09/05 17:44:42 steve
872 * Add support for module instance arrays.
874 * Revision 1.82 2004/03/10 04:51:24 steve
875 * Add support for system function table files.
877 * Revision 1.81 2004/02/18 17:11:56 steve
878 * Use perm_strings for named langiage items.
880 * Revision 1.80 2004/02/15 00:19:29 steve
881 * Report elaboration errors without crashing.
883 * Revision 1.79 2003/11/26 01:37:14 steve
884 * Properly initialize vpi_module_list with system.
886 * Revision 1.78 2003/11/13 05:55:33 steve
887 * Move the DLL= flag to target config files.
889 * Revision 1.77 2003/11/13 04:09:49 steve
890 * Pass flags through the temporary config file.
892 * Revision 1.76 2003/11/13 03:10:38 steve
893 * ivl -F and -t flags are onpassed throught the -C file.
895 * Revision 1.75 2003/11/10 20:59:03 steve
896 * Design::get_flag returns const char* instead of string.
898 * Revision 1.74 2003/11/01 04:22:30 steve
899 * Accept functors in the config file.
901 * Revision 1.73 2003/10/26 22:43:42 steve
902 * Improve -V messages,
904 * Revision 1.72 2003/09/26 02:17:14 steve
905 * Delete pform when done with it.
907 * Revision 1.71 2003/09/25 00:25:14 steve
908 * Summary list of missing modules.
910 * Revision 1.70 2003/09/23 05:57:36 steve
911 * Pass -m flag from driver via iconfig file.
913 * Revision 1.69 2003/09/22 01:12:08 steve
914 * Pass more ivl arguments through the iconfig file.
916 * Revision 1.68 2003/06/20 00:53:19 steve
917 * Module attributes from the parser
918 * through to elaborated form.
920 * Revision 1.67 2003/04/24 05:25:27 steve
921 * Dump design even on errors.
923 * Revision 1.66 2003/03/01 06:25:30 steve
924 * Add the lex_strings string handler, and put
925 * scope names and system task/function names
926 * into this table. Also, permallocate event
927 * names from the beginning.