1 const char COPYRIGHT[] =
2 "Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)";
3
4 /*
5 * This source code is free software; you can redistribute it
6 * and/or modify it in source code form under the terms of the GNU
7 * General Public License as published by the Free Software
8 * Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 # include "config.h"
22 # include "version_base.h"
23 # include "version_tag.h"
24
25 const char NOTICE[] =
26 " This program is free software; you can redistribute it and/or modify\n"
27 " it under the terms of the GNU General Public License as published by\n"
28 " the Free Software Foundation; either version 2 of the License, or\n"
29 " (at your option) any later version.\n"
30 "\n"
31 " This program is distributed in the hope that it will be useful,\n"
32 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
33 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
34 " GNU General Public License for more details.\n"
35 "\n"
36 " You should have received a copy of the GNU General Public License along\n"
37 " with this program; if not, write to the Free Software Foundation, Inc.,\n"
38 " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
39 ;
40
41 # include <cstdio>
42 # include <iostream>
43 # include <fstream>
44 # include <queue>
45 # include <cstring>
46 # include <list>
47 # include <map>
48 # include <unistd.h>
49 # include <cstdlib>
50 #if defined(HAVE_TIMES)
51 # include <sys/times.h>
52 #endif
53 #if defined(HAVE_GETOPT_H)
54 # include <getopt.h>
55 #endif
56 # include "pform.h"
57 # include "parse_api.h"
58 # include "PGenerate.h"
59 # include "netlist.h"
60 # include "target.h"
61 # include "compiler.h"
62 # include "discipline.h"
63 # include "t-dll.h"
64
65 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
66 extern "C" int getopt(int argc, char*argv[], const char*fmt);
67 extern "C" int optind;
68 extern "C" const char*optarg;
69 #endif
70
71 #if defined(__CYGWIN__) && !defined(HAVE_GETOPT_H)
72 extern "C" int getopt(int argc, char*argv[], const char*fmt);
73 extern "C" int optind;
74 extern "C" const char*optarg;
75 #endif
76
77 #if defined(TRAP_SIGINT_FOR_DEBUG)
78 /*
79 * This is a debugging aid. Do not compile it in general, but leave it
80 * here for those days when I need the ability to cleanly exit on a
81 * signal interrupt.
82 */
83 # include <csignal>
signals_handler(int sig)84 static void signals_handler(int sig)
85 {
86 fprintf(stderr, "Exit on signal %d\n", sig);
87 exit(1);
88 }
89 #endif
90
91 # include "ivl_alloc.h"
92
93 /* Count errors detected in flag processing. */
94 unsigned flag_errors = 0;
95
96 const char*basedir = strdup(".");
97
98 /*
99 * These are the language support control flags. These support which
100 * language features (the generation) to support. The generation_flag
101 * is a major mode, and the gn_* flags control specific sub-features.
102 */
103 generation_t generation_flag = GN_DEFAULT;
104 bool gn_icarus_misc_flag = true;
105 bool gn_cadence_types_flag = true;
106 bool gn_specify_blocks_flag = true;
107 bool gn_supported_assertions_flag = true;
108 bool gn_unsupported_assertions_flag = true;
109 bool gn_io_range_error_flag = true;
110 bool gn_strict_ca_eval_flag = false;
111 bool gn_strict_expr_width_flag = false;
112 bool gn_shared_loop_index_flag = true;
113 bool gn_verilog_ams_flag = false;
114
115 /*
116 * For some generations we allow a system function to be called
117 * as a task and only print a warning message. The default for
118 * this is that it is a run time error.
119 */
120 ivl_sfunc_as_task_t def_sfunc_as_task = IVL_SFUNC_AS_TASK_ERROR;
121
122 map<string,const char*> flags;
123 char*vpi_module_list = 0;
add_vpi_module(const char * name)124 void add_vpi_module(const char*name)
125 {
126 if (vpi_module_list == 0) {
127 vpi_module_list = strdup(name);
128
129 } else {
130 char*tmp = (char*)realloc(vpi_module_list,
131 strlen(vpi_module_list)
132 + strlen(name)
133 + 2);
134 strcat(tmp, ",");
135 strcat(tmp, name);
136 vpi_module_list = tmp;
137 }
138 flags["VPI_MODULE_LIST"] = vpi_module_list;
139 load_vpi_module(name);
140 }
141
142 map<perm_string,unsigned> missing_modules;
143 map<perm_string,bool> library_file_map;
144
145 vector<perm_string> source_files;
146
147 list<const char*> library_suff;
148
149 list<perm_string> roots;
150
151 char*ivlpp_string = 0;
152
153 char depfile_mode = 'a';
154 char* depfile_name = NULL;
155 FILE *depend_file = NULL;
156
157 /*
158 * These are the warning enable flags.
159 */
160 bool warn_implicit = false;
161 bool warn_implicit_dimensions = false;
162 bool warn_timescale = false;
163 bool warn_portbinding = false;
164 bool warn_inf_loop = false;
165 bool warn_ob_select = false;
166 bool warn_sens_entire_vec = false;
167 bool warn_sens_entire_arr = false;
168 bool warn_anachronisms = false;
169 bool warn_floating_nets = false;
170
171 /*
172 * Ignore errors about missing modules
173 */
174 bool ignore_missing_modules = false;
175
176 /*
177 * Debug message class flags.
178 */
179 bool debug_scopes = false;
180 bool debug_eval_tree = false;
181 bool debug_elaborate = false;
182 bool debug_emit = false;
183 bool debug_synth2 = false;
184 bool debug_optimizer = false;
185
186 /*
187 * Compilation control flags.
188 */
189 bool separate_compilation = false;
190
191 /*
192 * Optimization control flags.
193 */
194 unsigned opt_const_func = 0;
195
196 /*
197 * Miscellaneous flags.
198 */
199 bool disable_virtual_pins = false;
200 unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364?
201 unsigned recursive_mod_limit = 10;
202 bool disable_concatz_generation = false;
203
204 /*
205 * Verbose messages enabled.
206 */
207 bool verbose_flag = false;
208
209 unsigned integer_width = 32;
210
211 /*
212 * Width limit for unsized expressions.
213 */
214 unsigned width_cap = 65536;
215
216 int def_ts_units = 0;
217 int def_ts_prec = 0;
218
219 /*
220 * Keep a heap of identifier strings that I encounter. This is a more
221 * efficient way to allocate those strings.
222 */
223 StringHeapLex lex_strings;
224
225 StringHeapLex filename_strings;
226
227 StringHeapLex bits_strings;
228
229 /*
230 * In library searches, Windows file names are never case sensitive.
231 */
232 #if defined(__MINGW32__)
233 const bool CASE_SENSITIVE = false;
234 #else
235 const bool CASE_SENSITIVE = true;
236 #endif
237
238 /*
239 * Are we doing synthesis?
240 */
241 bool synthesis = false;
242
243 extern void cprop(Design*des);
244 extern void exposenodes(Design*des);
245 extern void synth(Design*des);
246 extern void synth2(Design*des);
247 extern void syn_rules(Design*des);
248 extern void nodangle(Design*des);
249
250 typedef void (*net_func)(Design*);
251 static struct net_func_map {
252 const char*name;
253 void (*func)(Design*);
254 } func_table[] = {
255 { "cprop", &cprop },
256 { "exposenodes", &exposenodes },
257 { "nodangle", &nodangle },
258 { "synth", &synth },
259 { "synth2", &synth2 },
260 { "syn-rules", &syn_rules },
261 { 0, 0 }
262 };
263
264 queue<net_func> net_func_queue;
265
name_to_net_func(const string & name)266 net_func name_to_net_func(const string&name)
267 {
268 for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
269 if (name == func_table[idx].name)
270 return func_table[idx].func;
271
272 return 0;
273 }
274
net_func_to_name(const net_func func)275 const char *net_func_to_name(const net_func func)
276 {
277 for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
278 if (func == func_table[idx].func)
279 return func_table[idx].name;
280
281 return "This cannot happen";
282 }
283
process_generation_flag(const char * gen)284 static void process_generation_flag(const char*gen)
285 {
286 if (strcmp(gen,"1") == 0) { // FIXME: Deprecated for 1995
287 generation_flag = GN_VER1995;
288
289 } else if (strcmp(gen,"2") == 0) { // FIXME: Deprecated for 2001
290 generation_flag = GN_VER2001;
291
292 } else if (strcmp(gen,"2x") == 0) { // FIXME: Deprecated for 2001
293 generation_flag = GN_VER2001;
294 gn_icarus_misc_flag = true;
295
296 } else if (strcmp(gen,"1995") == 0) {
297 generation_flag = GN_VER1995;
298
299 } else if (strcmp(gen,"2001") == 0) {
300 generation_flag = GN_VER2001;
301
302 } else if (strcmp(gen,"2001-noconfig") == 0) {
303 generation_flag = GN_VER2001_NOCONFIG;
304
305 } else if (strcmp(gen,"2005") == 0) {
306 generation_flag = GN_VER2005;
307
308 } else if (strcmp(gen,"2005-sv") == 0) {
309 generation_flag = GN_VER2005_SV;
310
311 } else if (strcmp(gen,"2009") == 0) {
312 generation_flag = GN_VER2009;
313
314 } else if (strcmp(gen,"2012") == 0) {
315 generation_flag = GN_VER2012;
316
317 } else if (strcmp(gen,"icarus-misc") == 0) {
318 gn_icarus_misc_flag = true;
319
320 } else if (strcmp(gen,"no-icarus-misc") == 0) {
321 gn_icarus_misc_flag = false;
322
323 } else if (strcmp(gen,"xtypes") == 0) {
324 gn_cadence_types_flag = true;
325
326 } else if (strcmp(gen,"no-xtypes") == 0) {
327 gn_cadence_types_flag = false;
328
329 } else if (strcmp(gen,"specify") == 0) {
330 gn_specify_blocks_flag = true;
331
332 } else if (strcmp(gen,"no-specify") == 0) {
333 gn_specify_blocks_flag = false;
334
335 } else if (strcmp(gen,"assertions") == 0) {
336 gn_supported_assertions_flag = true;
337 gn_unsupported_assertions_flag = true;
338
339 } else if (strcmp(gen,"supported-assertions") == 0) {
340 gn_supported_assertions_flag = true;
341 gn_unsupported_assertions_flag = false;
342
343 } else if (strcmp(gen,"no-assertions") == 0) {
344 gn_supported_assertions_flag = false;
345 gn_unsupported_assertions_flag = false;
346
347 } else if (strcmp(gen,"verilog-ams") == 0) {
348 gn_verilog_ams_flag = true;
349
350 } else if (strcmp(gen,"no-verilog-ams") == 0) {
351 gn_verilog_ams_flag = false;
352
353 } else if (strcmp(gen,"io-range-error") == 0) {
354 gn_io_range_error_flag = true;
355
356 } else if (strcmp(gen,"no-io-range-error") == 0) {
357 gn_io_range_error_flag = false;
358
359 } else if (strcmp(gen,"strict-ca-eval") == 0) {
360 gn_strict_ca_eval_flag = true;
361
362 } else if (strcmp(gen,"no-strict-ca-eval") == 0) {
363 gn_strict_ca_eval_flag = false;
364
365 } else if (strcmp(gen,"strict-expr-width") == 0) {
366 gn_strict_expr_width_flag = true;
367
368 } else if (strcmp(gen,"no-strict-expr-width") == 0) {
369 gn_strict_expr_width_flag = false;
370
371 } else if (strcmp(gen,"shared-loop-index") == 0) {
372 gn_shared_loop_index_flag = true;
373
374 } else if (strcmp(gen,"no-shared-loop-index") == 0) {
375 gn_shared_loop_index_flag = false;
376
377 } else {
378 }
379 }
380
parm_to_flagmap(const string & flag)381 static void parm_to_flagmap(const string&flag)
382 {
383 string key;
384 const char*value;
385 unsigned off = flag.find('=');
386 if (off > flag.size()) {
387 key = flag;
388 value = strdup("");
389
390 } else {
391 key = flag.substr(0, off);
392 value = strdup(flag.substr(off+1).c_str());
393 }
394
395 flags[key] = value;
396 }
397
398 static void find_module_mention(map<perm_string,bool>&check_map, Module*m);
399 static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s);
400
401 /*
402 * Convert a string to a time unit or precision.
403 *
404 * Returns true on failure.
405 */
get_ts_const(const char * & cp,int & res,bool is_units)406 static bool get_ts_const(const char*&cp, int&res, bool is_units)
407 {
408 /* Check for the 1 digit. */
409 if (*cp != '1') {
410 if (is_units) {
411 cerr << "Error: Invalid +timescale units constant "
412 "(1st digit)." << endl;
413 } else {
414 cerr << "Error: Invalid +timescale precision constant "
415 "(1st digit)." << endl;
416 }
417 return true;
418 }
419 cp += 1;
420
421 /* Check the number of zeros after the 1. */
422 res = strspn(cp, "0");
423 if (res > 2) {
424 if (is_units) {
425 cerr << "Error: Invalid +timescale units constant "
426 "(number of zeros)." << endl;
427 } else {
428 cerr << "Error: Invalid +timescale precision constant "
429 "(number of zeros)." << endl;
430 }
431 return true;
432 }
433 cp += res;
434
435 /* Now process the scaling string. */
436 if (strncmp("s", cp, 1) == 0) {
437 res -= 0;
438 cp += 1;
439 return false;
440
441 } else if (strncmp("ms", cp, 2) == 0) {
442 res -= 3;
443 cp += 2;
444 return false;
445
446 } else if (strncmp("us", cp, 2) == 0) {
447 res -= 6;
448 cp += 2;
449 return false;
450
451 } else if (strncmp("ns", cp, 2) == 0) {
452 res -= 9;
453 cp += 2;
454 return false;
455
456 } else if (strncmp("ps", cp, 2) == 0) {
457 res -= 12;
458 cp += 2;
459 return false;
460
461 } else if (strncmp("fs", cp, 2) == 0) {
462 res -= 15;
463 cp += 2;
464 return false;
465
466 }
467
468 if (is_units) {
469 cerr << "Error: Invalid +timescale units scale." << endl;
470 } else {
471 cerr << "Error: Invalid +timescale precision scale." << endl;
472 }
473 return true;
474 }
475
476 /*
477 * Process a string with the following form (no space allowed):
478 *
479 * num = < '1' | '10' | '100' >
480 * scale = < 's' | 'ms' | 'us' | 'ns' | 'ps' | 'fs' >
481 *
482 * "<num> <scale> '/' <num> <scale>
483 *
484 * and set the default time units and precision if successful.
485 *
486 * Return true if we have an error processing the timescale string.
487 */
set_default_timescale(const char * ts_string)488 static bool set_default_timescale(const char*ts_string)
489 {
490 /* Because this came from a command file we can not have embedded
491 * space in this string. */
492 const char*cp = ts_string;
493 int units = 0;
494 int prec = 0;
495
496 /* Get the time units. */
497 if (get_ts_const(cp, units, true)) return true;
498
499 /* Skip the '/'. */
500 if (*cp != '/') {
501 cerr << "Error: +timescale separator '/' is missing." << endl;
502 return true;
503 }
504 cp += 1;
505
506 /* Get the time precision. */
507 if (get_ts_const(cp, prec, false)) return true;
508
509 /* The time unit must be greater than or equal to the precision. */
510 if (units < prec) {
511 cerr << "Error: +timescale unit must not be less than the "
512 "precision." << endl;
513 return true;
514 }
515
516 /* We have valid units and precision so set the global defaults. */
517 def_ts_units = units;
518 def_ts_prec = prec;
519 return false;
520 }
521
522 /*
523 * Read the contents of a config file. This file is a temporary
524 * configuration file made by the compiler driver to carry the bulky
525 * flags generated from the user. This reduces the size of the command
526 * line needed to invoke ivl.
527 *
528 * Each line of the iconfig file has the format:
529 *
530 * <keyword>:<value>
531 *
532 * The <value> is all the text after the ':' and up to but not
533 * including the end of the line. Thus, white spaces and ':'
534 * characters may appear here.
535 *
536 * The valid keys are:
537 *
538 * -y:<dir>
539 * -yl:<dir>
540 * -Y:<string>
541 *
542 * -T:<min/typ/max>
543 * Select which expression to use.
544 *
545 * -t:<target> (obsolete)
546 * Usually, "-t:dll"
547 *
548 * basedir:<path>
549 * Location to look for installed sub-components
550 *
551 * debug:<name>
552 * Activate a class of debug messages.
553 *
554 * depfile:<path>
555 * Give the path to an output dependency file.
556 *
557 * flag:<name>=<string>
558 * Generic compiler flag strings.
559 *
560 * functor:<name>
561 * Append a named functor to the processing path.
562 *
563 * generation:<1|2|2x|xtypes|no-xtypes|specify|no-specify>
564 * This is the generation flag
565 *
566 * ivlpp:<preprocessor command>
567 * This specifies the ivlpp command line used to process
568 * library modules as I read them in.
569 *
570 * iwidth:<bits>
571 * This specifies the width of integer variables. (that is,
572 * variables declared using the "integer" keyword.)
573 *
574 * library_file:<path>
575 * This marks that a source file with the given path is a
576 * library. Any modules in that file are marked as library
577 * modules.
578 *
579 * module:<name>
580 * Load a VPI module.
581 *
582 * out:<path>
583 * Path to the output file.
584 *
585 * sys_func:<path>
586 * Path to a system functions descriptor table
587 *
588 * root:<name>
589 * Specify a root module. There may be multiple of this.
590 *
591 * warnings:<string>
592 * Warning flag letters.
593 *
594 * ignore_missing_modules:<bool>
595 * true to ignore errors about missing modules
596 */
597 bool had_timescale = false;
read_iconfig_file(const char * ipath)598 static void read_iconfig_file(const char*ipath)
599 {
600 char buf[8*1024];
601 vector<pair<char*,bool> > to_build_library_index;
602
603 FILE*ifile = fopen(ipath, "r");
604 if (ifile == 0) {
605 cerr << "ERROR: Unable to read config file: " << ipath << endl;
606 return;
607 }
608
609 while (fgets(buf, sizeof buf, ifile) != 0) {
610 assert(strlen(buf) < sizeof buf);
611 if ((strlen(buf) == ((sizeof buf) - 1))
612 && buf[sizeof buf -2] != '\n') {
613 cerr << "WARNING: Line buffer overflow reading iconfig file: "
614 << ipath
615 << "." << endl;
616 assert(0);
617 }
618 if (buf[0] == '#')
619 continue;
620 char*cp = strchr(buf, ':');
621 if (cp == 0)
622 continue;
623
624 *cp++ = 0;
625 char*ep = cp + strlen(cp);
626 while (ep > cp) {
627 ep -= 1;
628 switch (*ep) {
629 case '\r':
630 case '\n':
631 case ' ':
632 case '\t':
633 *ep = 0;
634 break;
635 default:
636 ep = cp;
637 }
638 }
639
640 if (strcmp(buf, "basedir") == 0) {
641 free((void *)basedir);
642 basedir = strdup(cp);
643
644 } else if (strcmp(buf, "debug") == 0) {
645 if (strcmp(cp, "scopes") == 0) {
646 debug_scopes = true;
647 cerr << "debug: Enable scopes debug" << endl;
648 } else if (strcmp(cp,"eval_tree") == 0) {
649 debug_eval_tree = true;
650 cerr << "debug: Enable eval_tree debug" << endl;
651 } else if (strcmp(cp,"elaborate") == 0) {
652 debug_elaborate = true;
653 cerr << "debug: Enable elaborate debug" << endl;
654 } else if (strcmp(cp,"emit") == 0) {
655 debug_emit = true;
656 cerr << "debug: Enable emit debug" << endl;
657 } else if (strcmp(cp,"synth2") == 0) {
658 debug_synth2 = true;
659 cerr << "debug: Enable synth2 debug" << endl;
660 } else if (strcmp(cp,"optimizer") == 0) {
661 debug_optimizer = true;
662 cerr << "debug: Enable optimizer debug" << endl;
663 } else {
664 }
665
666 } else if (strcmp(buf, "depmode") == 0) {
667 depfile_mode = *cp;
668
669 } else if (strcmp(buf, "depfile") == 0) {
670 depfile_name = strdup(cp);
671
672 } else if (strcmp(buf, "flag") == 0) {
673 string parm = cp;
674 parm_to_flagmap(parm);
675
676 } else if (strcmp(buf,"functor") == 0) {
677 if (strncmp(cp, "synth", 5) == 0) {
678 synthesis = true; // We are doing synthesis.
679 }
680 net_func tmp = name_to_net_func(cp);
681 if (tmp == 0) {
682 cerr << "No such design transform function ``"
683 << cp << "''." << endl;
684 flag_errors += 1;
685 break;
686 }
687 net_func_queue.push(tmp);
688
689 } else if (strcmp(buf, "generation") == 0) {
690 process_generation_flag(cp);
691
692 } else if (strcmp(buf, "ivlpp") == 0) {
693 ivlpp_string = strdup(cp);
694
695 } else if (strcmp(buf, "iwidth") == 0) {
696 integer_width = strtoul(cp,0,10);
697
698 } else if (strcmp(buf, "widthcap") == 0) {
699 width_cap = strtoul(cp,0,10);
700
701 } else if (strcmp(buf, "library_file") == 0) {
702 perm_string path = filename_strings.make(cp);
703 library_file_map[path] = true;
704
705 } else if (strcmp(buf,"module") == 0) {
706 add_vpi_module(cp);
707
708 } else if (strcmp(buf, "out") == 0) {
709 free((void *)flags["-o"]);
710 flags["-o"] = strdup(cp);
711
712 } else if (strcmp(buf, "sys_func") == 0) {
713 load_sys_func_table(cp);
714
715 } else if (strcmp(buf, "root") == 0) {
716 roots.push_back(lex_strings.make(cp));
717
718 } else if (strcmp(buf,"warnings") == 0) {
719 /* Scan the warnings enable string for warning flags. */
720 for ( ; *cp ; cp += 1) switch (*cp) {
721 case 'f':
722 warn_floating_nets = true;
723 break;
724 case 'i':
725 warn_implicit = true;
726 break;
727 case 'd':
728 warn_implicit_dimensions = true;
729 break;
730 case 'l':
731 warn_inf_loop = true;
732 break;
733 case 's':
734 warn_ob_select = true;
735 break;
736 case 'p':
737 warn_portbinding = true;
738 break;
739 case 't':
740 warn_timescale = true;
741 break;
742 case 'v':
743 warn_sens_entire_vec = true;
744 break;
745 case 'a':
746 warn_sens_entire_arr = true;
747 break;
748 case 'n':
749 warn_anachronisms = true;
750 break;
751 default:
752 break;
753 }
754
755 } else if (strcmp(buf, "ignore_missing_modules") == 0) {
756 if (strcmp(cp, "true") == 0)
757 ignore_missing_modules = true;
758
759 } else if (strcmp(buf, "-y") == 0) {
760 to_build_library_index.push_back(make_pair(strdup(cp), CASE_SENSITIVE));
761
762 } else if (strcmp(buf, "-yl") == 0) {
763 to_build_library_index.push_back(make_pair(strdup(cp), false));
764
765 } else if (strcmp(buf, "-Y") == 0) {
766 library_suff.push_back(strdup(cp));
767
768 } else if (strcmp(buf,"-t") == 0) {
769 // NO LONGER USED
770
771 } else if (strcmp(buf,"-T") == 0) {
772 if (strcmp(cp,"min") == 0) {
773 min_typ_max_flag = MIN;
774 min_typ_max_warn = 0;
775 } else if (strcmp(cp,"typ") == 0) {
776 min_typ_max_flag = TYP;
777 min_typ_max_warn = 0;
778 } else if (strcmp(cp,"max") == 0) {
779 min_typ_max_flag = MAX;
780 min_typ_max_warn = 0;
781 } else {
782 cerr << "Invalid argument (" << optarg << ") to -T flag."
783 << endl;
784 flag_errors += 1;
785 }
786 } else if (strcmp(buf,"defparam") == 0) {
787 parm_to_defparam_list(cp);
788 } else if (strcmp(buf,"timescale") == 0) {
789 if (had_timescale) {
790 cerr << "Command File: Warning: default timescale "
791 "is being set multiple times." << endl;
792 cerr << " : using the last valid "
793 "+timescale found." << endl;
794 }
795 if (set_default_timescale(cp)) {
796 cerr << " : with +timescale+" << cp << "+" << endl;
797 flag_errors += 1;
798 } else had_timescale = true;
799 }
800 }
801 fclose(ifile);
802 for (vector<pair<char *, bool> >::iterator it = to_build_library_index.begin() ;
803 it != to_build_library_index.end() ; ++ it ) {
804 build_library_index(it->first, it->second);
805 free(it->first);
806 }
807 }
808
809 /*
810 * This function reads a list of source file names. Each name starts
811 * with the first non-space character, and ends with the last non-space
812 * character. Spaces in the middle are OK.
813 */
read_sources_file(const char * path)814 static void read_sources_file(const char*path)
815 {
816 char line_buf[2048];
817
818 FILE*fd = fopen(path, "r");
819 if (fd == 0) {
820 cerr << "ERROR: Unable to read source file list: " << path << endl;
821 return;
822 }
823
824 while (fgets(line_buf, sizeof line_buf, fd) != 0) {
825 // assertion test that we are not overflowing the line
826 // buffer. Really should make this more robust, but
827 // better to assert then go weird.
828 assert(strlen(line_buf) < sizeof line_buf);
829 if ((strlen(line_buf) == ((sizeof line_buf) - 1))
830 && line_buf[sizeof line_buf -2] != '\n') {
831 cerr << "WARNING: Line buffer overflow reading sources file: "
832 << path
833 << "." << endl;
834 assert(0);
835 }
836 char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
837 char*tail = cp + strlen(cp);
838 while (tail > cp) {
839 if (! isspace((int)tail[-1]))
840 break;
841 tail -= 1;
842 tail[0] = 0;
843 }
844
845 if (cp < tail)
846 source_files.push_back(filename_strings.make(cp));
847 }
848
849 fclose(fd);
850 }
851
852 extern Design* elaborate(list <perm_string> root);
853
854 #if defined(HAVE_TIMES)
cycles_diff(struct tms * a,struct tms * b)855 static double cycles_diff(struct tms *a, struct tms *b)
856 {
857 clock_t aa = a->tms_utime
858 + a->tms_stime
859 + a->tms_cutime
860 + a->tms_cstime;
861
862 clock_t bb = b->tms_utime
863 + b->tms_stime
864 + b->tms_cutime
865 + b->tms_cstime;
866
867 return (aa-bb)/(double)sysconf(_SC_CLK_TCK);
868 }
869 #else // ! defined(HAVE_TIMES)
870 // Provide dummies
871 struct tms { int x; };
times(struct tms *)872 inline static void times(struct tms *) { }
cycles_diff(struct tms *,struct tms *)873 inline static double cycles_diff(struct tms *, struct tms *) { return 0; }
874 #endif // ! defined(HAVE_TIMES)
875
EOC_cleanup(void)876 static void EOC_cleanup(void)
877 {
878 cleanup_sys_func_table();
879
880 for (list<const char*>::iterator suf = library_suff.begin() ;
881 suf != library_suff.end() ; ++ suf ) {
882 free((void *)*suf);
883 }
884 library_suff.clear();
885
886 free((void *) basedir);
887 free(ivlpp_string);
888 free(depfile_name);
889
890 for (map<string, const char*>::iterator flg = flags.begin() ;
891 flg != flags.end() ; ++ flg ) {
892 free((void *)flg->second);
893 }
894 flags.clear();
895
896 lex_strings.cleanup();
897 bits_strings.cleanup();
898 filename_strings.cleanup();
899 }
900
main(int argc,char * argv[])901 int main(int argc, char*argv[])
902 {
903 bool help_flag = false;
904 bool times_flag = false;
905 bool version_flag = false;
906
907 const char* net_path = 0;
908 const char* pf_path = 0;
909 int opt;
910
911 struct tms cycles[5];
912
913 #if defined(TRAP_SIGINT_FOR_DEBUG)
914 signal(SIGINT, &signals_handler);
915 #endif
916 if( ::getenv("IVL_WAIT_FOR_DEBUGGER") != 0 ) {
917 fprintf( stderr, "Waiting for debugger...\n");
918 bool debugger_release = false;
919 while( !debugger_release ) {
920 #if defined(__MINGW32__)
921 Sleep(1000);
922 #else
923 sleep(1);
924 #endif
925 }
926 }
927 library_suff.push_back(strdup(".v"));
928
929 flags["-o"] = strdup("a.out");
930 min_typ_max_flag = TYP;
931 min_typ_max_warn = 10;
932
933 while ((opt = getopt(argc, argv, "C:F:f:hN:P:p:Vv")) != EOF) switch (opt) {
934
935 case 'C':
936 read_iconfig_file(optarg);
937 break;
938 case 'F':
939 read_sources_file(optarg);
940 break;
941 case 'f':
942 parm_to_flagmap(optarg);
943 break;
944 case 'h':
945 help_flag = true;
946 break;
947 case 'N':
948 net_path = optarg;
949 break;
950 case 'P':
951 pf_path = optarg;
952 break;
953 case 'p':
954 parm_to_flagmap(optarg);
955 break;
956 case 'v':
957 verbose_flag = true;
958 # if defined(HAVE_TIMES)
959 times_flag = true;
960 # endif
961 flags["VVP_EXTRA_ARGS"] = strdup(" -v");
962 break;
963 case 'V':
964 version_flag = true;
965 break;
966 default:
967 flag_errors += 1;
968 break;
969 }
970
971 if (flag_errors)
972 return flag_errors;
973
974 if (version_flag) {
975 cout << "\nIcarus Verilog Parser/Elaborator version "
976 << VERSION << " (" << VERSION_TAG << ")" << endl << endl;
977 cout << COPYRIGHT << endl << endl;
978 cout << NOTICE << endl;
979
980 cout << " FLAGS DLL " << flags["DLL"] << endl;
981
982 dll_target_obj.test_version(flags["DLL"]);
983
984 return 0;
985 }
986
987 if (help_flag) {
988 cout << "Icarus Verilog Parser/Elaborator version "
989 << VERSION << " (" << VERSION_TAG << ")" << endl <<
990 "usage: ivl <options> <file>\n"
991 "options:\n"
992 "\t-C <name> Config file from driver.\n"
993 "\t-F <file> List of source files from driver.\n"
994 "\t-h Print usage information, and exit.\n"
995 "\t-N <file> Dump the elaborated netlist to <file>.\n"
996 "\t-P <file> Write the parsed input to <file>.\n"
997 "\t-p <assign> Set a parameter value.\n"
998 "\t-v Print progress indications"
999 #if defined(HAVE_TIMES)
1000 " and execution times"
1001 #endif
1002 ".\n"
1003 "\t-V Print version and copyright information, and exit.\n"
1004
1005 ;
1006 return 0;
1007 }
1008
1009 int arg = optind;
1010 while (arg < argc) {
1011 perm_string path = filename_strings.make(argv[arg++]);
1012 source_files.push_back(path);
1013 }
1014
1015 if (source_files.empty()) {
1016 cerr << "No input files." << endl;
1017 return 1;
1018 }
1019
1020 separate_compilation = source_files.size() > 1;
1021
1022 if( depfile_name ) {
1023 depend_file = fopen(depfile_name, "a");
1024 if(! depend_file) {
1025 perror(depfile_name);
1026 }
1027 }
1028
1029 lexor_keyword_mask = 0;
1030 switch (generation_flag) {
1031 case GN_VER2012:
1032 lexor_keyword_mask |= GN_KEYWORDS_1800_2012;
1033 // fallthrough
1034 case GN_VER2009:
1035 lexor_keyword_mask |= GN_KEYWORDS_1800_2009;
1036 // fallthrough
1037 case GN_VER2005_SV:
1038 lexor_keyword_mask |= GN_KEYWORDS_1800_2005;
1039 // fallthrough
1040 case GN_VER2005:
1041 lexor_keyword_mask |= GN_KEYWORDS_1364_2005;
1042 // fallthrough
1043 case GN_VER2001:
1044 lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
1045 // fallthrough
1046 case GN_VER2001_NOCONFIG:
1047 lexor_keyword_mask |= GN_KEYWORDS_1364_2001;
1048 // fallthrough
1049 case GN_VER1995:
1050 lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
1051 }
1052
1053 if (gn_cadence_types_flag)
1054 lexor_keyword_mask |= GN_KEYWORDS_ICARUS;
1055
1056 if (gn_verilog_ams_flag)
1057 lexor_keyword_mask |= GN_KEYWORDS_VAMS_2_3;
1058
1059 if (verbose_flag) {
1060 if (times_flag)
1061 times(cycles+0);
1062
1063 cout << "Using language generation: ";
1064 switch (generation_flag) {
1065 case GN_VER1995:
1066 cout << "IEEE1364-1995";
1067 break;
1068 case GN_VER2001_NOCONFIG:
1069 cout << "IEEE1364-2001-noconfig";
1070 break;
1071 case GN_VER2001:
1072 cout << "IEEE1364-2001";
1073 break;
1074 case GN_VER2005:
1075 cout << "IEEE1364-2005";
1076 break;
1077 case GN_VER2005_SV:
1078 cout << "IEEE1800-2005";
1079 break;
1080 case GN_VER2009:
1081 cout << "IEEE1800-2009";
1082 break;
1083 case GN_VER2012:
1084 cout << "IEEE1800-2012";
1085 break;
1086 }
1087
1088 if (gn_verilog_ams_flag)
1089 cout << ",verilog-ams";
1090
1091 if (gn_specify_blocks_flag)
1092 cout << ",specify";
1093 else
1094 cout << ",no-specify";
1095
1096 if (gn_cadence_types_flag)
1097 cout << ",xtypes";
1098 else
1099 cout << ",no-xtypes";
1100
1101 if (gn_icarus_misc_flag)
1102 cout << ",icarus-misc";
1103 else
1104 cout << ",no-icarus-misc";
1105
1106 cout << endl << "PARSING INPUT" << endl;
1107 }
1108
1109 const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"];
1110 if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0;
1111
1112 flag_tmp = flags["ARRAY_SIZE_LIMIT"];
1113 if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0);
1114
1115 flag_tmp = flags["RECURSIVE_MOD_LIMIT"];
1116 if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0);
1117
1118 flag_tmp = flags["DISABLE_CONCATZ_GENERATION"];
1119 if (flag_tmp) disable_concatz_generation = strcmp(flag_tmp,"true")==0;
1120
1121 /* Parse the input. Make the pform. */
1122 int rc = 0;
1123 for (unsigned idx = 0; idx < source_files.size(); idx += 1) {
1124 rc += pform_parse(source_files[idx]);
1125 }
1126
1127 if (pf_path) {
1128 ofstream out (pf_path);
1129 out << "PFORM DUMP NATURES:" << endl;
1130 for (map<perm_string,ivl_nature_t>::iterator cur = natures.begin()
1131 ; cur != natures.end() ; ++ cur ) {
1132 pform_dump(out, (*cur).second);
1133 }
1134 out << "PFORM DUMP DISCIPLINES:" << endl;
1135 for (map<perm_string,ivl_discipline_t>::iterator cur = disciplines.begin()
1136 ; cur != disciplines.end() ; ++ cur ) {
1137 pform_dump(out, (*cur).second);
1138 }
1139 out << "PFORM DUMP COMPILATION UNITS:" << endl;
1140 for (vector<PPackage*>::iterator pac = pform_units.begin()
1141 ; pac != pform_units.end() ; ++ pac) {
1142 pform_dump(out, *pac);
1143 }
1144 out << "PFORM DUMP PACKAGES:" << endl;
1145 for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
1146 ; pac != pform_packages.end() ; ++ pac) {
1147 pform_dump(out, pac->second);
1148 }
1149 out << "PFORM DUMP MODULES:" << endl;
1150 for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
1151 ; mod != pform_modules.end() ; ++ mod ) {
1152 pform_dump(out, (*mod).second);
1153 }
1154 out << "PFORM DUMP PRIMITIVES:" << endl;
1155 for (map<perm_string,PUdp*>::iterator idx = pform_primitives.begin()
1156 ; idx != pform_primitives.end() ; ++ idx ) {
1157 (*idx).second->dump(out);
1158 }
1159 }
1160
1161 if (rc) {
1162 return rc;
1163 }
1164
1165
1166 /* If the user did not give specific module(s) to start with,
1167 then look for modules that are not instantiated anywhere. */
1168
1169 if (roots.empty()) {
1170 map<perm_string,bool> mentioned_p;
1171 map<perm_string,Module*>::iterator mod;
1172 if (verbose_flag)
1173 cout << "LOCATING TOP-LEVEL MODULES" << endl << " ";
1174 for (mod = pform_modules.begin()
1175 ; mod != pform_modules.end() ; ++ mod ) {
1176 find_module_mention(mentioned_p, mod->second);
1177 }
1178
1179 for (mod = pform_modules.begin()
1180 ; mod != pform_modules.end() ; ++ mod ) {
1181
1182 /* Don't choose library modules. */
1183 if ((*mod).second->library_flag)
1184 continue;
1185
1186 /* Don't choose modules instantiated in other
1187 modules. */
1188 if (mentioned_p[(*mod).second->mod_name()])
1189 continue;
1190
1191 /* What's left might as well be chosen as a root. */
1192 if (verbose_flag)
1193 cout << " " << (*mod).second->mod_name();
1194 roots.push_back((*mod).second->mod_name());
1195 }
1196 if (verbose_flag)
1197 cout << endl;
1198 }
1199
1200 /* If there is *still* no guess for the root module, then give
1201 up completely, and complain. */
1202
1203 if (roots.empty()) {
1204 cerr << "No top level modules, and no -s option." << endl;
1205 return ignore_missing_modules ? 0 : 1;
1206 }
1207
1208
1209 if (verbose_flag) {
1210 if (times_flag) {
1211 times(cycles+1);
1212 cerr<<" ... done, "
1213 <<cycles_diff(cycles+1, cycles+0)<<" seconds."<<endl;
1214 }
1215 cout << "ELABORATING DESIGN" << endl;
1216 }
1217
1218 /* Decide if we are going to allow system functions to be called
1219 * as tasks. */
1220 if (gn_system_verilog()) {
1221 def_sfunc_as_task = IVL_SFUNC_AS_TASK_WARNING;
1222 }
1223
1224 /* On with the process of elaborating the module. */
1225 Design*des = elaborate(roots);
1226
1227 if ((des == 0) || (des->errors > 0)) {
1228 if (des != 0) {
1229 cerr << des->errors
1230 << " error(s) during elaboration." << endl;
1231 if (net_path) {
1232 ofstream out (net_path);
1233 des->dump(out);
1234 }
1235 } else {
1236 cerr << "Elaboration failed" << endl;
1237 }
1238
1239 goto errors_summary;
1240 }
1241
1242 des->set_flags(flags);
1243
1244 switch(min_typ_max_flag) {
1245 case MIN:
1246 des->set_delay_sel(Design::MIN);
1247 break;
1248 case TYP:
1249 des->set_delay_sel(Design::TYP);
1250 break;
1251 case MAX:
1252 des->set_delay_sel(Design::MAX);
1253 break;
1254 default:
1255 assert(0);
1256 }
1257
1258 /* Done with all the pform data. Delete the modules. */
1259 for (map<perm_string,Module*>::iterator idx = pform_modules.begin()
1260 ; idx != pform_modules.end() ; ++ idx ) {
1261
1262 delete (*idx).second;
1263 (*idx).second = 0;
1264 }
1265
1266 if (verbose_flag) {
1267 if (times_flag) {
1268 times(cycles+2);
1269 cerr<<" ... done, "
1270 <<cycles_diff(cycles+2, cycles+1)<<" seconds."<<endl;
1271 }
1272 cout << "RUNNING FUNCTORS" << endl;
1273 }
1274
1275 while (!net_func_queue.empty()) {
1276 net_func func = net_func_queue.front();
1277 net_func_queue.pop();
1278 if (verbose_flag)
1279 cerr<<" -F "<<net_func_to_name(func)<< " ..." <<endl;
1280 func(des);
1281 }
1282
1283 if (verbose_flag) {
1284 cout << "CALCULATING ISLANDS" << endl;
1285 }
1286 des->join_islands();
1287
1288 if (net_path) {
1289 if (verbose_flag)
1290 cerr<<" dumping netlist to " <<net_path<< "..." <<endl;
1291
1292 ofstream out (net_path);
1293 des->dump(out);
1294 }
1295
1296 if (des->errors) {
1297 cerr << des->errors
1298 << " error(s) in post-elaboration processing." <<
1299 endl;
1300 return des->errors;
1301 }
1302
1303 if (verbose_flag) {
1304 if (times_flag) {
1305 times(cycles+3);
1306 cerr<<" ... done, "
1307 <<cycles_diff(cycles+3, cycles+2)<<" seconds."<<endl;
1308 }
1309 }
1310
1311 if (verbose_flag) {
1312 cout << "CODE GENERATION" << endl;
1313 }
1314
1315 if (int emit_rc = des->emit(&dll_target_obj)) {
1316 if (emit_rc > 0) {
1317 cerr << "error: Code generation had "
1318 << emit_rc << " error(s)."
1319 << endl;
1320 return 1;
1321 }
1322 if (emit_rc < 0) {
1323 cerr << "error: Code generator failure: " << emit_rc << endl;
1324 return -1;
1325 }
1326 assert(emit_rc);
1327 }
1328
1329 if (verbose_flag) {
1330 if (times_flag) {
1331 times(cycles+4);
1332 cerr<<" ... done, "
1333 <<cycles_diff(cycles+4, cycles+3)<<" seconds."<<endl;
1334 } else {
1335 cout << "DONE." << endl;
1336 }
1337 }
1338
1339 if (verbose_flag) {
1340 cout << "STATISTICS" << endl;
1341 cout << "lex_string:"
1342 << " add_count=" << lex_strings.add_count()
1343 << " hit_count=" << lex_strings.add_hit_count()
1344 << endl;
1345 }
1346
1347 delete des;
1348 EOC_cleanup();
1349 return 0;
1350
1351 errors_summary:
1352 if (! missing_modules.empty()) {
1353 cerr << "*** These modules were missing:" << endl;
1354
1355 map<perm_string,unsigned>::const_iterator idx;
1356 for (idx = missing_modules.begin()
1357 ; idx != missing_modules.end() ; ++ idx )
1358 cerr << " " << (*idx).first
1359 << " referenced " << (*idx).second
1360 << " times."<< endl;
1361
1362 cerr << "***" << endl;
1363 }
1364
1365 return des? des->errors : 1;
1366 }
1367
find_module_mention(map<perm_string,bool> & check_map,Module * mod)1368 static void find_module_mention(map<perm_string,bool>&check_map, Module*mod)
1369 {
1370 list<PGate*> gates = mod->get_gates();
1371 list<PGate*>::const_iterator gate;
1372 for (gate = gates.begin(); gate != gates.end(); ++ gate ) {
1373 PGModule*tmp = dynamic_cast<PGModule*>(*gate);
1374 if (tmp) {
1375 // Note that this module has been instantiated
1376 check_map[tmp->get_type()] = true;
1377 }
1378 }
1379
1380 list<PGenerate*>::const_iterator cur;
1381 for (cur = mod->generate_schemes.begin()
1382 ; cur != mod->generate_schemes.end() ; ++ cur ) {
1383 find_module_mention(check_map, *cur);
1384 }
1385 }
1386
find_module_mention(map<perm_string,bool> & check_map,PGenerate * schm)1387 static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*schm)
1388 {
1389 list<PGate*>::const_iterator gate;
1390 for (gate = schm->gates.begin(); gate != schm->gates.end(); ++ gate ) {
1391 PGModule*tmp = dynamic_cast<PGModule*>(*gate);
1392 if (tmp) {
1393 // Note that this module has been instantiated
1394 check_map[tmp->get_type()] = true;
1395 }
1396 }
1397
1398 list<PGenerate*>::const_iterator cur;
1399 for (cur = schm->generate_schemes.begin()
1400 ; cur != schm->generate_schemes.end() ; ++ cur ) {
1401 find_module_mention(check_map, *cur);
1402 }
1403 }
1404