Change implicit conversions from bool to Sig* to explicit.
[yosys.git] / kernel / yosys.cc
index 8190d89028eb4ca553932977adb992379558b047..39d6a1ec1484f0833693d3ab88a00b7eeaa8a2aa 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
 #  include <unistd.h>
 #  include <dirent.h>
 #  include <sys/types.h>
-#  include <sys/wait.h>
 #  include <sys/stat.h>
+#  if !defined(YOSYS_DISABLE_SPAWN)
+#    include <sys/wait.h>
+#  endif
 #endif
 
 #if !defined(_WIN32) && defined(YOSYS_ENABLE_GLOB)
@@ -65,6 +67,7 @@
 #   define INIT_MODULE initlibyosys
        extern "C" void INIT_MODULE();
 #endif
+#include <signal.h>
 #endif
 
 #include <limits.h>
@@ -87,6 +90,12 @@ bool memhasher_active = false;
 uint32_t memhasher_rng = 123456;
 std::vector<void*> memhasher_store;
 
+std::string yosys_share_dirname;
+std::string yosys_abc_executable;
+
+void init_share_dirname();
+void init_abc_executable_name();
+
 void memhasher_on()
 {
 #if defined(__linux__) || defined(__FreeBSD__)
@@ -129,7 +138,7 @@ void yosys_banner()
        log(" |                                                                            |\n");
        log(" |  yosys -- Yosys Open SYnthesis Suite                                       |\n");
        log(" |                                                                            |\n");
-       log(" |  Copyright (C) 2012 - 2019  Clifford Wolf <clifford@clifford.at>           |\n");
+       log(" |  Copyright (C) 2012 - 2020  Claire Xenia Wolf <claire@yosyshq.com>         |\n");
        log(" |                                                                            |\n");
        log(" |  Permission to use, copy, modify, and/or distribute this software for any  |\n");
        log(" |  purpose with or without fee is hereby granted, provided that the above    |\n");
@@ -336,6 +345,7 @@ bool patmatch(const char *pattern, const char *string)
        return false;
 }
 
