2 * Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24 " This program is free software; you can redistribute it and/or modify\n"
25 " it under the terms of the GNU General Public License as published by\n"
26 " the Free Software Foundation; either version 2 of the License, or\n"
27 " (at your option) any later version.\n"
29 " This program is distributed in the hope that it will be useful,\n"
30 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
31 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
32 " GNU General Public License for more details.\n"
34 " You should have received a copy of the GNU General Public License\n"
35 " along with this program; if not, write to the Free Software\n"
36 " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
40 "Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile] [-g1|-g2|-g2x]\n"
41 " [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
42 " [-N file] [-o filename] [-p flag=value]\n"
43 " [-s topmodule] [-t target] [-T min|typ|max]\n"
44 " [-W class] [-y dir] [-Y suf] source_file(s)\n"
46 "See the man page for details.";
56 #include <sys/types.h>
57 #ifdef HAVE_SYS_WAIT_H
63 #ifdef HAVE_LIBIBERTY_H
64 #include <libiberty.h>
72 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
73 extern int getopt(int argc
, char*argv
[], const char*fmt
);
75 extern const char*optarg
;
78 #if !defined(WIFEXITED)
79 # define WIFEXITED(rc) ((rc&0x7f) == 0)
82 #if !defined(WEXITSTATUS)
83 # define WEXITSTATUS(rc) (rc>>8)
91 #include "cfparse_misc.h" /* cfparse() */
94 const char sep
= '\\';
99 extern void cfreset(FILE*fd
, const char*path
);
102 const char*pbase
= 0;
104 const char*opath
= "a.out";
105 const char*npath
= 0;
106 const char*targ
= "vvp";
107 const char*depfile
= 0;
109 const char*generation
= "2x";
110 const char*gen_specify
= "specify";
111 const char*gen_xtypes
= "xtypes";
112 const char*gen_icarus
= "icarus-misc";
113 const char*gen_io_range_error
= "io-range-error";
114 const char*gen_verilog_ams
= "no-verilog-ams";
116 /* Boolean: true means use a default include dir, false means don't */
117 int gen_std_include
= 1;
119 char warning_flags
[16] = "";
121 unsigned integer_width
= 32;
124 char*command_filename
= 0;
126 /* These are used to collect the list of file names that will be
127 passed to ivlpp. Keep the list in a file because it can be a long
129 char*source_path
= 0;
130 FILE*source_file
= 0;
131 unsigned source_count
= 0;
133 char*defines_path
= 0;
134 FILE*defines_file
= 0;
136 char*iconfig_path
= 0;
137 FILE*iconfig_file
= 0;
139 char*compiled_defines_path
= 0;
141 static char iconfig_common_path_buf
[4096] = "";
142 char*iconfig_common_path
= iconfig_common_path_buf
;
145 int verbose_flag
= 0;
152 static char ivl_root
[MAXSIZE
];
154 /* Structure to keep a FIFO list of the command files */
155 typedef struct t_command_file
{
157 struct t_command_file
*next
;
158 } s_command_file
, *p_command_file
;
159 p_command_file cmd_file_head
= NULL
; /* The FIFO head */
160 p_command_file cmd_file_tail
= NULL
; /* The FIFO tail */
162 /* Function to add a command file name to the FIFO. */
163 void add_cmd_file(const char* filename
)
167 new = (p_command_file
) malloc(sizeof(s_command_file
));
168 new->filename
= strdup(filename
);
170 if (cmd_file_head
== NULL
) {
174 cmd_file_tail
->next
= new;
179 /* Function to return the top command file name from the FIFO. */
184 if (cmd_file_head
== NULL
) filename
= NULL
;
188 filename
= cmd_file_head
->filename
;
189 head
= cmd_file_head
;
190 cmd_file_head
= cmd_file_head
->next
;
199 static FILE*fopen_safe(const char*path
)
204 fd
= _open(path
, _O_WRONLY
|_O_CREAT
|_O_EXCL
, 0700);
206 file
= _fdopen(fd
, "w");
212 static FILE*fopen_safe(const char*path
)
217 fd
= open(path
, O_WRONLY
|O_CREAT
|O_EXCL
, 0700);
219 file
= fdopen(fd
, "w");
225 static const char*my_tempfile(const char*str
, FILE**fout
)
230 static char pathbuf
[8192];
232 const char*tmpdir
= getenv("TMP");
234 tmpdir
= getenv("TMPDIR");
236 tmpdir
= getenv("TEMP");
246 assert((strlen(tmpdir
) + strlen(str
)) < sizeof pathbuf
- 10);
251 while ((retry
> 0) && (file
== NULL
)) {
252 unsigned code
= rand();
253 sprintf(pathbuf
, "%s%c%s%04x", tmpdir
, sep
, str
, code
);
254 file
= fopen_safe(pathbuf
);
263 * This is the default target type. It looks up the bits that are
264 * needed to run the command from the configuration file (which is
265 * already parsed for us) so we can handle must of the generic cases.
267 static int t_default(char*cmd
, unsigned ncmd
)
271 unsigned ncmd_start
= ncmd
;
274 snprintf(tmp
, sizeof tmp
, " | %s/ivl", base
);
276 cmd
= realloc(cmd
, ncmd
+rc
+1);
277 strcpy(cmd
+ncmd
, tmp
);
281 const char*vv
= " -v";
283 cmd
= realloc(cmd
, ncmd
+rc
+1);
284 strcpy(cmd
+ncmd
, vv
);
289 snprintf(tmp
, sizeof tmp
, " -N%s", npath
);
291 cmd
= realloc(cmd
, ncmd
+rc
+1);
292 strcpy(cmd
+ncmd
, tmp
);
296 snprintf(tmp
, sizeof tmp
, " -C%s", iconfig_path
);
298 cmd
= realloc(cmd
, ncmd
+rc
+1);
299 strcpy(cmd
+ncmd
, tmp
);
302 snprintf(tmp
, sizeof tmp
, " -C%s -- -", iconfig_common_path
);
304 cmd
= realloc(cmd
, ncmd
+rc
+1);
305 strcpy(cmd
+ncmd
, tmp
);
311 for (t
= cmd
+ncmd_start
; *t
; t
++)
313 if (*t
== '/') *t
= '\\';
320 printf("translate: %s\n", cmd
);
324 if ( ! getenv("IVERILOG_ICONFIG")) {
326 remove(iconfig_path
);
327 remove(defines_path
);
328 remove(compiled_defines_path
);
330 #ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */
336 fprintf(stderr
, "Failed to execute: %s\n", cmd
);
341 return WEXITSTATUS(rc
);
343 fprintf(stderr
, "Command signaled: %s\n", cmd
);
352 static void process_warning_switch(const char*name
)
354 if (strcmp(name
,"all") == 0) {
355 process_warning_switch("implicit");
356 process_warning_switch("portbind");
357 process_warning_switch("timescale");
358 } else if (strcmp(name
,"implicit") == 0) {
359 if (! strchr(warning_flags
, 'i'))
360 strcat(warning_flags
, "i");
361 } else if (strcmp(name
,"portbind") == 0) {
362 if (! strchr(warning_flags
, 'p'))
363 strcat(warning_flags
, "p");
364 } else if (strcmp(name
,"timescale") == 0) {
365 if (! strchr(warning_flags
, 't'))
366 strcat(warning_flags
, "t");
367 /* Since the infinite loop check is not part of 'all' it
368 * does not have a no- version. */
369 } else if (strcmp(name
,"infloop") == 0) {
370 if (! strchr(warning_flags
, 'l'))
371 strcat(warning_flags
, "l");
372 } else if (strcmp(name
,"no-implicit") == 0) {
373 char*cp
= strchr(warning_flags
, 'i');
374 if (cp
) while (*cp
) {
378 } else if (strcmp(name
,"no-portbind") == 0) {
379 char*cp
= strchr(warning_flags
, 'p');
380 if (cp
) while (*cp
) {
384 } else if (strcmp(name
,"no-timescale") == 0) {
385 char*cp
= strchr(warning_flags
, 't');
386 if (cp
) while (*cp
) {
393 void process_library_switch(const char *name
)
395 fprintf(iconfig_file
, "-y:%s\n", name
);
398 void process_library_nocase_switch(const char *name
)
400 fprintf(iconfig_file
, "-yl:%s\n", name
);
403 void process_library2_switch(const char *name
)
405 fprintf(iconfig_file
, "-Y:%s\n", name
);
408 void process_include_dir(const char *name
)
410 fprintf(defines_file
, "I:%s\n", name
);
413 void process_define(const char*name
)
415 fprintf(defines_file
,"D:%s\n", name
);
419 * This function is called while processing a file name in a command
420 * file, or a file name on the command line. Look to see if there is a
421 * .sft suffix, and if so pass that as a sys_func file. Otherwise, it
422 * is a Verilog source file to be written into the file list.
424 void process_file_name(const char*name
, int lib_flag
)
426 if (strlen(name
) > 4 && strcasecmp(".sft", name
+strlen(name
)-4) == 0) {
427 fprintf(iconfig_file
,"sys_func:%s\n", name
);
430 fprintf(source_file
, "%s\n", name
);
433 fprintf(iconfig_file
,"library_file:%s\n", name
);
437 int process_generation(const char*name
)
439 if (strcmp(name
,"1995") == 0)
442 else if (strcmp(name
,"2001") == 0)
445 else if (strcmp(name
,"2005") == 0)
448 else if (strcmp(name
,"1") == 0) { /* Deprecated: use 1995 */
450 gen_xtypes
= "no-xtypes";
451 gen_icarus
= "no-icarus-misc";
453 } else if (strcmp(name
,"2") == 0) { /* Deprecated: use 2001 */
455 gen_xtypes
= "no-xtypes";
456 gen_icarus
= "no-icarus-misc";
458 } else if (strcmp(name
,"2x") == 0) { /* Deprecated: use 2005/xtypes */
460 gen_xtypes
= "xtypes";
461 gen_icarus
= "icarus-misc";
463 } else if (strcmp(name
,"xtypes") == 0)
464 gen_xtypes
= "xtypes";
466 else if (strcmp(name
,"no-xtypes") == 0)
467 gen_xtypes
= "no-xtypes";
469 else if (strcmp(name
,"icarus-misc") == 0)
470 gen_icarus
= "icarus-misc";
472 else if (strcmp(name
,"no-icarus-misc") == 0)
473 gen_icarus
= "no-icarus-misc";
475 else if (strcmp(name
,"specify") == 0)
476 gen_specify
= "specify";
478 else if (strcmp(name
,"no-specify") == 0)
479 gen_specify
= "no-specify";
481 else if (strcmp(name
,"std-include") == 0)
484 else if (strcmp(name
,"no-std-include") == 0)
487 else if (strcmp(name
,"io-range-error") == 0)
488 gen_io_range_error
= "io-range-error";
490 else if (strcmp(name
,"no-io-range-error") == 0)
491 gen_io_range_error
= "no-io-range-error";
493 else if (strcmp(name
,"verilog-ams") == 0)
494 gen_verilog_ams
= "verilog-ams";
496 else if (strcmp(name
,"no-verilog-ams") == 0)
497 gen_verilog_ams
= "no-verilog-ams";
500 fprintf(stderr
, "Unknown/Unsupported Language generation "
502 fprintf(stderr
, "Supported generations are:\n");
503 fprintf(stderr
, " 1995 -- IEEE1364-1995\n"
504 " 2001 -- IEEE1364-2001\n"
505 " 2005 -- IEEE1364-2005\n"
506 "Other generation flags:\n"
507 " specify | no-specify\n"
508 " verilog-ams | no-verinlog-ams\n"
509 " std-include | no-std-include\n"
510 " xtypes | no-xtypes\n"
511 " icarus-misc | no-icarus-misc\n"
512 " io-range-error | no-io-range-error\n");
520 * If it exists add the SFT file for the given module.
522 void add_sft_file(const char *module
)
526 file
= (char *) malloc(strlen(base
)+1+strlen(module
)+4+1);
527 sprintf(file
, "%s%c%s.sft", base
, sep
, module
);
528 if (access(file
, R_OK
) == 0)
529 fprintf(iconfig_file
, "sys_func:%s\n", file
);
533 int main(int argc
, char **argv
)
538 int version_flag
= 0;
544 GetModuleFileName(NULL
,basepath
,1024);
546 /* Calculate the ivl_root from the path to the command. This
547 is necessary because of the installation process in
548 Windows. Mostly, it is those darn drive letters, but oh
549 well. We know the command path is formed like this:
551 D:\iverilog\bin\iverilog.exe
553 The IVL_ROOT in a Windows installation is the path:
557 so we chop the file name and the last directory by
558 turning the last two \ characters to null. Then we append
559 the lib\ivl to finish. */
561 strncpy(ivl_root
, basepath
, MAXSIZE
);
562 s
= strrchr(ivl_root
, sep
);
564 s
= strrchr(ivl_root
, sep
);
566 strcat(ivl_root
, "\\lib\\ivl");
572 /* In a UNIX environment, the IVL_ROOT from the Makefile is
573 dependable. It points to the $prefix/lib/ivl directory,
574 where the sub-parts are installed. */
575 strcpy(ivl_root
, IVL_ROOT
);
579 /* Create a temporary file for communicating input parameters
580 to the preprocessor. */
581 source_path
= strdup(my_tempfile("ivrlg", &source_file
));
582 if (NULL
== source_file
) {
583 fprintf(stderr
, "%s: Error opening temporary file %s\n",
584 argv
[0], source_path
);
585 fprintf(stderr
, "%s: Please check TMP or TMPDIR.\n", argv
[0]);
589 defines_path
= strdup(my_tempfile("ivrlg2", &defines_file
));
590 if (NULL
== defines_file
) {
591 fprintf(stderr
, "%s: Error opening temporary file %s\n",
592 argv
[0], defines_path
);
593 fprintf(stderr
, "%s: Please check TMP or TMPDIR.\n", argv
[0]);
600 fprintf(defines_file
, "D:__ICARUS__=1\n");
601 if (strcmp(gen_verilog_ams
,"verilog-ams") == 0)
602 fprintf(defines_file
, "D:__VAMS_ENABLE__=1\n");
604 /* Create another temporary file for passing configuration
605 information to ivl. */
607 if ( (iconfig_path
= getenv("IVERILOG_ICONFIG")) ) {
608 fprintf(stderr
, "%s: IVERILOG_ICONFIG=%s\n",
609 argv
[0], iconfig_path
);
611 iconfig_file
= fopen(iconfig_path
, "w");
615 iconfig_path
= strdup(my_tempfile("ivrlh", &iconfig_file
));
618 if (NULL
== iconfig_file
) {
619 fprintf(stderr
, "%s: Error opening temporary file %s\n",
620 argv
[0], iconfig_path
);
621 fprintf(stderr
, "%s: Please check TMP or TMPDIR.\n", argv
[0]);
625 fclose(defines_file
);
626 remove(defines_path
);
630 /* Create a temporary file (I only really need the path) that
631 can carry preprocessor precompiled defines to the library. */
633 compiled_defines_path
= strdup(my_tempfile("ivrli", &tmp_file
));
639 while ((opt
= getopt(argc
, argv
, "B:c:D:d:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF
) {
643 /* Undocumented feature: The preprocessor itself
644 may be located at a different location. If the
645 base starts with a 'P', set this special base
646 instead of the main base. */
647 if (optarg
[0] == 'P') {
655 add_cmd_file(optarg
);
658 process_define(optarg
);
664 fprintf(iconfig_file
, "flag:%s\n", optarg
);
667 fprintf(iconfig_file
, "debug:%s\n", optarg
);
671 rc
= process_generation(optarg
);
676 fprintf(stderr
, "%s\n", HELP
);
680 process_include_dir(optarg
);
688 fprintf(iconfig_file
, "module:%s\n", optarg
);
689 add_sft_file(optarg
);
704 fprintf(iconfig_file
, "root:%s\n", optarg
);
707 if (strcmp(optarg
,"min") == 0) {
709 } else if (strcmp(optarg
,"typ") == 0) {
711 } else if (strcmp(optarg
,"max") == 0) {
714 fprintf(stderr
, "%s: invalid -T%s argument\n",
729 process_warning_switch(optarg
);
732 process_library_switch(optarg
);
735 process_library2_switch(optarg
);
746 if (version_flag
|| verbose_flag
) {
747 printf("Icarus Verilog version " VERSION
" (" VERSION_TAG
")\n\n");
748 printf("Copyright 1998-2008 Stephen Williams\n");
755 /* Make a common conf file path to reflect the target. */
756 sprintf(iconfig_common_path
, "%s%c%s%s.conf",
757 base
,sep
, targ
, synth_flag
? "-s" : "");
759 /* Write values to the iconfig file. */
760 fprintf(iconfig_file
, "basedir:%s\n", base
);
762 /* Tell the core where to find the system.sft. This file
763 describes the system functions so that elaboration knows
764 how to handle them. */
765 fprintf(iconfig_file
, "sys_func:%s%csystem.sft\n", base
, sep
);
767 /* If verilog-ams is enabled, then include the va_math module
769 if (strcmp(gen_verilog_ams
,"verilog-ams") == 0) {
770 fprintf(iconfig_file
, "sys_func:%s%cva_math.sft\n", base
, sep
);
771 fprintf(iconfig_file
, "module:va_math\n");
774 if (mtm
!= 0) fprintf(iconfig_file
, "-T:%s\n", mtm
);
775 fprintf(iconfig_file
, "generation:%s\n", generation
);
776 fprintf(iconfig_file
, "generation:%s\n", gen_specify
);
777 fprintf(iconfig_file
, "generation:%s\n", gen_xtypes
);
778 fprintf(iconfig_file
, "generation:%s\n", gen_io_range_error
);
779 fprintf(iconfig_file
, "generation:%s\n", gen_verilog_ams
);
780 fprintf(iconfig_file
, "generation:%s\n", gen_icarus
);
781 fprintf(iconfig_file
, "warnings:%s\n", warning_flags
);
782 fprintf(iconfig_file
, "out:%s\n", opath
);
783 if (depfile
) fprintf(iconfig_file
, "depfile:%s\n", depfile
);
785 while ( (command_filename
= get_cmd_file()) ) {
788 if (( fp
= fopen(command_filename
, "r")) == NULL
) {
789 fprintf(stderr
, "%s: cannot open command file %s "
790 "for reading.\n", argv
[0], command_filename
);
794 cfreset(fp
, command_filename
);
797 fprintf(stderr
, "%s: parsing failed in base command "
798 "file %s.\n", argv
[0], command_filename
);
801 free(command_filename
);
805 fprintf(defines_file
, "M:%s\n", depfile
);
808 /* Finally, process all the remaining words on the command
809 line as file names. */
810 for (idx
= optind
; idx
< argc
; idx
+= 1)
811 process_file_name(argv
[idx
], 0);
813 /* If the use of a default include directory is not
814 specifically disabled, then write that directory as the
815 very last include directory to use... always. */
816 if (gen_std_include
) {
817 fprintf(defines_file
, "I:%s%cinclude", base
, sep
);
823 fclose(defines_file
);
826 if (source_count
== 0) {
827 fprintf(stderr
, "%s: no source files.\n\n%s\n", argv
[0], HELP
);
832 /* Start building the preprocess command line. */
834 sprintf(tmp
, "%s%civlpp %s%s -F%s -f%s -p%s ", pbase
,sep
,
835 verbose_flag
?" -v":"",
836 e_flag
?"":" -L", defines_path
, source_path
,
837 compiled_defines_path
);
840 cmd
= malloc(ncmd
+ 1);
843 /* If the -E flag was given on the command line, then all we
844 do is run the preprocessor and put the output where the
848 if (strcmp(opath
,"-") != 0) {
849 sprintf(tmp
, " > %s", opath
);
850 cmd
= realloc(cmd
, ncmd
+strlen(tmp
)+1);
851 strcpy(cmd
+ncmd
, tmp
);
856 printf("preprocess: %s\n", cmd
);
860 fclose(iconfig_file
);
861 if ( ! getenv("IVERILOG_ICONFIG")) {
862 remove(iconfig_path
);
863 remove(defines_path
);
864 remove(compiled_defines_path
);
869 fprintf(stderr
, "errors preprocessing Verilog program.\n");
870 return WEXITSTATUS(rc
);
873 fprintf(stderr
, "Command signaled: %s\n", cmd
);
880 fprintf(iconfig_file
, "iwidth:%u\n", integer_width
);
882 /* Write the preprocessor command needed to preprocess a
883 single file. This may be used to preprocess library
885 fprintf(iconfig_file
, "ivlpp:%s%civlpp -L -F%s -P%s\n",
886 pbase
, sep
, defines_path
, compiled_defines_path
);
888 /* Done writing to the iconfig file. Close it now. */
889 fclose(iconfig_file
);
891 return t_default(cmd
, ncmd
);