Ignore change on last edge
[yosys.git] / kernel / driver.cc
index f0d495b46e23459c797d1b546bb88f1f5770ab68..f8f940e892a806391c0ce90b5b3006bf9c9040cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  yosys -- Yosys Open SYnthesis Suite
  *
- *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
  *
  *  Permission to use, copy, modify, and/or distribute this software for any
  *  purpose with or without fee is hereby granted, provided that the above
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
        if (argc == 2)
        {
                // Run the first argument as a script file
-               run_frontend(argv[1], "script", 0, 0, 0);
+               run_frontend(argv[1], "script");
        }
 }
 
@@ -155,6 +155,19 @@ int yosys_history_offset = 0;
 std::string yosys_history_file;
 #endif
 
+#if defined(__wasm)
+extern "C" {
+       // FIXME: WASI does not currently support exceptions.
+       void* __cxa_allocate_exception(size_t thrown_size) throw() {
+               return malloc(thrown_size);
+       }
+       bool __cxa_uncaught_exception() throw();
+       void __cxa_throw(void* thrown_exception, struct std::type_info * tinfo, void (*dest)(void*)) {
+               std::terminate();
+       }
+}
+#endif
+
 void yosys_atexit()
 {
 #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
@@ -189,12 +202,13 @@ int main(int argc, char **argv)
        std::string output_filename = "";
        std::string scriptfile = "";
        std::string depsfile = "";
+       std::string topmodule = "";
        bool scriptfile_tcl = false;
-       bool got_output_filename = false;
        bool print_banner = true;
        bool print_stats = true;
        bool call_abort = false;
        bool timing_details = false;
+       bool run_shell = true;
        bool mode_v = false;
        bool mode_q = false;
 
@@ -254,9 +268,11 @@ int main(int argc, char **argv)
                printf("\n");
                printf("    -s scriptfile\n");
                printf("        execute the commands in the script file\n");
+#ifdef YOSYS_ENABLE_TCL
                printf("\n");
                printf("    -c tcl_scriptfile\n");
                printf("        execute the commands in the tcl script file (see 'help tcl' for details)\n");
+#endif
                printf("\n");
                printf("    -p command\n");
                printf("        execute the commands\n");
@@ -273,6 +289,9 @@ int main(int argc, char **argv)
                printf("    -A\n");
                printf("        will call abort() at the end of the script. for debugging\n");
                printf("\n");
+               printf("    -r <module_name>\n");
+               printf("        elaborate command line arguments using the specified top module\n");
+               printf("\n");
                printf("    -D <macro>[=<value>]\n");
                printf("        set the specified Verilog define (via \"read -define\")\n");
                printf("\n");
@@ -295,6 +314,9 @@ int main(int argc, char **argv)
                printf("    -E <depsfile>\n");
                printf("        write a Makefile dependencies file with in- and output file names\n");
                printf("\n");
+               printf("    -x <feature>\n");
+               printf("        do not print warnings for the specified experimental feature\n");
+               printf("\n");
                printf("    -g\n");
                printf("        globally enable debug log messages\n");
                printf("\n");
@@ -317,8 +339,14 @@ int main(int argc, char **argv)
                exit(0);
        }
 
+       if (argc == 2 && (!strcmp(argv[1], "-V") || !strcmp(argv[1], "-version") || !strcmp(argv[1], "--version")))
+       {
+               printf("%s\n", yosys_version_str);
+               exit(0);
+       }
+
        int opt;