+#if !defined(YOSYS_DISABLE_SPAWN)
 int run_command(const std::string &command, std::function<void(const std::string&)> process_line)
 {
        if (!process_line)
@@ -364,10 +374,16 @@ int run_command(const std::string &command, std::function<void(const std::string
        return WEXITSTATUS(ret);
 #endif
 }
+#endif
 
 std::string make_temp_file(std::string template_str)
 {
-#ifdef _WIN32
+#if defined(__wasm)
+       size_t pos = template_str.rfind("XXXXXX");
+       log_assert(pos != std::string::npos);
+       static size_t index = 0;
+       template_str.replace(pos, 6, stringf("%06zu", index++));
+#elif defined(_WIN32)
        if (template_str.rfind("/tmp/", 0) == 0) {
 #  ifdef __MINGW32__
                char longpath[MAX_PATH + 1];
@@ -416,10 +432,14 @@ std::string make_temp_file(std::string template_str)
 
 std::string make_temp_dir(std::string template_str)
 {
-#ifdef _WIN32
+#if defined(_WIN32)
        template_str = make_temp_file(template_str);
        mkdir(template_str.c_str());
        return template_str;
+#elif defined(__wasm)
+       template_str = make_temp_file(template_str);
+       mkdir(template_str.c_str(), 0777);
+       return template_str;
 #else
 #  ifndef NDEBUG
        size_t pos = template_str.rfind("XXXXXX");
@@ -510,18 +530,18 @@ void yosys_setup()
        if(already_setup)
                return;
        already_setup = true;
+       init_share_dirname();
+       init_abc_executable_name();
 
-       RTLIL::ID::A = "\\A";
-       RTLIL::ID::B = "\\B";
-       RTLIL::ID::Y = "\\Y";
-       RTLIL::ID::keep = "\\keep";
-       RTLIL::ID::whitebox = "\\whitebox";
-       RTLIL::ID::blackbox = "\\blackbox";
+#define X(_id) RTLIL::ID::_id = "\\" # _id;
+#include "kernel/constids.inc"
+#undef X
 
        #ifdef WITH_PYTHON
                PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
                Py_Initialize();
                PyRun_SimpleString("import sys");
+               signal(SIGINT, SIG_DFL);
        #endif
 
        Pass::init_register();
@@ -703,7 +723,7 @@ extern Tcl_Interp *yosys_get_tcl_interp()
 
 struct TclPass : public Pass {
        TclPass() : Pass("tcl", "execute a TCL script file") { }
-       void help() YS_OVERRIDE {
+       void help() override {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
                log("    tcl <filename> [args]\n");
@@ -720,7 +740,7 @@ struct TclPass : public Pass {
                log("the standard $argc and $argv variables.\n");
                log("\n");
        }
-       void execute(std::vector<std::string> args, RTLIL::Design *) YS_OVERRIDE {
+       void execute(std::vector<std::string> args, RTLIL::Design *) override {
                if (args.size() < 2)
                        log_cmd_error("Missing script file.\n");
 
@@ -779,7 +799,9 @@ std::string proc_self_dirname()
                path = (char *) realloc((void *) path, buflen);
        while (buflen > 0 && path[buflen-1] != '/')
                buflen--;
-       return std::string(path, buflen);
+       std::string str(path, buflen);
+       free(path);
+       return str;
 }
 #elif defined(_WIN32)
 std::string proc_self_dirname()
@@ -805,7 +827,7 @@ std::string proc_self_dirname()
                path += char(shortpath[i]);
        return path;
 }
-#elif defined(EMSCRIPTEN)
+#elif defined(EMSCRIPTEN) || defined(__wasm)
 std::string proc_self_dirname()
 {
        return "/";
@@ -814,39 +836,84 @@ std::string proc_self_dirname()
        #error "Don't know how to determine process executable base path!"
 #endif
 
-#ifdef EMSCRIPTEN
-std::string proc_share_dirname()
+#if defined(EMSCRIPTEN) || defined(__wasm)
+void init_share_dirname()
 {
-       return "/share/";
+       yosys_share_dirname = "/share/";
 }
 #else
-std::string proc_share_dirname()
+void init_share_dirname()
 {
        std::string proc_self_path = proc_self_dirname();
 #  if defined(_WIN32) && !defined(YOSYS_WIN32_UNIX_DIR)
        std::string proc_share_path = proc_self_path + "share\\";
-       if (check_file_exists(proc_share_path, true))
-               return proc_share_path;
+       if (check_file_exists(proc_share_path, true)) {
+               yosys_share_dirname = proc_share_path;
+               return;
+       }
        proc_share_path = proc_self_path + "..\\share\\";
-       if (check_file_exists(proc_share_path, true))
-               return proc_share_path;
+       if (check_file_exists(proc_share_path, true)) {
+               yosys_share_dirname = proc_share_path;
+               return;
+       }
 #  else
        std::string proc_share_path = proc_self_path + "share/";
-       if (check_file_exists(proc_share_path, true))
-               return proc_share_path;
-       proc_share_path = proc_self_path + "../share/yosys/";
-       if (check_file_exists(proc_share_path, true))
-               return proc_share_path;
+       if (check_file_exists(proc_share_path, true)) {
+               yosys_share_dirname = proc_share_path;
+               return;
+       }
+       proc_share_path = proc_self_path + "../share/" + proc_program_prefix()+ "yosys/";
+       if (check_file_exists(proc_share_path, true)) {
+               yosys_share_dirname = proc_share_path;
+               return;
+       }
 #    ifdef YOSYS_DATDIR
        proc_share_path = YOSYS_DATDIR "/";
-       if (check_file_exists(proc_share_path, true))
-               return proc_share_path;
+       if (check_file_exists(proc_share_path, true)) {
+               yosys_share_dirname = proc_share_path;
+               return;
+       }
 #    endif
 #  endif
-       log_error("proc_share_dirname: unable to determine share/ directory!\n");
 }
 #endif
 
+void init_abc_executable_name()
+{
+#ifdef ABCEXTERNAL
+       std::string exe_file;
+       if (std::getenv("ABC")) {
+               yosys_abc_executable = std::getenv("ABC");
+       } else {
+               yosys_abc_executable = ABCEXTERNAL;
+       }
+#else
+       yosys_abc_executable = proc_self_dirname() + proc_program_prefix()+ "yosys-abc";
+#endif
+#ifdef _WIN32
+#ifndef ABCEXTERNAL
+       if (!check_file_exists(yosys_abc_executable + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc.exe"))
+               yosys_abc_executable = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc";
+#endif
+#endif
+}
+
+std::string proc_share_dirname()
+{
+       if (yosys_share_dirname.empty())
+               log_error("init_share_dirname: unable to determine share/ directory!\n");
+       return yosys_share_dirname;
+}
+
+std::string proc_program_prefix()
+{
+       std::string program_prefix;
+#ifdef YOSYS_PROGRAM_PREFIX
+       program_prefix = YOSYS_PROGRAM_PREFIX;
+#endif
+       return program_prefix;
+}
+
 bool fgetline(FILE *f, std::string &buffer)
 {
        buffer = "";
@@ -911,7 +978,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
                else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0)
                        command = "json";
                else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0)
-                       command = "ilang";
+                       command = "rtlil";
                else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0)
                        command = "script";
                else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0)
@@ -1031,8 +1098,12 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
        if (command == "auto") {
                if (filename.size() > 2 && filename.compare(filename.size()-2, std::string::npos, ".v") == 0)
                        command = "verilog";
+               else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".sv") == 0)
+                       command = "verilog -sv";
                else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0)
-                       command = "ilang";
+                       command = "rtlil";
+               else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".cc") == 0)
+                       command = "cxxrtl";
                else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0)
                        command = "aiger";
                else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".blif") == 0)
@@ -1042,7 +1113,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
                else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0)
                        command = "json";
                else if (filename == "-")
