From f50e8a3c1baaff8cb3c6055a2b18caab8ce904e3 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Thu, 21 Dec 2023 21:44:02 +0300 Subject: [PATCH 01/33] Follow the XDG Base Directory Specification --- kernel/driver.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index c779611e097..c1995e7f7fc 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -244,7 +244,11 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("HOME") != NULL) { + if (getenv("XDG_DATA_HOME") != NULL && getenv("XDG_DATA_HOME")[0] != '\0') { + yosys_history_file = stringf("%s/yosys/.yosys_history", getenv("XDG_DATA_HOME")); + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); + } else if (getenv("HOME") != NULL) { yosys_history_file = stringf("%s/.yosys_history", getenv("HOME")); read_history(yosys_history_file.c_str()); yosys_history_offset = where_history(); From 31b45c9555752070c7a8909ade46a95093979188 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Sun, 7 Jan 2024 14:17:48 +0300 Subject: [PATCH 02/33] fix: xdg spec for hist --- kernel/driver.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index c1995e7f7fc..eda90745a21 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -244,15 +244,13 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("XDG_DATA_HOME") != NULL && getenv("XDG_DATA_HOME")[0] != '\0') { - yosys_history_file = stringf("%s/yosys/.yosys_history", getenv("XDG_DATA_HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); - } else if (getenv("HOME") != NULL) { - yosys_history_file = stringf("%s/.yosys_history", getenv("HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); + if (getenv("XDG_STATE_HOME") != NULL && getenv("XDG_STATE_HOME")[0] != '\0') { + yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + } else { + yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); } + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); #endif if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) From 54c3b63d241d9da6acfdcb4bcd1a1bb2387090eb Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Sun, 7 Jan 2024 14:34:27 +0300 Subject: [PATCH 03/33] fix: third time is the charm --- kernel/driver.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index eda90745a21..503899d302d 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -244,8 +244,10 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("XDG_STATE_HOME") != NULL && getenv("XDG_STATE_HOME")[0] != '\0') { - yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + } } else { yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); } From e093f57c1075104df8135df1c04f4d134d5a7db6 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Mon, 8 Jan 2024 08:49:04 +0300 Subject: [PATCH 04/33] fix: fail if neither HOME nor XDG_STATE_HOME are set --- kernel/driver.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 503899d302d..3a5e49cb451 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -247,12 +247,14 @@ int main(int argc, char **argv) if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { if (getenv("HOME") != NULL) { yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); } } else { yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); } - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); #endif if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) From c634d59c182b44d90891502ceb3a367e1c2be00b Mon Sep 17 00:00:00 2001 From: Gabriel Gouvine Date: Tue, 23 Jan 2024 10:47:01 +0000 Subject: [PATCH 05/33] Issue a warning instead of a syntax error for blif delay constraints --- frontends/blif/blifparse.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index ebbe082a2e8..731656866ea 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -256,6 +256,16 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool continue; } + if (!strcmp(cmd, ".area") || !strcmp(cmd, ".delay") || !strcmp(cmd, ".wire_load_slope") || !strcmp(cmd, ".wire") || + !strcmp(cmd, ".input_arrival") || !strcmp(cmd, ".default_input_arrival") || !strcmp(cmd, ".output_required") || + !strcmp(cmd, ".default_output_required") || !strcmp(cmd, ".input_drive") || !strcmp(cmd, ".default_input_drive") || + !strcmp(cmd, ".max_input_load") || !strcmp(cmd, ".default_max_input_load") || !strcmp(cmd, ".output_load") || + !strcmp(cmd, ".default_output_load")) + { + log_warning("Blif delay constraints (%s) are not supported.", cmd); + continue; + } + if (!strcmp(cmd, ".inputs") || !strcmp(cmd, ".outputs")) { char *p; From ec065186d309e1f5dba05eb652d75a7a0a84778c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 9 Jan 2024 11:52:41 +0100 Subject: [PATCH 06/33] opt_clean: Add commentary around wire cleaning, NFC --- passes/opt/opt_clean.cc | 46 +++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index a219e470813..c9d85028ea4 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -240,6 +240,7 @@ int count_nontrivial_wire_attrs(RTLIL::Wire *w) return count; } +// Should we pick `s2` over `s1` to represent a signal? bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPool &conns, pool &direct_wires) { RTLIL::Wire *w1 = s1.wire; @@ -292,9 +293,10 @@ bool check_public_name(RTLIL::IdString id) bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbose) { + // `register_signals` and `connected_signals` will help us decide later on + // on picking representatives out of groups of connected signals SigPool register_signals; SigPool connected_signals; - if (!purge_mode) for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; @@ -309,20 +311,27 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } SigMap assign_map(module); - pool direct_sigs; + + // construct a pool of wires which are directly driven by a known celltype, + // this will influence our choice of representatives pool direct_wires; - for (auto &it : module->cells_) { - RTLIL::Cell *cell = it.second; - if (ct_all.cell_known(cell->type)) - for (auto &it2 : cell->connections()) - if (ct_all.cell_output(cell->type, it2.first)) - direct_sigs.insert(assign_map(it2.second)); - } - for (auto &it : module->wires_) { - if (direct_sigs.count(assign_map(it.second)) || it.second->port_input) - direct_wires.insert(it.second); + { + pool direct_sigs; + for (auto &it : module->cells_) { + RTLIL::Cell *cell = it.second; + if (ct_all.cell_known(cell->type)) + for (auto &it2 : cell->connections()) + if (ct_all.cell_output(cell->type, it2.first)) + direct_sigs.insert(assign_map(it2.second)); + } + for (auto &it : module->wires_) { + if (direct_sigs.count(assign_map(it.second)) || it.second->port_input) + direct_wires.insert(it.second); + } } + // weight all options for representatives with `compare_signals`, + // the one that wins will be what `assign_map` maps to for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) { @@ -332,21 +341,30 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } } + // we are removing all connections module->connections_.clear(); + // used signals sigmapped SigPool used_signals; + // used signals pre-sigmapped SigPool raw_used_signals; + // used signals sigmapped, ignoring drivers (we keep track of this to set `unused_bits`) SigPool used_signals_nodrivers; + + // gather the usage information for cells for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; for (auto &it2 : cell->connections_) { - assign_map.apply(it2.second); + assign_map.apply(it2.second); // modify the cell connection in place raw_used_signals.add(it2.second); used_signals.add(it2.second); if (!ct_all.cell_output(cell->type, it2.first)) used_signals_nodrivers.add(it2.second); } } + + // gather the usage information for ports, wires with `keep`, + // also gather init bits dict init_bits; for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; @@ -374,6 +392,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } } + // set init attributes on all wires of a connected group for (auto wire : module->wires()) { bool found = false; Const val(State::Sx, wire->width); @@ -388,6 +407,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos wire->attributes[ID::init] = val; } + // now decide for each wire if we should be deleting it pool del_wires_queue; for (auto wire : module->wires()) { From 7afc0696e2ffefde3ea3c92a5b22c6de1309b68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 9 Jan 2024 11:54:38 +0100 Subject: [PATCH 07/33] opt_clean: Assert an impossible path isn't taken --- passes/opt/opt_clean.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c9d85028ea4..8b56895fef5 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -438,6 +438,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos goto delete_this_wire; } else if (!used_signals.check_any(s2)) { + // this path shouldn't be possible: this wire is used directly (otherwise it would get cleaned up above), and indirectly + // used wires are a superset of those used directly + log_assert(false); // delete wires that aren't used by anything indirectly, even though other wires may alias it goto delete_this_wire; } From 4fa314c0bd0a7f314809e180f196d0974535b0f5 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 30 Jan 2024 16:41:28 +0100 Subject: [PATCH 08/33] Add API to overwrite existing pass from plugin Signed-off-by: Claire Xenia Wolf --- kernel/register.cc | 8 +++----- kernel/register.h | 1 + passes/cmds/plugin.cc | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/kernel/register.cc b/kernel/register.cc index 9ffb17c1a97..1853e94d56b 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -108,9 +108,8 @@ Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_he void Pass::run_register() { - if (pass_register.count(pass_name)) + if (pass_register.count(pass_name) && !replace_existing_pass()) log_error("Unable to register pass '%s', pass already exists!\n", pass_name.c_str()); - pass_register[pass_name] = this; } @@ -447,13 +446,12 @@ Frontend::Frontend(std::string name, std::string short_help) : void Frontend::run_register() { - if (pass_register.count(pass_name)) + if (pass_register.count(pass_name) && !replace_existing_pass()) log_error("Unable to register pass '%s', pass already exists!\n", pass_name.c_str()); pass_register[pass_name] = this; - if (frontend_register.count(frontend_name)) + if (frontend_register.count(frontend_name) && !replace_existing_pass()) log_error("Unable to register frontend '%s', frontend already exists!\n", frontend_name.c_str()); - frontend_register[frontend_name] = this; } diff --git a/kernel/register.h b/kernel/register.h index 15750af2a40..08ce4b28787 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -70,6 +70,7 @@ struct Pass virtual void on_register(); virtual void on_shutdown(); + virtual bool replace_existing_pass() const { return false; } }; struct ScriptPass : Pass diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 08b4aa8c4ee..4ad7c165b1e 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -103,7 +103,6 @@ void load_plugin(std::string filename, std::vector aliases) loaded_plugins[orig_filename] = hdl; Pass::init_register(); - } } From 039634d9737dd7198d21e534b386203aebf0750a Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Wed, 31 Jan 2024 01:03:01 +0300 Subject: [PATCH 09/33] feat: mkdir with tree --- kernel/driver.cc | 101 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 3a5e49cb451..ee30c2b27f3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -53,6 +53,78 @@ # include #endif +#include // _stat +#include // errno, ENOENT, EEXIST +#if defined(_WIN32) +# include +# define mkdir(path, mode) _mkdir(path) +# define PATH_DELIMETER "\\" +#else +# define PATH_DELIMETER "/" +#endif + + + +bool isDirExist(const std::string& path) +{ +#if defined(_WIN32) + struct _stat info; + if (_stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & _S_IFDIR) != 0; +#else + struct stat info; + if (stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & S_IFDIR) != 0; +#endif +} +bool makePath(const std::string& path) +{ +#if defined(_WIN32) + int ret = _mkdir(path.c_str()); +#else + mode_t mode = 0755; + int ret = mkdir(path.c_str(), mode); +#endif + if (ret == 0) + return true; + + switch (errno) + { + case ENOENT: + // parent didn't exist, try to create it + { + int pos = path.find_last_of('/'); + if (pos == std::string::npos) +#if defined(_WIN32) + pos = path.find_last_of('\\'); + if (pos == std::string::npos) +#endif + return false; + if (!makePath( path.substr(0, pos) )) + return false; + } + // now, try to create again +#if defined(_WIN32) + return 0 == _mkdir(path.c_str()); +#else + return 0 == mkdir(path.c_str(), mode); +#endif + + case EEXIST: + // done! + return isDirExist(path); + + default: + return false; + } +} + USING_YOSYS_NAMESPACE char *optarg; @@ -244,16 +316,27 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { - if (getenv("HOME") != NULL) { - yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); + std::string state_dir; + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + state_dir = stringf("%s/.local/state", getenv("HOME")); + }else { + log("$HOME is empty. No history file will be created."); } - } else { - yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); + } else { + state_dir = stringf("%s", getenv("XDG_STATE_HOME")); + } + + if (!state_dir.empty()) { + std::string yosys_dir = state_dir + "/yosys"; + // mkdir(yosys_dir.c_str(), 0777); + makePath(yosys_dir); + + yosys_history_file = yosys_dir + "/history"; + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); + }else { + log("state_dir is empty. No history file will be created."); } #endif From 820232eacaa88e81be044a90dcc3b96e411dea8c Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Wed, 31 Jan 2024 19:50:31 +0300 Subject: [PATCH 10/33] fix: function naming and locations --- kernel/driver.cc | 75 +----------------------------------------------- kernel/yosys.cc | 65 +++++++++++++++++++++++++++++++++++++++-- kernel/yosys.h | 4 +++ 3 files changed, 68 insertions(+), 76 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index ee30c2b27f3..5f105ea0328 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -53,78 +53,6 @@ # include #endif -#include // _stat -#include // errno, ENOENT, EEXIST -#if defined(_WIN32) -# include -# define mkdir(path, mode) _mkdir(path) -# define PATH_DELIMETER "\\" -#else -# define PATH_DELIMETER "/" -#endif - - - -bool isDirExist(const std::string& path) -{ -#if defined(_WIN32) - struct _stat info; - if (_stat(path.c_str(), &info) != 0) - { - return false; - } - return (info.st_mode & _S_IFDIR) != 0; -#else - struct stat info; - if (stat(path.c_str(), &info) != 0) - { - return false; - } - return (info.st_mode & S_IFDIR) != 0; -#endif -} -bool makePath(const std::string& path) -{ -#if defined(_WIN32) - int ret = _mkdir(path.c_str()); -#else - mode_t mode = 0755; - int ret = mkdir(path.c_str(), mode); -#endif - if (ret == 0) - return true; - - switch (errno) - { - case ENOENT: - // parent didn't exist, try to create it - { - int pos = path.find_last_of('/'); - if (pos == std::string::npos) -#if defined(_WIN32) - pos = path.find_last_of('\\'); - if (pos == std::string::npos) -#endif - return false; - if (!makePath( path.substr(0, pos) )) - return false; - } - // now, try to create again -#if defined(_WIN32) - return 0 == _mkdir(path.c_str()); -#else - return 0 == mkdir(path.c_str(), mode); -#endif - - case EEXIST: - // done! - return isDirExist(path); - - default: - return false; - } -} - USING_YOSYS_NAMESPACE char *optarg; @@ -329,8 +257,7 @@ int main(int argc, char **argv) if (!state_dir.empty()) { std::string yosys_dir = state_dir + "/yosys"; - // mkdir(yosys_dir.c_str(), 0777); - makePath(yosys_dir); + create_directory(yosys_dir); yosys_history_file = yosys_dir + "/history"; read_history(yosys_history_file.c_str()); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 4409dc91ddd..0362bc1eb87 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -436,6 +436,25 @@ std::string make_temp_dir(std::string template_str) #endif } +bool check_dir_exists(const std::string& path) +{ +#if defined(_WIN32) + struct _stat info; + if (_stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & _S_IFDIR) != 0; +#else + struct stat info; + if (stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & S_IFDIR) != 0; +#endif +} + #ifdef _WIN32 bool check_file_exists(std::string filename, bool) { @@ -481,6 +500,48 @@ void remove_directory(std::string dirname) #endif } +bool create_directory(const std::string& path) +{ +#if defined(_WIN32) + int ret = _mkdir(path.c_str()); +#else + mode_t mode = 0755; + int ret = mkdir(path.c_str(), mode); +#endif + if (ret == 0) + return true; + + switch (errno) + { + case ENOENT: + // parent didn't exist, try to create it + { + std::string::size_type pos = path.find_last_of('/'); + if (pos == std::string::npos) +#if defined(_WIN32) + pos = path.find_last_of('\\'); + if (pos == std::string::npos) +#endif + return false; + if (!create_directory( path.substr(0, pos) )) + return false; + } + // now, try to create again +#if defined(_WIN32) + return 0 == _mkdir(path.c_str()); +#else + return 0 == mkdir(path.c_str(), mode); +#endif + + case EEXIST: + // done! + return check_dir_exists(path); + + default: + return false; + } +} + std::string escape_filename_spaces(const std::string& filename) { std::string out; @@ -781,10 +842,10 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a int yosys_tcl_iterp_init(Tcl_Interp *interp) { - if (Tcl_Init(interp)!=TCL_OK) + if (Tcl_Init(interp)!=TCL_OK) log_warning("Tcl_Init() call failed - %s\n",Tcl_ErrnoMsg(Tcl_GetErrno())); Tcl_CreateCommand(interp, "yosys", tcl_yosys_cmd, NULL, NULL); - return TCL_OK ; + return TCL_OK ; } void yosys_tcl_activate_repl() diff --git a/kernel/yosys.h b/kernel/yosys.h index 97a79861e15..76ad01aa985 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -66,6 +66,8 @@ #include #include #include +#include +#include #ifdef WITH_PYTHON #include @@ -341,8 +343,10 @@ std::string get_base_tmpdir(); std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); bool check_file_exists(std::string filename, bool is_exec = false); +bool check_dir_exists(const std::string& path); bool is_absolute_path(std::string filename); void remove_directory(std::string dirname); +bool create_directory(const std::string& path); std::string escape_filename_spaces(const std::string& filename); template int GetSize(const T &obj) { return obj.size(); } From dd5dc06863d0e9fe76ff0d2f4cffbe9869bfa92f Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Wed, 31 Jan 2024 20:14:32 +0300 Subject: [PATCH 11/33] fix: save history file on windows --- kernel/driver.cc | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 5f105ea0328..a5201464d48 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -245,26 +245,34 @@ int main(int argc, char **argv) #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) std::string state_dir; - if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { - if (getenv("HOME") != NULL) { - state_dir = stringf("%s/.local/state", getenv("HOME")); - }else { - log("$HOME is empty. No history file will be created."); - } - } else { - state_dir = stringf("%s", getenv("XDG_STATE_HOME")); - } + #if defined(_WIN32) + if (getenv("HOMEDRIVE") != NULL && getenv("HOMEPATH") != NULL) { + state_dir = stringf("%s%s/.local/state", getenv("HOMEDRIVE"), getenv("HOMEPATH")); + } else { + log("$HOMEDRIVE and/or $HOMEPATH is empty. No history file will be created."); + } + #else + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + state_dir = stringf("%s/.local/state", getenv("HOME")); + } else { + log("$HOME is empty. No history file will be created."); + } + } else { + state_dir = stringf("%s", getenv("XDG_STATE_HOME")); + } + #endif if (!state_dir.empty()) { std::string yosys_dir = state_dir + "/yosys"; - create_directory(yosys_dir); + create_directory(yosys_dir); yosys_history_file = yosys_dir + "/history"; read_history(yosys_history_file.c_str()); yosys_history_offset = where_history(); - }else { - log("state_dir is empty. No history file will be created."); - } + } else { + log("state_dir is empty. No history file will be created."); + } #endif if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) From c1d32886540bd22bd78646b0694a67c49f1550a5 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Fri, 2 Feb 2024 01:25:58 +0300 Subject: [PATCH 12/33] chore: use similar variable/function names --- kernel/yosys.cc | 24 ++++++++++++------------ kernel/yosys.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 0362bc1eb87..c7f5bebdab7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -436,18 +436,18 @@ std::string make_temp_dir(std::string template_str) #endif } -bool check_dir_exists(const std::string& path) +bool check_directory_exists(const std::string& dirname) { #if defined(_WIN32) struct _stat info; - if (_stat(path.c_str(), &info) != 0) + if (_stat(dirname.c_str(), &info) != 0) { return false; } return (info.st_mode & _S_IFDIR) != 0; #else struct stat info; - if (stat(path.c_str(), &info) != 0) + if (stat(dirname.c_str(), &info) != 0) { return false; } @@ -500,13 +500,13 @@ void remove_directory(std::string dirname) #endif } -bool create_directory(const std::string& path) +bool create_directory(const std::string& dirname) { #if defined(_WIN32) - int ret = _mkdir(path.c_str()); + int ret = _mkdir(dirname.c_str()); #else mode_t mode = 0755; - int ret = mkdir(path.c_str(), mode); + int ret = mkdir(dirname.c_str(), mode); #endif if (ret == 0) return true; @@ -516,26 +516,26 @@ bool create_directory(const std::string& path) case ENOENT: // parent didn't exist, try to create it { - std::string::size_type pos = path.find_last_of('/'); + std::string::size_type pos = dirname.find_last_of('/'); if (pos == std::string::npos) #if defined(_WIN32) - pos = path.find_last_of('\\'); + pos = dirname.find_last_of('\\'); if (pos == std::string::npos) #endif return false; - if (!create_directory( path.substr(0, pos) )) + if (!create_directory( dirname.substr(0, pos) )) return false; } // now, try to create again #if defined(_WIN32) - return 0 == _mkdir(path.c_str()); + return 0 == _mkdir(dirname.c_str()); #else - return 0 == mkdir(path.c_str(), mode); + return 0 == mkdir(dirname.c_str(), mode); #endif case EEXIST: // done! - return check_dir_exists(path); + return check_directory_exists(dirname); default: return false; diff --git a/kernel/yosys.h b/kernel/yosys.h index 76ad01aa985..0a4641d1819 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -343,10 +343,10 @@ std::string get_base_tmpdir(); std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); bool check_file_exists(std::string filename, bool is_exec = false); -bool check_dir_exists(const std::string& path); +bool check_directory_exists(const std::string& dirname); bool is_absolute_path(std::string filename); void remove_directory(std::string dirname); -bool create_directory(const std::string& path); +bool create_directory(const std::string& dirname); std::string escape_filename_spaces(const std::string& filename); template int GetSize(const T &obj) { return obj.size(); } From 7dbe288d6fafb821976f51967b6c65abd53891f7 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Fri, 2 Feb 2024 02:39:04 +0300 Subject: [PATCH 13/33] fix: descriptive logs --- kernel/driver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index a5201464d48..373295b1de3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -271,7 +271,7 @@ int main(int argc, char **argv) read_history(yosys_history_file.c_str()); yosys_history_offset = where_history(); } else { - log("state_dir is empty. No history file will be created."); + log("Directory to put history file does not exist. If you are on Windows either $HOMEDRIVE or $HOMEPATH is empty."); } #endif From 3f457f23887456ae6c927f6fd2147f453c267672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sun, 4 Feb 2024 23:20:38 +0100 Subject: [PATCH 14/33] ci: Fix CXXSTD typo --- .github/workflows/test-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 5d929f581e6..cd990d7bdae 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -111,7 +111,7 @@ jobs: shell: bash run: | make config-${CC%%-*} - make -j${{ env.procs }} CCXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC + make -j${{ env.procs }} CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC - name: Run tests if: (matrix.cpp_std == 'c++11') && (matrix.compiler == 'gcc-11') From 97b8ee5ab958f1f2b73a74af2d0d113e815bdc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sun, 4 Feb 2024 23:29:46 +0100 Subject: [PATCH 15/33] ci: Get a dump of yosys-config into the build log --- .github/workflows/test-linux.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index cd990d7bdae..70aa1f68e4c 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -118,3 +118,7 @@ jobs: shell: bash run: | make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC + + - name: Log yosys-config output + run: | + ./yosys-config From 0cdd4273b4aa0ac98ce99a9dc888965c96fed382 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 5 Feb 2024 15:41:50 +1300 Subject: [PATCH 16/33] ci: ignore yosys-config return code --- .github/workflows/test-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 70aa1f68e4c..28c17a6c0e0 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -121,4 +121,4 @@ jobs: - name: Log yosys-config output run: | - ./yosys-config + ./yosys-config || true From bc66dfd9ea31f79f97e43f6b48d775245b47cdf4 Mon Sep 17 00:00:00 2001 From: Ethan Mahintorabi Date: Mon, 5 Feb 2024 07:10:25 +0000 Subject: [PATCH 17/33] verific: Fixes incorrect aldff inference in verific importer The following SV module at HEAD imported with verific, ```systemverilog module my_module( input logic [4:0] a, input logic clk, input logic enable, output logic [4:0] z ); reg [4:0] pipeline_register; always @(posedge clk) begin pipeline_register <= enable ? a : pipeline_register; end assign z = pipeline_register; endmodule : my_module ``` results in the following output verilog ```systemverilog /* Generated by 0.36 */ (* top = 1 *) (* hdlname = "my_module" *) (* src = "/tmp/temp_directory_zTwd0l/my_input.v:2.12-2.21" *) module my_module(clk, enable, a, z); wire [4:0] _0_; (* src = "/tmp/temp_directory_zTwd0l/my_input.v:3.25-3.26" *) input [4:0] a; wire [4:0] a; (* src = "/tmp/temp_directory_zTwd0l/my_input.v:4.19-4.22" *) input clk; wire clk; (* src = "/tmp/temp_directory_zTwd0l/my_input.v:5.19-5.25" *) input enable; wire enable; (* src = "/tmp/temp_directory_zTwd0l/my_input.v:6.26-6.27" *) output [4:0] z; wire [4:0] z; (* src = "/tmp/temp_directory_zTwd0l/my_input.v:10.12-12.8" *) \$aldff #( .ALOAD_POLARITY(32'd1), .CLK_POLARITY(32'd1), .WIDTH(32'd5) ) _1_ ( .AD(5'hxx), .ALOAD(1'h0), .CLK(clk), .D(_0_), .Q(z) ); (* src = "/tmp/temp_directory_zTwd0l/my_input.v:11.28-11.58" *) \$mux #( .WIDTH(32'd5) ) _2_ ( .A(z), .B(a), .S(enable), .Y(_0_) ); endmodule ``` Yosys is incorrectly infering aldffs due to an incorrect conversion of logical 1 and 0 SigBits. My PR unifies the conversion of Verific::Net objects into SigBits using Yosys' internal representation of special signals like 0,1,x,z. After my PR these signals are correctly converted into DFFs. Signed-off-by: Ethan Mahintorabi --- frontends/verific/verific.cc | 40 ++++++++++++++++++++++-------------- frontends/verific/verific.h | 1 + 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4123c374183..a809af21a75 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -343,36 +343,46 @@ void VerificImporter::import_attributes(dict &att } } +RTLIL::SigBit VerificImporter::netToSigBit(Verific::Net *net) { + if (net && net->IsGnd()) + return RTLIL::State::S0; + else if (net && net->IsPwr()) + return RTLIL::State::S1; + else if (net && net->IsX()) + return RTLIL::State::Sx; + else if (net) + return net_map_at(net); + else + return RTLIL::State::Sz; +} + RTLIL::SigSpec VerificImporter::operatorInput(Instance *inst) { RTLIL::SigSpec sig; - for (int i = int(inst->InputSize())-1; i >= 0; i--) - if (inst->GetInputBit(i)) - sig.append(net_map_at(inst->GetInputBit(i))); - else - sig.append(RTLIL::State::Sz); + for (int i = int(inst->InputSize())-1; i >= 0; i--) { + Net *net = inst->GetInputBit(i); + sig.append(netToSigBit(net)); + } return sig; } RTLIL::SigSpec VerificImporter::operatorInput1(Instance *inst) { RTLIL::SigSpec sig; - for (int i = int(inst->Input1Size())-1; i >= 0; i--) - if (inst->GetInput1Bit(i)) - sig.append(net_map_at(inst->GetInput1Bit(i))); - else - sig.append(RTLIL::State::Sz); + for (int i = int(inst->Input1Size())-1; i >= 0; i--) { + Net *net = inst->GetInput1Bit(i); + sig.append(netToSigBit(net)); + } return sig; } RTLIL::SigSpec VerificImporter::operatorInput2(Instance *inst) { RTLIL::SigSpec sig; - for (int i = int(inst->Input2Size())-1; i >= 0; i--) - if (inst->GetInput2Bit(i)) - sig.append(net_map_at(inst->GetInput2Bit(i))); - else - sig.append(RTLIL::State::Sz); + for (int i = int(inst->Input2Size())-1; i >= 0; i--) { + Net *net = inst->GetInput2Bit(i); + sig.append(netToSigBit(net)); + } return sig; } diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index 44485751c7e..0b9616e1944 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -83,6 +83,7 @@ struct VerificImporter RTLIL::IdString new_verific_id(Verific::DesignObj *obj); void import_attributes(dict &attributes, Verific::DesignObj *obj, Verific::Netlist *nl = nullptr); + RTLIL::SigBit netToSigBit(Verific::Net *net); RTLIL::SigSpec operatorInput(Verific::Instance *inst); RTLIL::SigSpec operatorInput1(Verific::Instance *inst); RTLIL::SigSpec operatorInput2(Verific::Instance *inst); From ff578ecabddc4f29eee15d5bf0da96087b32cfcb Mon Sep 17 00:00:00 2001 From: Ethan Mahintorabi Date: Mon, 5 Feb 2024 07:23:04 +0000 Subject: [PATCH 18/33] fix formatting Signed-off-by: Ethan Mahintorabi --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index a809af21a75..dff9c777b84 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -351,7 +351,7 @@ RTLIL::SigBit VerificImporter::netToSigBit(Verific::Net *net) { else if (net && net->IsX()) return RTLIL::State::Sx; else if (net) - return net_map_at(net); + return net_map_at(net); else return RTLIL::State::Sz; } From 57db87c99f1d9058ca94d404877afc4d798d5185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 5 Feb 2024 17:25:55 +0100 Subject: [PATCH 19/33] py_wrap_generator: Handle const-qualified callbacks --- misc/py_wrap_generator.py | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index 7fe78e03a58..a65d24d9218 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -1257,6 +1257,7 @@ def from_string(str_def, containing_file, class_, line_number, namespace): func.is_static = False func.is_inline = False func.is_virtual = False + func.is_const = False func.ret_attr_type = attr_types.default func.is_operator = False func.member_of = None @@ -1334,6 +1335,11 @@ def from_string(str_def, containing_file, class_, line_number, namespace): found = find_closing(str_def, "(", ")") if found == -1: return None + + post_qualifiers = str_def[found + 1:].lstrip().replace("{", " {") + " " + if post_qualifiers.startswith("const "): + func.is_const = True + str_def = str_def[0:found] if func.name in blacklist_methods: return None @@ -1379,6 +1385,12 @@ def mangled_name(self): def gen_alias(self): self.alias = self.mangled_name + def gen_post_qualifiers(self, derived=False): + if self.member_of != None and self.member_of.link_type == link_types.derive and self.is_virtual and derived: + # we drop the qualifiers when deriving callbacks to be implemented in Python + return '' + return ' const' if self.is_const else '' + def gen_decl(self): if self.duplicate: return "" @@ -1392,7 +1404,7 @@ def gen_decl(self): text += ", " if len(self.args) > 0: text = text[:-2] - text += ");\n" + text += f"){self.gen_post_qualifiers()};\n" return text def gen_decl_virtual(self): @@ -1411,12 +1423,18 @@ def gen_decl_virtual(self): if len(self.args) > 0: text = text[:-2] text += ")" - if len(self.args) == 0: + if len(self.args) == 0 and self.ret_type.name == "void": text += "{}" else: text += "\n\t\t{" for arg in self.args: text += "\n\t\t\t(void)" + arg.gen_varname() + ";" + if self.ret_type.name == "void": + pass + elif self.ret_type.name == "bool": + text += "\n\t\t\treturn false;" + else: + raise NotImplementedError(self.ret_type.name) text += "\n\t\t}\n" text += "\n\t\tvirtual " if self.is_static: @@ -1427,7 +1445,7 @@ def gen_decl_virtual(self): text += ", " if len(self.args) > 0: text = text[:-2] - text += ") override;\n" + text += f"){self.gen_post_qualifiers()} override;\n" return text def gen_decl_hash_py(self): @@ -1452,7 +1470,7 @@ def gen_def(self): text += ", " if len(self.args) > 0: text = text[:-2] - text +=")\n\t{" + text += f"){self.gen_post_qualifiers()}\n\t{{" for arg in self.args: text += arg.gen_translation() text += "\n\t\t" @@ -1507,16 +1525,17 @@ def gen_def_virtual(self): text += ", " if len(self.args) > 0: text = text[:-2] - text += ")\n\t{" + text += f"){self.gen_post_qualifiers()}\n\t{{" for arg in self.args: text += arg.gen_translation_cpp() - text += "\n\t\t" + return_stmt = "return " if self.ret_type.name != "void" else "" + text += f"\n\t\t{return_stmt}" if self.member_of == None: text += "::" + self.namespace + "::" + self.alias + "(" elif self.is_static: text += self.member_of.namespace + "::" + self.member_of.name + "::" + self.name + "(" else: - text += "py_" + self.alias + "(" + text += f"const_cast<{self.member_of.name}*>(this)->py_" + self.alias + "(" for arg in self.args: text += arg.gen_call_cpp() + ", " if len(self.args) > 0: @@ -1547,11 +1566,13 @@ def gen_default_impl(self): call_string = call_string[0:-2] call_string += ");" + return_stmt = "return " if self.ret_type.name != "void" else "" + text += ")\n\t\t{" - text += "\n\t\t\tif(boost::python::override py_" + self.alias + " = this->get_override(\"py_" + self.alias + "\"))" - text += "\n\t\t\t\t" + call_string + text += "\n\t\t\tif (boost::python::override py_" + self.alias + " = this->get_override(\"py_" + self.alias + "\"))" + text += f"\n\t\t\t\t{return_stmt}" + call_string text += "\n\t\t\telse" - text += "\n\t\t\t\t" + self.member_of.name + "::" + call_string + text += f"\n\t\t\t\t{return_stmt}" + self.member_of.name + "::" + call_string text += "\n\t\t}" text += "\n\n\t\t" + self.ret_type.gen_text() + " default_py_" + self.alias + "(" @@ -1559,8 +1580,8 @@ def gen_default_impl(self): text += arg.gen_listitem() + ", " if len(self.args) > 0: text = text[:-2] - text += ")\n\t\t{" - text += "\n\t\t\tthis->" + self.member_of.name + "::" + call_string + text += f")\n\t\t{{" + text += f"\n\t\t\t{return_stmt}this->" + self.member_of.name + "::" + call_string text += "\n\t\t}" return text @@ -1584,9 +1605,9 @@ def gen_boost_py(self): for a in self.args: text += a.gen_listitem_hash() + ", " if len(self.args) > 0: - text = text[0:-2] + ")>" + text = text[0:-2] + f"){self.gen_post_qualifiers(True)}>" else: - text += "void)>" + text += f"void){self.gen_post_qualifiers(True)}>" if self.is_operator: text += "(\"" + wrappable_operators[self.name.replace("operator","")] + "\"" From 1df2a209e51da6eaf0dde7c52e40b60a7e7908a5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 00:15:26 +0000 Subject: [PATCH 20/33] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c79cb185b1e..90110680275 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.37+74 +YOSYS_VER := 0.37+83 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 0470cbb00d82730fd310eb870d8988af840fc150 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 12 Jan 2024 16:30:37 +0100 Subject: [PATCH 21/33] hierarchy: Without a known top module, derive all deferred modules This fixes hierarchy when used with cell libraries that were loaded with -defer and also makes more of the hierarchy visible to the auto-top heuristic. --- passes/hierarchy/hierarchy.cc | 12 ++++++++++++ tests/verilog/param_no_default.ys | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 90f890e8075..6fcda5d7644 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1006,6 +1006,18 @@ struct HierarchyPass : public Pass { if (mod->get_bool_attribute(ID::top)) top_mod = mod; + if (top_mod == nullptr) + { + std::vector abstract_ids; + for (auto module : design->modules()) + if (module->name.begins_with("$abstract")) + abstract_ids.push_back(module->name); + for (auto abstract_id : abstract_ids) + design->module(abstract_id)->derive(design, {}); + for (auto abstract_id : abstract_ids) + design->remove(design->module(abstract_id)); + } + if (top_mod == nullptr && auto_top_mode) { log_header(design, "Finding top of design hierarchy..\n"); dict db; diff --git a/tests/verilog/param_no_default.ys b/tests/verilog/param_no_default.ys index cc34c6a53e3..0509f6a1aa5 100644 --- a/tests/verilog/param_no_default.ys +++ b/tests/verilog/param_no_default.ys @@ -1,5 +1,5 @@ read_verilog -sv param_no_default.sv -hierarchy +hierarchy -top top proc flatten opt -full From d00843d436f4ebaed19c4a49f6e5dc78960fdf00 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 6 Feb 2024 10:36:30 +0100 Subject: [PATCH 22/33] Add -nordff to test --- tests/verific/memory_semantics.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/verific/memory_semantics.ys b/tests/verific/memory_semantics.ys index adcd3a4ca7c..7287f847ff6 100644 --- a/tests/verific/memory_semantics.ys +++ b/tests/verific/memory_semantics.ys @@ -89,6 +89,6 @@ EOF hierarchy -top top proc opt_clean -memory -nomap +memory -nomap -nordff select -assert-count 1 t:$mem_v2 sim -assert -clock clk -n 20 From 16ff3e0a30c4aebd1d6735d39ccd697d467e85e4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 00:14:46 +0000 Subject: [PATCH 23/33] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 90110680275..63d973e2df6 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.37+83 +YOSYS_VER := 0.37+90 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a98d363d9dc87f0c06b88b1cf8d75f10a4feef29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 8 Feb 2024 00:03:02 +0100 Subject: [PATCH 24/33] synth: Run script in full in help mode --- techlibs/common/synth.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 006a3c8dd84..b01c5e56cee 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -230,13 +230,13 @@ struct SynthPass : public ScriptPass { if (check_label("coarse")) { run("proc"); - if (help_mode || flatten) + if (flatten || help_mode) run("flatten", " (if -flatten)"); run("opt_expr"); run("opt_clean"); run("check"); run("opt -nodffe -nosdff"); - if (!nofsm) + if (!nofsm || help_mode) run("fsm" + fsm_opts, " (unless -nofsm)"); run("opt"); run("wreduce"); @@ -246,8 +246,8 @@ struct SynthPass : public ScriptPass { run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)"); else if (lut) run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut)); - if (booth) - run("booth"); + if (booth || help_mode) + run("booth", " (if -booth)"); if (!noalumacc) run("alumacc", " (unless -noalumacc)"); if (!noshare) @@ -274,7 +274,7 @@ struct SynthPass : public ScriptPass { } run("opt -fast"); - if (!noabc && !flowmap) { + if ((!noabc && !flowmap) || help_mode) { #ifdef YOSYS_ENABLE_ABC if (help_mode) { run(abc + " -fast", " (unless -noabc, unless -lut)"); From 7a3316dd78f891a8fd919edf5484583df9152c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 8 Feb 2024 00:03:15 +0100 Subject: [PATCH 25/33] synth: Tweak phrasing of `-booth` help --- techlibs/common/synth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index b01c5e56cee..e5013678aa4 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -60,7 +60,7 @@ struct SynthPass : public ScriptPass { log(" do not run abc (as if yosys was compiled without ABC support)\n"); log("\n"); log(" -booth\n"); - log(" run the booth pass to convert $mul to Booth encoded multipliers"); + log(" run the booth pass to map $mul to Booth encoded multipliers\n"); log("\n"); log(" -noalumacc\n"); log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n"); From 2797d675695686fe5e6f6bc35988034cb67b77e4 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 8 Feb 2024 09:19:19 +0100 Subject: [PATCH 26/33] Move block and change message to debug --- kernel/driver.cc | 62 +++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 373295b1de3..ebd262bb608 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -243,38 +243,6 @@ int main(int argc, char **argv) bool mode_v = false; bool mode_q = false; -#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - std::string state_dir; - #if defined(_WIN32) - if (getenv("HOMEDRIVE") != NULL && getenv("HOMEPATH") != NULL) { - state_dir = stringf("%s%s/.local/state", getenv("HOMEDRIVE"), getenv("HOMEPATH")); - } else { - log("$HOMEDRIVE and/or $HOMEPATH is empty. No history file will be created."); - } - #else - if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { - if (getenv("HOME") != NULL) { - state_dir = stringf("%s/.local/state", getenv("HOME")); - } else { - log("$HOME is empty. No history file will be created."); - } - } else { - state_dir = stringf("%s", getenv("XDG_STATE_HOME")); - } - #endif - - if (!state_dir.empty()) { - std::string yosys_dir = state_dir + "/yosys"; - create_directory(yosys_dir); - - yosys_history_file = yosys_dir + "/history"; - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); - } else { - log("Directory to put history file does not exist. If you are on Windows either $HOMEDRIVE or $HOMEPATH is empty."); - } -#endif - if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) { printf("\n"); @@ -562,6 +530,36 @@ int main(int argc, char **argv) if (print_banner) yosys_banner(); +#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) + std::string state_dir; + #if defined(_WIN32) + if (getenv("HOMEDRIVE") != NULL && getenv("HOMEPATH") != NULL) { + state_dir = stringf("%s%s/.local/state", getenv("HOMEDRIVE"), getenv("HOMEPATH")); + } else { + log_debug("$HOMEDRIVE and/or $HOMEPATH is empty. No history file will be created."); + } + #else + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + state_dir = stringf("%s/.local/state", getenv("HOME")); + } else { + log_debug("$HOME is empty. No history file will be created."); + } + } else { + state_dir = stringf("%s", getenv("XDG_STATE_HOME")); + } + #endif + + if (!state_dir.empty()) { + std::string yosys_dir = state_dir + "/yosys"; + create_directory(yosys_dir); + + yosys_history_file = yosys_dir + "/history"; + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); + } +#endif + if (print_stats) log_hasher = new SHA1; From a38273c19d58f5dc58cf7ed6a3367a32452d193e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 8 Feb 2024 12:19:42 +0100 Subject: [PATCH 27/33] add log_suppressed and fixed formatting --- kernel/driver.cc | 56 +++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index ebd262bb608..8d9ecc91adc 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -531,33 +531,33 @@ int main(int argc, char **argv) yosys_banner(); #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - std::string state_dir; - #if defined(_WIN32) - if (getenv("HOMEDRIVE") != NULL && getenv("HOMEPATH") != NULL) { - state_dir = stringf("%s%s/.local/state", getenv("HOMEDRIVE"), getenv("HOMEPATH")); - } else { - log_debug("$HOMEDRIVE and/or $HOMEPATH is empty. No history file will be created."); - } - #else - if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { - if (getenv("HOME") != NULL) { - state_dir = stringf("%s/.local/state", getenv("HOME")); - } else { - log_debug("$HOME is empty. No history file will be created."); - } - } else { - state_dir = stringf("%s", getenv("XDG_STATE_HOME")); - } - #endif - - if (!state_dir.empty()) { - std::string yosys_dir = state_dir + "/yosys"; - create_directory(yosys_dir); - - yosys_history_file = yosys_dir + "/history"; - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); - } + std::string state_dir; + #if defined(_WIN32) + if (getenv("HOMEDRIVE") != NULL && getenv("HOMEPATH") != NULL) { + state_dir = stringf("%s%s/.local/state", getenv("HOMEDRIVE"), getenv("HOMEPATH")); + } else { + log_debug("$HOMEDRIVE and/or $HOMEPATH is empty. No history file will be created.\n"); + } + #else + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + state_dir = stringf("%s/.local/state", getenv("HOME")); + } else { + log_debug("$HOME is empty. No history file will be created.\n"); + } + } else { + state_dir = stringf("%s", getenv("XDG_STATE_HOME")); + } + #endif + + if (!state_dir.empty()) { + std::string yosys_dir = state_dir + "/yosys"; + create_directory(yosys_dir); + + yosys_history_file = yosys_dir + "/history"; + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); + } #endif if (print_stats) @@ -591,6 +591,8 @@ int main(int argc, char **argv) for (auto &fn : plugin_filenames) load_plugin(fn, {}); + log_suppressed(); + if (!vlog_defines.empty()) { std::string vdef_cmd = "read -define"; for (auto vdef : vlog_defines) From 1236bb65b61998ad2aab43f52f737c7eef6caec6 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 8 Feb 2024 11:32:15 +0000 Subject: [PATCH 28/33] read_verilog: don't include empty `opt_sva_label` in span. Consider this SystemVerilog file: module top(...); input clk; input [7:0] data; input ack; always @(posedge clk) if (ack) begin assert(data != 8'h0a); end endmodule Before this commit, the span for the assert was: if (ack) begin> assert(data != 8'h0a)<; After this commit, the span for the assert is: if (ack) begin >assert(data != 8'h0a)<; This helps editor integrations that only look at the beginning of the span. --- frontends/verilog/verilog_parser.y | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index cb8c453c087..039e83491e7 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2484,7 +2484,7 @@ assert: delete $5; } else { AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5); - SET_AST_NODE_LOC(node, @1, @6); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2497,7 +2497,7 @@ assert: delete $5; } else { AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5); - SET_AST_NODE_LOC(node, @1, @6); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2510,7 +2510,7 @@ assert: delete $6; } else { AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6); - SET_AST_NODE_LOC(node, @1, @7); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @7); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2523,7 +2523,7 @@ assert: delete $6; } else { AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6); - SET_AST_NODE_LOC(node, @1, @7); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @7); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2533,7 +2533,7 @@ assert: } | opt_sva_label TOK_COVER opt_property '(' expr ')' ';' { AstNode *node = new AstNode(AST_COVER, $5); - SET_AST_NODE_LOC(node, @1, @6); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) { node->str = *$1; delete $1; @@ -2542,7 +2542,7 @@ assert: } | opt_sva_label TOK_COVER opt_property '(' ')' ';' { AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false)); - SET_AST_NODE_LOC(node, @1, @5); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @5); if ($1 != nullptr) { node->str = *$1; delete $1; @@ -2551,7 +2551,7 @@ assert: } | opt_sva_label TOK_COVER ';' { AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false)); - SET_AST_NODE_LOC(node, @1, @2); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @2); if ($1 != nullptr) { node->str = *$1; delete $1; @@ -2563,7 +2563,7 @@ assert: delete $5; } else { AstNode *node = new AstNode(AST_ASSUME, $5); - SET_AST_NODE_LOC(node, @1, @6); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @6); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); @@ -2578,7 +2578,7 @@ assert: delete $6; } else { AstNode *node = new AstNode(AST_FAIR, $6); - SET_AST_NODE_LOC(node, @1, @7); + SET_AST_NODE_LOC(node, ($1 != nullptr ? @1 : @2), @7); if ($1 != nullptr) node->str = *$1; ast_stack.back()->children.push_back(node); From 66479a223208a990cd3cf203d3fbafb5cd2c078c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 8 Feb 2024 11:15:26 +0100 Subject: [PATCH 29/33] hashlib: Add missing `stdint.h` include We use `uint32_t` `uint64_t` etc. so add an explicit include. --- kernel/hashlib.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 25aa94b8002..e8ddddd3357 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -17,6 +17,8 @@ #include #include +#include + namespace hashlib { const int hashtable_size_trigger = 2; From af1a5cfeb9b6cd9ed86adf04dd5aad688392b466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 8 Feb 2024 17:46:00 +0100 Subject: [PATCH 30/33] Address `SigBit`/`SigSpec` confusion issues under c++20 --- passes/opt/opt_dff.cc | 2 +- passes/opt/opt_ffinv.cc | 3 ++- passes/opt/opt_lut.cc | 8 ++++++-- passes/pmgen/ice40_dsp.pmg | 4 ++-- passes/pmgen/xilinx_dsp.pmg | 4 ++-- passes/pmgen/xilinx_dsp48a.pmg | 4 ++-- passes/pmgen/xilinx_dsp_CREG.pmg | 2 +- passes/pmgen/xilinx_dsp_cascade.pmg | 4 ++-- passes/techmap/extract_fa.cc | 2 +- 9 files changed, 19 insertions(+), 14 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index f090d20b2e8..b77be45151b 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -353,7 +353,7 @@ struct OptDffWorker // Try a more complex conversion to plain async reset. State val_neutral = ff.pol_set ? State::S0 : State::S1; Const val_arst; - SigSpec sig_arst; + SigBit sig_arst; if (ff.sig_clr[0] == val_neutral) sig_arst = ff.sig_set[0]; else diff --git a/passes/opt/opt_ffinv.cc b/passes/opt/opt_ffinv.cc index 3f7b4bc4a71..d982ef2d239 100644 --- a/passes/opt/opt_ffinv.cc +++ b/passes/opt/opt_ffinv.cc @@ -38,6 +38,7 @@ struct OptFfInvWorker // - ... which has no other users // - all users of FF are LUTs bool push_d_inv(FfData &ff) { + log_assert(ff.width == 1); if (index.query_is_input(ff.sig_d)) return false; if (index.query_is_output(ff.sig_d)) @@ -90,7 +91,7 @@ struct OptFfInvWorker int flip_mask = 0; SigSpec sig_a = lut->getPort(ID::A); for (int i = 0; i < GetSize(sig_a); i++) { - if (index.sigmap(sig_a[i]) == index.sigmap(ff.sig_q)) { + if (index.sigmap(sig_a[i]) == index.sigmap(ff.sig_q[0])) { flip_mask |= 1 << i; } } diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 3907285f3e6..fbe61b6695a 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -167,7 +167,11 @@ struct OptLutWorker legal = false; break; } - if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic.second->getPort(dlogic_conn.second))) + + if (lut_dlogic.second->getPort(dlogic_conn.second).size() != 1) + continue; + + if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic.second->getPort(dlogic_conn.second)[0])) { log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second)); log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic.second->type.c_str(), dlogic_conn.second.c_str(), log_signal(lut_dlogic.second->getPort(dlogic_conn.second))); @@ -314,7 +318,7 @@ struct OptLutWorker auto lutA = worklist.pop(); SigSpec lutA_input = sigmap(lutA->getPort(ID::A)); - SigSpec lutA_output = sigmap(lutA->getPort(ID::Y)[0]); + SigBit lutA_output = sigmap(lutA->getPort(ID::Y)[0]); int lutA_width = lutA->getParam(ID::WIDTH).as_int(); int lutA_arity = luts_arity[lutA]; pool &lutA_dlogic_inputs = luts_dlogic_inputs[lutA]; diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 4de4791228e..9099dd3c470 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -346,7 +346,7 @@ endmatch code argQ argD { if (clock != SigBit()) { - if (port(ff, \CLK) != clock) + if (port(ff, \CLK)[0] != clock) reject; if (param(ff, \CLK_POLARITY).as_bool() != clock_pol) reject; @@ -393,7 +393,7 @@ endmatch code argQ if (ff) { if (clock != SigBit()) { - if (port(ff, \CLK) != clock) + if (port(ff, \CLK)[0] != clock) reject; if (param(ff, \CLK_POLARITY).as_bool() != clock_pol) reject; diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index 0cd23c09da0..817a15a1e8f 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -415,7 +415,7 @@ match ff filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ) filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ - filter clock == SigBit() || port(ff, \CLK) == clock + filter clock == SigBit() || port(ff, \CLK)[0] == clock endmatch code argQ @@ -465,7 +465,7 @@ match ff filter GetSize(port(ff, \D)) >= offset + GetSize(argD) filter port(ff, \D).extract(offset, GetSize(argD)) == argD - filter clock == SigBit() || port(ff, \CLK) == clock + filter clock == SigBit() || port(ff, \CLK)[0] == clock endmatch code argQ diff --git a/passes/pmgen/xilinx_dsp48a.pmg b/passes/pmgen/xilinx_dsp48a.pmg index dce1b61b005..f3bd9bc9567 100644 --- a/passes/pmgen/xilinx_dsp48a.pmg +++ b/passes/pmgen/xilinx_dsp48a.pmg @@ -354,7 +354,7 @@ match ff filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ) filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ - filter clock == SigBit() || port(ff, \CLK) == clock + filter clock == SigBit() || port(ff, \CLK)[0] == clock endmatch code argQ @@ -404,7 +404,7 @@ match ff filter GetSize(port(ff, \D)) >= offset + GetSize(argD) filter port(ff, \D).extract(offset, GetSize(argD)) == argD - filter clock == SigBit() || port(ff, \CLK) == clock + filter clock == SigBit() || port(ff, \CLK)[0] == clock endmatch code argQ diff --git a/passes/pmgen/xilinx_dsp_CREG.pmg b/passes/pmgen/xilinx_dsp_CREG.pmg index 95379771a2d..49e79dd8723 100644 --- a/passes/pmgen/xilinx_dsp_CREG.pmg +++ b/passes/pmgen/xilinx_dsp_CREG.pmg @@ -135,7 +135,7 @@ match ff filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ) filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ - filter clock == SigBit() || port(ff, \CLK) == clock + filter clock == SigBit() || port(ff, \CLK)[0] == clock endmatch code argQ diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 06601554c6b..29fc27dfed6 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -46,7 +46,7 @@ pattern xilinx_dsp_cascade udata > unextend udata >> chain longest_chain state next -state clock +state clock state AREG BREG // Variables used for subpatterns @@ -395,7 +395,7 @@ match ff filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ) filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ - filter clock == SigBit() || port(ff, \CLK) == clock + filter clock == SigBit() || port(ff, \CLK)[0] == clock endmatch code argQ diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 117fdd54cf6..ec1979f3b6d 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -281,7 +281,7 @@ struct ExtractFaWorker void assign_new_driver(SigBit bit, SigBit new_driver) { Cell *cell = driver.at(bit); - if (sigmap(cell->getPort(ID::Y)) == bit) { + if (sigmap(cell->getPort(ID::Y)) == SigSpec(bit)) { cell->setPort(ID::Y, module->addWire(NEW_ID)); module->connect(bit, new_driver); } From 043f1e2bcba3d3ee447ffbf5b2caefd706b7374d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 8 Feb 2024 17:47:21 +0100 Subject: [PATCH 31/33] opt_lut: Remove leftover `-dlogic` help --- passes/opt/opt_lut.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 3907285f3e6..877d56bb13d 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -529,12 +529,6 @@ struct OptLutPass : public Pass { log("\n"); log("This pass combines cascaded $lut cells with unused inputs.\n"); log("\n"); - log(" -dlogic :=[:=...]\n"); - log(" preserve connections to dedicated logic cell that has ports\n"); - log(" connected to LUT inputs . this includes\n"); - log(" the case where both LUT and dedicated logic input are connected to\n"); - log(" the same constant.\n"); - log("\n"); log(" -tech ice40\n"); log(" treat the design as a LUT-mapped circuit for the iCE40 architecture\n"); log(" and preserve connections to SB_CARRY as appropriate\n"); From 8e3a718e308049ef997da623768700b2d5ab83e1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:15:19 +0000 Subject: [PATCH 32/33] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 63d973e2df6..11032350a5e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.37+90 +YOSYS_VER := 0.37+119 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 543faed9c8cd7c33bbb407577d56e4b7444ba61c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 9 Feb 2024 08:16:24 +0100 Subject: [PATCH 33/33] Release version 0.38 --- CHANGELOG | 18 +++++++++++++++++- Makefile | 4 ++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 990f9e17d75..bf7d3527294 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,24 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.37 .. Yosys 0.38-dev +Yosys 0.37 .. Yosys 0.38 -------------------------- + * New commands and options + - Added option "-tech" to "opt_lut" pass. + - Added option "-nokeep_prints" to "hierarchy" pass. + - Added option "-nolower" to "async2sync" and "clk2fflogic" pass. + - Added option "-lower" to "chformal" pass. + + * Various + - Added $check cell to represent assertions with messages. + - Allow capturing $print cell output in CXXRTL. + - Added API to overwrite existing pass from plugin. + - Follow the XDG Base Directory Specification for storing history files. + - Without a known top module, derive all deferred modules (hierarchy pass). + - Detect and error out on combinational loops in write_aiger. + + * Verific support + - Added option "-no-split-complex-ports" to "verific -import". Yosys 0.36 .. Yosys 0.37 -------------------------- diff --git a/Makefile b/Makefile index 11032350a5e..37f62e50057 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.37+119 +YOSYS_VER := 0.38 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline a5c7f69.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline a5c7f69.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is #