-       while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:P:E:")) != -1)
+       while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:r:D:P:E:x:")) != -1)
        {
                switch (opt)
                {
@@ -342,6 +370,7 @@ int main(int argc, char **argv)
                        exit(0);
                case 'S':
                        passes_commands.push_back("synth");
+                       run_shell = false;
                        break;
                case 'g':
                        log_force_debug++;
@@ -354,19 +383,23 @@ int main(int argc, char **argv)
                        break;
                case 'H':
                        passes_commands.push_back("help");
+                       run_shell = false;
                        break;
                case 'h':
                        passes_commands.push_back(stringf("help %s", optarg));
+                       run_shell = false;
                        break;
                case 'b':
                        backend_command = optarg;
+                       run_shell = false;
                        break;
                case 'p':
                        passes_commands.push_back(optarg);
+                       run_shell = false;
                        break;
                case 'o':
                        output_filename = optarg;
-                       got_output_filename = true;
+                       run_shell = false;
                        break;
                case 'l':
                case 'L':
@@ -398,28 +431,24 @@ int main(int argc, char **argv)
                case 's':
                        scriptfile = optarg;
                        scriptfile_tcl = false;
+                       run_shell = false;
                        break;
                case 'c':
                        scriptfile = optarg;
                        scriptfile_tcl = true;
+                       run_shell = false;
                        break;
                case 'W':
-                       log_warn_regexes.push_back(std::regex(optarg,
-                                       std::regex_constants::nosubs |
-                                       std::regex_constants::optimize |
-                                       std::regex_constants::egrep));
+                       log_warn_regexes.push_back(YS_REGEX_COMPILE(optarg));
                        break;
                case 'w':
-                       log_nowarn_regexes.push_back(std::regex(optarg,
-                                       std::regex_constants::nosubs |
-                                       std::regex_constants::optimize |
-                                       std::regex_constants::egrep));
+                       log_nowarn_regexes.push_back(YS_REGEX_COMPILE(optarg));
                        break;
                case 'e':
-                       log_werror_regexes.push_back(std::regex(optarg,
-                                       std::regex_constants::nosubs |
-                                       std::regex_constants::optimize |
-                                       std::regex_constants::egrep));
+                       log_werror_regexes.push_back(YS_REGEX_COMPILE(optarg));
+                       break;
+               case 'r':
+                       topmodule = optarg;
                        break;
                case 'D':
                        vlog_defines.push_back(optarg);
@@ -449,6 +478,9 @@ int main(int argc, char **argv)
                case 'E':
                        depsfile = optarg;
                        break;
+               case 'x':
+                       log_experimentals_ignored.insert(optarg);
+                       break;
                default:
                        fprintf(stderr, "Run '%s -h' for help.\n", argv[0]);
                        exit(1);
@@ -488,12 +520,6 @@ int main(int argc, char **argv)
        for (auto &fn : plugin_filenames)
                load_plugin(fn, {});
 
-       if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) {
-               if (!got_output_filename)
-                       backend_command = "";
-               shell(yosys_design);
-       }
-
        if (!vlog_defines.empty()) {
                std::string vdef_cmd = "read -define";
                for (auto vdef : vlog_defines)
@@ -502,7 +528,11 @@ int main(int argc, char **argv)
        }
 
        while (optind < argc)
-               run_frontend(argv[optind++], frontend_command, output_filename == "-" ? &backend_command : NULL);
+               if (run_frontend(argv[optind++], frontend_command))
+                       run_shell = false;
+
+       if (!topmodule.empty())
+               run_pass("hierarchy -top " + topmodule);
 
        if (!scriptfile.empty()) {
                if (scriptfile_tcl) {
@@ -513,13 +543,15 @@ int main(int argc, char **argv)
                        log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n");
 #endif
                } else
-                       run_frontend(scriptfile, "script", output_filename == "-" ? &backend_command : NULL);
+                       run_frontend(scriptfile, "script");
        }
 
        for (auto it = passes_commands.begin(); it != passes_commands.end(); it++)
                run_pass(*it);
 
-       if (!backend_command.empty())
+       if (run_shell)
+               shell(yosys_design);
+       else
                run_backend(output_filename, backend_command);
 
        yosys_design->check();
@@ -546,6 +578,10 @@ int main(int argc, char **argv)
                fprintf(f, "\n");
        }
 
+       if (log_expect_no_warnings && log_warnings_count_noexpect)
+               log_error("Unexpected warnings found: %d unique messages, %d total, %d expected\n", GetSize(log_warnings),
+                                       log_warnings_count, log_warnings_count - log_warnings_count_noexpect);
+
        if (print_stats)
        {
                std::string hash = log_hasher->final().substr(0, 10);
@@ -561,6 +597,10 @@ int main(int argc, char **argv)
 
                if (log_warnings_count)
                        log("Warnings: %d unique messages, %d total\n", GetSize(log_warnings), log_warnings_count);
+
+               if (!log_experimentals.empty())
+                       log("Warnings: %d experimental features used (not excluded with -x).\n", GetSize(log_experimentals));
+
 #ifdef _WIN32
                log("End of script. Logfile hash: %s\n", hash.c_str());
 #else
@@ -576,9 +616,11 @@ int main(int argc, char **argv)
                        ru_buffer.ru_utime.tv_usec += ru_buffer_children.ru_utime.tv_usec;
                        ru_buffer.ru_stime.tv_sec += ru_buffer_children.ru_stime.tv_sec;
                        ru_buffer.ru_stime.tv_usec += ru_buffer_children.ru_stime.tv_usec;
+#if defined(__linux__) || defined(__FreeBSD__)
                        ru_buffer.ru_maxrss = std::max(ru_buffer.ru_maxrss, ru_buffer_children.ru_maxrss);
+#endif
                }
-#  if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__)
                meminfo = stringf(", MEM: %.2f MB peak",
                                ru_buffer.ru_maxrss / 1024.0);
 #endif
@@ -648,6 +690,8 @@ int main(int argc, char **argv)
        }
 #endif
 
+       log_check_expected();
+
        yosys_atexit();
 
        memhasher_off();