-                       command = "ilang";
+                       command = "rtlil";
                else if (filename.empty())
                        return;
                else
@@ -1094,30 +1165,29 @@ static char *readline_obj_generator(const char *text, int state)
 
                if (design->selected_active_module.empty())
                {
-                       for (auto &it : design->modules_)
-                               if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
-                                       obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+                       for (auto mod : design->modules())
+                               if (RTLIL::unescape_id(mod->name).compare(0, len, text) == 0)
+                                       obj_names.push_back(strdup(log_id(mod->name)));
                }
-               else
-               if (design->modules_.count(design->selected_active_module) > 0)
+               else if (design->module(design->selected_active_module) != nullptr)
                {
-                       RTLIL::Module *module = design->modules_.at(design->selected_active_module);
+                       RTLIL::Module *module = design->module(design->selected_active_module);
 
-                       for (auto &it : module->wires_)
-                               if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
-                                       obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+                       for (auto w : module->wires())
+                               if (RTLIL::unescape_id(w->name).compare(0, len, text) == 0)
+                                       obj_names.push_back(strdup(log_id(w->name)));
 
                        for (auto &it : module->memories)
                                if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
-                                       obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+                                       obj_names.push_back(strdup(log_id(it.first)));
 
-                       for (auto &it : module->cells_)
-                               if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
-                                       obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+                       for (auto cell : module->cells())
+                               if (RTLIL::unescape_id(cell->name).compare(0, len, text) == 0)
+                                       obj_names.push_back(strdup(log_id(cell->name)));
 
                        for (auto &it : module->processes)
                                if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
-                                       obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+                                       obj_names.push_back(strdup(log_id(it.first)));
                }
 
                std::sort(obj_names.begin(), obj_names.end());
@@ -1200,7 +1270,7 @@ void shell(RTLIL::Design *design)
 
 struct ShellPass : public Pass {
        ShellPass() : Pass("shell", "enter interactive command mode") { }
-       void help() YS_OVERRIDE {
+       void help() override {
                log("\n");
                log("    shell\n");
                log("\n");
@@ -1232,7 +1302,7 @@ struct ShellPass : public Pass {
                log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n");
                log("\n");
        }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override {
                extra_args(args, 1, design, false);
                shell(design);
        }
@@ -1241,7 +1311,7 @@ struct ShellPass : public Pass {
 #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
 struct HistoryPass : public Pass {
        HistoryPass() : Pass("history", "show last interactive commands") { }
-       void help() YS_OVERRIDE {
+       void help() override {
                log("\n");
                log("    history\n");
                log("\n");
@@ -1250,7 +1320,7 @@ struct HistoryPass : public Pass {
                log("from executed scripts.\n");
                log("\n");
        }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override {
                extra_args(args, 1, design, false);
 #ifdef YOSYS_ENABLE_READLINE
                for(HIST_ENTRY **list = history_list(); *list != NULL; list++)
@@ -1265,7 +1335,7 @@ struct HistoryPass : public Pass {
 
 struct ScriptCmdPass : public Pass {
        ScriptCmdPass() : Pass("script", "execute commands from file or wire") { }
-       void help() YS_OVERRIDE {
+       void help() override {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
                log("    script <filename> [<from_label>:<to_label>]\n");
@@ -1288,7 +1358,7 @@ struct ScriptCmdPass : public Pass {
                log("'-module' mode can be exited by using the 'cd' command.\n");
                log("\n");
        }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override
        {
                bool scriptwire = false;