summaryrefslogtreecommitdiff
path: root/kernel/yosys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/yosys.cc')
-rw-r--r--kernel/yosys.cc113
1 files changed, 95 insertions, 18 deletions
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 822cab93..791d40ec 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -33,7 +33,7 @@
# include <dlfcn.h>
#endif
-#ifdef _WIN32
+#if defined(_WIN32)
# include <windows.h>
# include <io.h>
#elif defined(__APPLE__)
@@ -41,13 +41,15 @@
# include <unistd.h>
# include <dirent.h>
# include <sys/stat.h>
-# include <glob.h>
#else
# include <unistd.h>
# include <dirent.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <sys/stat.h>
+#endif
+
+#if !defined(_WIN32) && defined(YOSYS_ENABLE_GLOB)
# include <glob.h>
#endif
@@ -55,6 +57,16 @@
# include <sys/sysctl.h>
#endif
+#ifdef WITH_PYTHON
+#if PY_MAJOR_VERSION >= 3
+# define INIT_MODULE PyInit_libyosys
+ extern "C" PyObject* INIT_MODULE();
+#else
+# define INIT_MODULE initlibyosys
+ extern "C" void INIT_MODULE();
+#endif
+#endif
+
#include <limits.h>
#include <errno.h>
@@ -117,7 +129,7 @@ void yosys_banner()
log(" | |\n");
log(" | yosys -- Yosys Open SYnthesis Suite |\n");
log(" | |\n");
- log(" | Copyright (C) 2012 - 2018 Clifford Wolf <clifford@clifford.at> |\n");
+ log(" | Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at> |\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");
@@ -139,14 +151,16 @@ void yosys_banner()
int ceil_log2(int x)
{
+#if defined(__GNUC__)
+ return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0;
+#else
if (x <= 0)
return 0;
-
for (int i = 0; i < 32; i++)
if (((x-1) >> i) == 0)
return i;
-
log_abort();
+#endif
}
std::string stringf(const char *fmt, ...)
@@ -166,7 +180,7 @@ std::string vstringf(const char *fmt, va_list ap)
std::string string;
char *str = NULL;
-#if defined(_WIN32 )|| defined(__CYGWIN__)
+#if defined(_WIN32 )|| defined(__CYGWIN__)
int sz = 64, rc;
while (1) {
va_list apc;
@@ -216,12 +230,18 @@ std::string next_token(std::string &text, const char *sep, bool long_strings)
if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') {
string sep_string = sep;
- for (size_t i = pos_begin+1; i < text.size(); i++)
+ for (size_t i = pos_begin+1; i < text.size(); i++) {
if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) {
std::string token = text.substr(pos_begin, i-pos_begin+1);
text = text.substr(i+1);
return token;
}
+ if (i+1 < text.size() && text[i] == '"' && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) {
+ std::string token = text.substr(pos_begin, i-pos_begin+1);
+ text = text.substr(i+2);
+ return token + ";";
+ }
+ }
}
size_t pos_end = text.find_first_of(sep, pos_begin);
@@ -464,26 +484,61 @@ void remove_directory(std::string dirname)
#endif
}
+std::string escape_filename_spaces(const std::string& filename)
+{
+ std::string out;
+ out.reserve(filename.size());
+ for (auto c : filename)
+ {
+ if (c == ' ')
+ out += "\\ ";
+ else
+ out.push_back(c);
+ }
+ return out;
+}
+
int GetSize(RTLIL::Wire *wire)
{
return wire->width;
}
+bool already_setup = false;
+
void yosys_setup()
{
+ if(already_setup)
+ return;
+ already_setup = true;
// if there are already IdString objects then we have a global initialization order bug
IdString empty_id;
log_assert(empty_id.index_ == 0);
IdString::get_reference(empty_id.index_);
+ #ifdef WITH_PYTHON
+ PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
+ Py_Initialize();
+ PyRun_SimpleString("import sys");
+ #endif
+
Pass::init_register();
yosys_design = new RTLIL::Design;
yosys_celltypes.setup();
log_push();
}
+bool yosys_already_setup()
+{
+ return already_setup;
+}
+
+bool already_shutdown = false;
+
void yosys_shutdown()
{
+ if(already_shutdown)
+ return;
+ already_shutdown = true;
log_pop();
delete yosys_design;
@@ -511,9 +566,16 @@ void yosys_shutdown()
dlclose(it.second);
loaded_plugins.clear();
+#ifdef WITH_PYTHON
+ loaded_python_plugins.clear();
+#endif
loaded_plugin_aliases.clear();
#endif
+#ifdef WITH_PYTHON
+ Py_Finalize();
+#endif
+
IdString empty_id;
IdString::put_reference(empty_id.index_);
}
@@ -564,7 +626,7 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern)
{
std::vector<std::string> results;
-#ifdef _WIN32
+#if defined(_WIN32) || !defined(YOSYS_ENABLE_GLOB)
results.push_back(filename_pattern);
#else
glob_t globbuf;
@@ -589,6 +651,10 @@ void rewrite_filename(std::string &filename)
filename = filename.substr(1, GetSize(filename)-2);
if (filename.substr(0, 2) == "+/")
filename = proc_share_dirname() + filename.substr(2);
+#ifndef _WIN32
+ if (filename.substr(0, 2) == "~/")
+ filename = filename.replace(0, 1, getenv("HOME"));
+#endif
}
#ifdef YOSYS_ENABLE_TCL
@@ -637,8 +703,9 @@ extern Tcl_Interp *yosys_get_tcl_interp()
struct TclPass : public Pass {
TclPass() : Pass("tcl", "execute a TCL script file") { }
void help() YS_OVERRIDE {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" tcl <filename>\n");
+ log(" tcl <filename> [args]\n");
log("\n");
log("This command executes the tcl commands in the specified file.\n");
log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n");
@@ -648,14 +715,24 @@ struct TclPass : public Pass {
log("'proc' and 'rename' are wrapped to tcl commands 'procs' and 'renames'\n");
log("in order to avoid a name collision with the built in commands.\n");
log("\n");
+ log("If any arguments are specified, these arguments are provided to the script via\n");
+ log("the standard $argc and $argv variables.\n");
+ log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
+ void execute(std::vector<std::string> args, RTLIL::Design *) YS_OVERRIDE {
if (args.size() < 2)
log_cmd_error("Missing script file.\n");
- if (args.size() > 2)
- extra_args(args, 1, design, false);
- if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK)
- log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp()));
+
+ std::vector<Tcl_Obj*> script_args;
+ for (auto it = args.begin() + 2; it != args.end(); ++it)
+ script_args.push_back(Tcl_NewStringObj((*it).c_str(), (*it).size()));
+
+ Tcl_Interp *interp = yosys_get_tcl_interp();
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argc", 4), NULL, Tcl_NewIntObj(script_args.size()), 0);
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv", 4), NULL, Tcl_NewListObj(script_args.size(), script_args.data()), 0);
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv0", 5), NULL, Tcl_NewStringObj(args[1].c_str(), args[1].size()), 0);
+ if (Tcl_EvalFile(interp, args[1].c_str()) != TCL_OK)
+ log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
}
} TclPass;
#endif
@@ -733,7 +810,7 @@ std::string proc_self_dirname()
return "/";
}
#else
- #error Dont know how to determine process executable base path!
+ #error "Don't know how to determine process executable base path!"
#endif
#ifdef EMSCRIPTEN
@@ -799,7 +876,7 @@ static void handle_label(std::string &command, bool &from_to_active, const std::
while (pos < GetSize(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n')
label += command[pos++];
- if (label.back() == ':' && GetSize(label) > 1)
+ if (GetSize(label) > 1 && label.back() == ':')
{
label = label.substr(0, GetSize(label)-1);
command = command.substr(pos);
@@ -821,7 +898,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
command = "verilog";
else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv")
command = "verilog -sv";
- else if (filename.size() > 2 && filename.substr(filename.size()-4) == ".vhd")
+ else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".vhd")
command = "vhdl";
else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif")
command = "blif";
@@ -833,7 +910,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
command = "ilang";
else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys")
command = "script";
- else if (filename.size() > 2 && filename.substr(filename.size()-4) == ".tcl")
+ else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".tcl")
command = "tcl";
else if (filename == "-")
command = "script";