diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 089e65ca7..74c3e2639 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -32,9 +32,9 @@ jobs: # oldest supported - 'clang-14' - 'gcc-10' - # newest - - 'clang' - - 'gcc' + # newest, make sure to update maximum standard step to match + - 'clang-18' + - 'gcc-13' include: # macOS - os: macos-13 @@ -72,7 +72,7 @@ jobs: # maximum standard, only on newest compilers - name: Build C++20 - if: ${{ matrix.compiler == 'clang' || matrix.compiler == 'gcc'}} + if: ${{ matrix.compiler == 'clang-18' || matrix.compiler == 'gcc-13' }} shell: bash run: | make config-$CC_SHORT diff --git a/Makefile b/Makefile index f2c17d632..f75a05ff4 100644 --- a/Makefile +++ b/Makefile @@ -164,7 +164,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.47+116 +YOSYS_VER := 0.47+149 # 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/appendix/rtlil_text.rst b/docs/source/appendix/rtlil_text.rst index 2c7a82d19..b1bc9c582 100644 --- a/docs/source/appendix/rtlil_text.rst +++ b/docs/source/appendix/rtlil_text.rst @@ -242,7 +242,7 @@ Processes Declares a process, with zero or more attributes, with the given identifier in the enclosing module. The body of a process consists of zero or more -assignments, exactly one switch, and zero or more syncs. +assignments followed by zero or more switches and zero or more syncs. See :ref:`sec:rtlil_process` for an overview of processes. @@ -250,7 +250,7 @@ See :ref:`sec:rtlil_process` for an overview of processes. ::= * ::= process - ::= * ? * * + ::= * * * ::= assign ::= ::= @@ -262,8 +262,8 @@ Switches Switches test a signal for equality against a list of cases. Each case specifies a comma-separated list of signals to check against. If there are no signals in the list, then the case is the default case. The body of a case consists of zero -or more switches and assignments. Both switches and cases may have zero or more -attributes. +or more assignments followed by zero or more switches. Both switches and cases +may have zero or more attributes. .. code:: BNF @@ -272,7 +272,7 @@ attributes. ::= * ::= case ? ::= (, )* - ::= ( | )* + ::= * * ::= end Syncs diff --git a/docs/source/conf.py b/docs/source/conf.py index 0de8cd445..b9a908167 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -56,6 +56,9 @@ if os.getenv("READTHEDOCS"): else: release = yosys_ver todo_include_todos = False +elif os.getenv("YOSYS_DOCS_RELEASE") is not None: + release = yosys_ver + todo_include_todos = False else: release = yosys_ver todo_include_todos = True @@ -87,5 +90,9 @@ def setup(app: Sphinx) -> None: from util.RtlilLexer import RtlilLexer app.add_lexer("RTLIL", RtlilLexer) - from furo_ys.lexers.YoscryptLexer import YoscryptLexer - app.add_lexer("yoscrypt", YoscryptLexer) + try: + from furo_ys.lexers.YoscryptLexer import YoscryptLexer + app.add_lexer("yoscrypt", YoscryptLexer) + except ModuleNotFoundError: + from pygments.lexers.special import TextLexer + app.add_lexer("yoscrypt", TextLexer) diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 170ed560f..2c1910d13 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -31,6 +31,11 @@ void rtlil_frontend_yyerror(char const *s) YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_yyget_lineno(), s); } +void rtlil_frontend_yywarning(char const *s) +{ + YOSYS_NAMESPACE_PREFIX log_warning("In line %d: %s\n", rtlil_frontend_yyget_lineno(), s); +} + YOSYS_NAMESPACE_BEGIN struct RTLILFrontend : public Frontend { diff --git a/frontends/rtlil/rtlil_frontend.h b/frontends/rtlil/rtlil_frontend.h index 189260605..31cfb80b4 100644 --- a/frontends/rtlil/rtlil_frontend.h +++ b/frontends/rtlil/rtlil_frontend.h @@ -42,6 +42,7 @@ YOSYS_NAMESPACE_END extern int rtlil_frontend_yydebug; int rtlil_frontend_yylex(void); void rtlil_frontend_yyerror(char const *s); +void rtlil_frontend_yywarning(char const *s); void rtlil_frontend_yyrestart(FILE *f); int rtlil_frontend_yyparse(void); int rtlil_frontend_yylex_destroy(void); diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y index deb37d9a6..fc7615364 100644 --- a/frontends/rtlil/rtlil_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -344,6 +344,16 @@ assign_stmt: TOK_ASSIGN sigspec sigspec EOL { if (attrbuf.size() != 0) rtlil_frontend_yyerror("dangling attribute"); + + // See https://github.com/YosysHQ/yosys/pull/4765 for discussion on this + // warning + if (!switch_stack.back()->empty()) { + rtlil_frontend_yywarning( + "case rule assign statements after switch statements may cause unexpected behaviour. " + "The assign statement is reordered to come before all switch statements." + ); + } + case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3)); delete $2; delete $3; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 22512c67d..48a88c68f 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2186,12 +2186,6 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma log(" assert condition %s.\n", log_signal(cond)); Cell *cell = module->addAssert(new_verific_id(inst), cond, State::S1); - // Initialize FF feeding condition to 1, in case it is not - // used by rest of design logic, to prevent failing on - // initial uninitialized state - if (cond.is_wire() && !cond.wire->name.isPublic()) - cond.wire->attributes[ID::init] = Const(1,1); - import_attributes(cell->attributes, inst); continue; } @@ -3566,6 +3560,7 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("veri_preserve_assignments", 1); RuntimeFlags::SetVar("veri_preserve_comments", 1); RuntimeFlags::SetVar("veri_preserve_drivers", 1); + RuntimeFlags::SetVar("veri_create_empty_box", 1); // Workaround for VIPER #13851 RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1); diff --git a/kernel/drivertools.h b/kernel/drivertools.h index 079701c35..8929c3426 100644 --- a/kernel/drivertools.h +++ b/kernel/drivertools.h @@ -364,7 +364,7 @@ public: unsigned int hash() const { - unsigned int inner; + unsigned int inner = 0; switch (type_) { case DriveType::NONE: @@ -385,6 +385,9 @@ public: case DriveType::MULTIPLE: inner = multiple_.hash(); break; + default: + log_abort(); + break; } return mkhash((unsigned int)type_, inner); } @@ -912,7 +915,7 @@ public: unsigned int hash() const { - unsigned int inner; + unsigned int inner = 0; switch (type_) { case DriveType::NONE: @@ -933,6 +936,9 @@ public: case DriveType::MULTIPLE: inner = multiple_.hash(); break; + default: + log_abort(); + break; } return mkhash((unsigned int)type_, inner); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 350a6afe3..b4ce02d57 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -814,6 +814,7 @@ struct RTLIL::AttrObject void set_bool_attribute(const RTLIL::IdString &id, bool value=true); bool get_bool_attribute(const RTLIL::IdString &id) const; + [[deprecated("Use Module::get_blackbox_attribute() instead.")]] bool get_blackbox_attribute(bool ignore_wb=false) const { return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); } @@ -1291,6 +1292,10 @@ public: virtual void optimize(); virtual void makeblackbox(); + bool get_blackbox_attribute(bool ignore_wb=false) const { + return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); + } + void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); void new_connections(const std::vector &new_conn); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 00df6e1d6..34d40cb99 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1019,8 +1019,10 @@ struct HierarchyPass : public Pass { if (top_mod == nullptr) for (auto mod : design->modules()) - if (mod->get_bool_attribute(ID::top)) + if (mod->get_bool_attribute(ID::top)) { + log("Attribute `top' found on module `%s'. Setting top module to %s.\n", log_id(mod), log_id(mod)); top_mod = mod; + } if (top_mod == nullptr) { diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index fa5c2a825..cb67d6329 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -36,3 +36,4 @@ $(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2softlogic.v)) $(eval $(call add_share_file,share/choices,techlibs/common/choices/kogge-stone.v)) +$(eval $(call add_share_file,share/choices,techlibs/common/choices/han-carlson.v)) diff --git a/techlibs/common/choices/han-carlson.v b/techlibs/common/choices/han-carlson.v new file mode 100644 index 000000000..2ddcf75e9 --- /dev/null +++ b/techlibs/common/choices/han-carlson.v @@ -0,0 +1,57 @@ +(* techmap_celltype = "$lcu" *) +module _80_lcu_han_carlson (P, G, CI, CO); + parameter WIDTH = 2; + + (* force_downto *) + input [WIDTH-1:0] P, G; + input CI; + + (* force_downto *) + output [WIDTH-1:0] CO; + + integer i, j; + (* force_downto *) + reg [WIDTH-1:0] p, g; + + always @* begin + i = 0; + p = P; + g = G; + + // in almost all cases CI will be constant zero + g[0] = g[0] | (p[0] & CI); + if (i < $clog2(WIDTH)) begin + + // First layer: BK + for (j = WIDTH - 1; j >= 0; j = j - 1) begin + if (j % 2 == 1) begin + g[j] = g[j] | p[j] & g[j - 1]; + p[j] = p[j] & p[j - 1]; + end + end + + // Inner (log(WIDTH) - 1) layers: KS + for (i = 1; i < $clog2(WIDTH); i = i + 1) begin + for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin + if (j % 2 == 1) begin + g[j] = g[j] | p[j] & g[j - 2**i]; + p[j] = p[j] & p[j - 2**i]; + end + end + end + + // Last layer: BK + if (i < ($clog2(WIDTH) + 1)) begin + for (j = WIDTH - 1; j >= 0; j = j - 1) begin + if ((j % 2 == 0) && (j > 0)) begin + g[j] = g[j] | p[j] & g[j - 1]; + p[j] = p[j] & p[j - 1]; + end + end + end + + end + end + + assign CO = g; +endmodule diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh index 2b26d8c98..b997fa12d 100755 --- a/tests/gen-tests-makefile.sh +++ b/tests/gen-tests-makefile.sh @@ -20,6 +20,13 @@ generate_ys_test() { generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file%.*}.log $yosys_args_ $ys_file" } +# $ generate_tcl_test tcl_file [yosys_args] +generate_tcl_test() { + tcl_file=$1 + yosys_args_=${2:-} + generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file%.*}.log $yosys_args_ $tcl_file" +} + # $ generate_bash_test bash_file generate_bash_test() { bash_file=$1 @@ -29,6 +36,7 @@ generate_bash_test() { # $ generate_tests [-y|--yosys-scripts] [-s|--prove-sv] [-b|--bash] [-a|--yosys-args yosys_args] generate_tests() { do_ys=false + do_tcl=false do_sv=false do_sh=false yosys_args="" @@ -40,6 +48,10 @@ generate_tests() { do_ys=true shift ;; + -t|--tcl-scripts) + do_tcl=true + shift + ;; -s|--prove-sv) do_sv=true shift @@ -59,7 +71,7 @@ generate_tests() { esac done - if [[ ! ( $do_ys = true || $do_sv = true || $do_sh = true ) ]]; then + if [[ ! ( $do_ys = true || $do_tcl = true || $do_sv = true || $do_sh = true ) ]]; then echo >&2 "Error: No file types selected" exit 1 fi @@ -72,6 +84,11 @@ generate_tests() { generate_ys_test "$x" "$yosys_args" done fi; + if [[ $do_tcl = true ]]; then + for x in *.tcl; do + generate_tcl_test "$x" "$yosys_args" + done + fi; if [[ $do_sv = true ]]; then for x in *.sv; do if [ ! -f "${x%.sv}.ys" ]; then diff --git a/tests/techmap/han-carlson.tcl b/tests/techmap/han-carlson.tcl new file mode 100644 index 000000000..0d9068b5e --- /dev/null +++ b/tests/techmap/han-carlson.tcl @@ -0,0 +1,15 @@ +yosys -import + +read_verilog +/choices/han-carlson.v +read_verilog -icells lcu_refined.v +design -save init + +for {set i 1} {$i <= 16} {incr i} { + design -load init + chparam -set WIDTH $i + yosys proc + opt_clean + equiv_make lcu _80_lcu_han_carlson equiv + equiv_simple equiv + equiv_status -assert equiv +} diff --git a/tests/techmap/kogge-stone.tcl b/tests/techmap/kogge-stone.tcl new file mode 100644 index 000000000..1209b1338 --- /dev/null +++ b/tests/techmap/kogge-stone.tcl @@ -0,0 +1,15 @@ +yosys -import + +read_verilog +/choices/kogge-stone.v +read_verilog -icells lcu_refined.v +design -save init + +for {set i 1} {$i <= 16} {incr i} { + design -load init + chparam -set WIDTH $i + yosys proc + opt_clean + equiv_make lcu _80_lcu_kogge_stone equiv + equiv_simple equiv + equiv_status -assert equiv +} diff --git a/tests/techmap/kogge-stone.ys b/tests/techmap/kogge-stone.ys deleted file mode 100644 index fc3637f10..000000000 --- a/tests/techmap/kogge-stone.ys +++ /dev/null @@ -1 +0,0 @@ -test_cell -s 1711533949 -n 10 -map +/techmap.v -map +/choices/kogge-stone.v $lcu diff --git a/tests/techmap/lcu_refined.v b/tests/techmap/lcu_refined.v new file mode 100644 index 000000000..e0747f3f2 --- /dev/null +++ b/tests/techmap/lcu_refined.v @@ -0,0 +1,13 @@ +module lcu (P, G, CI, CO); + parameter WIDTH = 2; + + input [WIDTH-1:0] P, G; + input CI; + + output [WIDTH-1:0] CO; + + reg [WIDTH-1:0] p, g; + + \$lcu #(.WIDTH(WIDTH)) impl (.P(P), .G(G), .CI(CI), .CO(CO)); + +endmodule diff --git a/tests/techmap/run-test.sh b/tests/techmap/run-test.sh index 581847ab0..16741cace 100755 --- a/tests/techmap/run-test.sh +++ b/tests/techmap/run-test.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash set -eu source ../gen-tests-makefile.sh -run_tests --yosys-scripts --bash --yosys-args "-e 'select out of bounds'" +run_tests --yosys-scripts --tcl-scripts --bash --yosys-args "-e 'select out of bounds'" diff --git a/tests/verific/blackbox.ys b/tests/verific/blackbox.ys new file mode 100644 index 000000000..fbf689e3d --- /dev/null +++ b/tests/verific/blackbox.ys @@ -0,0 +1,24 @@ +verific -sv -lib <