aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/yosys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/yosys.cc')
-rw-r--r--kernel/yosys.cc106
1 files changed, 94 insertions, 12 deletions
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 530d78796..8da57fd4e 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -2,11 +2,11 @@
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- *
+ *
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@@ -104,7 +104,7 @@ void yosys_banner()
log(" | |\n");
log(" | yosys -- Yosys Open SYnthesis Suite |\n");
log(" | |\n");
- log(" | Copyright (C) 2012 - 2015 Clifford Wolf <clifford@clifford.at> |\n");
+ log(" | Copyright (C) 2012 - 2016 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");
@@ -124,6 +124,18 @@ void yosys_banner()
log("\n");
}
+int ceil_log2(int x)
+{
+ if (x <= 0)
+ return 0;
+
+ for (int i = 0; i < 32; i++)
+ if (((x-1) >> i) == 0)
+ return i;
+
+ log_abort();
+}
+
std::string stringf(const char *fmt, ...)
{
std::string string;
@@ -168,7 +180,7 @@ std::string vstringf(const char *fmt, va_list ap)
int readsome(std::istream &f, char *s, int n)
{
- int rc = f.readsome(s, n);
+ int rc = int(f.readsome(s, n));
// f.readsome() sometimes returns 0 on a non-empty stream..
if (rc == 0) {
@@ -182,13 +194,23 @@ int readsome(std::istream &f, char *s, int n)
return rc;
}
-std::string next_token(std::string &text, const char *sep)
+std::string next_token(std::string &text, const char *sep, bool long_strings)
{
size_t pos_begin = text.find_first_not_of(sep);
if (pos_begin == std::string::npos)
pos_begin = text.size();
+ 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++)
+ 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;
+ }
+ }
+
size_t pos_end = text.find_first_of(sep, pos_begin);
if (pos_end == std::string::npos)
@@ -199,6 +221,26 @@ std::string next_token(std::string &text, const char *sep)
return token;
}
+std::vector<std::string> split_tokens(const std::string &text, const char *sep)
+{
+ std::vector<std::string> tokens;
+ std::string current_token;
+ for (char c : text) {
+ if (strchr(sep, c)) {
+ if (!current_token.empty()) {
+ tokens.push_back(current_token);
+ current_token.clear();
+ }
+ } else
+ current_token += c;
+ }
+ if (!current_token.empty()) {
+ tokens.push_back(current_token);
+ current_token.clear();
+ }
+ return tokens;
+}
+
// this is very similar to fnmatch(). the exact rules used by this
// function are:
//
@@ -376,6 +418,15 @@ bool check_file_exists(std::string filename, bool is_exec)
}
#endif
+bool is_absolute_path(std::string filename)
+{
+#ifdef _WIN32
+ return filename[0] == '/' || filename[0] == '\\' || (filename[0] != 0 && filename[1] == ':');
+#else
+ return filename[0] == '/';
+#endif
+}
+
void remove_directory(std::string dirname)
{
#ifdef _WIN32
@@ -496,6 +547,14 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter)
return buffer;
}
+void rewrite_filename(std::string &filename)
+{
+ if (filename.substr(0, 1) == "\"" && filename.substr(GetSize(filename)-1) == "\"")
+ filename = filename.substr(1, GetSize(filename)-2);
+ if (filename.substr(0, 2) == "+/")
+ filename = proc_share_dirname() + filename.substr(2);
+}
+
#ifdef YOSYS_ENABLE_TCL
static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
{
@@ -549,7 +608,7 @@ struct TclPass : public Pass {
log("The tcl command 'yosys -import' can be used to import all yosys\n");
log("commands directly as tcl commands to the tcl shell. The yosys\n");
log("command 'proc' is wrapped using the tcl command 'procs' in order\n");
- log("to avoid a name collision with the tcl builting command 'proc'.\n");
+ log("to avoid a name collision with the tcl builtin command 'proc'.\n");
log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
@@ -619,26 +678,38 @@ std::string proc_self_dirname()
#error Dont know how to determine process executable base path!
#endif
+#ifdef EMSCRIPTEN
+std::string proc_share_dirname()
+{
+ return "/share";
+}
+#else
std::string proc_share_dirname()
{
std::string proc_self_path = proc_self_dirname();
-#ifdef _WIN32
+# ifdef _WIN32
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\\";
if (check_file_exists(proc_share_path, true))
return proc_share_path;
-#else
+# 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;
-#endif
+# ifdef YOSYS_DATDIR
+ proc_share_path = YOSYS_DATDIR "/";
+ if (check_file_exists(proc_share_path, true))
+ return proc_share_path;
+# endif
+# endif
log_error("proc_share_dirname: unable to determine share/ directory!\n");
}
+#endif
bool fgetline(FILE *f, std::string &buffer)
{
@@ -664,6 +735,9 @@ static void handle_label(std::string &command, bool &from_to_active, const std::
while (pos < GetSize(command) && (command[pos] == ' ' || command[pos] == '\t'))
pos++;
+ if (pos < GetSize(command) && command[pos] == '#')
+ return;
+
while (pos < GetSize(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n')
label += command[pos++];
@@ -689,6 +763,10 @@ 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")
+ command = "vhdl";
+ else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif")
+ command = "blif";
else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il")
command = "ilang";
else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys")
@@ -802,6 +880,10 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
command = "ilang";
else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif")
command = "blif";
+ else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".edif")
+ command = "edif";
+ else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".json")
+ command = "json";
else if (filename == "-")
command = "ilang";
else if (filename.empty())
@@ -1018,8 +1100,8 @@ struct HistoryPass : public Pass {
} HistoryPass;
#endif
-struct ScriptPass : public Pass {
- ScriptPass() : Pass("script", "execute commands from script file") { }
+struct ScriptCmdPass : public Pass {
+ ScriptCmdPass() : Pass("script", "execute commands from script file") { }
virtual void help() {
log("\n");
log(" script <filename> [<from_label>:<to_label>]\n");
@@ -1045,7 +1127,7 @@ struct ScriptPass : public Pass {
else
extra_args(args, 2, design, false);
}
-} ScriptPass;
+} ScriptCmdPass;
YOSYS_NAMESPACE_END