diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 66c0b1971..e4c776ed9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -43,7 +43,7 @@ body: attributes: value: > When providing steps to reproduce the issue, please ensure that the issue - is reproducible in the current git master of Yosys. Also ensure to + is reproducible in the current git main of Yosys. Also ensure to provide all necessary source files needed. diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml index e8064e485..00e5309bf 100644 --- a/.github/workflows/test-docs.yml +++ b/.github/workflows/test-docs.yml @@ -3,7 +3,7 @@ name: Build and test doc code samples on: pull_request: branches: - - master + - main jobs: test-docs: diff --git a/Makefile b/Makefile index 624cbe28e..aa55ac525 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ - +# CONFIG := none # CONFIG := clang CONFIG := gcc # CONFIG := afl-gcc @@ -141,7 +141,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+124 +YOSYS_VER := 0.39+147 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -217,7 +217,7 @@ endif ifeq ($(CONFIG),clang) CXX = clang++ CXXFLAGS += -std=$(CXXSTD) -Os -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -Wno-c++11-narrowing $(ABC_ARCHFLAGS)" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" ifneq ($(SANITIZER),) $(info [Clang Sanitizer] $(SANITIZER)) @@ -265,7 +265,7 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" else ifeq ($(CONFIG),emcc) CXX = emcc CXXFLAGS := -std=$(CXXSTD) $(filter-out -fPIC -ggdb,$(CXXFLAGS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8 -Wno-c++11-narrowing" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" EMCC_CXXFLAGS := -Os -Wno-warn-absolute-paths EMCC_LINKFLAGS := --embed-file share EMCC_LINKFLAGS += -s NO_EXIT_RUNTIME=1 @@ -317,7 +317,7 @@ CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) -Os -D_WASI_EMULATED_PROCESS_CLOCKS $(fi LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS)) LIBS := -lwasi-emulated-process-clocks $(filter-out -lrt,$(LIBS)) ABCMKARGS += AR="$(AR)" RANLIB="$(RANLIB)" -ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -D_WASI_EMULATED_PROCESS_CLOCKS -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING -DABC_NO_RLIMIT -Wno-c++11-narrowing" +ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -D_WASI_EMULATED_PROCESS_CLOCKS -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING -DABC_NO_RLIMIT" ABCMKARGS += OPTFLAGS="-Os" EXE = .wasm @@ -360,8 +360,12 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gcc" CXX="$(CXX)" EXE = .exe -else ifneq ($(CONFIG),none) -$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64) +else ifeq ($(CONFIG),none) +CXXFLAGS += -std=$(CXXSTD) -Os +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" + +else +$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64, none) endif ifeq ($(ENABLE_LIBYOSYS),1) @@ -1127,6 +1131,9 @@ echo-git-rev: echo-abc-rev: @echo "$(ABCREV)" +echo-cxx: + @echo "$(CXX)" + -include libs/*/*.d -include frontends/*/*.d -include passes/*/*.d diff --git a/README.md b/README.md index c330d4f74..4647efbe9 100644 --- a/README.md +++ b/README.md @@ -105,11 +105,17 @@ For Cygwin use the following command to install all prerequisites, or select the setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build,zlib-devel -To configure the build system to use a specific compiler, use one of +The environment variable `CXX` can be used to control the C++ compiler used, or +run one of the following: $ make config-clang $ make config-gcc +Note that these will result in `make` ignoring the `CXX` environment variable, +unless `CXX` is assigned in the call to make, e.g. + + $ make CXX=$CXX + For other compilers and build configurations it might be necessary to make some changes to the config section of the Makefile. diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc index 9989feed5..1c163dba5 100644 --- a/backends/jny/jny.cc +++ b/backends/jny/jny.cc @@ -124,7 +124,7 @@ struct JnyWriter design->sort(); f << "{\n"; - f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\",\n"; + f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\",\n"; f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_version_str).c_str()); f << " \"version\": \"0.0.1\",\n"; f << " \"invocation\": \"" << escape_string(invk) << "\",\n"; @@ -426,7 +426,7 @@ struct JnyBackend : public Backend { log(" Don't include property information in the netlist output.\n"); log("\n"); log("The JSON schema for JNY output files is located in the \"jny.schema.json\" file\n"); - log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json\"\n"); + log("which is located at \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\"\n"); log("\n"); } diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index 799b4ec48..916bef9fa 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -633,9 +633,9 @@ with the mapping to ``SB_RAM40_4K`` done by :cmd:ref:`techmap` using into flip flops (the ``logic fallback``) with :cmd:ref:`memory_map`. .. |techlibs/ice40/brams.txt| replace:: :file:`techlibs/ice40/brams.txt` -.. _techlibs/ice40/brams.txt: https://github.com/YosysHQ/yosys/tree/master/techlibs/ice40/brams.txt +.. _techlibs/ice40/brams.txt: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams.txt .. |techlibs/ice40/brams_map.v| replace:: :file:`techlibs/ice40/brams_map.v` -.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/master/techlibs/ice40/brams_map.v +.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams_map.v .. literalinclude:: /cmd/synth_ice40.rst :language: yoscrypt diff --git a/docs/source/test_suites.rst b/docs/source/test_suites.rst index 2edb0e67d..7a6b74977 100644 --- a/docs/source/test_suites.rst +++ b/docs/source/test_suites.rst @@ -16,8 +16,8 @@ Automatic testing .. _Yosys Git repo: https://github.com/YosysHQ/yosys -.. |test-linux| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-linux.yml/badge.svg?branch=master -.. |test-macos| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-macos.yml/badge.svg?branch=master +.. |test-linux| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-linux.yml/badge.svg?branch=main +.. |test-macos| image:: https://github.com/YosysHQ/yosys/actions/workflows/test-macos.yml/badge.svg?branch=main For up to date information, including OS versions, refer to `the git actions page`_. diff --git a/docs/source/using_yosys/more_scripting/interactive_investigation.rst b/docs/source/using_yosys/more_scripting/interactive_investigation.rst index ed798d6b6..f56543beb 100644 --- a/docs/source/using_yosys/more_scripting/interactive_investigation.rst +++ b/docs/source/using_yosys/more_scripting/interactive_investigation.rst @@ -18,7 +18,7 @@ in the circuit diagrams generated by it. The code used is included in the Yosys code base under |code_examples/show|_. .. |code_examples/show| replace:: :file:`docs/source/code_examples/show` -.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/show +.. _code_examples/show: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/show A simple circuit ^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ The code used is included in the Yosys code base under |code_examples/scrambler|_. .. |code_examples/scrambler| replace:: :file:`docs/source/code_examples/scrambler` -.. _code_examples/scrambler: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/scrambler +.. _code_examples/scrambler: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/scrambler Changing design hierarchy ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/using_yosys/more_scripting/model_checking.rst b/docs/source/using_yosys/more_scripting/model_checking.rst index 0b97d384e..92a9d85ce 100644 --- a/docs/source/using_yosys/more_scripting/model_checking.rst +++ b/docs/source/using_yosys/more_scripting/model_checking.rst @@ -29,7 +29,7 @@ Let's take a look at an example included in the Yosys code base under |code_examples/synth_flow|_: .. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` -.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/synth_flow +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow .. literalinclude:: /code_examples/synth_flow/techmap_01_map.v :language: verilog @@ -81,7 +81,7 @@ The code used in this section is included in the Yosys code base under |code_examples/axis|_. .. |code_examples/axis| replace:: :file:`docs/source/code_examples/axis` -.. _code_examples/axis: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/axis +.. _code_examples/axis: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/axis The following AXI4 Stream Master has a bug. But the bug is not exposed if the slave keeps ``tready`` asserted all the time. (Something a test bench might do.) diff --git a/docs/source/using_yosys/more_scripting/selections.rst b/docs/source/using_yosys/more_scripting/selections.rst index d4def881c..6aa3465cc 100644 --- a/docs/source/using_yosys/more_scripting/selections.rst +++ b/docs/source/using_yosys/more_scripting/selections.rst @@ -405,7 +405,7 @@ those cases selection variables must be used to capture more complex selections. Example code from |code_examples/selections|_: .. |code_examples/selections| replace:: :file:`docs/source/code_examples/selections` -.. _code_examples/selections: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/selections +.. _code_examples/selections: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/selections .. literalinclude:: /code_examples/selections/select.v :language: verilog diff --git a/docs/source/using_yosys/synthesis/cell_libs.rst b/docs/source/using_yosys/synthesis/cell_libs.rst index a72384537..476269abf 100644 --- a/docs/source/using_yosys/synthesis/cell_libs.rst +++ b/docs/source/using_yosys/synthesis/cell_libs.rst @@ -21,7 +21,7 @@ detail in the :doc:`/getting_started/example_synth` document. To learn more about these commands, check out :ref:`interactive_show`. -.. _example project: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/intro +.. _example project: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/intro A simple counter ~~~~~~~~~~~~~~~~ diff --git a/docs/source/using_yosys/synthesis/extract.rst b/docs/source/using_yosys/synthesis/extract.rst index 678efba86..bbe1870df 100644 --- a/docs/source/using_yosys/synthesis/extract.rst +++ b/docs/source/using_yosys/synthesis/extract.rst @@ -15,7 +15,7 @@ The extract pass Example code can be found in |code_examples/macc|_. .. |code_examples/macc| replace:: :file:`docs/source/code_examples/macc` -.. _code_examples/macc: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/macc +.. _code_examples/macc: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/macc .. literalinclude:: /code_examples/macc/macc_simple_test.ys diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 7df75fb88..3dbafeaab 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -36,7 +36,7 @@ Example |code_examples/synth_flow|_. .. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` -.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/synth_flow +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow .. figure:: /_images/code_examples/synth_flow/memory_01.* :class: width-helper @@ -92,7 +92,7 @@ leftover memory cells unable to be converted are then picked up by For more on the lib format for :cmd:ref:`memory_libmap`, see `passes/memory/memlib.md -`_ +`_ Supported memory patterns ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst index 785be7adc..b49834380 100644 --- a/docs/source/using_yosys/synthesis/proc.rst +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -31,7 +31,7 @@ Example |code_examples/synth_flow|_. .. |code_examples/synth_flow| replace:: :file:`docs/source/code_examples/synth_flow` -.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/synth_flow +.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow .. literalinclude:: /code_examples/synth_flow/proc_01.v :language: verilog diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 2c159e3f0..68e1740be 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -24,7 +24,7 @@ Code examples from this section are included in the |code_examples/extensions|_ directory of the Yosys source code. .. |code_examples/extensions| replace:: :file:`docs/source/code_examples/extensions` -.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/extensions +.. _code_examples/extensions: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/extensions Program components and data formats @@ -254,7 +254,7 @@ The following is the complete code of the "stubnets" example module. It is included in the Yosys source distribution under |code_examples/stubnets|_. .. |code_examples/stubnets| replace:: :file:`docs/source/code_examples/stubnets` -.. _code_examples/stubnets: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/stubnets +.. _code_examples/stubnets: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/stubnets .. literalinclude:: /code_examples/stubnets/stubnets.cc :language: c++ diff --git a/docs/source/yosys_internals/techmap.rst b/docs/source/yosys_internals/techmap.rst index ef2bbd87a..ab161ed92 100644 --- a/docs/source/yosys_internals/techmap.rst +++ b/docs/source/yosys_internals/techmap.rst @@ -16,7 +16,7 @@ Code examples used in this document are included in the Yosys code base under |code_examples/techmap|_. .. |code_examples/techmap| replace:: :file:`docs/source/code_examples/techmap` -.. _code_examples/techmap: https://github.com/YosysHQ/yosys/tree/master/docs/source/code_examples/techmap +.. _code_examples/techmap: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/techmap Mapping OR3X1 diff --git a/guidelines/Windows b/guidelines/Windows index 2af0620fa..c4548c37c 100644 --- a/guidelines/Windows +++ b/guidelines/Windows @@ -44,7 +44,7 @@ Visual Studio builds are not directly supported by build scripts, but they are s 1. Easy way - - Go to https://github.com/YosysHQ/yosys/actions/workflows/vs.yml?query=branch%3Amaster + - Go to https://github.com/YosysHQ/yosys/actions/workflows/vs.yml?query=branch%3Amain - Click on the most recent completed run - In Artifacts region find vcxsrc and click on it to download - Unpack downloaded ZIP file diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 2ed0d5036..09cdfd55b 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -307,6 +307,87 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) } } +void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + log_assert(cell->type == ID($mem_v2)); + Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE); + int n_rd_ports = cell->getParam(ID::RD_PORTS).as_int(); + int abits = cell->getParam(ID::ABITS).as_int(); + int width = cell->getParam(ID::WIDTH).as_int(); + + for (int i = 0; i < n_rd_ports; i++) { + if (rd_clk_enable[i] != State::S0) { + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::RD_ARST, i, ID::RD_DATA, i * width + k, -1); + continue; + } + + for (int j = 0; j < abits; j++) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::RD_ADDR, i * abits + j, + ID::RD_DATA, i * width + k, -1); + } +} + +void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + log_assert(cell->type.in(ID($memrd), ID($memrd_v2))); + int abits = cell->getParam(ID::ABITS).as_int(); + int width = cell->getParam(ID::WIDTH).as_int(); + + if (cell->getParam(ID::CLK_ENABLE).as_bool()) { + if (cell->type == ID($memrd_v2)) { + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ARST, 0, ID::DATA, k, -1); + } + return; + } + + for (int j = 0; j < abits; j++) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ADDR, j, ID::DATA, k, -1); +} + +void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + if (cell->type == ID($mem_v2)) + packed_mem_op(db, cell); + else if (cell->type.in(ID($memrd), ID($memrd_v2))) + memrd_op(db, cell); + else if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit))) + return; /* no edges here */ + else + log_abort(); +} + +void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int width = cell->getPort(ID::Q).size(); + + if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) { + for (int k = 0; k < width; k++) { + db->add_edge(cell, ID::D, k, ID::Q, k, -1); + db->add_edge(cell, ID::EN, 0, ID::Q, k, -1); + } + } + + if (cell->hasPort(ID::CLR)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::CLR, 0, ID::Q, k, -1); + if (cell->hasPort(ID::SET)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::SET, 0, ID::Q, k, -1); + if (cell->hasPort(ID::ALOAD)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ALOAD, 0, ID::Q, k, -1); + if (cell->hasPort(ID::AD)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::AD, k, ID::Q, k, -1); + if (cell->hasPort(ID::ARST)) + for (int k = 0; k < width; k++) + db->add_edge(cell, ID::ARST, 0, ID::Q, k, -1); +} + PRIVATE_NAMESPACE_END bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) @@ -361,6 +442,18 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } + if (cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit))) { + mem_op(this, cell); + return true; + } + + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + ff_op(this, cell); + return true; + } + + // FIXME: $mul $div $mod $divfloor $modfloor $slice $concat + // FIXME: $lut $sop $alu $lcu $macc $fa // FIXME: $mul $div $mod $divfloor $modfloor $pow $slice $concat $bweqx // FIXME: $lut $sop $alu $lcu $macc $fa $logic_and $logic_or $bwmux diff --git a/kernel/utils.h b/kernel/utils.h index 8fa223824..3216c5eb5 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -149,7 +149,7 @@ template , typename OPS = hash_ops> cla std::map node_to_index; std::vector> edges; std::vector sorted; - std::set> loops; + std::set> loops; TopoSort() : indirect_cmp(nodes) { @@ -220,10 +220,10 @@ template , typename OPS = hash_ops> cla if (active_cells[root_index]) { found_loops = true; if (analyze_loops) { - std::set loop; + std::vector loop; for (int i = GetSize(active_stack) - 1; i >= 0; i--) { const int index = active_stack[i]; - loop.insert(nodes[index]); + loop.push_back(nodes[index]); if (index == root_index) break; } diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index 8b39d59e3..eee215015 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -46,7 +46,7 @@ Open "Git Bash" in this directory and run: mv yosys yosys.bak git clone https://github.com/YosysHQ/yosys.git yosys cd yosys - git checkout -B master $(git rev-parse HEAD | cut -c1-10) + git checkout -B main $(git rev-parse HEAD | cut -c1-10) unzip ../genfiles.zip EOT diff --git a/misc/jny.schema.json b/misc/jny.schema.json index 0fff8ee57..278b1a55f 100644 --- a/misc/jny.schema.json +++ b/misc/jny.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/YosysHQ/yosys/master/misc/jny.schema.json", + "$id": "https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json", "title": "Yosys JSON Netlist metadata", "description": "Yosys JSON Netlist", "type": "object", diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index d1c83f04d..255c32fba 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/celledges.h" #include "kernel/celltypes.h" #include "kernel/utils.h" @@ -102,10 +103,10 @@ struct CheckPass : public Pass { SigMap sigmap(module); dict> wire_drivers; + dict driver_cells; dict wire_drivers_count; pool used_wires; - TopoSort topo; - + TopoSort> topo; for (auto &proc_it : module->processes) { std::vector all_cases = {&proc_it.second->root_case}; @@ -150,6 +151,50 @@ struct CheckPass : public Pass { } } + struct CircuitEdgesDatabase : AbstractCellEdgesDatabase { + TopoSort> &topo; + SigMap sigmap; + + CircuitEdgesDatabase(TopoSort> &topo, SigMap &sigmap) + : topo(topo), sigmap(sigmap) {} + + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, + RTLIL::IdString to_port, int to_bit, int) override { + SigSpec from_portsig = cell->getPort(from_port); + SigSpec to_portsig = cell->getPort(to_port); + log_assert(from_bit >= 0 && from_bit < from_portsig.size()); + log_assert(to_bit >= 0 && to_bit < to_portsig.size()); + SigBit from = sigmap(from_portsig[from_bit]); + SigBit to = sigmap(to_portsig[to_bit]); + + if (from.wire && to.wire) + topo.edge(std::make_pair(from.wire->name, from.offset), std::make_pair(to.wire->name, to.offset)); + } + + bool add_edges_from_cell(Cell *cell) { + if (AbstractCellEdgesDatabase::add_edges_from_cell(cell)) + return true; + + // We don't have accurate cell edges, do the fallback of all input-output pairs + for (auto &conn : cell->connections()) { + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + if (bit.wire) + topo.edge(std::make_pair(bit.wire->name, bit.offset), + std::make_pair(cell->name, -1)); + + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + if (bit.wire) + topo.edge(std::make_pair(cell->name, -1), + std::make_pair(bit.wire->name, bit.offset)); + } + return true; + } + }; + + CircuitEdgesDatabase edges_db(topo, sigmap); + for (auto cell : module->cells()) { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { @@ -158,31 +203,30 @@ struct CheckPass : public Pass { counter++; cell_allowed:; } - for (auto &conn : cell->connections()) { - SigSpec sig = sigmap(conn.second); - bool logic_cell = yosys_celltypes.cell_evaluable(cell->type); - if (cell->input(conn.first)) - for (auto bit : sig) - if (bit.wire) { - if (logic_cell) - topo.edge(stringf("wire %s", log_signal(bit)), - stringf("cell %s (%s)", log_id(cell), log_id(cell->type))); - used_wires.insert(bit); - } - if (cell->output(conn.first)) - for (int i = 0; i < GetSize(sig); i++) { - if (logic_cell) - topo.edge(stringf("cell %s (%s)", log_id(cell), log_id(cell->type)), - stringf("wire %s", log_signal(sig[i]))); - if (sig[i].wire || !cell->input(conn.first)) - wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)", - log_id(conn.first), i, log_id(cell), log_id(cell->type))); - } - if (!cell->input(conn.first) && cell->output(conn.first)) - for (auto bit : sig) - if (bit.wire) wire_drivers_count[bit]++; + for (auto &conn : cell->connections()) { + bool input = cell->input(conn.first); + bool output = cell->output(conn.first); + + SigSpec sig = sigmap(conn.second); + for (int i = 0; i < sig.size(); i++) { + SigBit bit = sig[i]; + + if (input && bit.wire) + used_wires.insert(bit); + if (output && !input && bit.wire) + wire_drivers_count[bit]++; + if (output && (bit.wire || !input)) + wire_drivers[bit].push_back(stringf("port %s[%d] of cell %s (%s)", log_id(conn.first), i, + log_id(cell), log_id(cell->type))); + if (output) + driver_cells[bit] = cell; + } } + + if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2)) \ + || RTLIL::builtin_ff_cell_types().count(cell->type)) + edges_db.add_edges_from_cell(cell); } pool init_bits; @@ -239,8 +283,72 @@ struct CheckPass : public Pass { topo.sort(); for (auto &loop : topo.loops) { string message = stringf("found logic loop in module %s:\n", log_id(module)); - for (auto &str : loop) - message += stringf(" %s\n", str.c_str()); + + // `loop` only contains wire bits, or an occassional special helper node for cells for + // which we have done the edges fallback. The cell and its ports that led to an edge is + // an information we need to recover now. For that we need to have the previous wire bit + // of the loop at hand. + SigBit prev; + for (auto it = loop.rbegin(); it != loop.rend(); it++) + if (it->second != -1) { // skip the fallback helper nodes + prev = SigBit(module->wire(it->first), it->second); + break; + } + log_assert(prev != SigBit()); + + for (auto &pair : loop) { + if (pair.second == -1) + continue; // helper node for edges fallback, we can ignore it + + struct MatchingEdgePrinter : AbstractCellEdgesDatabase { + std::string &message; + SigMap &sigmap; + SigBit from, to; + int nhits; + const int HITS_LIMIT = 3; + + MatchingEdgePrinter(std::string &message, SigMap &sigmap, SigBit from, SigBit to) + : message(message), sigmap(sigmap), from(from), to(to), nhits(0) {} + + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, + RTLIL::IdString to_port, int to_bit, int) override { + SigBit edge_from = sigmap(cell->getPort(from_port))[from_bit]; + SigBit edge_to = sigmap(cell->getPort(to_port))[to_bit]; + + if (edge_from == from && edge_to == to && nhits++ < HITS_LIMIT) + message += stringf(" %s[%d] --> %s[%d]\n", log_id(from_port), from_bit, + log_id(to_port), to_bit); + if (nhits == HITS_LIMIT) + message += " ...\n"; + } + }; + + Wire *wire = module->wire(pair.first); + log_assert(wire); + SigBit bit(module->wire(pair.first), pair.second); + log_assert(driver_cells.count(bit)); + Cell *driver = driver_cells.at(bit); + + std::string driver_src; + if (driver->has_attribute(ID::src)) { + std::string src_attr = driver->get_src_attribute(); + driver_src = stringf(" source: %s", src_attr.c_str()); + } + message += stringf(" cell %s (%s)%s\n", log_id(driver), log_id(driver->type), driver_src.c_str()); + MatchingEdgePrinter printer(message, sigmap, prev, bit); + printer.add_edges_from_cell(driver); + + if (wire->name.isPublic()) { + std::string wire_src; + if (wire->has_attribute(ID::src)) { + std::string src_attr = wire->get_src_attribute(); + wire_src = stringf(" source: %s", src_attr.c_str()); + } + message += stringf(" wire %s%s\n", log_signal(SigBit(wire, pair.second)), wire_src.c_str()); + } + + prev = bit; + } log_warning("%s", message.c_str()); counter++; } diff --git a/tests/opt/opt_dff_qd.ys b/tests/opt/opt_dff_qd.ys index 7b0b4c224..c6232643f 100644 --- a/tests/opt/opt_dff_qd.ys +++ b/tests/opt/opt_dff_qd.ys @@ -7,7 +7,7 @@ module top(...); input CLK; input EN; (* init = 24'h555555 *) -output [19:0] Q; +output [17:0] Q; input SRST; input ARST; input [1:0] CLR; @@ -23,26 +23,20 @@ $sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_V $dffsr #(.CLK_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.CLK(CLK), .SET(SET), .CLR(CLR), .D(Q[15:14]), .Q(Q[15:14])); $dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff8 (.CLK(CLK), .EN(EN), .SET(SET), .CLR(CLR), .D(Q[17:16]), .Q(Q[17:16])); -$dlatch #(.EN_POLARITY(1'b1), .WIDTH(2)) ff9 (.EN(EN), .D(Q[19:18]), .Q(Q[19:18])); -$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff10 (.EN(EN), .ARST(ARST), .D(Q[21:20]), .Q(Q[21:20])); -$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff11 (.EN(EN), .SET(SET), .CLR(CLR), .D(Q[23:22]), .Q(Q[23:22])); - endmodule EOT design -save orig -# Equivalence check will fail for unmapped adlatch and dlatchsr due to negative hold hack. -delete top/ff10 top/ff11 equiv_opt -undef -assert -multiclock opt_dff -keepdc design -load orig opt_dff -keepdc select -assert-count 1 t:$and select -assert-count 3 t:$dffe -select -assert-count 3 t:$dlatch -select -assert-count 3 t:$sr +select -assert-count 2 t:$dlatch +select -assert-count 2 t:$sr select -assert-none t:$and t:$dffe t:$dlatch t:$sr %% %n t:* %i design -load orig @@ -50,7 +44,7 @@ simplemap opt_dff -keepdc select -assert-count 2 t:$_AND_ select -assert-count 6 t:$_DFFE_??_ -select -assert-count 6 t:$_DLATCH_?_ -select -assert-count 6 t:$_SR_??_ +select -assert-count 4 t:$_DLATCH_?_ +select -assert-count 4 t:$_SR_??_ select -assert-none t:$_AND_ t:$_DFFE_??_ t:$_DLATCH_?_ t:$_SR_??_ %% %n t:* %i diff --git a/tests/various/check.ys b/tests/various/check.ys new file mode 100644 index 000000000..41b996091 --- /dev/null +++ b/tests/various/check.ys @@ -0,0 +1,43 @@ +design -reset +read -vlog2k <