From bd439fc5245374c41e6073a1f70e5691de28eda6 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Thu, 23 Jan 2025 13:40:32 -0800 Subject: [PATCH] Reapply "Merge upstream" This reverts commit e73d51dbf08605e0f9df1de955447b784e1b0f10. --- .github/actions/setup-build-env/action.yml | 2 +- .github/workflows/test-compile.yml | 9 ++--- COPYING | 2 +- Makefile | 2 +- docs/source/conf.py | 23 +++++++++++ docs/source/yosys_internals/hashing.rst | 19 +++++++-- frontends/verific/verific.cc | 3 +- kernel/hashlib.h | 46 +++++++++++----------- kernel/register.cc | 2 +- kernel/rtlil.h | 14 +++++-- kernel/scopeinfo.h | 17 +++++--- kernel/yosys.cc | 2 +- libs/json11/json11.cpp | 1 + passes/fsm/fsm_extract.cc | 14 +++++++ passes/techmap/flatten.cc | 3 ++ 15 files changed, 110 insertions(+), 49 deletions(-) diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index 30bc2326a..b40eac0bd 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -8,7 +8,7 @@ runs: shell: bash run: | sudo apt-get update - sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libnsl-dev libbz2-dev libdwarf-dev libelf-dev elfutils libdw-dev + sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libbz2-dev libnsl-dev libdwarf-dev libelf-dev elfutils libdw-dev - name: Install macOS Dependencies if: runner.os == 'macOS' diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 74c3e2639..203c20bb4 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -30,18 +30,15 @@ jobs: - ubuntu-latest compiler: # oldest supported - - 'clang-14' + - 'clang-10' - 'gcc-10' # newest, make sure to update maximum standard step to match - - 'clang-18' + - 'clang-19' - 'gcc-13' include: # macOS - os: macos-13 compiler: 'clang' - # oldest clang not available on ubuntu-latest - - os: ubuntu-20.04 - compiler: 'clang-10' fail-fast: false steps: - name: Checkout Yosys @@ -72,7 +69,7 @@ jobs: # maximum standard, only on newest compilers - name: Build C++20 - if: ${{ matrix.compiler == 'clang-18' || matrix.compiler == 'gcc-13' }} + if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-13' }} shell: bash run: | make config-$CC_SHORT diff --git a/COPYING b/COPYING index e8b123be2..2d962dddc 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ ISC License -Copyright (C) 2012 - 2020 Claire Xenia Wolf +Copyright (C) 2012 - 2025 Claire Xenia Wolf Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/Makefile b/Makefile index 482798db9..20c463064 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.48+77 +YOSYS_VER := 0.48+98 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo diff --git a/docs/source/conf.py b/docs/source/conf.py index 8c8555b71..de0b9cf4d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -11,6 +11,29 @@ yosys_ver = "0.48" # select HTML theme html_theme = 'furo-ys' html_css_files = ['custom.css'] +html_theme_options: dict[str] = { + "source_repository": "https://github.com/YosysHQ/yosys/", + "source_branch": "main", + "source_directory": "docs/source/", +} + +# try to fix the readthedocs detection +html_context: dict[str] = { + "READTHEDOCS": True, + "display_github": True, + "github_user": "YosysHQ", + "github_repo": "yosys", + "slug": "yosys", +} + +# override source_branch if not main +git_slug = os.getenv("READTHEDOCS_VERSION_NAME") +if git_slug not in [None, "latest", "stable"]: + html_theme_options["source_branch"] = git_slug + +# edit only works on branches, not tags +if os.getenv("READTHEDOCS_VERSION_TYPE", "branch") != "branch": + html_theme_options["top_of_page_buttons"] = ["view"] # These folders are copied to the documentation's HTML output html_static_path = ['_static', "_images"] diff --git a/docs/source/yosys_internals/hashing.rst b/docs/source/yosys_internals/hashing.rst index 338ee5fd6..c6e22c0cf 100644 --- a/docs/source/yosys_internals/hashing.rst +++ b/docs/source/yosys_internals/hashing.rst @@ -97,8 +97,8 @@ Making a type hashable Let's first take a look at the external interface on a simplified level. Generally, to get the hash for ``T obj``, you would call the utility function -``run_hash(const T& obj)``, corresponding to ``hash_top_ops::hash(obj)``, -the default implementation of which is ``hash_ops::hash_into(Hasher(), obj)``. +``run_hash(const T& obj)``, corresponding to ``hash_ops::hash(obj)``, +the default implementation of which uses ``hash_ops::hash_into(Hasher(), obj)``. ``Hasher`` is the class actually implementing the hash function, hiding its initialized internal state, and passing it out on ``hash_t yield()`` with perhaps some finalization steps. @@ -121,8 +121,14 @@ size containers like ``std::vector`` the size of the container is hashed first. That is also how implementing hashing for a custom record data type should be - unless there is strong reason to do otherwise, call ``h.eat(m)`` on the ``Hasher h`` you have received for each member in sequence and ``return -h;``. If you do have a strong reason to do so, look at how -``hash_top_ops`` is implemented in ``kernel/rtlil.h``. +h;``. + +The ``hash_ops::hash(obj)`` method is not indended to be called when +context of implementing the hashing for a record or other compound type. +When writing it, you should connect it to ``hash_ops::hash_into(Hasher h)`` +as shown below. If you have a strong reason to do so, and you have +to create a special implementation for top-level hashing, look at how +``hash_ops::hash(...)`` is implemented in ``kernel/rtlil.h``. Porting plugins from the legacy interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -148,6 +154,11 @@ based on the existance and value of `YS_HASHING_VERSION`. h.eat(b); return h; } + Hasher T::hash() const { + Hasher h; + h.eat(*this); + return h; + } #else #error "Unsupported hashing interface" #endif diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index fe83e3666..ebd3d53eb 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1535,7 +1535,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma log("Importing module %s.\n", RTLIL::id2cstr(module->name)); } import_attributes(module->attributes, nl, nl); - module->set_string_attribute(ID::hdlname, nl->CellBaseName()); + if (module->name.isPublic()) + module->set_string_attribute(ID::hdlname, nl->CellBaseName()); module->set_string_attribute(ID(library), nl->Owner()->Owner()->Name()); #ifdef VERIFIC_VHDL_SUPPORT if (nl->IsFromVhdl()) { diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 4acfa7f2d..6e3eb32a4 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -61,19 +61,9 @@ namespace legacy { } }; -/** - * Hash a type with an accumulator in a record or array context - */ template struct hash_ops; -/** - * Hash a single instance in isolation. - * Can have explicit specialization, but the default redirects to hash_ops - */ -template -struct hash_top_ops; - inline unsigned int mkhash_xorshift(unsigned int a) { if (sizeof(a) == 4) { a ^= a << 13; @@ -147,15 +137,14 @@ private: using Hasher = HasherDJB32; -template -struct hash_top_ops { - static inline bool cmp(const T &a, const T &b) { - return hash_ops::cmp(a, b); - } - static inline Hasher hash(const T &a) { - return hash_ops::hash_into(a, Hasher()); - } -}; +// Boilerplate compressor for trivially implementing +// top-level hash method with hash_into +#define HASH_TOP_LOOP_FST [[nodiscard]] static inline Hasher hash +#define HASH_TOP_LOOP_SND { \ + Hasher h; \ + h = hash_into(a, h); \ + return h; \ +} template struct hash_ops { @@ -183,6 +172,7 @@ struct hash_ops { return a.hash_into(h); } } + HASH_TOP_LOOP_FST (const T &a) HASH_TOP_LOOP_SND }; template struct hash_ops> { @@ -194,6 +184,7 @@ template struct hash_ops> { h = hash_ops::hash_into(a.second, h); return h; } + HASH_TOP_LOOP_FST (std::pair a) HASH_TOP_LOOP_SND }; template struct hash_ops> { @@ -211,6 +202,7 @@ template struct hash_ops> { h = element_ops_t::hash_into(std::get(a), h); return h; } + HASH_TOP_LOOP_FST (std::tuple a) HASH_TOP_LOOP_SND }; template struct hash_ops> { @@ -223,6 +215,7 @@ template struct hash_ops> { h.eat(k); return h; } + HASH_TOP_LOOP_FST (std::vector a) HASH_TOP_LOOP_SND }; template struct hash_ops> { @@ -234,6 +227,7 @@ template struct hash_ops> { h = hash_ops::hash_into(k, h); return h; } + HASH_TOP_LOOP_FST (std::array a) HASH_TOP_LOOP_SND }; struct hash_cstr_ops { @@ -245,6 +239,7 @@ struct hash_cstr_ops { h.hash32(*(a++)); return h; } + HASH_TOP_LOOP_FST (const char *a) HASH_TOP_LOOP_SND }; template <> struct hash_ops : hash_cstr_ops {}; @@ -256,6 +251,7 @@ struct hash_ptr_ops { [[nodiscard]] static inline Hasher hash_into(const void *a, Hasher h) { return hash_ops::hash_into((uintptr_t)a, h); } + HASH_TOP_LOOP_FST (const void *a) HASH_TOP_LOOP_SND }; struct hash_obj_ops { @@ -270,6 +266,8 @@ struct hash_obj_ops { h.eat(0); return h; } + template + HASH_TOP_LOOP_FST (const T *a) HASH_TOP_LOOP_SND }; /** * If you find yourself using this function, think hard @@ -280,7 +278,7 @@ struct hash_obj_ops { template [[nodiscard]] Hasher::hash_t run_hash(const T& obj) { - return hash_top_ops::hash(obj).yield(); + return hash_ops::hash(obj).yield(); } /** Refer to docs/source/yosys_internals/hashing.rst */ @@ -352,10 +350,10 @@ inline unsigned int hashtable_size(unsigned int min_size) throw std::length_error("hash table exceeded maximum size."); } -template> class dict; -template> class idict; -template> class pool; -template> class mfp; +template> class dict; +template> class idict; +template> class pool; +template> class mfp; template class dict { diff --git a/kernel/register.cc b/kernel/register.cc index d6e765ce4..11cf5b0e4 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -1221,7 +1221,7 @@ struct LicensePass : public Pass { log(" | |\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); log(" | |\n"); - log(" | Copyright (C) 2012 - 2024 Claire Xenia Wolf |\n"); + log(" | Copyright (C) 2012 - 2025 Claire Xenia Wolf |\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"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 06b7cd08d..4ddce7d25 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -398,13 +398,16 @@ struct RTLIL::IdString namespace hashlib { template <> - struct hash_top_ops { + struct hash_ops { static inline bool cmp(const RTLIL::IdString &a, const RTLIL::IdString &b) { return a == b; } - static inline Hasher hash(const RTLIL::IdString id) { + [[nodiscard]] static inline Hasher hash(const RTLIL::IdString id) { return id.hash_top(); } + [[nodiscard]] static inline Hasher hash_into(const RTLIL::IdString id, Hasher h) { + return id.hash_into(h); + } }; }; @@ -926,13 +929,16 @@ struct RTLIL::SigBit namespace hashlib { template <> - struct hash_top_ops { + struct hash_ops { static inline bool cmp(const RTLIL::SigBit &a, const RTLIL::SigBit &b) { return a == b; } - static inline Hasher hash(const RTLIL::SigBit sb) { + [[nodiscard]] static inline Hasher hash(const RTLIL::SigBit sb) { return sb.hash_top(); } + [[nodiscard]] static inline Hasher hash_into(const RTLIL::SigBit sb, Hasher h) { + return sb.hash_into(h); + } }; }; diff --git a/kernel/scopeinfo.h b/kernel/scopeinfo.h index 703dc315f..3bc1a8162 100644 --- a/kernel/scopeinfo.h +++ b/kernel/scopeinfo.h @@ -337,12 +337,14 @@ template std::vector parse_hdlname(const O* object) { std::vector path; - if (!object->name.isPublic()) - return path; for (auto const &item : object->get_hdlname_attribute()) path.push_back("\\" + item); - if (path.empty()) + if (path.empty() && object->name.isPublic()) path.push_back(object->name); + if (!path.empty() && !(object->name.isPublic() || object->name.begins_with("$paramod") || object->name.begins_with("$abstract"))) { + path.pop_back(); + path.push_back(object->name); + } return path; } @@ -351,17 +353,22 @@ std::pair, IdString> parse_scopename(const O* object) { std::vector path; IdString trailing = object->name; - if (object->name.isPublic()) { + if (object->name.isPublic() || object->name.begins_with("$paramod") || object->name.begins_with("$abstract")) { for (auto const &item : object->get_hdlname_attribute()) path.push_back("\\" + item); if (!path.empty()) { trailing = path.back(); path.pop_back(); } + } else if (object->has_attribute(ID::hdlname)) { + for (auto const &item : object->get_hdlname_attribute()) + path.push_back("\\" + item); + if (!path.empty()) { + path.pop_back(); + } } else { for (auto const &item : split_tokens(object->get_string_attribute(ID(scopename)), " ")) path.push_back("\\" + item); - } return {path, trailing}; } diff --git a/kernel/yosys.cc b/kernel/yosys.cc index cd98cdc0a..ef81d042c 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -144,7 +144,7 @@ void yosys_banner() log("\n"); log(" /----------------------------------------------------------------------------\\\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); - log(" | Copyright (C) 2012 - 2024 Claire Xenia Wolf |\n"); + log(" | Copyright (C) 2012 - 2025 Claire Xenia Wolf |\n"); log(" | Distributed under an ISC-like license, type \"license\" to see terms |\n"); log(" \\----------------------------------------------------------------------------/\n"); log(" %s\n", yosys_version_str); diff --git a/libs/json11/json11.cpp b/libs/json11/json11.cpp index 189e63881..cdd81c6a9 100644 --- a/libs/json11/json11.cpp +++ b/libs/json11/json11.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace json11 { diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 6114dd34b..143ae7b54 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -377,6 +377,13 @@ static void extract_fsm(RTLIL::Wire *wire) fsm_cell->setPort(ID::CTRL_OUT, ctrl_out); fsm_cell->parameters[ID::NAME] = RTLIL::Const(wire->name.str()); fsm_cell->attributes = wire->attributes; + if(fsm_cell->attributes.count(ID::hdlname)) { + auto hdlname = fsm_cell->get_hdlname_attribute(); + hdlname.pop_back(); + fsm_cell->set_hdlname_attribute(hdlname); + fsm_cell->set_string_attribute(ID(scopename), fsm_cell->get_string_attribute(ID::hdlname)); + fsm_cell->attributes.erase(ID::hdlname); + } fsm_data.copy_to_cell(fsm_cell); // rename original state wire @@ -385,6 +392,13 @@ static void extract_fsm(RTLIL::Wire *wire) wire->attributes.erase(ID::fsm_encoding); wire->name = stringf("$fsm$oldstate%s", wire->name.c_str()); module->wires_[wire->name] = wire; + if(wire->attributes.count(ID::hdlname)) { + auto hdlname = wire->get_hdlname_attribute(); + hdlname.pop_back(); + wire->set_hdlname_attribute(hdlname); + wire->set_string_attribute(ID(scopename), wire->get_string_attribute(ID::hdlname)); + wire->attributes.erase(ID::hdlname); + } // unconnect control outputs from old drivers diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index 7e14a979e..23bc9638a 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -360,6 +360,9 @@ struct FlattenPass : public Pass { FlattenWorker worker; + if (design->scratchpad.count("flatten.separator")) + worker.separator = design->scratchpad_get_string("flatten.separator"); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-wb") {