diff options
Diffstat (limited to 'kernel/yosys.cc')
-rw-r--r-- | kernel/yosys.cc | 106 |
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 |