diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f754d16c7..2ed92c913 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -6,6 +6,8 @@ body: attributes: value: > + Learn more in our [Reporting bugs](https://yosyshq.readthedocs.io/projects/yosys/en/latest/yosys_internals/extending_yosys/contributing.html#reporting-bugs) docs section. We fix well-reported bugs the fastest. + If you have a general question, please ask it on the [Discourse forum](https://yosyshq.discourse.group/). diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index 60fe481e7..c1d3e2b01 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -42,7 +42,7 @@ runs: if: runner.os == 'Linux' && inputs.get-build-deps == 'true' uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: - packages: bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev + packages: bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libgtest-dev libgmock-dev version: ${{ inputs.runs-on }}-buildys - name: Linux docs dependencies @@ -52,15 +52,6 @@ runs: packages: graphviz xdot version: ${{ inputs.runs-on }}-docsys - # if updating test dependencies, make sure to update - # docs/source/yosys_internals/extending_yosys/test_suites.rst to match. - - name: Linux test dependencies - if: runner.os == 'Linux' && inputs.get-test-deps == 'true' - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 - with: - packages: libgtest-dev - version: ${{ inputs.runs-on }}-testys - - name: Install macOS Dependencies if: runner.os == 'macOS' shell: bash diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4bca5a8a5..74ecbe0ad 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: true persist-credentials: false @@ -23,7 +23,7 @@ jobs: get-build-deps: true - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: cpp queries: security-extended,security-and-quality @@ -32,4 +32,4 @@ jobs: run: make yosys -j6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/extra-builds.yml b/.github/workflows/extra-builds.yml index e8b11ef2f..7209b3645 100644 --- a/.github/workflows/extra-builds.yml +++ b/.github/workflows/extra-builds.yml @@ -1,22 +1,20 @@ name: Test extra build flows on: - # always test main - push: - branches: - - main - # test PRs pull_request: - # allow triggering tests, ignores skip check + merge_group: + #push: + # branches: [ main ] workflow_dispatch: jobs: pre_job: runs-on: ubuntu-latest outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check + if: ${{ github.event_name != 'merge_group' }} uses: fkirc/skip-duplicate-actions@v5 with: # don't run on documentation changes @@ -25,20 +23,28 @@ jobs: # but never cancel main cancel_others: ${{ github.ref != 'refs/heads/main' }} + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi + vs-prep: name: Prepare Visual Studio build runs-on: ubuntu-latest needs: [pre_job] - if: needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true persist-credentials: false - run: sudo apt-get install libfl-dev - name: Build run: make vcxsrc YOSYS_COMPILER="Visual Studio" VCX_DIR_NAME=yosys-win32-vcxsrc-latest - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: vcxsrc path: yosys-win32-vcxsrc-latest.zip @@ -47,9 +53,9 @@ jobs: name: Visual Studio build runs-on: windows-latest needs: [vs-prep, pre_job] - if: needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: vcxsrc path: . @@ -64,17 +70,17 @@ jobs: wasi-build: name: WASI build needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true persist-credentials: false - name: Build run: | - WASI_SDK=wasi-sdk-27.0-x86_64-linux - WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz + WASI_SDK=wasi-sdk-33.0-x86_64-linux + WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-33/wasi-sdk-33.0-x86_64-linux.tar.gz if ! [ -d ${WASI_SDK} ]; then curl -L ${WASI_SDK_URL} | tar xzf -; fi FLEX_VER=2.6.4 @@ -102,6 +108,7 @@ jobs: ENABLE_ZLIB := 0 CXXFLAGS += -I$(pwd)/flex-prefix/include + LINKFLAGS += -Wl,-z,stack-size=8388608 -Wl,--stack-first -Wl,--strip-all END make -C build -f ../Makefile CXX=clang -j$(nproc) @@ -109,14 +116,14 @@ jobs: nix-build: name: "Build nix flake" needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest] fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true persist-credentials: false @@ -124,3 +131,21 @@ jobs: with: install_url: https://releases.nixos.org/nix/nix-2.30.0/install - run: nix build .?submodules=1 -L + + extra-builds-result: + runs-on: ubuntu-latest + needs: + - vs-build + - wasi-build + - nix-build + if: always() + steps: + - name: Check results + run: | + echo "Needs results: ${{ join(needs.*.result, ',') }}" + if [[ "${{ join(needs.*.result, ',') }}" == *failure* ]] || \ + [[ "${{ join(needs.*.result, ',') }}" == *cancelled* ]]; then + echo "Some jobs failed or were cancelled" + exit 1 + fi + - run: echo "All good" diff --git a/.github/workflows/prepare-docs.yml b/.github/workflows/prepare-docs.yml index f19b1c7af..06c465c44 100644 --- a/.github/workflows/prepare-docs.yml +++ b/.github/workflows/prepare-docs.yml @@ -1,12 +1,18 @@ name: Build docs artifact with Verific -on: [push, pull_request] +on: + pull_request: + merge_group: + push: + branches: [ main, "docs-preview/**", "docs-preview*" ] + tags: [ "*" ] + workflow_dispatch: jobs: check_docs_rebuild: runs-on: ubuntu-latest outputs: - skip_check: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} docs_export: ${{ steps.docs_var.outputs.docs_export }} env: docs_export: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/docs-preview') || startsWith(github.ref, 'refs/tags/') }} @@ -17,16 +23,26 @@ jobs: paths_ignore: '["**/README.md"]' # don't cancel in case we're updating docs cancel_others: 'false' - # only run on push *or* pull_request, not both - concurrent_skipping: ${{ env.docs_export && 'never' || 'same_content_newer'}} + # push filtering means we only want to skip duplicates for PRs + do_not_skip: '["workflow_dispatch", "merge_group", "push"]' + concurrent_skipping: 'same_content_newer' + - id: docs_var run: echo "docs_export=${docs_export}" >> $GITHUB_OUTPUT + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi + prepare-docs: # docs builds are needed for anything on main, any tagged versions, and any tag # or branch starting with docs-preview needs: check_docs_rebuild - if: ${{ needs.check_docs_rebuild.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }} + if: ${{ needs.check_docs_rebuild.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys @@ -75,7 +91,7 @@ jobs: make -C docs html -j$procs TARGETS= EXTRA_TARGETS= - name: Trigger RTDs build - if: ${{ needs.check_docs_rebuild.outputs.docs_export == 'true' }} + if: ${{ needs.check_docs_rebuild.outputs.docs_export == 'true' && github.repository == 'YosysHQ/yosys' }} uses: dfm/rtds-action@v1.1.0 with: webhook_url: ${{ secrets.RTDS_WEBHOOK_URL }} diff --git a/.github/workflows/source-vendor.yml b/.github/workflows/source-vendor.yml index dc9480ef6..d85b2af08 100644 --- a/.github/workflows/source-vendor.yml +++ b/.github/workflows/source-vendor.yml @@ -1,13 +1,18 @@ name: Create source archive with vendored dependencies -on: [push, workflow_dispatch] +on: + pull_request: + merge_group: + push: + branches: [ main ] + workflow_dispatch: jobs: vendor-sources: runs-on: ubuntu-latest steps: - name: Checkout repository with submodules - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: 'recursive' persist-credentials: false @@ -27,7 +32,7 @@ jobs: gzip yosys-src-vendored.tar - name: Store tarball artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: vendored-sources path: yosys-src-vendored.tar.gz diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 8c1a3bbd2..5e990d0a5 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -1,22 +1,20 @@ name: Build and run tests on: - # always test main - push: - branches: - - main - # test PRs pull_request: - # allow triggering tests, ignores skip check + merge_group: + #push: + # branches: [ main ] workflow_dispatch: jobs: pre_job: runs-on: ubuntu-latest outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check + if: ${{ github.event_name != 'merge_group' }} uses: fkirc/skip-duplicate-actions@v5 with: # don't run on documentation changes @@ -25,12 +23,21 @@ jobs: # but never cancel main cancel_others: ${{ github.ref != 'refs/heads/main' }} + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi + pre_docs_job: runs-on: ubuntu-latest outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check + if: ${{ github.event_name != 'merge_group' }} uses: fkirc/skip-duplicate-actions@v5 with: # don't run on readme changes @@ -39,6 +46,14 @@ jobs: # but never cancel main cancel_others: ${{ github.ref != 'refs/heads/main' }} + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi + build-yosys: name: Reusable build runs-on: ${{ matrix.os }} @@ -53,7 +68,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: true persist-credentials: false @@ -71,6 +86,7 @@ jobs: cd build make -f ../Makefile config-$CC make -f ../Makefile -j$procs + make -f ../Makefile unit-test -j$procs - name: Log yosys-config output run: | @@ -80,10 +96,10 @@ jobs: shell: bash run: | cd build - tar -cvf ../build.tar share/ yosys yosys-* + tar -cvf ../build.tar share/ yosys yosys-* libyosys.so - name: Store build artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: build-${{ matrix.os }} path: build.tar @@ -102,7 +118,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -114,7 +130,7 @@ jobs: get-iverilog: true - name: Download build artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: build-${{ matrix.os }} @@ -130,7 +146,7 @@ jobs: - name: Run tests shell: bash run: | - make -j$procs test TARGETS= EXTRA_TARGETS= CONFIG=$CC + make -j$procs vanilla-test TARGETS= EXTRA_TARGETS= CONFIG=$CC - name: Report errors if: ${{ failure() }} @@ -150,7 +166,7 @@ jobs: os: [ubuntu-latest] steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -160,7 +176,7 @@ jobs: runs-on: ${{ matrix.os }} - name: Download build artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: build-${{ matrix.os }} @@ -190,7 +206,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -202,7 +218,7 @@ jobs: get-docs-deps: true - name: Download build artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: build-${{ matrix.os }} @@ -224,7 +240,7 @@ jobs: name: Try build docs runs-on: [self-hosted, linux, x64, fast] needs: [pre_docs_job] - if: ${{ needs.pre_docs_job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }} + if: ${{ needs.pre_docs_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} strategy: matrix: docs-target: [html, latexpdf] @@ -263,3 +279,22 @@ jobs: name: docs-build-${{ matrix.docs-target }} path: docs/build/ retention-days: 7 + + test-build-result: + runs-on: ubuntu-latest + needs: + - test-yosys + - test-cells + - test-docs + - test-docs-build + if: always() + steps: + - name: Check results + run: | + echo "Needs results: ${{ join(needs.*.result, ',') }}" + if [[ "${{ join(needs.*.result, ',') }}" == *failure* ]] || \ + [[ "${{ join(needs.*.result, ',') }}" == *cancelled* ]]; then + echo "Some jobs failed or were cancelled" + exit 1 + fi + - run: echo "All good" diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 31c8bccf6..9c75784bf 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -1,22 +1,20 @@ name: Compiler testing on: - # always test main - push: - branches: - - main - # test PRs pull_request: - # allow triggering tests, ignores skip check + merge_group: + #push: + # branches: [ main ] workflow_dispatch: jobs: pre_job: runs-on: ubuntu-latest outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check + if: ${{ github.event_name != 'merge_group' }} uses: fkirc/skip-duplicate-actions@v5 with: # don't run on documentation changes @@ -25,10 +23,18 @@ jobs: # but never cancel main cancel_others: ${{ github.ref != 'refs/heads/main' }} + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi + test-compile: runs-on: ${{ matrix.os }} needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' env: CXXFLAGS: ${{ startsWith(matrix.compiler, 'gcc') && '-Wp,-D_GLIBCXX_ASSERTIONS' || ''}} CC_SHORT: ${{ startsWith(matrix.compiler, 'gcc') && 'gcc' || 'clang' }} @@ -53,7 +59,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: true persist-credentials: false @@ -89,3 +95,19 @@ jobs: run: | make config-$CC_SHORT make -j$procs CXXSTD=c++20 compile-only + + test-compile-result: + runs-on: ubuntu-latest + needs: + - test-compile + if: always() + steps: + - name: Check results + run: | + echo "Needs results: ${{ join(needs.*.result, ',') }}" + if [[ "${{ join(needs.*.result, ',') }}" == *failure* ]] || \ + [[ "${{ join(needs.*.result, ',') }}" == *cancelled* ]]; then + echo "Some jobs failed or were cancelled" + exit 1 + fi + - run: echo "All good" diff --git a/.github/workflows/test-sanitizers.yml b/.github/workflows/test-sanitizers.yml index 4c8e3ec51..6f3c10903 100644 --- a/.github/workflows/test-sanitizers.yml +++ b/.github/workflows/test-sanitizers.yml @@ -1,31 +1,41 @@ name: Check clang sanitizers on: - # always test main - push: - branches: - - main - # ignore PRs due to time needed - # allow triggering tests, ignores skip check + pull_request: + merge_group: + #push: + # branches: [ main ] workflow_dispatch: jobs: pre_job: runs-on: ubuntu-latest outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check + if: ${{ github.event_name != 'merge_group' }} uses: fkirc/skip-duplicate-actions@v5 with: # don't run on documentation changes paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' + # cancel previous builds if a new commit is pushed + # but never cancel main + cancel_others: ${{ github.ref != 'refs/heads/main' }} + + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi run_san: name: Build and run tests runs-on: ${{ matrix.os }} needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' env: CC: clang ASAN_OPTIONS: halt_on_error=1 @@ -37,7 +47,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: true persist-credentials: false @@ -64,7 +74,7 @@ jobs: - name: Run tests shell: bash run: | - make -j$procs test TARGETS= EXTRA_TARGETS= + make -j$procs vanilla-test TARGETS= EXTRA_TARGETS= - name: Report errors if: ${{ failure() }} @@ -72,7 +82,18 @@ jobs: run: | find tests/**/*.err -print -exec cat {} \; - - name: Run unit tests - shell: bash + test-sanitizers-result: + runs-on: ubuntu-latest + needs: + - run_san + if: always() + steps: + - name: Check results run: | - make -j$procs unit-test ENABLE_LIBYOSYS=1 + echo "Needs results: ${{ join(needs.*.result, ',') }}" + if [[ "${{ join(needs.*.result, ',') }}" == *failure* ]] || \ + [[ "${{ join(needs.*.result, ',') }}" == *cancelled* ]]; then + echo "Some jobs failed or were cancelled" + exit 1 + fi + - run: echo "All good" \ No newline at end of file diff --git a/.github/workflows/test-verific-cfg.yml b/.github/workflows/test-verific-cfg.yml new file mode 100644 index 000000000..232ca6bd7 --- /dev/null +++ b/.github/workflows/test-verific-cfg.yml @@ -0,0 +1,109 @@ +name: Build various Verific configurations + +on: + workflow_dispatch: + +jobs: + test-verific-cfg: + if: github.repository_owner == 'YosysHQ' + runs-on: [self-hosted, linux, x64, fast] + steps: + - name: Checkout Yosys + uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: true + - name: Runtime environment + run: | + echo "procs=$(nproc)" >> $GITHUB_ENV + + - name: verific [SV] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs + + - name: verific [VHDL] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs + + - name: verific [SV + VHDL] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs + + - name: verific [SV + HIER] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs + + - name: verific [VHDL + HIER] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs + + - name: verific [SV + VHDL + HIER] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 0" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs + + - name: verific [SV + VHDL + HIER + EDIF + LIBERTY] + run: | + make config-clang + echo "ENABLE_VERIFIC := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_SYSTEMVERILOG := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_VHDL := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_HIER_TREE := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf + echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0" >> Makefile.conf + echo "ENABLE_CCACHE := 1" >> Makefile.conf + make -j$procs diff --git a/.github/workflows/test-verific.yml b/.github/workflows/test-verific.yml index 6619e1124..132aac589 100644 --- a/.github/workflows/test-verific.yml +++ b/.github/workflows/test-verific.yml @@ -1,22 +1,20 @@ name: Build and run tests with Verific (Linux) on: - # always test main - push: - branches: - - main - # test PRs pull_request: - # allow triggering tests, ignores skip check + merge_group: + #push: + # branches: [ main ] workflow_dispatch: jobs: - pre-job: + pre_job: runs-on: ubuntu-latest outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} + should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check + if: ${{ github.event_name != 'merge_group' }} uses: fkirc/skip-duplicate-actions@v5 with: # don't run on documentation changes @@ -25,9 +23,17 @@ jobs: # but never cancel main cancel_others: ${{ github.ref != 'refs/heads/main' }} + - id: set_output + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "should_skip=false" >> $GITHUB_OUTPUT + else + echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT + fi + test-verific: - needs: pre-job - if: ${{ needs.pre-job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }} + needs: pre_job + if: ${{ needs.pre_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys @@ -67,26 +73,21 @@ jobs: - name: Run Yosys tests run: | - make -j$procs test + make -j$procs vanilla-test - name: Run Verific specific Yosys tests run: | make -C tests/sva - cd tests/svtypes && bash run-test.sh + make -C tests/svtypes - name: Run SBY tests - if: ${{ github.ref == 'refs/heads/main' }} + if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} run: | make -C sby run_ci - - name: Run unit tests - shell: bash - run: | - make -j$procs unit-test ENABLE_LTO=1 ENABLE_LIBYOSYS=1 - test-pyosys: - needs: pre-job - if: ${{ needs.pre-job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }} + needs: pre_job + if: ${{ needs.pre_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys @@ -122,3 +123,20 @@ jobs: run: | export PYTHONPATH=${GITHUB_WORKSPACE}/.local/usr/lib/python3/site-packages:$PYTHONPATH python3 tests/pyosys/run_tests.py + + test-verific-result: + runs-on: ubuntu-latest + needs: + - test-verific + - test-pyosys + if: always() + steps: + - name: Check results + run: | + echo "Needs results: ${{ join(needs.*.result, ',') }}" + if [[ "${{ join(needs.*.result, ',') }}" == *failure* ]] || \ + [[ "${{ join(needs.*.result, ',') }}" == *cancelled* ]]; then + echo "Some jobs failed or were cancelled" + exit 1 + fi + - run: echo "All good" diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml deleted file mode 100644 index b32498baf..000000000 --- a/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: update-flake-lock -on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00 - -jobs: - lockfile: - if: github.repository == 'YosysHQ/Yosys' - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - token: ${{CI_CREATE_PR_TOKEN}} - pr-title: "Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR - dependencies - automated diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml deleted file mode 100644 index 78d34db46..000000000 --- a/.github/workflows/version.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Bump version - -on: - workflow_dispatch: - schedule: - - cron: '0 0 * * *' - -jobs: - bump-version: - if: github.repository == 'YosysHQ/Yosys' - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - persist-credentials: false - - name: Take last commit - id: log - run: echo "message=$(git log --no-merges -1 --oneline)" >> $GITHUB_OUTPUT - - name: Bump version - if: ${{ !contains(steps.log.outputs.message, 'Bump version') }} - run: | - make bumpversion - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - git add Makefile - git commit -m "Bump version" - - name: Push changes # push the output folder to your repo - if: ${{ !contains(steps.log.outputs.message, 'Bump version') }} - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 8e055f526..8139b5af5 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -49,7 +49,7 @@ jobs: name: Build Wheels | ${{ matrix.os.name }} | ${{ matrix.os.archs }} runs-on: ${{ matrix.os.runner }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 submodules: true @@ -108,13 +108,13 @@ jobs: PATH="$PWD/bison/src:$PATH" CIBW_BEFORE_BUILD: bash ./.github/workflows/wheels/cibw_before_build.sh CIBW_TEST_COMMAND: python3 {project}/tests/pyosys/run_tests.py - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: python-wheels-${{ matrix.os.runner }} path: ./wheelhouse/*.whl upload_wheels: name: Upload Wheels - if: (github.repository == 'YosysHQ/Yosys') && (github.event_name == 'workflow_dispatch') + if: (github.repository == 'YosysHQ/yosys') && (github.event_name == 'workflow_dispatch') runs-on: ubuntu-latest # Specifying a GitHub environment is optional, but strongly encouraged environment: pypi @@ -123,7 +123,7 @@ jobs: id-token: write needs: build_wheels steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: path: "." pattern: python-wheels-* diff --git a/.github/workflows/wheels/cibw_before_all.sh b/.github/workflows/wheels/cibw_before_all.sh index 1aef650d7..6450ce273 100644 --- a/.github/workflows/wheels/cibw_before_all.sh +++ b/.github/workflows/wheels/cibw_before_all.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e -x # Build-time dependencies diff --git a/Brewfile b/Brewfile index 917f1bdb4..2530b323c 100644 --- a/Brewfile +++ b/Brewfile @@ -9,6 +9,6 @@ brew "python3" brew "uv" brew "xdot" brew "bash" -brew "llvm@20" +brew "llvm" brew "lld" brew "googletest" diff --git a/CHANGELOG b/CHANGELOG index 69f8ab1ce..01faf44c2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,9 +2,86 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.60 .. Yosys 0.61-dev +Yosys 0.65 .. Yosys 0.66-dev -------------------------- +Yosys 0.64 .. Yosys 0.65 +-------------------------- + * New commands and options + - Added "arith_tree" pass to convert add/sub/macc chains + to carry-save adder trees. + - Removed "-force" option from "share" pass. + + * Various + - read_verilog: support positional assignment patterns + for unpacked arrays. + +Yosys 0.63 .. Yosys 0.64 +-------------------------- + * New commands and options + - Added "synth_analogdevices" pass to support synthesis + for Analog Devices FPGAs. + + * Various + - Removed rarely-used options from ABC/ABC9. + - Removed "-S" option from "abc" pass. + - Removed "-fast" option from "abc9" and "abc9_exe". + - Calls to "abc -g AND -fast" to map logic to + AND-Inverter Graph form should be replaced with + "aigmap". + - The above change was made to SBY, so we recommend + updating it. + - Added hardware latch support for Gowin FPGAs. + +Yosys 0.62 .. Yosys 0.63 +-------------------------- + * Various + - Added DSP inference for Gowin GW1N and GW2A. + - Added support for subtract in preadder for Xilinx arch. + - Added infrastructure to run a sat solver as a command. + + * New commands and options + - Added "-ignore-unknown-cells" option to "equiv_induct" + and "equiv_simple" pass. + - Added "-force-params" option to "memory_libmap" pass. + - Added "-select-solver" option to "sat" pass. + - Added "-default_params" option to "write_verilog" pass. + - Added "-nodsp" option to "synth_gowin" pass. + +Yosys 0.61 .. Yosys 0.62 +-------------------------- + * Various + - verific: Added "-sv2017" flag option to support System + Verilog 2017. + - verific: Added VHDL related flags to "-f" and "-F" and + support reading VHDL file from file lists. + - Updated cell libs with proper module declaration where + non standard (...) style was used. + + * New commands and options + - Added "-word" option to "lut2mux" pass to enable emitting + word level cells. + - Added experimental "opt_balance_tree" pass to convert + cascaded cells into tree of cells to improve timing. + - Added "-gatesi" option to "write_blif" pass to init gates + under gates_mode in BLIF format. + - Added "-on" and "-off" options to "debug" pass for + persistent debug logging. + - Added "linux_perf" pass to control performance recording. + +Yosys 0.60 .. Yosys 0.61 +-------------------------- + * Various + - Removed "cover" pass for coverage tracking. + - Avoid merging formal properties with "opt_merge" pass. + - Parallelize "opt_merge" pass. + + * New commands and options + - Added "design_equal" pass to support fuzz-test comparison. + - Added "lut2bmux" pass to convert $lut to $bmux. + - Added "-legalize" option to "read_rtlil" pass to prevent + semantic errors. + Yosys 0.59 .. Yosys 0.60 -------------------------- * Various diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 403292b0b..849d1fb00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,70 +1,15 @@ -# Introduction +# Contributing to Yosys -Thanks for thinking about contributing to the Yosys project. If this is your +Thanks for considering helping out. If this is your first time contributing to an open source project, please take a look at the -following guide: +following guide about the basics: https://opensource.guide/how-to-contribute/#orienting-yourself-to-a-new-project. -Information about the Yosys coding style is available on our Read the Docs: -https://yosys.readthedocs.io/en/latest/yosys_internals/extending_yosys/contributing.html. +Check out our [Contributing guidelines](https://yosys.readthedocs.io/en/latest/yosys_internals/extending_yosys/contributing.html) to learn the best ways to -# Using the issue tracker ++ get help ++ report bugs ++ contribute code ++ review code -The [issue tracker](https://github.com/YosysHQ/yosys/issues) is used for -tracking bugs or other problems with Yosys or its documentation. It is also the -place to go for requesting new features. -When [creating a new issue](https://github.com/YosysHQ/yosys/issues/new/choose), -we have a few templates available. Please make use of these! It will make it -much easier for someone to respond and help. - -### Bug reports - -Before you submit an issue, please check out the [how-to guide for -`bugpoint`](https://yosys.readthedocs.io/en/latest/using_yosys/bugpoint.html). -This guide will take you through the process of using the [`bugpoint` -command](https://yosys.readthedocs.io/en/latest/cmd/bugpoint.html) in Yosys to -produce a [minimal, complete and verifiable -example](https://stackoverflow.com/help/minimal-reproducible-example) (MVCE). -Providing an MVCE with your bug report drastically increases the likelihood that -someone will be able to help resolve your issue. - - -# Using pull requests - -If you are working on something to add to Yosys, or fix something that isn't -working quite right, make a [PR](https://github.com/YosysHQ/yosys/pulls)! An -open PR, even as a draft, tells everyone that you're working on it and they -don't have to. It can also be a useful way to solicit feedback on in-progress -changes. See below to find the best way to [ask us -questions](#asking-questions). - -In general, all changes to the code are done as a PR, with [Continuous -Integration (CI)](https://github.com/YosysHQ/yosys/actions) tools that -automatically run the full suite of tests compiling and running Yosys. Please -make use of this! If you're adding a feature: add a test! Not only does it -verify that your feature is working as expected, but it can also be a handy way -for people to see how the feature is used. If you're fixing a bug: add a test! -If you can, do this first; it's okay if the test starts off failing - you -already know there is a bug. CI also helps to make sure that your changes still -work under a range of compilers, settings, and targets. - - -### Labels - -We use [labels](https://github.com/YosysHQ/yosys/labels) to help categorise -issues and PRs. If a label seems relevant to your work, please do add it; this -also includes the labels beggining with 'status-'. The 'merge-' labels are used -by maintainers for tracking and communicating which PRs are ready and pending -merge; please do not use these labels if you are not a maintainer. - - -# Asking questions - -If you have a question about how to use Yosys, please ask on our [Discourse forum](https://yosyshq.discourse.group/) or in our [discussions -page](https://github.com/YosysHQ/yosys/discussions). -The Discourse is also a great place to ask questions about developing or -contributing to Yosys. - -We have open [dev 'jour fixe' (JF) meetings](https://docs.google.com/document/d/1SapA6QAsJcsgwsdKJDgnGR2mr97pJjV4eeXg_TVJhRU/edit?usp=sharing) where developers from YosysHQ and the -community come together to discuss open issues and PRs. This is also a good -place to talk to us about how to implement larger PRs. +If you're reading this file offline and don't have internet access, you can [read the contributing.rst file locally](docs/source/yosys_internals/extending_yosys/contributing.rst). diff --git a/COPYING b/COPYING index 2d962dddc..a3ca45b42 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ ISC License -Copyright (C) 2012 - 2025 Claire Xenia Wolf +Copyright (C) 2012 - 2026 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/Dockerfile b/Dockerfile deleted file mode 100644 index 9806696e0..000000000 --- a/Dockerfile +++ /dev/null @@ -1,58 +0,0 @@ -ARG IMAGE="python:3-slim-buster" - -#--- - -FROM $IMAGE AS base - -RUN apt-get update -qq \ - && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ - ca-certificates \ - clang \ - lld \ - curl \ - libffi-dev \ - libreadline-dev \ - tcl-dev \ - graphviz \ - xdot \ - && apt-get autoclean && apt-get clean && apt-get -y autoremove \ - && update-ca-certificates \ - && rm -rf /var/lib/apt/lists - -#--- - -FROM base AS build - -RUN apt-get update -qq \ - && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ - bison \ - flex \ - gawk \ - gcc \ - git \ - iverilog \ - pkg-config \ - && apt-get autoclean && apt-get clean && apt-get -y autoremove \ - && rm -rf /var/lib/apt/lists - -COPY . /yosys - -ENV PREFIX /opt/yosys - -RUN cd /yosys \ - && make \ - && make install \ - && make test - -#--- - -FROM base - -COPY --from=build /opt/yosys /opt/yosys - -ENV PATH /opt/yosys/bin:$PATH - -RUN useradd -m yosys -USER yosys - -CMD ["yosys"] diff --git a/Makefile b/Makefile index 6bea3c7b2..3c5c10cda 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ VPATH := $(YOSYS_SRC) UNITESTPATH := $(YOSYS_SRC)/tests/unit export CXXSTD ?= c++17 -CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include +CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror=unused -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LIBS := $(LIBS) -lstdc++ -lm PLUGIN_LINKFLAGS := PLUGIN_LIBS := @@ -161,7 +161,19 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.60+64 +YOSYS_VER := 0.65 + +ifneq (, $(shell command -v git 2>/dev/null)) +ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) + GIT_COMMIT_COUNT := $(or $(shell git rev-list --count v$(YOSYS_VER)..HEAD 2>/dev/null),0) + ifneq ($(GIT_COMMIT_COUNT),0) + YOSYS_VER := $(YOSYS_VER)+$(GIT_COMMIT_COUNT) + endif +else + YOSYS_VER := $(YOSYS_VER)+post +endif +endif + YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) @@ -185,9 +197,6 @@ endif OBJS = kernel/version_$(GIT_REV).o -bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 5bafeb7.. | wc -l`/;" Makefile - ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) # set ABCEXTERNAL = to use an external ABC instance @@ -282,18 +291,19 @@ ifeq ($(WASI_SDK),) CXX = clang++ AR = llvm-ar RANLIB = llvm-ranlib -WASIFLAGS := -target wasm32-wasi $(WASIFLAGS) +WASIFLAGS := -target wasm32-wasip1 $(WASIFLAGS) else CXX = $(WASI_SDK)/bin/clang++ AR = $(WASI_SDK)/bin/ar RANLIB = $(WASI_SDK)/bin/ranlib endif -CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) $(OPT_LEVEL) -D_WASI_EMULATED_PROCESS_CLOCKS $(filter-out -fPIC,$(CXXFLAGS)) -LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS)) +CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) $(OPT_LEVEL) -D_WASI_EMULATED_PROCESS_CLOCKS -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false $(filter-out -fPIC,$(CXXFLAGS)) +LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS)) -fwasm-exceptions -lunwind 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" ABCMKARGS += OPTFLAGS="-Os" +LTOFLAGS = EXE = .wasm DISABLE_SPAWN := 1 @@ -604,6 +614,7 @@ $(eval $(call add_include_file,kernel/bitpattern.h)) $(eval $(call add_include_file,kernel/cellaigs.h)) $(eval $(call add_include_file,kernel/celledges.h)) $(eval $(call add_include_file,kernel/celltypes.h)) +$(eval $(call add_include_file,kernel/newcelltypes.h)) $(eval $(call add_include_file,kernel/consteval.h)) $(eval $(call add_include_file,kernel/constids.inc)) $(eval $(call add_include_file,kernel/cost.h)) @@ -638,6 +649,7 @@ $(eval $(call add_include_file,kernel/yosys_common.h)) $(eval $(call add_include_file,kernel/yw.h)) $(eval $(call add_include_file,libs/ezsat/ezsat.h)) $(eval $(call add_include_file,libs/ezsat/ezminisat.h)) +$(eval $(call add_include_file,libs/ezsat/ezcmdline.h)) ifeq ($(ENABLE_ZLIB),1) $(eval $(call add_include_file,libs/fst/fstapi.h)) endif @@ -645,8 +657,6 @@ $(eval $(call add_include_file,libs/sha1/sha1.h)) $(eval $(call add_include_file,libs/json11/json11.hpp)) $(eval $(call add_include_file,passes/fsm/fsmdata.h)) $(eval $(call add_include_file,passes/techmap/libparse.h)) -$(eval $(call add_include_file,frontends/ast/ast.h)) -$(eval $(call add_include_file,frontends/ast/ast_binding.h)) $(eval $(call add_include_file,frontends/blif/blifparse.h)) $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) @@ -685,6 +695,7 @@ OBJS += libs/json11/json11.o OBJS += libs/ezsat/ezsat.o OBJS += libs/ezsat/ezminisat.o +OBJS += libs/ezsat/ezcmdline.o OBJS += libs/minisat/Options.o OBJS += libs/minisat/SimpSolver.o @@ -793,9 +804,30 @@ endif $(Q) mkdir -p $(dir $@) $(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $< +YOSYS_REPO := +ifneq (, $(shell command -v git 2>/dev/null)) +ifneq (, $(shell git rev-parse --git-dir 2>/dev/null)) + GIT_REMOTE := $(strip $(shell git config --get remote.origin.url 2>/dev/null | $(AWK) '{print tolower($$0)}')) + ifneq ($(strip $(GIT_REMOTE)),) + YOSYS_REPO := $(strip $(shell echo $(GIT_REMOTE) | $(AWK) -F '[:/]' '{gsub(/\.git$$/, "", $$NF); printf "%s/%s", $$(NF-1), $$NF}')) + endif + ifeq ($(strip $(YOSYS_REPO)),yosyshq/yosys) + YOSYS_REPO := + endif + GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null) + ifeq ($(filter main HEAD release/v%,$(GIT_BRANCH)),) + YOSYS_REPO := $(YOSYS_REPO) at $(GIT_BRANCH) + endif + YOSYS_REPO := $(strip $(YOSYS_REPO)) +endif +endif + YOSYS_GIT_STR := $(GIT_REV)$(GIT_DIRTY) YOSYS_COMPILER := $(notdir $(CXX)) $(shell $(CXX) --version | tr ' ()' '\n' | grep '^[0-9]' | head -n1) $(filter -f% -m% -O% -DNDEBUG,$(CXXFLAGS)) YOSYS_VER_STR := Yosys $(YOSYS_VER) (git sha1 $(YOSYS_GIT_STR), $(YOSYS_COMPILER)) +ifneq ($(strip $(YOSYS_REPO)),) + YOSYS_VER_STR := $(YOSYS_VER_STR) [$(YOSYS_REPO)] +endif kernel/version_$(GIT_REV).cc: $(YOSYS_SRC)/Makefile $(P) rm -f kernel/version_*.o kernel/version_*.d kernel/version_*.cc @@ -887,107 +919,15 @@ else ABCOPT="" endif -# Tests that generate .mk with tests/gen-tests-makefile.sh -MK_TEST_DIRS = -MK_TEST_DIRS += tests/arch/anlogic -MK_TEST_DIRS += tests/arch/ecp5 -MK_TEST_DIRS += tests/arch/efinix -MK_TEST_DIRS += tests/arch/gatemate -MK_TEST_DIRS += tests/arch/gowin -MK_TEST_DIRS += tests/arch/ice40 -MK_TEST_DIRS += tests/arch/intel_alm -MK_TEST_DIRS += tests/arch/machxo2 -MK_TEST_DIRS += tests/arch/microchip -MK_TEST_DIRS += tests/arch/nanoxplore -MK_TEST_DIRS += tests/arch/nexus -MK_TEST_DIRS += tests/arch/quicklogic/pp3 -MK_TEST_DIRS += tests/arch/quicklogic/qlf_k6n10f -MK_TEST_DIRS += tests/arch/xilinx -MK_TEST_DIRS += tests/bugpoint -MK_TEST_DIRS += tests/opt -MK_TEST_DIRS += tests/sat -MK_TEST_DIRS += tests/sdc -MK_TEST_DIRS += tests/sim -MK_TEST_DIRS += tests/svtypes -MK_TEST_DIRS += tests/techmap -MK_TEST_DIRS += tests/various -MK_TEST_DIRS += tests/rtlil -ifeq ($(ENABLE_VERIFIC),1) -ifneq ($(YOSYS_NOVERIFIC),1) -MK_TEST_DIRS += tests/verific -endif -endif -MK_TEST_DIRS += tests/verilog +test: vanilla-test unit-test -# Tests that don't generate .mk -SH_TEST_DIRS = -SH_TEST_DIRS += tests/simple -SH_TEST_DIRS += tests/simple_abc9 -SH_TEST_DIRS += tests/hana -SH_TEST_DIRS += tests/asicworld -# SH_TEST_DIRS += tests/realmath -SH_TEST_DIRS += tests/share -SH_TEST_DIRS += tests/opt_share -SH_TEST_DIRS += tests/fsm -SH_TEST_DIRS += tests/memlib -SH_TEST_DIRS += tests/bram -SH_TEST_DIRS += tests/svinterfaces -SH_TEST_DIRS += tests/xprop -SH_TEST_DIRS += tests/select -SH_TEST_DIRS += tests/peepopt -SH_TEST_DIRS += tests/proc -SH_TEST_DIRS += tests/blif -SH_TEST_DIRS += tests/arch -SH_TEST_DIRS += tests/rpc -SH_TEST_DIRS += tests/memfile -SH_TEST_DIRS += tests/fmt -SH_TEST_DIRS += tests/cxxrtl -SH_TEST_DIRS += tests/liberty -ifeq ($(ENABLE_FUNCTIONAL_TESTS),1) -SH_TEST_DIRS += tests/functional -endif +.PHONY: vanilla-test -# Tests that don't generate .mk and need special args -SH_ABC_TEST_DIRS = -SH_ABC_TEST_DIRS += tests/memories -SH_ABC_TEST_DIRS += tests/aiger -SH_ABC_TEST_DIRS += tests/alumacc - -# seed-tests/ is a dummy string, not a directory -.PHONY: seed-tests -seed-tests: $(SH_TEST_DIRS:%=seed-tests/%) -.PHONY: seed-tests/% -seed-tests/%: %/run-test.sh $(TARGETS) $(EXTRA_TARGETS) - +cd $* && bash run-test.sh $(SEEDOPT) - +@echo "...passed tests in $*" - -# abcopt-tests/ is a dummy string, not a directory -.PHONY: abcopt-tests -abcopt-tests: $(SH_ABC_TEST_DIRS:%=abcopt-tests/%) -abcopt-tests/%: %/run-test.sh $(TARGETS) $(EXTRA_TARGETS) - +cd $* && bash run-test.sh $(ABCOPT) $(SEEDOPT) - +@echo "...passed tests in $*" - -# makefile-tests/ is a dummy string, not a directory -.PHONY: makefile-tests -makefile-tests: $(MK_TEST_DIRS:%=makefile-tests/%) -# this target actually emits .mk files -%.mk: - +cd $(dir $*) && bash run-test.sh -# this one spawns submake on each -makefile-tests/%: %/run-test.mk $(TARGETS) $(EXTRA_TARGETS) - $(MAKE) -C $* -f run-test.mk - +@echo "...passed tests in $*" - -test: makefile-tests abcopt-tests seed-tests - @echo "" - @echo " Passed \"make test\"." -ifeq ($(ENABLE_VERIFIC),1) -ifeq ($(YOSYS_NOVERIFIC),1) - @echo " Ran tests without verific support due to YOSYS_NOVERIFIC=1." -endif -endif - @echo "" +vanilla-test: $(TARGETS) $(EXTRA_TARGETS) + @$(MAKE) -C tests vanilla-test \ + $(if $(ENABLE_VERIFIC),ENABLE_VERIFIC=$(ENABLE_VERIFIC)) \ + $(if $(YOSYS_NOVERIFIC),YOSYS_NOVERIFIC=$(YOSYS_NOVERIFIC)) \ + SEEDOPT=$(SEEDOPT) ABCOPT=$(ABCOPT) VALGRIND ?= valgrind --error-exitcode=1 --leak-check=full --show-reachable=yes --errors-for-leak-kinds=all @@ -1013,11 +953,11 @@ ystests: $(TARGETS) $(EXTRA_TARGETS) # Unit test unit-test: libyosys.so - @$(MAKE) -C $(UNITESTPATH) CXX="$(CXX)" CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" \ + @$(MAKE) -f $(UNITESTPATH)/Makefile CXX="$(CXX)" CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" \ CXXFLAGS="$(CXXFLAGS)" LINKFLAGS="$(LINKFLAGS)" LIBS="$(LIBS)" ROOTPATH="$(CURDIR)" clean-unit-test: - @$(MAKE) -C $(UNITESTPATH) clean + @$(MAKE) -f $(UNITESTPATH)/Makefile clean install-dev: $(PROGRAM_PREFIX)yosys-config share $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) @@ -1028,14 +968,14 @@ install-dev: $(PROGRAM_PREFIX)yosys-config share install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) $(INSTALL_SUDO) cp $(filter-out libyosys.so libyosys.a,$(TARGETS)) $(DESTDIR)$(BINDIR) -ifneq ($(filter $(PROGRAM_PREFIX)yosys,$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys; fi +ifneq ($(filter $(PROGRAM_PREFIX)yosys$(EXE),$(TARGETS)),) + if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys$(EXE); fi endif -ifneq ($(filter $(PROGRAM_PREFIX)yosys-abc,$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-abc; fi +ifneq ($(filter $(PROGRAM_PREFIX)yosys-abc$(EXE),$(TARGETS)),) + if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-abc$(EXE); fi endif -ifneq ($(filter $(PROGRAM_PREFIX)yosys-filterlib,$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-filterlib; fi +ifneq ($(filter $(PROGRAM_PREFIX)yosys-filterlib$(EXE),$(TARGETS)),) + if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-filterlib$(EXE); fi endif $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR) $(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/. @@ -1153,16 +1093,8 @@ clean: clean-py clean-unit-test rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) rm -f kernel/version_*.o kernel/version_*.cc rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d - rm -rf tests/asicworld/*.out tests/asicworld/*.log - rm -rf tests/hana/*.out tests/hana/*.log - rm -rf tests/simple/*.out tests/simple/*.log - rm -rf tests/memories/*.out tests/memories/*.log tests/memories/*.dmp - rm -rf tests/sat/*.log tests/techmap/*.log tests/various/*.log - rm -rf tests/bram/temp tests/fsm/temp tests/realmath/temp tests/share/temp tests/smv/temp tests/various/temp rm -rf vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_* - rm -f tests/svinterfaces/*.log_stdout tests/svinterfaces/*.log_stderr tests/svinterfaces/dut_result.txt tests/svinterfaces/reference_result.txt tests/svinterfaces/a.out tests/svinterfaces/*_syn.v tests/svinterfaces/*.diff - rm -f tests/tools/cmp_tbdata - rm -f $(addsuffix /run-test.mk,$(MK_TEST_DIRS)) + -$(MAKE) -C $(YOSYS_SRC)/tests clean -$(MAKE) -C $(YOSYS_SRC)/docs clean rm -rf docs/util/__pycache__ rm -f libyosys.so diff --git a/README.md b/README.md index 427d59c9e..df65a6a10 100644 --- a/README.md +++ b/README.md @@ -114,8 +114,8 @@ To build Yosys simply type 'make' in this directory. $ sudo make install Tests are located in the tests subdirectory and can be executed using the test -target. Note that you need gawk as well as a recent version of iverilog (i.e. -build from git). Then, execute tests via: +target. Note that you need gawk, a recent version of iverilog, and gtest. +Execute tests via: $ make test @@ -246,6 +246,8 @@ Building the documentation Note that there is no need to build the manual if you just want to read it. Simply visit https://yosys.readthedocs.io/en/latest/ instead. +If you're offline, you can read the sources, replacing `.../en/latest` +with `docs/source`. In addition to those packages listed above for building Yosys from source, the following are used for building the website: diff --git a/abc b/abc index 9182a8048..5d51a5e42 160000 --- a/abc +++ b/abc @@ -1 +1 @@ -Subproject commit 9182a8048d0bc86b39a6cb6b0488a7e1d10b2607 +Subproject commit 5d51a5e420f5de493d07bf61109a977248c86ffb diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 95f4c19e2..0c49e84b8 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -930,7 +930,9 @@ struct AigerBackend : public Backend { log(" make indexes zero based, enable using map files with smt solvers.\n"); log("\n"); log(" -ywmap \n"); - log(" write a map file for conversion to and from yosys witness traces.\n"); + log(" write a map file for conversion to and from yosys witness traces,\n"); + log(" also allows for mapping AIGER bad-state properties and invariant\n"); + log(" constraints back to individual formal properties by name.\n"); log("\n"); log(" -I, -O, -B, -L\n"); log(" If the design contains no input/output/assert/flip-flop then create one\n"); diff --git a/backends/aiger2/aiger.cc b/backends/aiger2/aiger.cc index babc29826..2f28869d9 100644 --- a/backends/aiger2/aiger.cc +++ b/backends/aiger2/aiger.cc @@ -21,9 +21,12 @@ // - gracefully handling inout ports (an error message probably) // - undriven wires // - zero-width operands +// - decide how to unify this with cellaigs +// - break up Index into something smaller +// - (C++20) remove snprintf-into-std::ostream weirdness #include "kernel/register.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/rtlil.h" USING_YOSYS_NAMESPACE @@ -45,8 +48,22 @@ PRIVATE_NAMESPACE_BEGIN // TODO //#define ARITH_OPS ID($add), ID($sub), ID($neg) -#define KNOWN_OPS BITWISE_OPS, REDUCE_OPS, LOGIC_OPS, GATE_OPS, ID($pos), CMP_OPS, \ - ID($pmux), ID($bmux) /*, ARITH_OPS*/ +static constexpr auto known_ops = []() constexpr { + StaticCellTypes::Categories::Category c{}; + for (auto id : {BITWISE_OPS}) + c.set_id(id); + for (auto id : {REDUCE_OPS}) + c.set_id(id); + for (auto id : {LOGIC_OPS}) + c.set_id(id); + for (auto id : {GATE_OPS}) + c.set_id(id); + for (auto id : {CMP_OPS}) + c.set_id(id); + for (auto id : {ID($pos), ID($pmux), ID($bmux)}) + c.set_id(id); + return c; +}(); template struct Index { @@ -92,7 +109,7 @@ struct Index { int pos = index_wires(info, m); for (auto cell : m->cells()) { - if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port))) + if (known_ops(cell->type) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port))) continue; Module *submodule = m->design->module(cell->type); @@ -104,7 +121,7 @@ struct Index { pos += index_module(submodule); } else { if (allow_blackboxes) { - info.found_blackboxes.insert(cell); + info.found_blackboxes.insert(cell); } else { // Even if we don't allow blackboxes these might still be // present outside of any traversed input cones, so we @@ -163,6 +180,11 @@ struct Index { if (!strashing) { return (static_cast(this))->emit_gate(a, b); } else { + // AigMaker::node2index + + // In XAIGER, the ordering of inputs is used to distinguish between AND + // and XOR gates. AND gates have their first input literal be larger + // than their second, and vice-versa for XORs. if (a < b) std::swap(a, b); auto pair = std::make_pair(a, b); @@ -183,7 +205,9 @@ struct Index { Lit OR(Lit a, Lit b) { - return NOT(AND(NOT(a), NOT(b))); + Lit not_a = NOT(a); + Lit not_b = NOT(b); + return NOT(AND(not_a, not_b)); } Lit MUX(Lit a, Lit b, Lit s) @@ -197,17 +221,24 @@ struct Index { return b; } - return OR(AND(a, NOT(s)), AND(b, s)); + Lit not_s = NOT(s); + Lit a_active = AND(a, not_s); + Lit b_active = AND(b, s); + return OR(a_active, b_active); } Lit XOR(Lit a, Lit b) { - return OR(AND(a, NOT(b)), AND(NOT(a), b)); + Lit not_a = NOT(a); + Lit not_b = NOT(b); + Lit a_and_not_b = AND(a, not_b); + Lit not_a_and_b = AND(not_a, b); + return OR(a_and_not_b, not_a_and_b); } Lit XNOR(Lit a, Lit b) { - return NOT(OR(AND(a, NOT(b)), AND(NOT(a), b))); + return NOT(XOR(a, b)); } Lit CARRY(Lit a, Lit b, Lit c) @@ -219,7 +250,10 @@ struct Index { return AND(a, b); } } - return OR(AND(a, b), AND(c, OR(a, b))); + Lit a_or_b = OR(a, b); + Lit a_or_b_and_c = AND(c, a_or_b); + Lit a_and_b = AND(a, b); + return OR(a_and_b, a_or_b_and_c); } Lit REDUCE(std::vector lits, bool op_xor=false) @@ -269,7 +303,7 @@ struct Index { } else if (cell->type.in(ID($lt), ID($le), ID($gt), ID($ge))) { if (cell->type.in(ID($gt), ID($ge))) std::swap(aport, bport); - int carry = cell->type.in(ID($le), ID($ge)) ? CFALSE : CTRUE; + int carry = cell->type.in(ID($le), ID($ge)) ? CFALSE : CTRUE; Lit a = Writer::EMPTY_LIT; Lit b = Writer::EMPTY_LIT; // TODO: this might not be the most economic structure; revisit at a later date @@ -367,7 +401,7 @@ struct Index { } else if (cell->type.in(ID($xor), ID($_XOR_))) { return XOR(a, b); } else if (cell->type.in(ID($xnor), ID($_XNOR_))) { - return NOT(XOR(a, b)); + return XNOR(a, b); } else if (cell->type.in(ID($_ANDNOT_))) { return AND(a, NOT(b)); } else if (cell->type.in(ID($_ORNOT_))) { @@ -387,7 +421,9 @@ struct Index { if (oport == ID::Y) { return XOR(ab, c); } else /* oport == ID::X */ { - return OR(AND(a, b), AND(c, ab)); + Lit a_and_b = AND(a, b); + Lit c_and_ab = AND(c, ab); + return OR(a_and_b, c_and_ab); } } else if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { Lit c, d; @@ -398,10 +434,15 @@ struct Index { else d = cell->type == ID($_AOI3_) ? CTRUE : CFALSE; - if (/* aoi */ cell->type.in(ID($_AOI3_), ID($_AOI4_))) - return NOT(OR(AND(a, b), AND(c, d))); - else - return NOT(AND(OR(a, b), OR(c, d))); + if (/* aoi */ cell->type.in(ID($_AOI3_), ID($_AOI4_))) { + Lit a_and_b = AND(a, b); + Lit c_and_d = AND(c, d); + return NOT(OR(a_and_b, c_and_d)); + } else { + Lit a_or_b = OR(a, b); + Lit c_or_d = OR(c, d); + return NOT(AND(a_or_b, c_or_d)); + } } else { log_abort(); } @@ -422,7 +463,11 @@ struct Index { sels.push_back(NOT(s)); } - return OR(AND(REDUCE(sels), a), NOT(REDUCE(bar))); + Lit reduce_sels = REDUCE(sels); + Lit reduce_sels_and_a = AND(reduce_sels, a); + Lit reduce_bar = NOT(REDUCE(bar)); + + return OR(reduce_sels_and_a, reduce_bar); } else if (cell->type == ID($bmux)) { SigSpec aport = cell->getPort(ID::A); SigSpec sport = cell->getPort(ID::S); @@ -492,7 +537,7 @@ struct Index { Design *design = index.design; auto &minfo = leaf_minfo(index); if (!minfo.suboffsets.count(cell)) - log_error("Reached unsupport cell %s (%s in %s)\n", log_id(cell->type), log_id(cell), log_id(cell->module)); + log_error("Reached unsupported cell %s (%s in %s)\n", log_id(cell->type), log_id(cell), log_id(cell->module)); Module *def = design->module(cell->type); log_assert(def); levels.push_back(Level(index.modules.at(def), cell)); @@ -511,13 +556,13 @@ struct Index { { std::string ret; bool first = true; - for (auto pair : levels) { + for (auto [minfo, cell] : levels) { if (!first) ret += "."; - if (!pair.second) - ret += RTLIL::unescape_id(pair.first.module->name); + if (!cell) + ret += RTLIL::unescape_id(minfo.module->name); else - ret += RTLIL::unescape_id(pair.second->name); + ret += RTLIL::unescape_id(cell->name); first = false; } return ret; @@ -526,8 +571,8 @@ struct Index { int hash() const { int hash = 0; - for (auto pair : levels) - hash += (uintptr_t) pair.second; + for (auto [_, cell] : levels) + hash += (uintptr_t) cell; return hash; } @@ -536,9 +581,12 @@ struct Index { if (levels.size() != other.levels.size()) return false; - for (int i = 0; i < levels.size(); i++) - if (levels[i].second != other.levels[i].second) + for (int i = 0; i < levels.size(); i++) { + auto* cell = levels[i].second; + auto* other_cell = other.levels[i].second; + if (cell != other_cell) return false; + } return true; } @@ -579,7 +627,7 @@ struct Index { // an output of a cell Cell *driver = bit.wire->driverCell(); - if (driver->type.in(KNOWN_OPS)) { + if (known_ops(driver->type)) { ret = impl_op(cursor, driver, bit.wire->driverPort(), bit.offset); } else { Module *def = cursor.enter(*this, driver); @@ -701,6 +749,9 @@ struct AigerWriter : Index { nands++; lit_counter += 2; + // In XAIGER, the ordering of inputs is used to distinguish between AND + // and XOR gates. AND gates have their first input literal be larger + // than their second, and vice-versa for XORs. if (a < b) std::swap(a, b); encode(out - a); encode(a - b); @@ -717,7 +768,7 @@ struct AigerWriter : Index { log_assert(lit_counter == (Lit) (ninputs + nlatches + nands) * 2 + 2); char buf[128]; - snprintf(buf, sizeof(buf) - 1, "aig %08d %08d %08d %08d %08d\n", + snprintf(buf, sizeof(buf), "aig %08d %08d %08d %08d %08d\n", ninputs + nlatches + nands, ninputs, nlatches, noutputs, nands); f->write(buf, strlen(buf)); } @@ -730,15 +781,16 @@ struct AigerWriter : Index { // populate inputs std::vector inputs; for (auto id : top->ports) { - Wire *w = top->wire(id); - log_assert(w); - if (w->port_input && !w->port_output) - for (int i = 0; i < w->width; i++) { - pi_literal(SigBit(w, i)) = lit_counter; - inputs.push_back(SigBit(w, i)); - lit_counter += 2; - ninputs++; - } + Wire *w = top->wire(id); + log_assert(w); + if (w->port_input && !w->port_output) + for (int i = 0; i < w->width; i++) { + auto bit = SigBit(w, i); + pi_literal(bit) = lit_counter; + inputs.push_back(bit); + lit_counter += 2; + ninputs++; + } } this->f = f; @@ -746,35 +798,38 @@ struct AigerWriter : Index { write_header(); // insert padding where output literals will go (once known) for (auto id : top->ports) { - Wire *w = top->wire(id); - log_assert(w); - if (w->port_output) { - for (auto bit : SigSpec(w)) { - (void) bit; - char buf[16]; - snprintf(buf, sizeof(buf) - 1, "%08d\n", 0); - f->write(buf, strlen(buf)); - noutputs++; + Wire *w = top->wire(id); + log_assert(w); + if (w->port_output) { + for (auto bit : SigSpec(w)) { + (void) bit; + char buf[16]; + snprintf(buf, sizeof(buf), "%08d\n", 0); + f->write(buf, strlen(buf)); + noutputs++; + } } } - } auto data_start = f->tellp(); // now the guts std::vector> outputs; for (auto w : top->wires()) - if (w->port_output) { - for (auto bit : SigSpec(w)) - outputs.push_back({bit, eval_po(bit)}); - } + if (w->port_output) { + for (auto bit : SigSpec(w)) + // Each call to eval_po eventually reaches emit_gate and + // encode which writes to f. + outputs.push_back({bit, eval_po(bit)}); + } + auto data_end = f->tellp(); // revisit header and the list of outputs f->seekp(file_start); write_header(); - for (auto pair : outputs) { + for (auto [_, po] : outputs) { char buf[16]; - snprintf(buf, sizeof(buf) - 1, "%08d\n", pair.second); + snprintf(buf, sizeof(buf), "%08d\n", po); f->write(buf, strlen(buf)); } // double check we arrived at the same offset for the @@ -783,12 +838,13 @@ struct AigerWriter : Index { f->seekp(data_end); int i = 0; - for (auto pair : outputs) { - if (SigSpec(pair.first).is_wire()) { + for (auto [bit, _] : outputs) { + if (SigSpec(bit).is_wire()) { + // primary output symbol char buf[32]; - snprintf(buf, sizeof(buf) - 1, "o%d ", i); + snprintf(buf, sizeof(buf), "o%d ", i); f->write(buf, strlen(buf)); - std::string name = RTLIL::unescape_id(pair.first.wire->name); + std::string name = RTLIL::unescape_id(bit.wire->name); f->write(name.data(), name.size()); f->put('\n'); } @@ -797,8 +853,9 @@ struct AigerWriter : Index { i = 0; for (auto bit : inputs) { if (SigSpec(bit).is_wire()) { + // primary input symbol char buf[32]; - snprintf(buf, sizeof(buf) - 1, "i%d ", i); + snprintf(buf, sizeof(buf), "i%d ", i); f->write(buf, strlen(buf)); std::string name = RTLIL::unescape_id(bit.wire->name); f->write(name.data(), name.size()); @@ -871,33 +928,34 @@ struct XAigerAnalysis : Index { Wire *w = top->wire(id); log_assert(w); if (w->port_input && !w->port_output) - for (int i = 0; i < w->width; i++) - pi_literal(SigBit(w, i)) = 0; + for (int i = 0; i < w->width; i++) + pi_literal(SigBit(w, i)) = 0; } HierCursor cursor; for (auto box : top_minfo->found_blackboxes) { Module *def = design->module(box->type); if (!(def && def->has_attribute(ID::abc9_box_id))) - for (auto &conn : box->connections_) - if (box->port_dir(conn.first) != RTLIL::PD_INPUT) - for (auto bit : conn.second) - pi_literal(bit, &cursor) = 0; + for (auto &conn : box->connections_) + if (box->port_dir(conn.first) != RTLIL::PD_INPUT) + for (auto bit : conn.second) + pi_literal(bit, &cursor) = 0; } - for (auto w : top->wires()) - if (w->port_output) { - for (auto bit : SigSpec(w)) - (void) eval_po(bit); + for (auto w : top->wires()) { + if (w->port_output) { + for (auto bit : SigSpec(w)) + (void) eval_po(bit); + } } for (auto box : top_minfo->found_blackboxes) { Module *def = design->module(box->type); if (!(def && def->has_attribute(ID::abc9_box_id))) - for (auto &conn : box->connections_) - if (box->port_dir(conn.first) == RTLIL::PD_INPUT) - for (auto bit : conn.second) - (void) eval_po(bit); + for (auto &conn : box->connections_) + if (box->port_dir(conn.first) == RTLIL::PD_INPUT) + for (auto bit : conn.second) + (void) eval_po(bit); } } }; @@ -916,15 +974,15 @@ struct XAigerWriter : AigerWriter { std::vector pos; std::vector pis; - // * The aiger output port sequence is COs (inputs to modeled boxes), - // inputs to opaque boxes, then module outputs. COs going first is - // required by abc. - // * proper_pos_counter counts ports which follow after COs - // * The mapping file `pseudopo` and `po` statements use indexing relative - // to the first port following COs. - // * If a module output is directly driven by an opaque box, the emission - // of the po statement in the mapping file is skipped. This is done to - // aid re-integration of the mapped result. + // * The aiger output port sequence is COs (inputs to modeled boxes), + // inputs to opaque boxes, then module outputs. COs going first is + // required by abc. + // * proper_pos_counter counts ports which follow after COs + // * The mapping file `pseudopo` and `po` statements use indexing relative + // to the first port following COs. + // * If a module output is directly driven by an opaque box, the emission + // of the po statement in the mapping file is skipped. This is done to + // aid re-integration of the mapped result. int proper_pos_counter = 0; pool driven_by_opaque_box; @@ -1202,29 +1260,29 @@ struct XAigerWriter : AigerWriter { reset_counters(); for (auto w : top->wires()) - if (w->port_input && !w->port_output) - for (int i = 0; i < w->width; i++) - ensure_pi(SigBit(w, i)); + if (w->port_input && !w->port_output) + for (int i = 0; i < w->width; i++) + ensure_pi(SigBit(w, i)); int proper_po_num = 0; for (auto w : top->wires()) - if (w->port_output) - proper_po_num += w->width; + if (w->port_output) + proper_po_num += w->width; prep_boxes(proper_po_num); for (auto w : top->wires()) - if (w->port_output) - for (int i = 0; i < w->width; i++) { - // When a module output is directly driven by an opaque box, we - // don't emit it to the mapping file to aid re-integration, but we - // do emit a proper PO. - if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) { - map_file << "po " << proper_pos_counter << " " << i - << " " << w->name.c_str() << "\n"; - } - proper_pos_counter++; - pos.push_back(std::make_pair(SigBit(w, i), HierCursor{})); - } + if (w->port_output) + for (int i = 0; i < w->width; i++) { + // When a module output is directly driven by an opaque box, we + // don't emit it to the mapping file to aid re-integration, but we + // do emit a proper PO. + if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) { + map_file << "po " << proper_pos_counter << " " << i + << " " << w->name.c_str() << "\n"; + } + proper_pos_counter++; + pos.push_back(std::make_pair(SigBit(w, i), HierCursor{})); + } this->f = f; // start with the header @@ -1234,7 +1292,7 @@ struct XAigerWriter : AigerWriter { // insert padding where output literals will go (once known) for (auto _ : pos) { char buf[16]; - snprintf(buf, sizeof(buf) - 1, "%08d\n", 0); + snprintf(buf, sizeof(buf), "%08d\n", 0); f->write(buf, strlen(buf)); } auto data_start = f->tellp(); @@ -1251,35 +1309,36 @@ struct XAigerWriter : AigerWriter { write_header(); for (auto lit : outlits) { char buf[16]; - snprintf(buf, sizeof(buf) - 1, "%08d\n", lit); + snprintf(buf, sizeof(buf), "%08d\n", lit); f->write(buf, strlen(buf)); } // double check we arrived at the same offset for the // main data section log_assert(data_start == f->tellp()); - // extensions + // XAIGER extensions f->seekp(0, std::ios::end); - f->put('c'); + f->put('c'); // 'c': comment (marks beginning of extensions) // insert empty 'r' and 's' sections (abc crashes if we provide 'a' without those) - f->put('r'); - write_be32(*f, 4); - write_be32(*f, 0); - f->put('s'); - write_be32(*f, 4); - write_be32(*f, 0); + f->put('r'); // 'r': register classes + write_be32(*f, 4); // length in bytes + write_be32(*f, 0); // no register classes - f->put('h'); + f->put('s'); // 's': register initial values + write_be32(*f, 4); // length in bytes + write_be32(*f, 0); // no register initial values + + f->put('h'); // 'h': hierarchy information // TODO: get rid of std::string copy std::string h_buffer_str = h_buffer.str(); - write_be32(*f, h_buffer_str.size()); - f->write(h_buffer_str.data(), h_buffer_str.size()); + write_be32(*f, h_buffer_str.size()); // length in bytes + f->write(h_buffer_str.data(), h_buffer_str.size()); // data #if 1 - f->put('a'); - write_be32(*f, 0); // size to be filled later + f->put('a'); // 'a': additional AIG (used for holes) + write_be32(*f, 0); // length in bytes (to be filled later) auto holes_aiger_start = f->tellp(); { AigerWriter holes_writer; @@ -1291,7 +1350,7 @@ struct XAigerWriter : AigerWriter { auto holes_aiger_size = f->tellp() - holes_aiger_start; f->seekp(holes_aiger_start, std::ios::beg); f->seekp(-4, std::ios::cur); - write_be32(*f, holes_aiger_size); + write_be32(*f, holes_aiger_size); // length in bytes #endif f->seekp(0, std::ios::end); @@ -1331,41 +1390,50 @@ struct Aiger2Backend : Backend { log(" perform structural hashing while writing\n"); log("\n"); log(" -flatten\n"); - log(" allow descending into submodules and write a flattened view of the design\n"); - log(" hierarchy starting at the selected top\n"); - log("\n"); + log(" allow descending into submodules and write a flattened view of the design\n"); + log(" hierarchy starting at the selected top\n"); + log("\n"); log("This command is able to ingest all combinational cells except for:\n"); log("\n"); - pool supported = {KNOWN_OPS}; - CellTypes ct; - ct.setup_internals_eval(); log(" "); int col = 0; - for (auto pair : ct.cell_types) - if (!supported.count(pair.first)) { - if (col + pair.first.size() + 2 > 72) { + for (size_t i = 0; i < StaticCellTypes::builder.count; i++) { + auto &cell = StaticCellTypes::builder.cells[i]; + if (!cell.features.is_evaluable) + continue; + if (cell.features.is_stdcell) + continue; + if (known_ops(cell.type)) + continue; + std::string name = log_id(cell.type); + if (col + name.size() + 2 > 72) { log("\n "); col = 0; } - col += pair.first.size() + 2; - log("%s, ", log_id(pair.first)); + col += name.size() + 2; + log("%s, ", name.c_str()); } log("\n"); log("\n"); log("And all combinational gates except for:\n"); log("\n"); - CellTypes ct2; - ct2.setup_stdcells(); log(" "); col = 0; - for (auto pair : ct2.cell_types) - if (!supported.count(pair.first)) { - if (col + pair.first.size() + 2 > 72) { + for (size_t i = 0; i < StaticCellTypes::builder.count; i++) { + auto &cell = StaticCellTypes::builder.cells[i]; + if (!cell.features.is_evaluable) + continue; + if (!cell.features.is_stdcell) + continue; + if (known_ops(cell.type)) + continue; + std::string name = log_id(cell.type); + if (col + name.size() + 2 > 72) { log("\n "); col = 0; } - col += pair.first.size() + 2; - log("%s, ", log_id(pair.first)); + col += name.size() + 2; + log("%s, ", name.c_str()); } log("\n"); } @@ -1423,20 +1491,20 @@ struct XAiger2Backend : Backend { log(" perform structural hashing while writing\n"); log("\n"); log(" -flatten\n"); - log(" allow descending into submodules and write a flattened view of the design\n"); - log(" hierarchy starting at the selected top\n"); - log("\n"); - log(" -mapping_prep\n"); - log(" after the file is written, prepare the module for reintegration of\n"); - log(" a mapping in a subsequent command. all cells which are not blackboxed nor\n"); - log(" whiteboxed are removed from the design as well as all wires which only\n"); - log(" connect to removed cells\n"); - log(" (conflicts with -flatten)\n"); - log("\n"); - log(" -map2 \n"); - log(" write a map2 file which 'read_xaiger2 -sc_mapping' can read to\n"); - log(" reintegrate a mapping\n"); - log(" (conflicts with -flatten)\n"); + log(" allow descending into submodules and write a flattened view of the design\n"); + log(" hierarchy starting at the selected top\n"); + log("\n"); + log(" -mapping_prep\n"); + log(" after the file is written, prepare the module for reintegration of\n"); + log(" a mapping in a subsequent command. all cells which are not blackboxed nor\n"); + log(" whiteboxed are removed from the design as well as all wires which only\n"); + log(" connect to removed cells\n"); + log(" (conflicts with -flatten)\n"); + log("\n"); + log(" -map2 \n"); + log(" write a map2 file which 'read_xaiger2 -sc_mapping' can read to\n"); + log(" reintegrate a mapping\n"); + log(" (conflicts with -flatten)\n"); log("\n"); } diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index ab7861802..cc339bcbc 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -24,7 +24,7 @@ #include "kernel/rtlil.h" #include "kernel/register.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/log.h" #include @@ -44,6 +44,7 @@ struct BlifDumperConfig bool iattr_mode; bool blackbox_mode; bool noalias_mode; + bool gatesi_mode; std::string buf_type, buf_in, buf_out; std::map> unbuf_types; @@ -51,7 +52,7 @@ struct BlifDumperConfig BlifDumperConfig() : icells_mode(false), conn_mode(false), impltf_mode(false), gates_mode(false), cname_mode(false), iname_mode(false), param_mode(false), attr_mode(false), iattr_mode(false), - blackbox_mode(false), noalias_mode(false) { } + blackbox_mode(false), noalias_mode(false), gatesi_mode(false) { } }; struct BlifDumper @@ -60,7 +61,7 @@ struct BlifDumper RTLIL::Module *module; RTLIL::Design *design; BlifDumperConfig *config; - CellTypes ct; + NewCellTypes ct; SigMap sigmap; dict init_bits; @@ -118,16 +119,21 @@ struct BlifDumper return str; } - const std::string str_init(RTLIL::SigBit sig) + template const std::string str_init(RTLIL::SigBit sig) { sigmap.apply(sig); - if (init_bits.count(sig) == 0) - return " 2"; + if (init_bits.count(sig) == 0) { + if constexpr (Space) + return " 2"; + else + return "2"; + } - string str = stringf(" %d", init_bits.at(sig)); - - return str; + if constexpr (Space) + return stringf(" %d", init_bits.at(sig)); + else + return stringf("%d", init_bits.at(sig)); } const char *subckt_or_gate(std::string cell_type) @@ -469,6 +475,11 @@ struct BlifDumper f << stringf(".names %s %s\n1 1\n", str(rhs_bit), str(lhs_bit)); } + if (config->gatesi_mode) { + for (auto &&init_bit : init_bits) + f << stringf(".gateinit %s=%s\n", str(init_bit.first), str_init(init_bit.first)); + } + f << stringf(".end\n"); } @@ -550,6 +561,9 @@ struct BlifBackend : public Backend { log(" -impltf\n"); log(" do not write definitions for the $true, $false and $undef wires.\n"); log("\n"); + log(" -gatesi\n"); + log(" write initial bit(s) with .gateinit for gates that needs to be initialized.\n"); + log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override { @@ -640,6 +654,10 @@ struct BlifBackend : public Backend { config.noalias_mode = true; continue; } + if (args[argidx] == "-gatesi") { + config.gatesi_mode = true; + continue; + } break; } extra_args(f, filename, args, argidx); diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 71913d2db..ab5576e43 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2776,7 +2776,8 @@ struct CxxrtlWorker { { RTLIL::Module *top_module = nullptr; std::vector modules; - TopoSort topo_design; + using Order = IdString::compare_ptr_by_name; + TopoSort topo_design; for (auto module : design->modules()) { if (!design->selected_module(module)) continue; diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h index fbbe2373f..521cce4b0 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl.h @@ -614,7 +614,7 @@ struct value : public expr_base> { int64_t divisor_shift = divisor.ctlz() - dividend.ctlz(); assert(divisor_shift >= 0); divisor = divisor.shl(value{(chunk::type) divisor_shift}); - for (size_t step = 0; step <= divisor_shift; step++) { + for (size_t step = 0; step <= (uint64_t) divisor_shift; step++) { quotient = quotient.shl(value{1u}); if (!dividend.ucmp(divisor)) { dividend = dividend.sub(divisor); @@ -1119,7 +1119,7 @@ struct fmt_part { case STRING: { buf.reserve(Bits/8); - for (int i = 0; i < Bits; i += 8) { + for (size_t i = 0; i < Bits; i += 8) { char ch = 0; for (int j = 0; j < 8 && i + j < int(Bits); j++) if (val.bit(i + j)) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 61d6ee254..145477b6b 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -23,7 +23,7 @@ #include "kernel/rtlil.h" #include "kernel/register.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/log.h" #include @@ -138,7 +138,7 @@ struct EdifBackend : public Backend { bool lsbidx = false; std::map> lib_cell_ports; bool nogndvcc = false, gndvccy = false, keepmode = false; - CellTypes ct(design); + NewCellTypes ct(design); EdifNames edif_names; size_t argidx; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 78eab17da..ad16d50ab 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -20,7 +20,7 @@ #include "kernel/rtlil.h" #include "kernel/register.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/log.h" #include @@ -117,7 +117,7 @@ struct IntersynthBackend : public Backend { std::set conntypes_code, celltypes_code; std::string netlists_code; - CellTypes ct(design); + NewCellTypes ct(design); for (auto lib : libs) ct.setup_design(lib); diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index d80622029..9d0ebc2aa 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -20,7 +20,7 @@ #include "kernel/rtlil.h" #include "kernel/register.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/log.h" #include "kernel/mem.h" #include "libs/json11/json11.hpp" @@ -32,7 +32,7 @@ PRIVATE_NAMESPACE_BEGIN struct Smt2Worker { - CellTypes ct; + NewCellTypes ct; SigMap sigmap; RTLIL::Module *module; bool bvmode, memmode, wiresmode, verbose, statebv, statedt, forallmode; diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index 4e47117b3..9dfbd2a25 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -735,6 +735,12 @@ def ywfile_signal(sig, step, mask=None): output = [] + def ywfile_signal_error(reason, detail=None): + msg = f"Yosys witness signal mismatch for {sig.pretty()}: {reason}" + if detail: + msg += f" ({detail})" + raise ValueError(msg) + if sig.path in smt_wires: for wire in smt_wires[sig.path]: width, offset = wire["width"], wire["offset"] @@ -765,6 +771,12 @@ def ywfile_signal(sig, step, mask=None): for mem in smt_mems[sig.memory_path]: width, size, bv = mem["width"], mem["size"], mem["statebv"] + if sig.memory_addr is not None and sig.memory_addr >= size: + ywfile_signal_error( + "memory address out of bounds", + f"address={sig.memory_addr} size={size}", + ) + smt_expr = smt.net_expr(topmod, f"s{step}", mem["smtpath"]) if bv: @@ -781,18 +793,34 @@ def ywfile_signal(sig, step, mask=None): smt_expr = "((_ extract %d %d) %s)" % (slice_high, sig.offset, smt_expr) output.append((0, sig.width, smt_expr)) + else: + ywfile_signal_error("memory not found in design") output.sort() output = [chunk for chunk in output if chunk[0] != chunk[1]] + if not output: + if sig.memory_path: + ywfile_signal_error("memory signal has no matching bits in design") + else: + ywfile_signal_error("signal not found in design") + pos = 0 for start, end, smt_expr in output: - assert start == pos + if start != pos: + ywfile_signal_error( + "signal width/offset mismatch", + f"expected coverage at bit {pos}", + ) pos = end - assert pos == sig.width + if pos != sig.width: + ywfile_signal_error( + "signal width/offset mismatch", + f"covered {pos} of {sig.width} bits", + ) if len(output) == 1: return output[0][-1] diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index a6ccbf27f..acefad060 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -20,7 +20,7 @@ #include "kernel/rtlil.h" #include "kernel/register.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/log.h" #include @@ -29,7 +29,7 @@ PRIVATE_NAMESPACE_BEGIN struct SmvWorker { - CellTypes ct; + NewCellTypes ct; SigMap sigmap; RTLIL::Module *module; std::ostream &f; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 8d77160fd..73ffcbf3e 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -95,7 +95,8 @@ bool VERILOG_BACKEND::id_is_verilog_escaped(const std::string &str) { PRIVATE_NAMESPACE_BEGIN -bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs, noparallelcase; +bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs, + noparallelcase, default_params; int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter; dict auto_name_map; std::set reg_wires; @@ -421,6 +422,13 @@ void dump_attributes(std::ostream &f, std::string indent, dictattributes, "\n", /*modattr=*/false, /*regattr=*/reg_wires.count(wire->name)); @@ -2143,6 +2151,9 @@ void dump_case_actions(std::ostream &f, std::string indent, RTLIL::CaseRule *cs) bool dump_proc_switch_ifelse(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw) { + if (sw->cases.empty()) + return true; + for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) { if ((*it)->compare.size() == 0) { break; @@ -2435,6 +2446,10 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) f << indent + " " << "reg " << id(initial_id) << " = 0;\n"; } + if (default_params) + for (auto p : module->parameter_default_values) + dump_parameter(f, indent + " ", p.first, p.second); + // first dump input / output according to their order in module->ports for (auto port : module->ports) dump_wire(f, indent + " ", module->wire(port)); @@ -2542,6 +2557,10 @@ struct VerilogBackend : public Backend { log(" use 'defparam' statements instead of the Verilog-2001 syntax for\n"); log(" cell parameters.\n"); log("\n"); + log(" -default_params\n"); + log(" emit module parameter declarations from\n"); + log(" parameter_default_values.\n"); + log("\n"); log(" -blackboxes\n"); log(" usually modules with the 'blackbox' attribute are ignored. with\n"); log(" this option set only the modules with the 'blackbox' attribute\n"); @@ -2579,6 +2598,7 @@ struct VerilogBackend : public Backend { siminit = false; simple_lhs = false; noparallelcase = false; + default_params = false; auto_prefix = ""; bool blackboxes = false; @@ -2639,6 +2659,10 @@ struct VerilogBackend : public Backend { defparam = true; continue; } + if (arg == "-defaultparams") { + default_params = true; + continue; + } if (arg == "-decimal") { decimal = true; continue; diff --git a/docs/source/_images/Makefile b/docs/source/_images/Makefile index 71f52c578..dc75c97c9 100644 --- a/docs/source/_images/Makefile +++ b/docs/source/_images/Makefile @@ -32,8 +32,9 @@ FORCE: TEX_FILES := $(shell find . -name *.tex) all_tex: $(TEX_FILES:.tex=.pdf) $(TEX_FILES:.tex=.svg) +# limit output size to US letter (same as latexpdf output) to avoid oversize error %.pdf: %.dot - $(FAKETIME) dot -Tpdf -o $@ $< + $(FAKETIME) dot -Tpdf -Gsize="8.5,11" -o $@ $< %.pdf: %.tex cd $(@D) && $(FAKETIME) pdflatex $(`. + +The reproduction steps are ideally a code-block (starting and ending with +triple backquotes) containing +the minimized design (Verilog or RTLIL), followed by a code-block containing +the minimized yosys script OR a command line call to yosys with +code-formatting (starting and ending with single backquotes). .. code-block:: markdown @@ -86,9 +57,9 @@ Reproduction Steps `yosys -p ': minimum sequence of commands;' min.v` -- alternatively can provide a single code-block which includes the minimized - design as a "here document" followed by the sequence of commands which - reproduce the error +Alternatively, you can provide a single code-block which includes the minimized +design as a "here document" followed by the sequence of commands which +reproduce the error + see :doc:`/using_yosys/more_scripting/load_design` for more on heredocs. @@ -101,7 +72,9 @@ Reproduction Steps # minimum sequence of commands ``` -- any environment variables or command line options should also be mentioned +Don't forget to mention: + +- any important environment variables or command line options - if the problem occurs for a range of values/designs, what is that range - if you're using an external tool, such as ``valgrind``, to detect the issue, what version of that tool are you using and what options are you giving it @@ -115,46 +88,57 @@ Reproduction Steps around Yosys such as OpenLane; you should instead minimize your input and reproduction steps to just the Yosys part. -"Expected Behaviour" -~~~~~~~~~~~~~~~~~~~~ +.. _MVCE: https://stackoverflow.com/help/minimal-reproducible-example +.. _how-to guide for bugpoint: https://yosys.readthedocs.io/en/latest/using_yosys/bugpoint.html -- if you have a similar design/script that doesn't give the error, include it - here as a reference -- if the bug is that an error *should* be raised but isn't, are there any other - commands with similar error messages - - -"Actual Behaviour" +Expected Behaviour ~~~~~~~~~~~~~~~~~~ -- any error messages go here -- any details relevant to the crash that were found with ``--trace`` or - ``--debug`` flags -- if you identified the point of failure in the source code, you could mention - it here, or as a comment below +Describe what you'd expect to happen when we follow the reproduction steps +if the bug was fixed. - + if possible, use a permalink to the source on GitHub - + you can browse the source repository for a certain commit with the failure +If you have a similar design/script that doesn't give the error, include it +here as a reference. If the bug is that an error *should* be raised but isn't, +note if there are any other commands with similar error messages. + + +Actual Behaviour +~~~~~~~~~~~~~~~~ + +Describe what you actually see when you follow the reproduction steps. + +This can include: + +* any error messages +* any details relevant to the crash that were found with ``--trace`` or + ``--debug`` flags +* the part of the source code that triggers the bug + + * if possible, use a permalink to the source on GitHub + * you can browse the source repository for a certain commit with the failure and open the source file, select the relevant lines (click on the line number for the first relevant line, then while holding shift click on the line number for the last relevant line), click on the ``...`` that appears and select "Copy permalink" - + should look something like + * should look something like ``https://github.com/YosysHQ/yosys/blob//path/to/file#L139-L147`` - + clicking on "Preview" should reveal a code block containing the lines of + * clicking on "Preview" should reveal a code block containing the lines of source specified, with a link to the source file at the given commit -Additional details +Additional Details ~~~~~~~~~~~~~~~~~~ -- once you have created the issue, any additional details can be added as a - comment on that issue -- could include any additional context as to what you were doing when you first - encountered the bug -- was this issue discovered through the use of a fuzzer -- if you've minimized the script, consider including the `bugpoint` script you - used, or the original script, e.g. +Anything else you think might be helpful or relevant when verifying or fixing +the bug. + +Once you have created the issue, any additional details can be added as a +comment on that issue. You can include any additional context as to what you +were doing when you first encountered the bug. + +If this issue discovered through the use of a fuzzer, ALWAYS declare that. +If you've minimized the script, consider including the `bugpoint` script you +used, or the original script, for example: .. code-block:: markdown @@ -171,8 +155,257 @@ Additional details Minimized from `yosys -p ': original sequence of commands to produce error;' design.v` -- if you're able to, it may also help to share the original un-minimized design - - + if the design is too big for a comment, consider turning it into a `Gist`_ +If possible, it may also help to share the original un-minimized design. +If the design is too big for a comment, consider turning it into a `Gist`_ .. _Gist: https://gist.github.com/ + +Contributing code +----------------- + +Code that matters +~~~~~~~~~~~~~~~~~ + +If you're adding complex functionality, or modifying core parts of yosys, +we highly recommend discussing your motivation and approach +ahead of time on the `Discourse forum`_. Please, be as explicit and concrete +as possible when explaining the motivation for what you're building. +Additionally, if you do so on the forum first before you starting hacking +away at C++, you might solve your problem without writing a single line +of code! + +PRs are considered for relevance, priority, and quality +based on their descriptions first, code second. + +Before you build or fix something, also search for existing `issues`_. + +We have open `developer 'jour fixe' (Dev JF) meetings`_ +where developers from YosysHQ and the +community come together to discuss open issues and PRs. This is also a good +place to talk to us about how to implement larger PRs. + +.. _`developer 'jour fixe' (Dev JF) meetings`: https://docs.google.com/document/d/1SapA6QAsJcsgwsdKJDgnGR2mr97pJjV4eeXg_TVJhRU/edit?usp=sharing +.. _`Discourse forum`: https://yosyshq.discourse.group/ +.. _`issues`: https://github.com/YosysHQ/yosys/issues + +Making sense +~~~~~~~~~~~~ + +Given enough effort, the behavior of any code can be figured out to any +desired extent. However, the author of the code is by far in the best +position to make this as easy as possible. + +Yosys is a long-standing project and has accumulated a lot of C-style code +that's not written to be read, just written to run. We improve this bit +by bit when opportunities arise, but it is what it is. +New additions are expected to be a lot cleaner. + +The purpose and behavior of the code changed should be described clearly. +Your change should contain exactly what it needs to match that description. +This means: + +* nothing more than that - no dead code, no undocumented features +* nothing missing - if something is partially built, that's fine, + but you have to make that clear. For example, some passes + only support some types of cells + +Here are some software engineering approaches that help: + +* Use abstraction to model the problem and hide details + + * Maximize the usage of types (structs over loose variables), + not necessarily in an object-oriented way + * Use functions, scopes, type aliases + +* In new passes, make sure the logic behind how and why it works is actually provided + in coherent comments, and that variable and type naming is consistent with the terms + you use in the description. +* The logic of the implementation should be described in mathematical + or algorithm theory terms. Correctness, termination, computational complexity. + Make it clear if you're re-implementing a classic data structure for logic synthesis + or graph traversal etc. + +* There's various ways of traversing the design with use-def indices (for getting + drivers and driven signals) available in Yosys. They have advantages and sometimes + disadvantages. Prefer not re-implementing these +* Prefer references over pointers, and smart pointers over raw pointers +* Aggressively deduplicate code. Within functions, within passes, + across passes, even against existing code +* Prefer declaring things ``const`` +* Prefer range-based for loops over C-style + +Common mistakes +~~~~~~~~~~~~~~~ + +* Deleting design objects invalidates iterators. Defer deletions or hold a copy + of the list of pointers to design objects +* Deleting wires can get sketchy and is intended to be done solely by + the ``opt_clean`` pass so just don't do it +* Iterating over an entire design and checking if things are selected is more + inefficient than using the ``selected_*`` methods +* Remember to call ``fixup_ports`` at the end if you're modifying module interfaces + +Testing your change +~~~~~~~~~~~~~~~~~~~ + +Untested code can't be maintained. Inevitable codebase-wide changes +are likely to break anything untested. Tests also help reviewers understand +the purpose of the code change in practice. + +Your code needs to come with tests. If it's a feature, a test that covers +representative examples of the added behavior. If it's a bug fix, it should +reproduce the original isolated bug. But in some situations, adding a test +isn't viable. If you can't provide a test, explain this decision. + +Prefer writing unit tests (:file:`tests/unit`) for isolated tests to +the internals of more serious code changes, like those to the core of yosys, +or more algorithmic ones. + +The rest of the test suite is mostly based on running Yosys on various Yosys +and Tcl scripts that manually call Yosys commands. +See :doc:`/yosys_internals/extending_yosys/test_suites` for more information +about how our test suite is structured. +The basic test writing approach is checking +for the presence of some kind of object or pattern with ``-assert-count`` in +:doc:`/using_yosys/more_scripting/selections`. + +It's often best to use equivalence checking with ``equiv_opt -assert`` +or similar to prove that the changes done to the design by a modified pass +preserve equivalence. But some code isn't meant to preserve equivalence. +Sometimes proving equivalence takes an impractically long time for larger +inputs. Also beware, the ``equiv_`` passes are a bit quirky and might even +have incorrect results in unusual situations. + +.. Changes to core parts of Yosys or passes that are included in synthesis flows +.. can change runtime and memory usage - for the better or for worse. This strongly +.. depends on the design involved. Such risky changes should then be benchmarked +.. with various designs. + +.. TODO Emil benchmarking + +Coding style +~~~~~~~~~~~~ + +Yosys is written in C++17. + +In general Yosys uses ``int`` instead of ``size_t``. To avoid compiler warnings +for implicit type casts, always use ``GetSize(foobar)`` instead of +``foobar.size()``. (``GetSize()`` is defined in :file:`kernel/yosys.h`) + +For auto formatting code, a :file:`.clang-format` file is present top-level. +Yosys code is using tabs for indentation. A tab is 8 characters wide, +but prefer not relying on it. A continuation of a statement +in the following line is indented by two additional tabs. Lines are +as long as you want them to be. A good rule of thumb is to break lines +at about column 150. Opening braces can be put on the same or next line +as the statement opening the block (if, switch, for, while, do). +Put the opening brace on its own line for larger blocks, especially +blocks that contains blank lines. Remove trailing whitespace on sight. + +Otherwise stick to the `Linux Kernel Coding Style`_. + +.. _Linux Kernel Coding Style: https://www.kernel.org/doc/Documentation/process/coding-style.rst + +Pull requests (PRs) +~~~~~~~~~~~~~~~~~~~ + +If you are working on something to add to Yosys, or fix something that isn't +working quite right, +make a `pull request (PR)`_. + +An open PR, even as a draft, tells everyone that you're working on it and they +don't have to. It can also be a useful way to solicit feedback on in-progress +changes. + +We use `labels`_ to help categorise +issues and PRs. If a label seems relevant to your work, please do add it; this +also includes the labels beginning with 'status-'. The 'merge-' labels are used +by maintainers for tracking and communicating which PRs are ready and pending +merge; please do not use these labels if you are not a maintainer. + +.. _`pull request (PR)`: https://github.com/YosysHQ/yosys/pulls +.. _`labels`: https://github.com/YosysHQ/yosys/labels + +Git style +~~~~~~~~~ + +We don't have a strict commit message style. + +Some style hints: + +* Refactor and document existing code if you touch it, + but in separate commits from your functional changes +* Prefer smaller commits organized by good chunks. Git has a lot of features + like fixup commits, interactive rebase with autosquash + +Reviewing PRs +------------- + +Reviewing PRs is a totally valid form of external contributing to the project! + +Who's the reviewer? +~~~~~~~~~~~~~~~~~~~ + +YosysHQ GmbH is a company with a mandate to make decisions for the good +of YosysHQ open source software. It was co-founded by Claire Xenia Wolf, +the original author of Yosys. +Within it, we allocate reviews based on expertise with the topic at hand +as well as member time constraints. However, decisions including reviews +are also contributed by people external to the company. + +If you're intimately acquainted with a part of the codebase, we will be happy +to defer to your experience and have you review PRs. The official way we like +is our CODEOWNERS file in the git repository. What we're looking for in code +owners is activity and trust. For activity, if you're only interested in +a yosys pass for example for the time you spend writing a thesis, it might be +better to focus on writing good tests and docs in the PRs you submit rather than +to commit to code ownership and therefore to be responsible for fixing things +and reviewing other people's PRs at various unexpected points later. If you're +prolific in some part of the codebase and not a code owner, we still value your +experience and may tag you in PRs. + +As a matter of fact, the purpose of code ownership is to avoid maintainer +burnout by removing orphaned parts of the codebase. If you become a code owner +and stop being responsive, in the future, we might decide to remove such code +if convenient and costly to maintain. It's simply more respectful of the users' +time to explicitly cut something out than let it "bitrot". Larger projects like +LLVM or linux could not survive without such things, but Yosys is far smaller, +and there are implicit expectations of stability we aim to +respect within reason. + +.. TODO this deserves its own section elsewhere I think? But it would be distracting elsewhere + +Sometimes, multiple maintainers may add review comments. This is considered +healthy collaborative even if it might create disagreement at times. If +somebody is already reviewing a PR, others, even non-maintainers are free to +leave comments with extra observations and alternate perspectives in a +collaborative spirit. + +How to review +~~~~~~~~~~~~~ + +First, read everything above about contributing. Those are the values you +should gently enforce as a reviewer. They're ordered by importance, but +explicitly, descriptions are more important than code, long-form comments +describing the design are more important than piecemeal comments, etc. + +If a PR is poorly described, incomplete, tests are broken, or if the +author is not responding, please don't feel pressured to take over their +role by reverse engineering the code or fixing things for them, unless +there are good reasons to do so. + +If a PR author submits LLM outputs they haven't understood themselves, +they will not be able to implement feedback. Take this into consideration +as well. We do not ban LLM code from the codebase, we ban bad code. + +Reviewers may have diverse styles of communication while reviewing - one +may do one thorough review, another may prefer a back and forth with the +basics out the way before digging into the code. Generally, PRs may have +several requests for modifications and long discussions, but often +they just are good enough to merge as-is. + +The CI is required to go green for merging. New contributors need a CI +run to be triggered by a maintainer before their PRs take up computing +resources. It's a single click from the github web interface. +We test on various platforms and compilers. Sanitizer builds are only +tested on the main branch. diff --git a/docs/source/yosys_internals/extending_yosys/test_suites.rst b/docs/source/yosys_internals/extending_yosys/test_suites.rst index 81a79e77f..d3422b23a 100644 --- a/docs/source/yosys_internals/extending_yosys/test_suites.rst +++ b/docs/source/yosys_internals/extending_yosys/test_suites.rst @@ -8,7 +8,44 @@ Running the included test suite The Yosys source comes with a test suite to avoid regressions and keep everything working as expected. Tests can be run by calling ``make test`` from -the root Yosys directory. +the root Yosys directory. By default, this runs vanilla and unit tests. + +Vanilla tests +~~~~~~~~~~~~~ + +These make up the majority of our testing coverage. +They can be run with ``make vanilla-test`` and are based on calls to +make subcommands (``make makefile-tests``) and shell scripts +(``make seed-tests`` and ``make abcopt-tests``). Both use ``run-test.sh`` +files, but make-based tests only call ``tests/gen-tests-makefile.sh`` +to generate a makefile appropriate for the given directory, so only +afterwards when make is invoked do the tests actually run. + +Usually their structure looks something like this: +you write a .ys file that gets automatically run, +which runs a frontend like ``read_verilog`` or ``read_rtlil`` with +a relative path or a heredoc, then runs some commands including the command +under test, and then uses :doc:`/using_yosys/more_scripting/selections` +with ``-assert-count``. Usually it's unnecessary to "register" the test anywhere +as if it's being added to an existing directory, depending +on how the ``run-test.sh`` in that directory works. + +Unit tests +~~~~~~~~~~ + +Running the unit tests requires the following additional packages: + +.. tab:: Ubuntu + + .. code:: console + + sudo apt-get install libgtest-dev + +.. tab:: macOS + + No additional requirements. + +Unit tests can be run with ``make unit-test``. Functional tests ~~~~~~~~~~~~~~~~ @@ -41,23 +78,6 @@ instructions `_. Then, set the :makevar:`ENABLE_FUNCTIONAL_TESTS` make variable when calling ``make test`` and the functional tests will be run as well. -Unit tests -~~~~~~~~~~ - -Running the unit tests requires the following additional packages: - -.. tab:: Ubuntu - - .. code:: console - - sudo apt-get install libgtest-dev - -.. tab:: macOS - - No additional requirements. - -Unit tests can be run with ``make unit-test``. - Docs tests ~~~~~~~~~~ diff --git a/examples/aiger/README b/examples/aiger/README index 4e7694e95..13dce2035 100644 --- a/examples/aiger/README +++ b/examples/aiger/README @@ -14,7 +14,7 @@ in the PATH. E.g. extract the release to /usr/local/libexec/super_prove and then create a /usr/local/bin/super_prove file with the following contents (and "chmod +x" that file): - #!/bin/bash + #!/usr/bin/env bash exec /usr/local/libexec/super_prove/bin/super_prove.sh "$@" The "demo.sh" script also expects the "z3" SMT2 solver in the PATH for diff --git a/examples/aiger/demo.sh b/examples/aiger/demo.sh index 8728b6722..a1217bbd2 100644 --- a/examples/aiger/demo.sh +++ b/examples/aiger/demo.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex yosys -p ' read_verilog -formal demo.v diff --git a/examples/anlogic/build.sh b/examples/anlogic/build.sh index e0f6b4cfe..9b6e8c479 100755 --- a/examples/anlogic/build.sh +++ b/examples/anlogic/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex yosys demo.ys $TD_HOME/bin/td build.tcl diff --git a/examples/basys3/run.sh b/examples/basys3/run.sh index 10f059103..deb68d432 100644 --- a/examples/basys3/run.sh +++ b/examples/basys3/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash yosys run_yosys.ys vivado -nolog -nojournal -mode batch -source run_vivado.tcl vivado -nolog -nojournal -mode batch -source run_prog.tcl diff --git a/examples/cmos/testbench.sh b/examples/cmos/testbench.sh index 061704b64..856169ab9 100644 --- a/examples/cmos/testbench.sh +++ b/examples/cmos/testbench.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex diff --git a/examples/cmos/testbench_digital.sh b/examples/cmos/testbench_digital.sh index d7ab0fe1f..2e70e874c 100644 --- a/examples/cmos/testbench_digital.sh +++ b/examples/cmos/testbench_digital.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex diff --git a/examples/gowin/run.sh b/examples/gowin/run.sh index cd260101e..960624464 100644 --- a/examples/gowin/run.sh +++ b/examples/gowin/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex yosys -p "synth_gowin -top demo -vout demo_syn.v" demo.v $GOWIN_HOME/bin/gowin -d demo_syn.v -cst demo.cst -sdc demo.sdc -p GW1NR-9-QFN88-6 -pn GW1NR-LV9QN88C6/I5 -cfg device.cfg -bit -tr -ph -timing -gpa -rpt -warning_all diff --git a/examples/igloo2/runme.sh b/examples/igloo2/runme.sh index a08894e0a..7349ff603 100644 --- a/examples/igloo2/runme.sh +++ b/examples/igloo2/runme.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex yosys -p 'synth_sf2 -top example -edif netlist.edn -vlog netlist.vm' example.v export LM_LICENSE_FILE=${LM_LICENSE_FILE:-1702@localhost} diff --git a/examples/intel/DE2i-150/quartus_compile/runme_quartus b/examples/intel/DE2i-150/quartus_compile/runme_quartus index 83aa3b609..2bc29582c 100644 --- a/examples/intel/DE2i-150/quartus_compile/runme_quartus +++ b/examples/intel/DE2i-150/quartus_compile/runme_quartus @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash export REV="de2i" diff --git a/examples/intel/MAX10/runme_postsynth b/examples/intel/MAX10/runme_postsynth index f16210540..657c05fa8 100644 --- a/examples/intel/MAX10/runme_postsynth +++ b/examples/intel/MAX10/runme_postsynth @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash iverilog -D POST_IMPL -o verif_post -s tb_top tb_top.v top.vqm $(yosys-config --datdir/altera_intel/max10/cells_comb_max10.v) vvp -N verif_post diff --git a/examples/intel/asicworld_lfsr/run_cycloneiv b/examples/intel/asicworld_lfsr/run_cycloneiv index c7498bded..077b7fbde 100755 --- a/examples/intel/asicworld_lfsr/run_cycloneiv +++ b/examples/intel/asicworld_lfsr/run_cycloneiv @@ -1,2 +1,2 @@ -#!/bin/env bash +#!/usr/bin/env bash yosys -p "synth_intel -family cycloneiv -top lfsr_updown -vqm top.vqm" lfsr_updown.v diff --git a/examples/intel/asicworld_lfsr/run_max10 b/examples/intel/asicworld_lfsr/run_max10 index b75d552bb..8fccb57f8 100755 --- a/examples/intel/asicworld_lfsr/run_max10 +++ b/examples/intel/asicworld_lfsr/run_max10 @@ -1,2 +1,2 @@ -#!/bin/env bash +#!/usr/bin/env bash yosys -p "synth_intel -family max10 -top lfsr_updown -vqm top.vqm" lfsr_updown.v diff --git a/examples/intel/asicworld_lfsr/runme_postsynth b/examples/intel/asicworld_lfsr/runme_postsynth index c3b26b034..ad5ca39d4 100755 --- a/examples/intel/asicworld_lfsr/runme_postsynth +++ b/examples/intel/asicworld_lfsr/runme_postsynth @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash iverilog -D POST_IMPL -o verif_post -s tb lfsr_updown_tb.v top.vqm $(yosys-config --datdir/altera_intel/max10/cells_comb_max10.v) vvp -N verif_post diff --git a/examples/intel/asicworld_lfsr/runme_presynth b/examples/intel/asicworld_lfsr/runme_presynth index 51118bb4b..3ed6618d3 100755 --- a/examples/intel/asicworld_lfsr/runme_presynth +++ b/examples/intel/asicworld_lfsr/runme_presynth @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash iverilog -o presynth lfsr_updown_tb.v lfsr_updown.v &&\ diff --git a/examples/mimas2/run.sh b/examples/mimas2/run.sh index aafde78ed..b16341ece 100644 --- a/examples/mimas2/run.sh +++ b/examples/mimas2/run.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env sh set -e yosys run_yosys.ys edif2ngd example.edif diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 4df37c0cd..9931ef78f 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -37,7 +37,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "aigerparse.h" YOSYS_NAMESPACE_BEGIN @@ -286,10 +286,15 @@ end_of_header: RTLIL::IdString escaped_s = stringf("\\%s", s); RTLIL::Wire* wire; - if (c == 'i') wire = inputs[l1]; - else if (c == 'l') wire = latches[l1]; - else if (c == 'o') { + if (c == 'i') { + log_assert(l1 < inputs.size()); + wire = inputs[l1]; + } else if (c == 'l') { + log_assert(l1 < latches.size()); + wire = latches[l1]; + } else if (c == 'o') { wire = module->wire(escaped_s); + log_assert(l1 < outputs.size()); if (wire) { // Could have been renamed by a latch module->swap_names(wire, outputs[l1]); @@ -297,9 +302,9 @@ end_of_header: goto next; } wire = outputs[l1]; - } - else if (c == 'b') wire = bad_properties[l1]; - else log_abort(); + } else if (c == 'b') { + wire = bad_properties[l1]; + } else log_abort(); module->rename(wire, escaped_s); } @@ -652,6 +657,9 @@ void AigerReader::parse_aiger_binary() unsigned l1, l2, l3; std::string line; + if (M != I + L + A) + log_error("Binary AIGER input is malformed: maximum variable index M is %u, but number of inputs, latches and AND gates adds up to %u.\n", M, I + L + A); + // Parse inputs int digits = decimal_digits(I); for (unsigned i = 1; i <= I; ++i) { diff --git a/frontends/aiger2/xaiger.cc b/frontends/aiger2/xaiger.cc index 510da0be8..bbec47861 100644 --- a/frontends/aiger2/xaiger.cc +++ b/frontends/aiger2/xaiger.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN uint32_t read_be32(std::istream &f) { return ((uint32_t) f.get() << 24) | - ((uint32_t) f.get() << 16) | + ((uint32_t) f.get() << 16) | ((uint32_t) f.get() << 8) | (uint32_t) f.get(); } @@ -80,9 +80,9 @@ struct Xaiger2Frontend : public Frontend { extra_args(f, filename, args, argidx, true); if (map_filename.empty()) - log_error("A '-map2' argument required\n"); + log_error("A '-map2' argument is required\n"); if (module_name.empty()) - log_error("A '-module_name' argument required\n"); + log_error("A '-module_name' argument is required\n"); Module *module = design->module(module_name); if (!module) @@ -128,10 +128,10 @@ struct Xaiger2Frontend : public Frontend { int woffset; std::string name; if (!(map_file >> pi_idx >> woffset >> name)) - log_error("Bad map file (1)\n"); + log_error("Bad map file: couldn't read 'pi' line\n"); int lit = (2 * pi_idx) + 2; if (lit < 0 || lit >= (int) bits.size()) - log_error("Bad map file (2)\n"); + log_error("Bad map file: primary input literal out of range\n"); Wire *w = module->wire(name); if (!w || woffset < 0 || woffset >= w->width) log_error("Map file references non-existent signal bit %s[%d]\n", @@ -141,9 +141,9 @@ struct Xaiger2Frontend : public Frontend { int box_seq; std::string name; if (!(map_file >> box_seq >> name)) - log_error("Bad map file (20)\n"); + log_error("Bad map file: couldn't read 'box' line\n"); if (box_seq < 0) - log_error("Bad map file (21)\n"); + log_error("Bad map file: box out of range\n"); Cell *box = module->cell(RTLIL::escape_id(name)); if (!box) @@ -158,7 +158,7 @@ struct Xaiger2Frontend : public Frontend { } if (!def) - log_error("Bad map file (22)\n"); + log_error("Bad map file: no module found for box type '%s'\n", log_id(box->type)); if (box_seq >= (int) boxes.size()) { boxes.resize(box_seq + 1); @@ -403,15 +403,15 @@ struct Xaiger2Frontend : public Frontend { int woffset; std::string name; if (!(map_file >> po_idx >> woffset >> name)) - log_error("Bad map file (3)\n"); + log_error("Bad map file: couldn't read 'po' line\n"); po_idx += co_counter; if (po_idx < 0 || po_idx >= (int) outputs.size()) - log_error("Bad map file (4)\n"); + log_error("Bad map file: primary output index out of range\n"); int lit = outputs[po_idx]; if (lit < 0 || lit >= (int) bits.size()) - log_error("Bad map file (5)\n"); + log_error("Bad map file: primary output literal out of range\n"); if (bits[lit] == RTLIL::Sm) - log_error("Bad map file (6)\n"); + log_error("Bad map file: primary output literal is a marker\n"); Wire *w = module->wire(name); if (!w || woffset < 0 || woffset >= w->width) log_error("Map file references non-existent signal bit %s[%d]\n", @@ -423,15 +423,15 @@ struct Xaiger2Frontend : public Frontend { std::string box_name; std::string box_port; if (!(map_file >> po_idx >> poffset >> box_name >> box_port)) - log_error("Bad map file (7)\n"); + log_error("Bad map file: couldn't read 'pseudopo' line\n"); po_idx += co_counter; if (po_idx < 0 || po_idx >= (int) outputs.size()) - log_error("Bad map file (8)\n"); + log_error("Bad map file: pseudo primary output index out of range\n"); int lit = outputs[po_idx]; if (lit < 0 || lit >= (int) bits.size()) - log_error("Bad map file (9)\n"); + log_error("Bad map file: pseudo primary output literal out of range\n"); if (bits[lit] == RTLIL::Sm) - log_error("Bad map file (10)\n"); + log_error("Bad map file: pseudo primary output literal is a marker\n"); Cell *cell = module->cell(box_name); if (!cell || !cell->hasPort(box_port)) log_error("Map file references non-existent box port %s/%s\n", diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 984c4294c..c190bc7d4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -100,6 +100,7 @@ std::string AST::type2str(AstNodeType type) X(AST_CAST_SIZE) X(AST_CONCAT) X(AST_REPLICATE) + X(AST_ASSIGN_PATTERN) X(AST_BIT_NOT) X(AST_BIT_AND) X(AST_BIT_OR) @@ -696,6 +697,16 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const fprintf(f, "}}"); break; + case AST_ASSIGN_PATTERN: + fprintf(f, "'{"); + for (int i = 0; i < GetSize(children); i++) { + if (i != 0) + fprintf(f, ", "); + children[i]->dumpVlog(f, ""); + } + fprintf(f, "}"); + break; + if (0) { case AST_BIT_NOT: txt = "~"; } if (0) { case AST_REDUCE_AND: txt = "&"; } if (0) { case AST_REDUCE_OR: txt = "|"; } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index fd8ecddd7..f92b4a5b8 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -78,6 +78,7 @@ namespace AST AST_CAST_SIZE, AST_CONCAT, AST_REPLICATE, + AST_ASSIGN_PATTERN, AST_BIT_NOT, AST_BIT_AND, AST_BIT_OR, diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 86ea70b51..d9bafcd3a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -342,6 +342,9 @@ struct AST_INTERNAL::ProcessGenerator // The most recently assigned $print or $check cell \PRIORITY. int last_effect_priority; + // Track which signals have been assigned in current_case to avoid unnecessary removeSignalFromCaseTree calls + pool current_case_assigned_bits; + ProcessGenerator(std::unique_ptr a, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(std::move(a)), initSyncSignals(initSyncSignalsArg), last_effect_priority(0) { // rewrite lookahead references @@ -403,6 +406,18 @@ struct AST_INTERNAL::ProcessGenerator if (GetSize(syncrule->signal) != 1) always->input_error("Found posedge/negedge event on a signal that is not 1 bit wide!\n"); addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true); + // Automatic (nosync) variables must not become flip-flops: remove + // them from clocked sync rules so that proc_dff does not infer + // an unnecessary register for a purely combinational temporary. + syncrule->actions.erase( + std::remove_if(syncrule->actions.begin(), syncrule->actions.end(), + [](const RTLIL::SigSig &ss) { + for (auto &chunk : ss.first.chunks()) + if (chunk.wire && chunk.wire->get_bool_attribute(ID::nosync)) + return true; + return false; + }), + syncrule->actions.end()); proc->syncs.push_back(syncrule); } if (proc->syncs.empty()) { @@ -418,6 +433,10 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map = subst_lvalue_from.to_sigbit_dict(RTLIL::SigSpec(RTLIL::State::Sx, GetSize(subst_lvalue_from))); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); + // Track initial assignments + for (auto &bit : subst_lvalue_to) + if (bit.wire != NULL) + current_case_assigned_bits.insert(bit); } // process the AST @@ -545,14 +564,42 @@ struct AST_INTERNAL::ProcessGenerator // e.g. when the last statement in the code "a = 23; if (b) a = 42; a = 0;" is processed this // function is called to clean up the first two assignments as they are overwritten by // the third assignment. - void removeSignalFromCaseTree(const RTLIL::SigSpec &pattern, RTLIL::CaseRule *cs) + void removeSignalFromCaseTree(const pool &pattern_bits, RTLIL::CaseRule *cs) { - for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) - it->first.remove2(pattern, &it->second); + // Optimization: check actions in reverse order and stop early if we've found all pattern bits + pool remaining_bits = pattern_bits; + + for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ++it) { + bool has_pattern = false; + for (auto &bit : it->first) { + if (bit.wire != NULL && remaining_bits.count(bit)) { + has_pattern = true; + remaining_bits.erase(bit); + } + } + + if (has_pattern) { + it->first.remove2(pattern_bits, &it->second); + } + + // Early exit if we've processed all bits in pattern + if (remaining_bits.empty()) + break; + } for (auto it = cs->switches.begin(); it != cs->switches.end(); it++) for (auto it2 = (*it)->cases.begin(); it2 != (*it)->cases.end(); it2++) - removeSignalFromCaseTree(pattern, *it2); + removeSignalFromCaseTree(pattern_bits, *it2); + } + + void removeSignalFromCaseTree(const RTLIL::SigSpec &pattern, RTLIL::CaseRule *cs) + { + pool pattern_bits; + pattern_bits.reserve(pattern.size()); + for (auto &bit : pattern) + if (bit.wire != NULL) + pattern_bits.insert(bit); + removeSignalFromCaseTree(pattern_bits, cs); } // add an assignment (aka "action") but split it up in chunks. this way huge assignments @@ -611,7 +658,23 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map.set(unmapped_lvalue[i], rvalue[i]); } - removeSignalFromCaseTree(lvalue, current_case); + // Check if any bits in lvalue have been assigned before in current_case + bool has_overlap = false; + for (auto &bit : lvalue) { + if (bit.wire != NULL && current_case_assigned_bits.count(bit)) { + has_overlap = true; + break; + } + } + + if (has_overlap) + removeSignalFromCaseTree(lvalue, current_case); + + // Track newly assigned bits + for (auto &bit : lvalue) + if (bit.wire != NULL) + current_case_assigned_bits.insert(bit); + remove_unwanted_lvalue_bits(lvalue, rvalue); current_case->actions.push_back(RTLIL::SigSig(lvalue, rvalue)); } @@ -658,9 +721,15 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; + pool backup_assigned_bits = std::move(current_case_assigned_bits); + current_case_assigned_bits.clear(); set_src_attr(current_case, child.get()); last_generated_case = current_case; addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); + // Track temp assignments + for (auto &bit : this_case_eq_ltemp) + if (bit.wire != NULL) + current_case_assigned_bits.insert(bit); for (auto& node : child->children) { if (node->type == AST_DEFAULT) default_case = current_case; @@ -674,6 +743,7 @@ struct AST_INTERNAL::ProcessGenerator else log_assert(current_case->compare.size() == 0); current_case = backup_case; + current_case_assigned_bits = std::move(backup_assigned_bits); subst_lvalue_map.restore(); subst_rvalue_map.restore(); @@ -702,8 +772,24 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); this_case_eq_lvalue.replace(subst_lvalue_map.stdmap()); - removeSignalFromCaseTree(this_case_eq_lvalue, current_case); + + // Check if any bits in lvalue have been assigned before in current_case + bool has_overlap = false; + for (auto &bit : this_case_eq_lvalue) { + if (bit.wire != NULL && current_case_assigned_bits.count(bit)) { + has_overlap = true; + break; + } + } + + if (has_overlap) + removeSignalFromCaseTree(this_case_eq_lvalue, current_case); + addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); + // Track newly assigned bits + for (auto &bit : this_case_eq_lvalue) + if (bit.wire != NULL) + current_case_assigned_bits.insert(bit); } break; @@ -712,7 +798,7 @@ struct AST_INTERNAL::ProcessGenerator break; case AST_ASSIGN: - ast->input_error("Found continous assignment in always/initial block!\n"); + ast->input_error("Found continuous assignment in always/initial block!\n"); break; case AST_PARAMETER: @@ -1126,6 +1212,15 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun sign_hint = false; break; + case AST_ASSIGN_PATTERN: + for (auto& child : children) { + sub_width_hint = 0; + sub_sign_hint = true; + child->detectSignWidthWorker(sub_width_hint, sub_sign_hint); + } + sign_hint = false; + break; + case AST_NEG: case AST_BIT_NOT: case AST_POS: @@ -1738,6 +1833,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return sig; } + case AST_ASSIGN_PATTERN: + input_error("Assignment pattern is only supported for whole unpacked array assignments.\n"); + // generate cells for unary operations: $not, $pos, $neg if (0) { case AST_BIT_NOT: type_name = ID($not); } if (0) { case AST_POS: type_name = ID($pos); } @@ -2085,8 +2183,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) check_unique_id(current_module, id, this, "cell"); RTLIL::Cell *cell = current_module->addCell(id, ""); set_src_attr(cell, this); - // Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass - cell->set_bool_attribute(ID::module_not_derived); for (auto it = children.begin(); it != children.end(); it++) { auto* child = it->get(); @@ -2149,6 +2245,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } log_abort(); } + + // Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass + if (cell->type.isPublic()) + cell->set_bool_attribute(ID::module_not_derived); + for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) input_error("Attribute `%s' with non-constant value.\n", attr.first); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b1331420e..48a4291d2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -91,6 +91,11 @@ void AstNode::fixup_hierarchy_flags(bool force_descend) children[0]->set_in_param_flag(true, force_descend); break; + case AST_ASSIGN_PATTERN: + for (auto& child : children) + child->set_in_param_flag(in_param, force_descend); + break; + case AST_GENFOR: case AST_FOR: for (auto& child : children) { @@ -269,6 +274,100 @@ static int add_dimension(AstNode *node, AstNode *rnode) node->input_error("Unpacked array in packed struct/union member %s\n", node->str); } +// Check if node is an unexpanded array reference (AST_IDENTIFIER -> AST_MEMORY without indexing) +static bool is_unexpanded_array_ref(AstNode *node) +{ + if (node->type != AST_IDENTIFIER) + return false; + if (node->id2ast == nullptr || node->id2ast->type != AST_MEMORY) + return false; + // No indexing children = whole array reference + return node->children.empty(); +} + +// Check if two memories have compatible unpacked dimensions for array assignment +static bool arrays_have_compatible_dims(AstNode *mem_a, AstNode *mem_b) +{ + if (mem_a->unpacked_dimensions != mem_b->unpacked_dimensions) + return false; + for (int i = 0; i < mem_a->unpacked_dimensions; i++) { + if (mem_a->dimensions[i].range_width != mem_b->dimensions[i].range_width) + return false; + } + // Also check packed dimensions (element width) + int a_width, a_size, a_bits; + int b_width, b_size, b_bits; + mem_a->meminfo(a_width, a_size, a_bits); + mem_b->meminfo(b_width, b_size, b_bits); + return a_width == b_width; +} + +// Check if mem_b matches mem_a's unpacked dimensions starting at first_dim. +static bool arrays_have_compatible_dims_from(AstNode *mem_a, int first_dim, AstNode *mem_b) +{ + if (mem_b->unpacked_dimensions != mem_a->unpacked_dimensions - first_dim) + return false; + for (int i = 0; i < mem_b->unpacked_dimensions; i++) { + if (mem_a->dimensions[first_dim + i].range_width != mem_b->dimensions[i].range_width) + return false; + } + // Also check packed dimensions (element width) + int a_width, a_size, a_bits; + int b_width, b_size, b_bits; + mem_a->meminfo(a_width, a_size, a_bits); + mem_b->meminfo(b_width, b_size, b_bits); + return a_width == b_width; +} + +// Convert per-dimension element positions to declared index values. +// Position 0 is the first declared element for each unpacked dimension. +static std::vector array_indices_from_position(AstNode *mem, const std::vector &position) +{ + int num_dims = mem->unpacked_dimensions; + log_assert(GetSize(position) == num_dims); + + std::vector indices(num_dims); + for (int d = 0; d < num_dims; d++) { + int low = mem->dimensions[d].range_right; + int high = low + mem->dimensions[d].range_width - 1; + indices[d] = mem->dimensions[d].range_swapped ? (low + position[d]) : (high - position[d]); + } + return indices; +} + +// Generate all element positions for a multi-dimensional unpacked array and +// call callback once for each combination. +static void foreach_array_position(AstNode *mem, std::function&)> callback) +{ + int num_dims = mem->unpacked_dimensions; + if (num_dims == 0) { + callback({}); + return; + } + + std::vector position(num_dims, 0); + std::vector sizes(num_dims); + + for (int d = 0; d < num_dims; d++) + sizes[d] = mem->dimensions[d].range_width; + + // Iterate through all position combinations (rightmost dimension fastest). + while (true) { + callback(position); + + int d = num_dims - 1; + while (d >= 0) { + position[d]++; + if (position[d] < sizes[d]) + break; + position[d] = 0; + d--; + } + if (d < 0) + break; + } +} + static int size_packed_struct(AstNode *snode, int base_offset) { // Struct members will be laid out in the structure contiguously from left to right. @@ -1653,6 +1752,12 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin children_are_self_determined = true; break; + case AST_ASSIGN_PATTERN: + // Assignment pattern elements are context-determined by the target element type. + // Keep child width context intact until whole-array assignment expansion creates scalar assignments. + detect_width_simple = true; + break; + case AST_NEG: case AST_BIT_NOT: case AST_POS: @@ -3200,6 +3305,217 @@ skip_dynamic_range_lvalue_expansion:; } } + // Expand array assignment: arr_out = arr_in OR arr_out = cond ? arr_a : arr_b OR arr_out = '{a, b} + // Supports multi-dimensional unpacked arrays + if ((type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE || type == AST_ASSIGN) && + is_unexpanded_array_ref(children[0].get())) + { + AstNode *lhs = children[0].get(); + AstNode *rhs = children[1].get(); + AstNode *lhs_mem = lhs->id2ast; + + // Case 1: Direct array assignment (b = a) + bool is_direct_assign = is_unexpanded_array_ref(rhs); + + // Case 2: Ternary array assignment (out = sel ? a : b) + bool is_ternary_assign = (rhs->type == AST_TERNARY && + is_unexpanded_array_ref(rhs->children[1].get()) && + is_unexpanded_array_ref(rhs->children[2].get())); + + // Case 3: Positional assignment pattern (out = '{a, b}) + bool is_pattern_assign = rhs->type == AST_ASSIGN_PATTERN; + + if (is_direct_assign || is_ternary_assign || is_pattern_assign) + { + AstNode *direct_rhs_mem = nullptr; + AstNode *true_mem = nullptr; + AstNode *false_mem = nullptr; + + int num_dims = lhs_mem->unpacked_dimensions; + int total_elements = 1; + for (int d = 0; d < num_dims; d++) + total_elements *= lhs_mem->dimensions[d].range_width; + int element_width, mem_size, addr_bits; + lhs_mem->meminfo(element_width, mem_size, addr_bits); + bool pattern_is_flat = false; + + // Helper to add indices to an array identifier clone. + auto add_indices_to_id = [&](std::unique_ptr id, const std::vector& indices) { + int indexed_dims = GetSize(indices); + if (indexed_dims == 1) { + // Single dimension: use AST_RANGE + id->children.push_back(std::make_unique(location, AST_RANGE, + mkconst_int(location, indices[0], true))); + } else { + // Multiple dimensions: use AST_MULTIRANGE + auto multirange = std::make_unique(location, AST_MULTIRANGE); + for (int idx : indices) { + multirange->children.push_back(std::make_unique(location, AST_RANGE, + mkconst_int(location, idx, true))); + } + id->children.push_back(std::move(multirange)); + } + id->integer = indexed_dims; + // Reset basic_prep so multirange gets resolved during subsequent simplify passes + id->basic_prep = false; + return id; + }; + + auto add_position_to_id = [&](std::unique_ptr id, AstNode *mem, const std::vector& position) { + return add_indices_to_id(std::move(id), array_indices_from_position(mem, position)); + }; + + // Validate nested assignment pattern shape against unpacked dimensions. + std::function validate_pattern_shape = [&](AstNode *pattern, int dim) { + log_assert(pattern->type == AST_ASSIGN_PATTERN); + + int expected = lhs_mem->dimensions[dim].range_width; + if (GetSize(pattern->children) != expected) + input_error("Assignment pattern element count mismatch at dimension %d: got %d, expected %d\n", + dim + 1, GetSize(pattern->children), expected); + + if (dim + 1 == num_dims) + return; + + for (auto& child : pattern->children) { + if (child->type == AST_ASSIGN_PATTERN) { + validate_pattern_shape(child.get(), dim + 1); + } else if (is_unexpanded_array_ref(child.get()) && + arrays_have_compatible_dims_from(lhs_mem, dim + 1, child->id2ast)) { + continue; + } else { + input_error("Nested assignment pattern or compatible array expression required for dimension %d\n", dim + 2); + } + } + }; + + // Select the assignment pattern element for an unpacked array position. + auto pattern_element_at_position = [&](const std::vector& position, int flat_index) { + if (pattern_is_flat) + return rhs->children[flat_index]->clone(); + + AstNode *pattern = rhs; + for (int d = 0; d < num_dims; d++) { + log_assert(pattern->type == AST_ASSIGN_PATTERN); + AstNode *element = pattern->children[position[d]].get(); + + if (d + 1 == num_dims) + return element->clone(); + + if (element->type == AST_ASSIGN_PATTERN) { + pattern = element; + } else { + std::vector subposition(position.begin() + d + 1, position.end()); + return add_position_to_id(element->clone(), element->id2ast, subposition); + } + } + log_abort(); + }; + + // Validate array compatibility + if (is_direct_assign) { + direct_rhs_mem = rhs->id2ast; + if (!arrays_have_compatible_dims(lhs_mem, direct_rhs_mem)) + input_error("Array dimension mismatch in assignment\n"); + } else if (is_ternary_assign) { + true_mem = rhs->children[1]->id2ast; + false_mem = rhs->children[2]->id2ast; + if (!arrays_have_compatible_dims(lhs_mem, true_mem) || + !arrays_have_compatible_dims(lhs_mem, false_mem)) + input_error("Array dimension mismatch in ternary expression\n"); + } else { + if (num_dims > 1 && GetSize(rhs->children) == lhs_mem->dimensions[0].range_width) { + validate_pattern_shape(rhs, 0); + } else if (num_dims == 1 && GetSize(rhs->children) == total_elements) { + pattern_is_flat = true; + } else { + if (num_dims > 1 && GetSize(rhs->children) == lhs_mem->dimensions[0].range_width) + validate_pattern_shape(rhs, 0); + int expected = num_dims > 1 ? lhs_mem->dimensions[0].range_width : total_elements; + input_error("Assignment pattern element count mismatch: got %d, expected %d\n", GetSize(rhs->children), expected); + } + } + + // Warn if array assignment expansion is large. + if (total_elements > 10000) + log_warning("Expanding array assignment with %d elements at %s, this may be slow.\n", + total_elements, location.to_string().c_str()); + + // Collect all assignments + std::vector> assignments; + std::vector> pattern_temp_assignments; + + foreach_array_position(lhs_mem, [&](const std::vector& position) { + auto lhs_idx = add_position_to_id(lhs->clone(), lhs_mem, position); + + std::unique_ptr rhs_expr; + if (is_direct_assign) { + rhs_expr = add_position_to_id(rhs->clone(), direct_rhs_mem, position); + } else if (is_ternary_assign) { + // Ternary case + AstNode *cond = rhs->children[0].get(); + AstNode *true_val = rhs->children[1].get(); + AstNode *false_val = rhs->children[2].get(); + + auto true_idx = add_position_to_id(true_val->clone(), true_mem, position); + auto false_idx = add_position_to_id(false_val->clone(), false_mem, position); + + rhs_expr = std::make_unique(location, AST_TERNARY, + cond->clone(), std::move(true_idx), std::move(false_idx)); + } else { + auto pattern_rhs = pattern_element_at_position(position, GetSize(assignments)); + + if (type == AST_ASSIGN_EQ) { + auto wire_tmp_owned = std::make_unique(location, AST_WIRE, + std::make_unique(location, AST_RANGE, + mkconst_int(location, element_width - 1, true), + mkconst_int(location, 0, true))); + auto wire_tmp = wire_tmp_owned.get(); + wire_tmp->str = stringf("$assignpattern$%s:%d$%d", + RTLIL::encode_filename(*location.begin.filename), location.begin.line, autoidx++); + current_scope[wire_tmp->str] = wire_tmp; + current_ast_mod->children.push_back(std::move(wire_tmp_owned)); + wire_tmp->set_attribute(ID::nosync, AstNode::mkconst_int(location, 1, false)); + while (wire_tmp->simplify(true, 1, -1, false)) { } + wire_tmp->is_logic = true; + wire_tmp->is_signed = lhs_mem->is_signed; + + auto tmp_id = std::make_unique(location, AST_IDENTIFIER); + tmp_id->str = wire_tmp->str; + pattern_temp_assignments.push_back(std::make_unique(location, AST_ASSIGN_EQ, + tmp_id->clone(), std::move(pattern_rhs))); + rhs_expr = std::move(tmp_id); + } else { + rhs_expr = std::move(pattern_rhs); + } + } + + auto assign = std::make_unique(location, type, + std::move(lhs_idx), std::move(rhs_expr)); + assign->was_checked = true; + assignments.push_back(std::move(assign)); + }); + + // For continuous assignments, add to module; for procedural, use block + if (type == AST_ASSIGN) { + // Add all but last to module + for (size_t i = 0; i + 1 < assignments.size(); i++) + current_ast_mod->children.push_back(std::move(assignments[i])); + // Last one replaces current node + newNode = std::move(assignments.back()); + } else { + // Wrap in AST_BLOCK for procedural + newNode = std::make_unique(location, AST_BLOCK); + for (auto& assign : pattern_temp_assignments) + newNode->children.push_back(std::move(assign)); + for (auto& assign : assignments) + newNode->children.push_back(std::move(assign)); + } + + goto apply_newNode; + } + } + // assignment with memory in left-hand side expression -> replace with memory write port if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 && @@ -4458,6 +4774,8 @@ replace_fcall_later:; tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end()); newNode = children.at(1)->is_string ? mkconst_str(location, tmp_bits) : mkconst_bits(location, tmp_bits, false); break; + case AST_ASSIGN_PATTERN: + goto not_const; default: not_const: break; @@ -4690,6 +5008,7 @@ void AstNode::expand_genblock(const std::string &prefix) switch (child->type) { case AST_WIRE: + case AST_AUTOWIRE: case AST_MEMORY: case AST_STRUCT: case AST_UNION: @@ -4718,6 +5037,93 @@ void AstNode::expand_genblock(const std::string &prefix) } break; + case AST_IDENTIFIER: + if (!child->str.empty() && prefix.size() > 0) { + bool is_resolved = false; + std::string identifier_str = child->str; + if (current_ast_mod != nullptr && identifier_str.compare(0, current_ast_mod->str.size(), current_ast_mod->str) == 0) { + if (identifier_str.at(current_ast_mod->str.size()) == '.') { + identifier_str = '\\' + identifier_str.substr(current_ast_mod->str.size()+1, identifier_str.size()); + } + } + // search starting in the innermost scope and then stepping outward + for (size_t ppos = prefix.size() - 1; ppos; --ppos) { + if (prefix.at(ppos) != '.') continue; + + std::string new_prefix = prefix.substr(0, ppos + 1); + auto attempt_resolve = [&new_prefix](const std::string &ident) -> std::string { + std::string new_name = prefix_id(new_prefix, ident); + if (current_scope.count(new_name)) + return new_name; + return {}; + }; + + // attempt to resolve the full identifier + std::string resolved = attempt_resolve(identifier_str); + if (!resolved.empty()) { + is_resolved = true; + break; + } + // attempt to resolve hierarchical prefixes within the identifier, + // as the prefix could refer to a local scope which exists but + // hasn't yet been elaborated + for (size_t spos = identifier_str.size() - 1; spos; --spos) { + if (identifier_str.at(spos) != '.') continue; + resolved = attempt_resolve(identifier_str.substr(0, spos)); + if (!resolved.empty()) { + is_resolved = true; + identifier_str = resolved + identifier_str.substr(spos); + ppos = 1; // break outer loop + break; + } + } + if (current_scope.count(identifier_str) == 0) { + AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; + for (auto& node : current_scope_ast->children) { + switch (node->type) { + case AST_PARAMETER: + case AST_LOCALPARAM: + case AST_WIRE: + case AST_AUTOWIRE: + case AST_GENVAR: + case AST_MEMORY: + case AST_FUNCTION: + case AST_TASK: + case AST_DPI_FUNCTION: + if (prefix_id(new_prefix, identifier_str) == node->str) { + is_resolved = true; + current_scope[node->str] = node.get(); + } + break; + case AST_ENUM: + current_scope[node->str] = node.get(); + for (auto& enum_node : node->children) { + log_assert(enum_node->type==AST_ENUM_ITEM); + if (prefix_id(new_prefix, identifier_str) == enum_node->str) { + is_resolved = true; + current_scope[enum_node->str] = enum_node.get(); + } + } + break; + default: + break; + } + } + } + } + if ((current_scope.count(identifier_str) == 0) && is_resolved == false) { + if (current_ast_mod == nullptr) { + input_error("Identifier `%s' is implicitly declared outside of a module.\n", child->str.c_str()); + } else if (flag_autowire || identifier_str == "\\$global_clock") { + auto auto_wire = std::make_unique(child->location, AST_AUTOWIRE); + auto_wire->str = identifier_str; + children.push_back(std::move(auto_wire)); + } else { + input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", identifier_str.c_str()); + } + } + } + break; default: break; } diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index bff347ea2..350d7cafe 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -470,6 +470,27 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool continue; } + if (!strcmp(cmd, ".gateinit")) + { + char *p = strtok(NULL, " \t\r\n"); + if (p == NULL) + goto error; + + char *n = strtok(p, "="); + char *init = strtok(NULL, "="); + if (n == NULL || init == NULL) + goto error; + if (init[0] != '0' && init[0] != '1') + goto error; + + if (blif_wire(n)->attributes.find(ID::init) == blif_wire(n)->attributes.end()) + blif_wire(n)->attributes.emplace(ID::init, Const(init[0] == '1' ? 1 : 0, 1)); + else + blif_wire(n)->attributes[ID::init] = Const(init[0] == '1' ? 1 : 0, 1); + + continue; + } + if (!strcmp(cmd, ".names")) { char *p; @@ -608,6 +629,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool goto try_next_value; } } + log_assert(i < lutptr->size()); lutptr->set(i, !strcmp(output, "0") ? RTLIL::State::S0 : RTLIL::State::S1); try_next_value:; } diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index 743ac5d9e..803931f32 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -302,6 +302,9 @@ void json_import(Design *design, string &modname, JsonNode *node) if (node->data_dict.count("attributes")) json_parse_attr_param(module->attributes, node->data_dict.at("attributes")); + if (node->data_dict.count("parameter_default_values")) + json_parse_attr_param(module->parameter_default_values, node->data_dict.at("parameter_default_values")); + dict signal_bits; if (node->data_dict.count("ports")) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 0aa1cee09..a006ae649 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -20,6 +20,7 @@ #include "passes/techmap/libparse.h" #include "kernel/register.h" #include "kernel/log.h" +#include YOSYS_NAMESPACE_BEGIN @@ -210,7 +211,10 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node) auto [iq_sig, iqn_sig] = find_latch_ff_wires(module, node); RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig; bool clk_polarity = true, clear_polarity = true, preset_polarity = true; + const std::string name = RTLIL::unescape_id(module->name); + std::optional clear_preset_var1; + std::optional clear_preset_var2; for (auto child : node->children) { if (child->id == "clocked_on") clk_sig = parse_func_expr(module, child->value.c_str()); @@ -220,10 +224,18 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node) clear_sig = parse_func_expr(module, child->value.c_str()); if (child->id == "preset") preset_sig = parse_func_expr(module, child->value.c_str()); + + for (auto& [id, var] : {pair{"clear_preset_var1", &clear_preset_var1}, {"clear_preset_var2", &clear_preset_var2}}) + if (child->id == id) { + if (child->value.size() != 1) + log_error("Unexpected length of clear_preset_var* value %s in FF cell %s\n", child->value, name); + *var = child->value[0]; + } + } if (clk_sig.size() == 0 || data_sig.size() == 0) - log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::unescape_id(module->name)); + log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", name); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) { @@ -248,36 +260,64 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node) } } - RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_)); - cell->setPort(ID::A, iq_sig); - cell->setPort(ID::Y, iqn_sig); + for (auto& [out_sig, cp_var, neg] : {tuple{iq_sig, clear_preset_var1, false}, {iqn_sig, clear_preset_var2, true}}) { + SigSpec q_sig = out_sig; + if (neg) { + q_sig = module->addWire(NEW_ID, out_sig.as_wire()); + module->addNotGate(NEW_ID, q_sig, out_sig); + } - cell = module->addCell(NEW_ID, ""); - cell->setPort(ID::D, data_sig); - cell->setPort(ID::Q, iq_sig); - cell->setPort(ID::C, clk_sig); + RTLIL::Cell* cell = module->addCell(NEW_ID, ""); + cell->setPort(ID::D, data_sig); + cell->setPort(ID::Q, q_sig); + cell->setPort(ID::C, clk_sig); - if (clear_sig.size() == 0 && preset_sig.size() == 0) { - cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + if (clear_sig.size() == 0 && preset_sig.size() == 0) { + cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + } + + if (clear_sig.size() == 1 && preset_sig.size() == 0) { + cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell->setPort(ID::R, clear_sig); + } + + if (clear_sig.size() == 0 && preset_sig.size() == 1) { + cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); + cell->setPort(ID::R, preset_sig); + } + + if (clear_sig.size() == 1 && preset_sig.size() == 1) { + cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + + SigBit s_sig = preset_sig; + SigBit r_sig = clear_sig; + if (cp_var && *cp_var != 'X') { + // Either set or reset dominates + bool set_dominates; + if (*cp_var == 'L') { + set_dominates = neg; + } else if (*cp_var == 'H') { + set_dominates = !neg; + } else { + log_error("FF cell %s has unsupported clear&preset behavior \'%c\'.\n", name, *cp_var); + } + log_debug("cell %s variable %d cp_var %c set dominates? %d\n", name, (int)neg + 1, *cp_var, set_dominates); + // S&R priority is well-defined now + if (set_dominates) { + r_sig = module->AndnotGate(NEW_ID, r_sig, s_sig); + } else { + s_sig = module->AndnotGate(NEW_ID, s_sig, r_sig); + } + } else { + log_debug("cell %s variable %d undef c&p behavior\n", name, (int)neg + 1); + } + + cell->setPort(ID::S, s_sig); + cell->setPort(ID::R, r_sig); + } + + log_assert(!cell->type.empty()); } - - if (clear_sig.size() == 1 && preset_sig.size() == 0) { - cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->setPort(ID::R, clear_sig); - } - - if (clear_sig.size() == 0 && preset_sig.size() == 1) { - cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->setPort(ID::R, preset_sig); - } - - if (clear_sig.size() == 1 && preset_sig.size() == 1) { - cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->setPort(ID::S, preset_sig); - cell->setPort(ID::R, clear_sig); - } - - log_assert(!cell->type.empty()); } static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool flag_ignore_miss_data_latch) @@ -797,3 +837,4 @@ skip_cell:; YOSYS_NAMESPACE_END + diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 271962725..7e2ec5460 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -40,6 +40,7 @@ struct RTLILFrontendWorker { bool flag_nooverwrite = false; bool flag_overwrite = false; bool flag_lib = false; + bool flag_legalize = false; int line_num; std::string line_buf; @@ -285,6 +286,7 @@ struct RTLILFrontendWorker { if (width > MAX_CONST_WIDTH) error("Constant width %lld out of range before `%s`.", width, error_token()); bits.reserve(width); + int start_idx = idx; while (true) { RTLIL::State bit; switch (line[idx]) { @@ -299,8 +301,9 @@ struct RTLILFrontendWorker { bits.push_back(bit); ++idx; } - done: - std::reverse(bits.begin(), bits.end()); + done: + if (start_idx < idx) + std::reverse(bits.begin(), bits.end()); if (GetSize(bits) > width) bits.resize(width); @@ -322,6 +325,17 @@ struct RTLILFrontendWorker { return val; } + RTLIL::Wire *legalize_wire(RTLIL::IdString id) + { + int wires_size = current_module->wires_size(); + if (wires_size == 0) + error("No wires found for legalization"); + int hash = hash_ops::hash(id).yield(); + RTLIL::Wire *wire = current_module->wire_at(abs(hash % wires_size)); + log("Legalizing wire `%s' to `%s'.\n", log_id(id), log_id(wire->name)); + return wire; + } + RTLIL::SigSpec parse_sigspec() { RTLIL::SigSpec sig; @@ -339,8 +353,12 @@ struct RTLILFrontendWorker { std::optional id = try_parse_id(); if (id.has_value()) { RTLIL::Wire *wire = current_module->wire(*id); - if (wire == nullptr) - error("Wire `%s' not found.", *id); + if (wire == nullptr) { + if (flag_legalize) + wire = legalize_wire(*id); + else + error("Wire `%s' not found.", *id); + } sig = RTLIL::SigSpec(wire); } else { sig = RTLIL::SigSpec(parse_const()); @@ -349,17 +367,44 @@ struct RTLILFrontendWorker { while (try_parse_char('[')) { int left = parse_integer(); - if (left >= sig.size() || left < 0) - error("bit index %d out of range", left); + if (left >= sig.size() || left < 0) { + if (flag_legalize) { + int legalized; + if (sig.size() == 0) + legalized = 0; + else + legalized = std::max(0, std::min(left, sig.size() - 1)); + log("Legalizing bit index %d to %d.\n", left, legalized); + left = legalized; + } else { + error("bit index %d out of range", left); + } + } if (try_parse_char(':')) { int right = parse_integer(); - if (right < 0) - error("bit index %d out of range", right); - if (left < right) - error("invalid slice [%d:%d]", left, right); - sig = sig.extract(right, left-right+1); + if (right < 0) { + if (flag_legalize) { + log("Legalizing bit index %d to %d.\n", right, 0); + right = 0; + } else + error("bit index %d out of range", right); + } + if (left < right) { + if (flag_legalize) { + log("Legalizing bit index %d to %d.\n", left, right); + left = right; + } else + error("invalid slice [%d:%d]", left, right); + } + if (flag_legalize && left >= sig.size()) + log("Legalizing slice %d:%d by igoring it\n", left, right); + else + sig = sig.extract(right, left - right + 1); } else { - sig = sig.extract(left); + if (flag_legalize && left >= sig.size()) + log("Legalizing slice %d by igoring it\n", left); + else + sig = sig.extract(left); } expect_char(']'); } @@ -476,8 +521,14 @@ struct RTLILFrontendWorker { { std::optional id = try_parse_id(); if (id.has_value()) { - if (current_module->wire(*id) != nullptr) - error("RTLIL error: redefinition of wire %s.", *id); + if (current_module->wire(*id) != nullptr) { + if (flag_legalize) { + log("Legalizing redefinition of wire %s.\n", *id); + pool wires = {current_module->wire(*id)}; + current_module->remove(wires); + } else + error("RTLIL error: redefinition of wire %s.", *id); + } wire = current_module->addWire(std::move(*id)); break; } @@ -528,8 +579,13 @@ struct RTLILFrontendWorker { { std::optional id = try_parse_id(); if (id.has_value()) { - if (current_module->memories.count(*id) != 0) - error("RTLIL error: redefinition of memory %s.", *id); + if (current_module->memories.count(*id) != 0) { + if (flag_legalize) { + log("Legalizing redefinition of memory %s.\n", *id); + current_module->remove(current_module->memories.at(*id)); + } else + error("RTLIL error: redefinition of memory %s.", *id); + } memory->name = std::move(*id); break; } @@ -551,14 +607,36 @@ struct RTLILFrontendWorker { expect_eol(); } + void legalize_width_parameter(RTLIL::Cell *cell, RTLIL::IdString port_name) + { + std::string width_param_name = port_name.str() + "_WIDTH"; + if (cell->parameters.count(width_param_name) == 0) + return; + RTLIL::Const ¶m = cell->parameters.at(width_param_name); + if (param.as_int() != 0) + return; + cell->parameters[width_param_name] = RTLIL::Const(cell->getPort(port_name).size()); + } + void parse_cell() { RTLIL::IdString cell_type = parse_id(); RTLIL::IdString cell_name = parse_id(); expect_eol(); - if (current_module->cell(cell_name) != nullptr) - error("RTLIL error: redefinition of cell %s.", cell_name); + if (current_module->cell(cell_name) != nullptr) { + if (flag_legalize) { + RTLIL::IdString new_name; + int suffix = 1; + do { + new_name = RTLIL::IdString(cell_name.str() + "_" + std::to_string(suffix)); + ++suffix; + } while (current_module->cell(new_name) != nullptr); + log("Legalizing redefinition of cell %s by renaming to %s.\n", cell_name, new_name); + cell_name = new_name; + } else + error("RTLIL error: redefinition of cell %s.", cell_name); + } RTLIL::Cell *cell = current_module->addCell(cell_name, cell_type); cell->attributes = std::move(attrbuf); @@ -587,9 +665,15 @@ struct RTLILFrontendWorker { expect_eol(); } else if (try_parse_keyword("connect")) { RTLIL::IdString port_name = parse_id(); - if (cell->hasPort(port_name)) - error("RTLIL error: redefinition of cell port %s.", port_name); + if (cell->hasPort(port_name)) { + if (flag_legalize) + log("Legalizing redefinition of cell port %s.", port_name); + else + error("RTLIL error: redefinition of cell port %s.", port_name); + } cell->setPort(std::move(port_name), parse_sigspec()); + if (flag_legalize) + legalize_width_parameter(cell, port_name); expect_eol(); } else if (try_parse_keyword("end")) { expect_eol(); @@ -606,6 +690,11 @@ struct RTLILFrontendWorker { error("dangling attribute"); RTLIL::SigSpec s1 = parse_sigspec(); RTLIL::SigSpec s2 = parse_sigspec(); + if (flag_legalize) { + int min_size = std::min(s1.size(), s2.size()); + s1 = s1.extract(0, min_size); + s2 = s2.extract(0, min_size); + } current_module->connect(std::move(s1), std::move(s2)); expect_eol(); } @@ -682,8 +771,13 @@ struct RTLILFrontendWorker { RTLIL::IdString proc_name = parse_id(); expect_eol(); - if (current_module->processes.count(proc_name) != 0) - error("RTLIL error: redefinition of process %s.", proc_name); + if (current_module->processes.count(proc_name) != 0) { + if (flag_legalize) { + log("Legalizing redefinition of process %s.\n", proc_name); + current_module->remove(current_module->processes.at(proc_name)); + } else + error("RTLIL error: redefinition of process %s.", proc_name); + } RTLIL::Process *proc = current_module->addProcess(std::move(proc_name)); proc->attributes = std::move(attrbuf); @@ -804,6 +898,11 @@ struct RTLILFrontend : public Frontend { log(" -lib\n"); log(" only create empty blackbox modules\n"); log("\n"); + log(" -legalize\n"); + log(" prevent semantic errors (e.g. reference to unknown wire, redefinition of wire/cell)\n"); + log(" by deterministically rewriting the input into something valid. Useful when using\n"); + log(" fuzzing to generate random but valid RTLIL.\n"); + log("\n"); } void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) override { @@ -828,6 +927,10 @@ struct RTLILFrontend : public Frontend { worker.flag_lib = true; continue; } + if (arg == "-legalize") { + worker.flag_legalize = true; + continue; + } break; } extra_args(f, filename, args, argidx); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 5790e92f0..6a1c81aa4 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -3114,9 +3114,11 @@ struct VerificPass : public Pass { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); #ifdef VERIFIC_SYSTEMVERILOG_SUPPORT - log(" verific {-vlog95|-vlog2k|-sv2005|-sv2009|-sv2012|-sv} ..\n"); + log(" verific {-vlog95|-vlog2k|-sv2005|-sv2009|-sv2012|\n"); + log(" -sv2017|-sv} ..\n"); log("\n"); log("Load the specified Verilog/SystemVerilog files into Verific.\n"); + log("Note that -sv option will use latest supported SystemVerilog standard.\n"); log("\n"); log("All files specified in one call to this command are one compilation unit.\n"); log("Files passed to different calls to this command are treated as belonging to\n"); @@ -3161,7 +3163,10 @@ struct VerificPass : public Pass { #endif #ifdef VERIFIC_SYSTEMVERILOG_SUPPORT log(" verific {-f|-F} [-vlog95|-vlog2k|-sv2005|-sv2009|\n"); - log(" -sv2012|-sv|-formal] \n"); +#ifdef VERIFIC_VHDL_SUPPORT + log(" -vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl|\n"); +#endif + log(" -sv2012|-sv2017|-sv|-formal] \n"); log("\n"); log("Load and execute the specified command file.\n"); log("Override verilog parsing mode can be set.\n"); @@ -3696,6 +3701,9 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && (args[argidx] == "-f" || args[argidx] == "-F")) { unsigned verilog_mode = veri_file::UNDEFINED; +#ifdef VERIFIC_VHDL_SUPPORT + unsigned vhdl_mode = vhdl_file::UNDEFINED; +#endif bool is_formal = false; const char* filename = nullptr; @@ -3714,10 +3722,38 @@ struct VerificPass : public Pass { } else if (args[argidx] == "-sv2009") { verilog_mode = veri_file::SYSTEM_VERILOG_2009; continue; - } else if (args[argidx] == "-sv2012" || args[argidx] == "-sv" || args[argidx] == "-formal") { + } else if (args[argidx] == "-sv2012") { + verilog_mode = veri_file::SYSTEM_VERILOG_2012; + continue; + } else if (args[argidx] == "-sv2017") { + verilog_mode = veri_file::SYSTEM_VERILOG_2017; + continue; + } else if (args[argidx] == "-sv" || args[argidx] == "-formal") { verilog_mode = veri_file::SYSTEM_VERILOG; if (args[argidx] == "-formal") is_formal = true; continue; +#ifdef VERIFIC_VHDL_SUPPORT + } else if (args[argidx] == "-vhdl87") { + vhdl_mode = vhdl_file::VHDL_87; + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1987").c_str()); + continue; + } else if (args[argidx] == "-vhdl93") { + vhdl_mode = vhdl_file::VHDL_93; + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); + continue; + } else if (args[argidx] == "-vhdl2k") { + vhdl_mode = vhdl_file::VHDL_2K; + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); + continue; + } else if (args[argidx] == "-vhdl2019") { + vhdl_mode = vhdl_file::VHDL_2019; + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2019").c_str()); + continue; + } else if (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl") { + vhdl_mode = vhdl_file::VHDL_2008; + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); + continue; +#endif } else if (args[argidx].compare(0, 1, "-") == 0) { cmd_error(args, argidx, "unknown option"); goto check_error; @@ -3742,10 +3778,36 @@ struct VerificPass : public Pass { veri_file::DefineMacro("VERIFIC"); veri_file::DefineMacro(is_formal ? "FORMAL" : "SYNTHESIS"); +#ifdef VERIFIC_VHDL_SUPPORT + if (vhdl_mode == vhdl_file::UNDEFINED) { + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); + vhdl_mode = vhdl_file::VHDL_2008; + } + int i; + Array *file_names_sv = new Array(POINTER_HASH); + FOREACH_ARRAY_ITEM(file_names, i, filename) { + std::string filename_str = filename; + if ((filename_str.substr(filename_str.find_last_of(".") + 1) == "vhd") || + (filename_str.substr(filename_str.find_last_of(".") + 1) == "vhdl")) { + if (!vhdl_file::Analyze(filename, work.c_str(), vhdl_mode)) { + verific_error_msg.clear(); + log_cmd_error("Reading VHDL sources failed.\n"); + } + } else { + file_names_sv->Insert(strdup(filename)); + } + } + if (!veri_file::AnalyzeMultipleFiles(file_names_sv, analysis_mode, work.c_str(), veri_file::MFCU)) { + verific_error_msg.clear(); + log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); + } + delete file_names_sv; +#else if (!veri_file::AnalyzeMultipleFiles(file_names, analysis_mode, work.c_str(), veri_file::MFCU)) { verific_error_msg.clear(); log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); } +#endif delete file_names; verific_import_pending = true; @@ -3753,7 +3815,8 @@ struct VerificPass : public Pass { } if (GetSize(args) > argidx && (args[argidx] == "-vlog95" || args[argidx] == "-vlog2k" || args[argidx] == "-sv2005" || - args[argidx] == "-sv2009" || args[argidx] == "-sv2012" || args[argidx] == "-sv" || args[argidx] == "-formal")) + args[argidx] == "-sv2009" || args[argidx] == "-sv2012" || args[argidx] == "-sv2017" || args[argidx] == "-sv" || + args[argidx] == "-formal")) { Array file_names; unsigned verilog_mode; @@ -3766,7 +3829,11 @@ struct VerificPass : public Pass { verilog_mode = veri_file::SYSTEM_VERILOG_2005; else if (args[argidx] == "-sv2009") verilog_mode = veri_file::SYSTEM_VERILOG_2009; - else if (args[argidx] == "-sv2012" || args[argidx] == "-sv" || args[argidx] == "-formal") + else if (args[argidx] == "-sv2012") + verilog_mode = veri_file::SYSTEM_VERILOG_2012; + else if (args[argidx] == "-sv2017") + verilog_mode = veri_file::SYSTEM_VERILOG_2017; + else if (args[argidx] == "-sv" || args[argidx] == "-formal") verilog_mode = veri_file::SYSTEM_VERILOG; else log_abort(); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 6c9e67dc5..29a739f81 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -500,7 +500,6 @@ struct VerilogFrontend : public Frontend { log("Parsing %s%s input from `%s' to AST representation.\n", parse_mode.formal ? "formal " : "", parse_mode.sv ? "SystemVerilog" : "Verilog", filename.c_str()); - log("verilog frontend filename %s\n", filename.c_str()); if (flag_relative_share) { auto share_path = proc_share_dirname(); if (filename.substr(0, share_path.length()) == share_path) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 684727d5b..b394ce074 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -84,7 +84,7 @@ int current_function_or_task_port_id; std::vector case_type_stack; bool do_not_require_port_stubs; - bool current_wire_rand, current_wire_const; + bool current_wire_rand, current_wire_const, current_wire_automatic; bool current_modport_input, current_modport_output; bool default_nettype_wire = true; std::istream* lexin; @@ -546,7 +546,7 @@ %token TOK_z "'z'" %type range range_or_multirange non_opt_range non_opt_multirange -%type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type +%type wire_type expr basic_expr concat_list assignment_pattern_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type %type opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number %type type_name %type opt_enum_init enum_type struct_type enum_struct_type func_return_type typedef_base_type @@ -958,14 +958,18 @@ delay: non_opt_delay | %empty; io_wire_type: - { extra->astbuf3 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; } + { extra->astbuf3 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; extra->current_wire_automatic = false; } wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness { $$ = std::move(extra->astbuf3); SET_RULE_LOC(@$, @2, @$); }; non_io_wire_type: - { extra->astbuf3 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; } - wire_type_const_rand wire_type_token wire_type_signedness - { $$ = std::move(extra->astbuf3); SET_RULE_LOC(@$, @2, @$); }; + { extra->astbuf3 = std::make_unique(@$, AST_WIRE); extra->current_wire_rand = false; extra->current_wire_const = false; extra->current_wire_automatic = false; } + opt_lifetime wire_type_const_rand wire_type_token wire_type_signedness + { + if (extra->current_wire_automatic) + extra->astbuf3->set_attribute(ID::nosync, AstNode::mkconst_int(extra->astbuf3->location, 1, false)); + $$ = std::move(extra->astbuf3); SET_RULE_LOC(@$, @2, @$); + }; wire_type: io_wire_type { $$ = std::move($1); } | @@ -1253,6 +1257,10 @@ opt_automatic: TOK_AUTOMATIC | %empty; +opt_lifetime: + TOK_AUTOMATIC { extra->current_wire_automatic = true; } | + %empty; + task_func_args_opt: TOK_LPAREN TOK_RPAREN | %empty | TOK_LPAREN { extra->albuf = nullptr; @@ -3341,6 +3349,11 @@ basic_expr: TOK_LCURL concat_list TOK_RCURL { $$ = std::move($2); } | + OP_CAST TOK_LCURL assignment_pattern_list optional_comma TOK_RCURL { + if (!mode->sv) + err_at_loc(@1, "Assignment patterns are only supported in SystemVerilog mode."); + $$ = std::move($3); + } | TOK_LCURL expr TOK_LCURL concat_list TOK_RCURL TOK_RCURL { $$ = std::make_unique(@$, AST_REPLICATE, std::move($2), std::move($4)); } | @@ -3572,6 +3585,16 @@ concat_list: $$->children.push_back(std::move($1)); }; +assignment_pattern_list: + expr { + $$ = std::make_unique(@$, AST_ASSIGN_PATTERN); + $$->children.push_back(std::move($1)); + } | + assignment_pattern_list TOK_COMMA expr { + $$ = std::move($1); + $$->children.push_back(std::move($3)); + }; + integral_number: TOK_CONSTVAL { $$ = std::move($1); } | TOK_UNBASED_UNSIZED_CONSTVAL { $$ = std::move($1); } | diff --git a/guidelines/GettingStarted b/guidelines/GettingStarted index 17fe32523..ea15df93f 100644 --- a/guidelines/GettingStarted +++ b/guidelines/GettingStarted @@ -5,7 +5,7 @@ Getting Started Outline of a Yosys command -------------------------- -Here is a the C++ code for a "hello_world" Yosys command (hello.cc): +Here is the C++ code for a "hello_world" Yosys command (hello.cc): #include "kernel/yosys.h" @@ -85,7 +85,7 @@ the declarations for the following types in kernel/rtlil.h: The module is a container with connected cells and wires in it. The design is a container with modules in it. -All this types are also available without the RTLIL:: prefix in the Yosys +All these types are also available without the RTLIL:: prefix in the Yosys namespace. 4. SigMap and other Helper Classes @@ -204,4 +204,4 @@ Notes on the existing codebase For historical reasons not all parts of Yosys adhere to the current coding style. When adding code to existing parts of the system, adhere to this guide -for the new code instead of trying to mimic the style of the surrounding code. \ No newline at end of file +for the new code instead of trying to mimic the style of the surrounding code. diff --git a/kernel/calc.cc b/kernel/calc.cc index 9b0885db9..84ac100ab 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -291,7 +291,7 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co if (pos < 0) result.set(i, vacant_bits); else if (pos >= BigInteger(GetSize(arg1))) - result.set(i, sign_ext ? arg1.back() : vacant_bits); + result.set(i, sign_ext && !arg1.empty() ? arg1.back() : vacant_bits); else result.set(i, arg1[pos.toInt()]); } diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 0f897cd58..ce351514b 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -66,14 +66,7 @@ struct AigMaker Cell *cell; idict aig_indices; - int the_true_node; - int the_false_node; - - AigMaker(Aig *aig, Cell *cell) : aig(aig), cell(cell) - { - the_true_node = -1; - the_false_node = -1; - } + AigMaker(Aig *aig, Cell *cell) : aig(aig), cell(cell) {} int node2index(const AigNode &node) { diff --git a/kernel/celledges.cc b/kernel/celledges.cc index c39ced95a..195d4b15b 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -112,6 +112,41 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) db->add_edge(cell, ID::A, i, ID::Y, 0, -1); } +void logic_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int a_width = GetSize(cell->getPort(ID::A)); + int b_width = GetSize(cell->getPort(ID::B)); + + for (int i = 0; i < a_width; i++) + db->add_edge(cell, ID::A, i, ID::Y, 0, -1); + for (int i = 0; i < b_width; i++) + db->add_edge(cell, ID::B, i, ID::Y, 0, -1); +} + +void concat_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int a_width = GetSize(cell->getPort(ID::A)); + int b_width = GetSize(cell->getPort(ID::B)); + + for (int i = 0; i < a_width; i++) + db->add_edge(cell, ID::A, i, ID::Y, i, -1); + for (int i = 0; i < b_width; i++) + db->add_edge(cell, ID::B, i, ID::Y, a_width + i, -1); +} + +void slice_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int offset = cell->getParam(ID::OFFSET).as_int(); + int a_width = GetSize(cell->getPort(ID::A)); + int y_width = GetSize(cell->getPort(ID::Y)); + + for (int i = 0; i < y_width; i++) { + int a_bit = offset + i; + if (a_bit >= 0 && a_bit < a_width) + db->add_edge(cell, ID::A, a_bit, ID::Y, i, -1); + } +} + void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { int a_width = GetSize(cell->getPort(ID::A)); @@ -254,7 +289,7 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) int skip = 1 << (k + 1); int base = skip -1; if (i % skip != base && i - a_width + 2 < 1 << b_width_capped) - db->add_edge(cell, ID::B, k, ID::Y, i, -1); + db->add_edge(cell, ID::B, k, ID::Y, i, -1); } else if (is_signed) { if (i - a_width + 2 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); @@ -388,6 +423,64 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) db->add_edge(cell, ID::ARST, 0, ID::Q, k, -1); } +void full_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + std::vector input_ports; + std::vector output_ports; + + for (auto &conn : cell->connections()) + { + RTLIL::IdString port = conn.first; + RTLIL::PortDir dir = cell->port_dir(port); + if (cell->input(port) || dir == RTLIL::PortDir::PD_INOUT) + input_ports.push_back(port); + if (cell->output(port) || dir == RTLIL::PortDir::PD_INOUT) + output_ports.push_back(port); + } + + for (auto out_port : output_ports) + { + int out_width = GetSize(cell->getPort(out_port)); + for (int out_bit = 0; out_bit < out_width; out_bit++) + { + for (auto in_port : input_ports) + { + int in_width = GetSize(cell->getPort(in_port)); + for (int in_bit = 0; in_bit < in_width; in_bit++) + db->add_edge(cell, in_port, in_bit, out_port, out_bit, -1); + } + } + } +} + +void bweqx_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int width = GetSize(cell->getPort(ID::Y)); + int a_width = GetSize(cell->getPort(ID::A)); + int b_width = GetSize(cell->getPort(ID::B)); + int max_width = std::min(width, std::min(a_width, b_width)); + + for (int i = 0; i < max_width; i++) { + db->add_edge(cell, ID::A, i, ID::Y, i, -1); + db->add_edge(cell, ID::B, i, ID::Y, i, -1); + } +} + +void bwmux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) +{ + int width = GetSize(cell->getPort(ID::Y)); + int a_width = GetSize(cell->getPort(ID::A)); + int b_width = GetSize(cell->getPort(ID::B)); + int s_width = GetSize(cell->getPort(ID::S)); + int max_width = std::min(width, std::min(a_width, std::min(b_width, s_width))); + + for (int i = 0; i < max_width; i++) { + db->add_edge(cell, ID::A, i, ID::Y, i, -1); + db->add_edge(cell, ID::B, i, ID::Y, i, -1); + db->add_edge(cell, ID::S, i, ID::Y, i, -1); + } +} + PRIVATE_NAMESPACE_END bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) @@ -417,6 +510,21 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } + if (cell->type.in(ID($logic_and), ID($logic_or))) { + logic_op(this, cell); + return true; + } + + if (cell->type == ID($slice)) { + slice_op(this, cell); + return true; + } + + if (cell->type == ID($concat)) { + concat_op(this, cell); + return true; + } + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { shift_op(this, cell); return true; @@ -442,6 +550,16 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } + if (cell->type == ID($bweqx)) { + bweqx_op(this, cell); + return true; + } + + if (cell->type == ID($bwmux)) { + bwmux_op(this, cell); + 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; @@ -452,13 +570,24 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return true; } - // FIXME: $mul $div $mod $divfloor $modfloor $slice $concat - // FIXME: $lut $sop $alu $lcu $macc $macc_v2 $fa - // FIXME: $mul $div $mod $divfloor $modfloor $pow $slice $concat $bweqx - // FIXME: $lut $sop $alu $lcu $macc $fa $logic_and $logic_or $bwmux + if (cell->type.in(ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) { + full_op(this, cell); + return true; + } - // FIXME: $_BUF_ $_NOT_ $_AND_ $_NAND_ $_OR_ $_NOR_ $_XOR_ $_XNOR_ $_ANDNOT_ $_ORNOT_ - // FIXME: $_MUX_ $_NMUX_ $_MUX4_ $_MUX8_ $_MUX16_ $_AOI3_ $_OAI3_ $_AOI4_ $_OAI4_ + if (cell->type.in(ID($lut), ID($sop), ID($alu), ID($lcu), ID($macc), ID($macc_v2))) { + full_op(this, cell); + return true; + } + + if (cell->type.in( + ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), + ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_), + ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), + ID($_OAI4_), ID($_TBUF_))) { + full_op(this, cell); + return true; + } // FIXME: $specify2 $specify3 $specrule ??? // FIXME: $equiv $set_tag $get_tag $overwrite_tag $original_tag @@ -468,4 +597,3 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL return false; } - diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 34b013dd9..ceff0bd1a 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -21,6 +21,7 @@ #define CELLTYPES_H #include "kernel/yosys.h" +#include "kernel/newcelltypes.h" YOSYS_NAMESPACE_BEGIN @@ -87,22 +88,22 @@ struct CellTypes { setup_internals_eval(); - setup_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y}, true); + setup_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y}); - setup_type(ID($assert), {ID::A, ID::EN}, pool(), true); - setup_type(ID($assume), {ID::A, ID::EN}, pool(), true); - setup_type(ID($live), {ID::A, ID::EN}, pool(), true); - setup_type(ID($fair), {ID::A, ID::EN}, pool(), true); - setup_type(ID($cover), {ID::A, ID::EN}, pool(), true); - setup_type(ID($initstate), pool(), {ID::Y}, true); - setup_type(ID($anyconst), pool(), {ID::Y}, true); - setup_type(ID($anyseq), pool(), {ID::Y}, true); - setup_type(ID($allconst), pool(), {ID::Y}, true); - setup_type(ID($allseq), pool(), {ID::Y}, true); - setup_type(ID($equiv), {ID::A, ID::B}, {ID::Y}, true); - setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool(), true); - setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool(), true); - setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool(), true); + setup_type(ID($assert), {ID::A, ID::EN}, pool()); + setup_type(ID($assume), {ID::A, ID::EN}, pool()); + setup_type(ID($live), {ID::A, ID::EN}, pool()); + setup_type(ID($fair), {ID::A, ID::EN}, pool()); + setup_type(ID($cover), {ID::A, ID::EN}, pool()); + setup_type(ID($initstate), pool(), {ID::Y}); + setup_type(ID($anyconst), pool(), {ID::Y}); + setup_type(ID($anyseq), pool(), {ID::Y}); + setup_type(ID($allconst), pool(), {ID::Y}); + setup_type(ID($allseq), pool(), {ID::Y}); + setup_type(ID($equiv), {ID::A, ID::B}, {ID::Y}); + setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool()); + setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool()); + setup_type(ID($specrule), {ID::SRC_EN, ID::DST_EN, ID::SRC, ID::DST}, pool()); setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool()); setup_type(ID($check), {ID::A, ID::EN, ID::ARGS, ID::TRG}, pool()); setup_type(ID($set_tag), {ID::A, ID::SET, ID::CLR}, {ID::Y}); @@ -195,7 +196,7 @@ struct CellTypes { setup_stdcells_eval(); - setup_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}, true); + setup_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}); } void setup_stdcells_eval() @@ -548,9 +549,6 @@ struct CellTypes } }; -// initialized by yosys_setup() -extern CellTypes yosys_celltypes; - YOSYS_NAMESPACE_END #endif diff --git a/kernel/consteval.h b/kernel/consteval.h index b13c7ea5c..d00ae8f33 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -24,9 +24,14 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/macc.h" +#include "kernel/newcelltypes.h" YOSYS_NAMESPACE_BEGIN +/** + * ConstEval provides on-demand constant propagation by traversing input cones + * with caching + */ struct ConstEval { RTLIL::Module *module; @@ -40,9 +45,8 @@ struct ConstEval ConstEval(RTLIL::Module *module, RTLIL::State defaultval = RTLIL::State::Sm) : module(module), assign_map(module), defaultval(defaultval) { - CellTypes ct; - ct.setup_internals(); - ct.setup_stdcells(); + auto ct = NewCellTypes(); + ct.static_cell_types = StaticCellTypes::Compat::nomem_noff; for (auto &it : module->cells_) { if (!ct.cell_known(it.second->type)) diff --git a/kernel/constids.inc b/kernel/constids.inc index c99aa788d..cfd12e3fb 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -459,9 +459,7 @@ X(EDGE_POL) X(EFX_ADD) X(EN) X(ENPOL) -X(EN_DST) X(EN_POLARITY) -X(EN_SRC) X(EQN) X(F) X(FDCE) @@ -835,6 +833,7 @@ X(abcgroup) X(acc_fir) X(acc_fir_i) X(add_carry) +X(aiger2_zbuf) X(allconst) X(allseq) X(always_comb) diff --git a/kernel/driver.cc b/kernel/driver.cc index fa78bad59..73b687f80 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -23,6 +23,7 @@ #define CXXOPTS_VECTOR_DELIMITER '\0' #include "libs/cxxopts/include/cxxopts.hpp" #include +#include #ifdef YOSYS_ENABLE_READLINE # include @@ -143,19 +144,6 @@ int yosys_history_offset = 0; std::string yosys_history_file; #endif -#if defined(__wasm) -extern "C" { - // FIXME: WASI does not currently support exceptions. - void* __cxa_allocate_exception(size_t thrown_size) throw() { - return malloc(thrown_size); - } - bool __cxa_uncaught_exception() throw(); - void __cxa_throw(void* thrown_exception, struct std::type_info * tinfo, void (*dest)(void*)) { - std::terminate(); - } -} -#endif - void yosys_atexit() { #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) @@ -195,6 +183,7 @@ namespace Yosys { int main(int argc, char **argv) { + auto wall_clock_start = std::chrono::steady_clock::now(); std::string frontend_command = "auto"; std::string backend_command = "auto"; std::vector vlog_defines; @@ -675,6 +664,7 @@ int main(int argc, char **argv) #ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash); + (void)wall_clock_start; #else std::string meminfo; std::string stats_divider = ", "; @@ -700,8 +690,11 @@ int main(int argc, char **argv) meminfo = stringf(", MEM: %.2f MB peak", ru_buffer.ru_maxrss / (1024.0 * 1024.0)); #endif - log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash, - stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, + double wall_seconds = std::chrono::duration( + std::chrono::steady_clock::now() - wall_clock_start).count(); + + log("End of script. Logfile hash: %s%stime: %.2fs, user: %.2fs, system: %.2fs%s\n", hash, + stats_divider.c_str(), wall_seconds, ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, meminfo.c_str()); #endif log("%s\n", yosys_maybe_version()); diff --git a/kernel/drivertools.h b/kernel/drivertools.h index ba7b2aa84..28d3be91e 100644 --- a/kernel/drivertools.h +++ b/kernel/drivertools.h @@ -25,7 +25,7 @@ #include "kernel/rtlil.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" YOSYS_NAMESPACE_BEGIN @@ -1093,10 +1093,10 @@ private: struct DriverMap { - CellTypes celltypes; + NewCellTypes celltypes; DriverMap() { celltypes.setup(); } - DriverMap(Design *design) { celltypes.setup(); celltypes.setup_design(design); } + DriverMap(Design *design) { celltypes.setup(design); } private: diff --git a/kernel/ffinit.h b/kernel/ffinit.h index 920fba307..8b4758f60 100644 --- a/kernel/ffinit.h +++ b/kernel/ffinit.h @@ -22,6 +22,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/threading.h" YOSYS_NAMESPACE_BEGIN @@ -35,34 +36,55 @@ struct FfInitVals sigmap = sigmap_; initbits.clear(); for (auto wire : module->wires()) + if (wire->attributes.count(ID::init)) + process_wire(wire); + } + + void process_wire(RTLIL::Wire *wire) + { + SigSpec wirebits = (*sigmap)(wire); + Const initval = wire->attributes.at(ID::init); + + for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) { - if (wire->attributes.count(ID::init) == 0) + SigBit bit = wirebits[i]; + State val = initval[i]; + + if (val != State::S0 && val != State::S1 && bit.wire != nullptr) continue; - SigSpec wirebits = (*sigmap)(wire); - Const initval = wire->attributes.at(ID::init); - - for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) - { - SigBit bit = wirebits[i]; - State val = initval[i]; - - if (val != State::S0 && val != State::S1 && bit.wire != nullptr) - continue; - - if (initbits.count(bit)) { - if (initbits.at(bit).first != val) - log_error("Conflicting init values for signal %s (%s = %s != %s).\n", - log_signal(bit), log_signal(SigBit(wire, i)), - log_signal(val), log_signal(initbits.at(bit).first)); - continue; - } - - initbits[bit] = std::make_pair(val,SigBit(wire,i)); + if (initbits.count(bit)) { + if (initbits.at(bit).first != val) + log_error("Conflicting init values for signal %s (%s = %s != %s).\n", + log_signal(bit), log_signal(SigBit(wire, i)), + log_signal(val), log_signal(initbits.at(bit).first)); + continue; } + + initbits[bit] = std::make_pair(val,SigBit(wire,i)); } } + void set_parallel(const SigMapView *sigmap_, ParallelDispatchThreadPool &thread_pool, RTLIL::Module *module) + { + sigmap = sigmap_; + initbits.clear(); + + const RTLIL::Module *const_module = module; + ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->wires_size(), 1000)); + ShardedVector init_wires(subpool); + subpool.run([const_module, &init_wires](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(const_module->wires_size())) { + RTLIL::Wire *wire = const_module->wire_at(i); + if (wire->attributes.count(ID::init)) + init_wires.insert(ctx, wire); + } + }); + + for (RTLIL::Wire *wire : init_wires) + process_wire(wire); + } + RTLIL::State operator()(RTLIL::SigBit bit) const { auto it = initbits.find((*sigmap)(bit)); diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index f0f00181c..8b724e69b 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -45,8 +45,7 @@ FstData::FstData(std::string filename) : ctx(nullptr) ctx = (fstReaderContext *)fstReaderOpen(filename.c_str()); if (!ctx) log_error("Error opening '%s' as FST file\n", filename); - int scale = (int)fstReaderGetTimescale(ctx); - timescale = pow(10.0, scale); + scale = (int)fstReaderGetTimescale(ctx); timescale_str = ""; int unit = 0; int zeros = 0; diff --git a/kernel/fstdata.h b/kernel/fstdata.h index a8ae40301..43f779cb5 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -55,7 +55,7 @@ class FstData std::string valueOf(fstHandle signal); fstHandle getHandle(std::string name); dict getMemoryHandles(std::string name); - double getTimescale() { return timescale; } + int getScale() { return scale; } const char *getTimescaleString() { return timescale_str.c_str(); } private: void extractVarNames(); @@ -69,7 +69,7 @@ private: uint64_t last_time; std::map past_data; uint64_t past_time; - double timescale; + int scale; // exponent of 10, e.g. -6 = us, -9 = ns std::string timescale_str; uint64_t start_time; uint64_t end_time; diff --git a/kernel/hashlib.h b/kernel/hashlib.h index ca600231a..937116178 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -55,6 +55,12 @@ namespace hashlib { * instead of pointers. */ +#if defined(__GNUC__) || defined(__clang__) +# define HASHLIB_ATTRIBUTE_WARN_UNUSED __attribute__((warn_unused)) +#else +# define HASHLIB_ATTRIBUTE_WARN_UNUSED +#endif + const int hashtable_size_trigger = 2; const int hashtable_size_factor = 3; @@ -402,7 +408,7 @@ private: }; template -class dict { +class HASHLIB_ATTRIBUTE_WARN_UNUSED dict { struct entry_t { std::pair udata; @@ -877,7 +883,7 @@ public: }; template -class pool +class HASHLIB_ATTRIBUTE_WARN_UNUSED pool { template friend class idict; @@ -1257,7 +1263,7 @@ public: }; template -class idict +class HASHLIB_ATTRIBUTE_WARN_UNUSED idict { pool database; @@ -1321,6 +1327,12 @@ public: return i < 0 ? 0 : 1; } + int lookup(const K &key) const + { + Hasher::hash_t hash = database.do_hash(key); + return database.do_lookup_no_rehash(key, hash); + } + void expect(const K &key, int i) { int j = (*this)(key); @@ -1354,7 +1366,7 @@ public: * i-prefixed methods operate on indices in parents */ template -class mfp +class HASHLIB_ATTRIBUTE_WARN_UNUSED mfp { idict database; class AtomicParent { diff --git a/kernel/log.cc b/kernel/log.cc index 2a1261621..b114f1eaf 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -90,11 +90,11 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&counter); - counter.QuadPart *= 1000000; + counter.QuadPart *= 1'000'000; counter.QuadPart /= freq.QuadPart; tv->tv_sec = long(counter.QuadPart / 1000000); - tv->tv_usec = counter.QuadPart % 1000000; + tv->tv_usec = counter.QuadPart % 1'000'000; return 0; } @@ -135,7 +135,7 @@ static void logv_string(std::string_view format, std::string str) { initial_tv = tv; if (tv.tv_usec < initial_tv.tv_usec) { tv.tv_sec--; - tv.tv_usec += 1000000; + tv.tv_usec += 1'000'000; } tv.tv_sec -= initial_tv.tv_sec; tv.tv_usec -= initial_tv.tv_usec; @@ -324,6 +324,14 @@ void log_formatted_file_info(std::string_view filename, int lineno, std::string log("%s:%d: Info: %s", filename, lineno, str); } +void log_suppressed() { + if (log_debug_suppressed && !log_make_debug) { + constexpr const char* format = "\n"; + logv_string(format, stringf(format, log_debug_suppressed)); + log_debug_suppressed = 0; + } +} + [[noreturn]] static void log_error_with_prefix(std::string_view prefix, std::string str) { @@ -345,7 +353,9 @@ static void log_error_with_prefix(std::string_view prefix, std::string str) } log_last_error = std::move(str); - log("%s%s", prefix, log_last_error); + std::string message(prefix); + message += log_last_error; + logv_string("%s%s", message); log_flush(); log_make_debug = bak_log_make_debug; @@ -355,7 +365,7 @@ static void log_error_with_prefix(std::string_view prefix, std::string str) item.current_count++; for (auto &[_, item] : log_expect_prefix_error) - if (std::regex_search(string(prefix) + string(log_last_error), item.pattern)) + if (std::regex_search(message, item.pattern)) item.current_count++; log_check_expected(); diff --git a/kernel/log.h b/kernel/log.h index 63faf7091..d132ba1a0 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -206,12 +206,7 @@ template log_formatted_cmd_error(fmt.format(args...)); } -static inline void log_suppressed() { - if (log_debug_suppressed && !log_make_debug) { - log("\n", log_debug_suppressed); - log_debug_suppressed = 0; - } -} +void log_suppressed(); struct LogMakeDebugHdl { bool status = false; diff --git a/kernel/log_help.cc b/kernel/log_help.cc index 93b91b08b..01c9a93f6 100644 --- a/kernel/log_help.cc +++ b/kernel/log_help.cc @@ -78,7 +78,7 @@ ContentListing* ContentListing::open_option(const string &text, } #define MAX_LINE_LEN 80 -void log_pass_str(const std::string &pass_str, std::string indent_str, bool leading_newline=false) { +void log_body_str(const std::string &pass_str, std::string indent_str, bool leading_newline=false, bool is_formatted=false) { if (pass_str.empty()) return; std::istringstream iss(pass_str); @@ -86,26 +86,30 @@ void log_pass_str(const std::string &pass_str, std::string indent_str, bool lead log("\n"); for (std::string line; std::getline(iss, line);) { log("%s", indent_str); - auto curr_len = indent_str.length(); - std::istringstream lss(line); - for (std::string word; std::getline(lss, word, ' ');) { - while (word[0] == '`' && word.back() == '`') - word = word.substr(1, word.length()-2); - if (curr_len + word.length() >= MAX_LINE_LEN-1) { - curr_len = 0; - log("\n%s", indent_str); - } - if (word.length()) { - log("%s ", word); - curr_len += word.length() + 1; + if (is_formatted) { + log("%s", line); + } else { + auto curr_len = indent_str.length(); + std::istringstream lss(line); + for (std::string word; std::getline(lss, word, ' ');) { + while (word[0] == '`' && word.back() == '`') + word = word.substr(1, word.length()-2); + if (curr_len + word.length() >= MAX_LINE_LEN-1) { + curr_len = 0; + log("\n%s", indent_str); + } + if (word.length()) { + log("%s ", word); + curr_len += word.length() + 1; + } } } log("\n"); } } -void log_pass_str(const std::string &pass_str, int indent=0, bool leading_newline=false) { +void log_body(const ContentListing &content, int indent=0, bool leading_newline=false) { std::string indent_str(indent*4, ' '); - log_pass_str(pass_str, indent_str, leading_newline); + log_body_str(content.body, indent_str, leading_newline, content.type.compare("code") == 0); } PrettyHelp *current_help = nullptr; @@ -134,16 +138,16 @@ void PrettyHelp::log_help() const { for (auto &content : _root_listing) { if (content.type.compare("usage") == 0) { - log_pass_str(content.body, 1, true); + log_body(content, 1, true); log("\n"); } else if (content.type.compare("option") == 0) { - log_pass_str(content.body, 1); + log_body(content, 1); for (auto text : content) { - log_pass_str(text.body, 2); + log_body(text, 2); log("\n"); } } else { - log_pass_str(content.body, 0); + log_body(content, 0); log("\n"); } } diff --git a/kernel/modtools.h b/kernel/modtools.h index a081c7556..285f22b2a 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -23,11 +23,28 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" YOSYS_NAMESPACE_BEGIN struct ModIndex : public RTLIL::Monitor { + struct PointerOrderedSigBit : public RTLIL::SigBit { + PointerOrderedSigBit(SigBit s) { + wire = s.wire; + if (wire) + offset = s.offset; + else + data = s.data; + } + inline bool operator<(const RTLIL::SigBit &other) const { + if (wire == other.wire) + return wire ? (offset < other.offset) : (data < other.data); + if (wire != nullptr && other.wire != nullptr) + return wire < other.wire; // look here + return (wire != nullptr) < (other.wire != nullptr); + } + }; struct PortInfo { RTLIL::Cell* cell; RTLIL::IdString port; @@ -77,7 +94,7 @@ struct ModIndex : public RTLIL::Monitor SigMap sigmap; RTLIL::Module *module; - std::map database; + std::map database; int auto_reload_counter; bool auto_reload_module; @@ -94,8 +111,11 @@ struct ModIndex : public RTLIL::Monitor { for (int i = 0; i < GetSize(sig); i++) { RTLIL::SigBit bit = sigmap(sig[i]); - if (bit.wire) + if (bit.wire) { database[bit].ports.erase(PortInfo(cell, port, i)); + if (!database[bit].is_input && !database[bit].is_output && database[bit].ports.empty()) + database.erase(bit); + } } } @@ -132,11 +152,11 @@ struct ModIndex : public RTLIL::Monitor } } - void check() + bool ok() { #ifndef NDEBUG if (auto_reload_module) - return; + return true; for (auto it : database) log_assert(it.first == sigmap(it.first)); @@ -156,9 +176,15 @@ struct ModIndex : public RTLIL::Monitor else if (!(it.second == database_bak.at(it.first))) log("ModuleIndex::check(): Different content for database[%s].\n", log_signal(it.first)); - log_assert(database == database_bak); + return false; } #endif + return true; + } + + void check() + { + log_assert(ok()); } void notify_connect(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override @@ -332,7 +358,7 @@ struct ModWalker RTLIL::Design *design; RTLIL::Module *module; - CellTypes ct; + NewCellTypes ct; SigMap sigmap; dict> signal_drivers; diff --git a/kernel/newcelltypes.h b/kernel/newcelltypes.h new file mode 100644 index 000000000..eb42019af --- /dev/null +++ b/kernel/newcelltypes.h @@ -0,0 +1,651 @@ +#ifndef NEWCELLTYPES_H +#define NEWCELLTYPES_H + +#include "kernel/rtlil.h" +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +/** + * This API is unstable. + * It may change or be removed in future versions and break dependent code. + */ + +namespace StaticCellTypes { + +// Given by last internal cell type IdString constids.inc, compilation error if too low +constexpr int MAX_CELLS = 300; +// Currently given by _MUX16_, compilation error if too low +constexpr int MAX_PORTS = 20; +struct CellTableBuilder { + struct PortList { + std::array ports{}; + size_t count = 0; + constexpr PortList() = default; + constexpr PortList(std::initializer_list init) { + for (auto p : init) { + ports[count++] = p; + } + } + constexpr auto begin() const { return ports.begin(); } + constexpr auto end() const { return ports.begin() + count; } + constexpr bool contains(RTLIL::IdString port) const { + for (size_t i = 0; i < count; i++) { + if (port == ports[i]) + return true; + } + + return false; + } + constexpr size_t size() const { return count; } + }; + struct Features { + bool is_evaluable = false; + bool is_combinatorial = false; + bool is_synthesizable = false; + bool is_stdcell = false; + bool is_ff = false; + bool is_mem_noff = false; + bool is_anyinit = false; + bool is_tristate = false; + }; + struct CellInfo { + RTLIL::IdString type; + PortList inputs, outputs; + Features features; + }; + std::array cells{}; + size_t count = 0; + + constexpr void setup_type(RTLIL::IdString type, std::initializer_list inputs, std::initializer_list outputs, const Features& features) { + cells[count++] = {type, PortList(inputs), PortList(outputs), features}; + } + constexpr void setup_internals_other() + { + Features features {}; + features.is_tristate = true; + setup_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y}, features); + + features = {}; + setup_type(ID($assert), {ID::A, ID::EN}, {}, features); + setup_type(ID($assume), {ID::A, ID::EN}, {}, features); + setup_type(ID($live), {ID::A, ID::EN}, {}, features); + setup_type(ID($fair), {ID::A, ID::EN}, {}, features); + setup_type(ID($cover), {ID::A, ID::EN}, {}, features); + setup_type(ID($initstate), {}, {ID::Y}, features); + setup_type(ID($anyconst), {}, {ID::Y}, features); + setup_type(ID($anyseq), {}, {ID::Y}, features); + setup_type(ID($allconst), {}, {ID::Y}, features); + setup_type(ID($allseq), {}, {ID::Y}, features); + setup_type(ID($equiv), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, {}, features); + setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, {}, features); + setup_type(ID($specrule), {ID::SRC_EN, ID::DST_EN, ID::SRC, ID::DST}, {}, features); + setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, {}, features); + setup_type(ID($check), {ID::A, ID::EN, ID::ARGS, ID::TRG}, {}, features); + setup_type(ID($set_tag), {ID::A, ID::SET, ID::CLR}, {ID::Y}, features); + setup_type(ID($get_tag), {ID::A}, {ID::Y}, features); + setup_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, {}, features); + setup_type(ID($original_tag), {ID::A}, {ID::Y}, features); + setup_type(ID($future_ff), {ID::A}, {ID::Y}, features); + setup_type(ID($scopeinfo), {}, {}, features); + setup_type(ID($input_port), {}, {ID::Y}, features); + setup_type(ID($connect), {ID::A, ID::B}, {}, features); + } + constexpr void setup_internals_eval() + { + Features features {}; + features.is_evaluable = true; + std::initializer_list unary_ops = { + ID($not), ID($pos), ID($buf), ID($neg), + ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), + ID($logic_not), ID($slice), ID($lut), ID($sop) + }; + + std::initializer_list binary_ops = { + ID($and), ID($or), ID($xor), ID($xnor), + ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), + ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow), + ID($logic_and), ID($logic_or), ID($concat), ID($macc), + ID($bweqx) + }; + + for (auto type : unary_ops) + setup_type(type, {ID::A}, {ID::Y}, features); + + for (auto type : binary_ops) + setup_type(type, {ID::A, ID::B}, {ID::Y}, features); + + for (auto type : {ID($mux), ID($pmux), ID($bwmux)}) + setup_type(type, {ID::A, ID::B, ID::S}, {ID::Y}, features); + + for (auto type : {ID($bmux), ID($demux)}) + setup_type(type, {ID::A, ID::S}, {ID::Y}, features); + + setup_type(ID($lcu), {ID::P, ID::G, ID::CI}, {ID::CO}, features); + setup_type(ID($alu), {ID::A, ID::B, ID::CI, ID::BI}, {ID::X, ID::Y, ID::CO}, features); + setup_type(ID($macc_v2), {ID::A, ID::B, ID::C}, {ID::Y}, features); + setup_type(ID($fa), {ID::A, ID::B, ID::C}, {ID::X, ID::Y}, features); + } + constexpr void setup_internals_ff() + { + Features features {}; + features.is_ff = true; + setup_type(ID($sr), {ID::SET, ID::CLR}, {ID::Q}, features); + setup_type(ID($ff), {ID::D}, {ID::Q}, features); + setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q}, features); + setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q}, features); + setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q}, features); + setup_type(ID($dffsre), {ID::CLK, ID::SET, ID::CLR, ID::D, ID::EN}, {ID::Q}, features); + setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q}, features); + setup_type(ID($adffe), {ID::CLK, ID::ARST, ID::D, ID::EN}, {ID::Q}, features); + setup_type(ID($aldff), {ID::CLK, ID::ALOAD, ID::AD, ID::D}, {ID::Q}, features); + setup_type(ID($aldffe), {ID::CLK, ID::ALOAD, ID::AD, ID::D, ID::EN}, {ID::Q}, features); + setup_type(ID($sdff), {ID::CLK, ID::SRST, ID::D}, {ID::Q}, features); + setup_type(ID($sdffe), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q}, features); + setup_type(ID($sdffce), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q}, features); + setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q}, features); + setup_type(ID($adlatch), {ID::EN, ID::D, ID::ARST}, {ID::Q}, features); + setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q}, features); + } + constexpr void setup_internals_anyinit() + { + Features features {}; + features.is_anyinit = true; + setup_type(ID($anyinit), {ID::D}, {ID::Q}, features); + } + constexpr void setup_internals_mem_noff() + { + Features features {}; + features.is_mem_noff = true; + // NOT setup_internals_ff() + + setup_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA}, features); + setup_type(ID($memrd_v2), {ID::CLK, ID::EN, ID::ARST, ID::SRST, ID::ADDR}, {ID::DATA}, features); + setup_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, {}, features); + setup_type(ID($memwr_v2), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, {}, features); + setup_type(ID($meminit), {ID::ADDR, ID::DATA}, {}, features); + setup_type(ID($meminit_v2), {ID::ADDR, ID::DATA, ID::EN}, {}, features); + setup_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA}, features); + setup_type(ID($mem_v2), {ID::RD_CLK, ID::RD_EN, ID::RD_ARST, ID::RD_SRST, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA}, features); + + // What? + setup_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT}, features); + } + constexpr void setup_stdcells_tristate() + { + Features features {}; + features.is_stdcell = true; + features.is_tristate = true; + setup_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}, features); + } + + constexpr void setup_stdcells_eval() + { + Features features {}; + features.is_stdcell = true; + features.is_evaluable = true; + setup_type(ID($_BUF_), {ID::A}, {ID::Y}, features); + setup_type(ID($_NOT_), {ID::A}, {ID::Y}, features); + setup_type(ID($_AND_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_NAND_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_OR_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_NOR_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_XOR_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_XNOR_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_ANDNOT_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_ORNOT_), {ID::A, ID::B}, {ID::Y}, features); + setup_type(ID($_MUX_), {ID::A, ID::B, ID::S}, {ID::Y}, features); + setup_type(ID($_NMUX_), {ID::A, ID::B, ID::S}, {ID::Y}, features); + setup_type(ID($_MUX4_), {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T}, {ID::Y}, features); + setup_type(ID($_MUX8_), {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U}, {ID::Y}, features); + setup_type(ID($_MUX16_), {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V}, {ID::Y}, features); + setup_type(ID($_AOI3_), {ID::A, ID::B, ID::C}, {ID::Y}, features); + setup_type(ID($_OAI3_), {ID::A, ID::B, ID::C}, {ID::Y}, features); + setup_type(ID($_AOI4_), {ID::A, ID::B, ID::C, ID::D}, {ID::Y}, features); + setup_type(ID($_OAI4_), {ID::A, ID::B, ID::C, ID::D}, {ID::Y}, features); + } + + constexpr void setup_stdcells_ff() { + Features features {}; + features.is_stdcell = true; + features.is_ff = true; + + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // setup_type(std::string("$_SR_") + c1 + c2 + "_", {ID::S, ID::R}, {ID::Q}, features); + setup_type(ID($_SR_NN_), {ID::S, ID::R}, {ID::Q}, features); + setup_type(ID($_SR_NP_), {ID::S, ID::R}, {ID::Q}, features); + setup_type(ID($_SR_PN_), {ID::S, ID::R}, {ID::Q}, features); + setup_type(ID($_SR_PP_), {ID::S, ID::R}, {ID::Q}, features); + + setup_type(ID($_FF_), {ID::D}, {ID::Q}, features); + + // for (auto c1 : list_np) + // setup_type(std::string("$_DFF_") + c1 + "_", {ID::C, ID::D}, {ID::Q}, features); + setup_type(ID::$_DFF_N_, {ID::C, ID::D}, {ID::Q}, features); + setup_type(ID::$_DFF_P_, {ID::C, ID::D}, {ID::Q}, features); + + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // setup_type(std::string("$_DFFE_") + c1 + c2 + "_", {ID::C, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID::$_DFFE_NN_, {ID::C, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID::$_DFFE_NP_, {ID::C, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID::$_DFFE_PN_, {ID::C, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID::$_DFFE_PP_, {ID::C, ID::D, ID::E}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_01) + // setup_type(std::string("$_DFF_") + c1 + c2 + c3 + "_", {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_NN0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_NN1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_NP0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_NP1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_PN0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_PN1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_PP0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFF_PP1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_01) + // for (auto c4 : list_np) + // setup_type(std::string("$_DFFE_") + c1 + c2 + c3 + c4 + "_", {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NN0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NN0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NN1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NN1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NP0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NP0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NP1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_NP1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PN0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PN0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PN1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PN1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PP0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PP0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PP1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFE_PP1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // setup_type(std::string("$_ALDFF_") + c1 + c2 + "_", {ID::C, ID::L, ID::AD, ID::D}, {ID::Q}, features); + setup_type(ID($_ALDFF_NN_), {ID::C, ID::L, ID::AD, ID::D}, {ID::Q}, features); + setup_type(ID($_ALDFF_NP_), {ID::C, ID::L, ID::AD, ID::D}, {ID::Q}, features); + setup_type(ID($_ALDFF_PN_), {ID::C, ID::L, ID::AD, ID::D}, {ID::Q}, features); + setup_type(ID($_ALDFF_PP_), {ID::C, ID::L, ID::AD, ID::D}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_np) + // setup_type(std::string("$_ALDFFE_") + c1 + c2 + c3 + "_", {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_NNN_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_NNP_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_NPN_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_NPP_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_PNN_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_PNP_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_PPN_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_ALDFFE_PPP_), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_np) + // setup_type(std::string("$_DFFSR_") + c1 + c2 + c3 + "_", {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_NNN_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_NNP_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_NPN_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_NPP_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_PNN_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_PNP_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_PPN_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DFFSR_PPP_), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_np) + // for (auto c4 : list_np) + // setup_type(std::string("$_DFFSRE_") + c1 + c2 + c3 + c4 + "_", {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NNNN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NNNP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NNPN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NNPP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NPNN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NPNP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NPPN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_NPPP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PNNN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PNNP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PNPN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PNPP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PPNN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PPNP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PPPN_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_DFFSRE_PPPP_), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_01) + // setup_type(std::string("$_SDFF_") + c1 + c2 + c3 + "_", {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_NN0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_NN1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_NP0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_NP1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_PN0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_PN1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_PP0_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_SDFF_PP1_), {ID::C, ID::R, ID::D}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_01) + // for (auto c4 : list_np) + // setup_type(std::string("$_SDFFE_") + c1 + c2 + c3 + c4 + "_", {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NN0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NN0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NN1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NN1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NP0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NP0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NP1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_NP1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PN0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PN0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PN1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PN1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PP0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PP0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PP1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFE_PP1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_01) + // for (auto c4 : list_np) + // setup_type(std::string("$_SDFFCE_") + c1 + c2 + c3 + c4 + "_", {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NN0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NN0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NN1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NN1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NP0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NP0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NP1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_NP1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PN0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PN0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PN1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PN1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PP0N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PP0P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PP1N_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + setup_type(ID($_SDFFCE_PP1P_), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}, features); + // for (auto c1 : list_np) + // setup_type(std::string("$_DLATCH_") + c1 + "_", {ID::E, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_N_), {ID::E, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_P_), {ID::E, ID::D}, {ID::Q}, features); + + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_01) + // setup_type(std::string("$_DLATCH_") + c1 + c2 + c3 + "_", {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_NN0_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_NN1_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_NP0_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_NP1_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_PN0_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_PN1_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_PP0_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCH_PP1_), {ID::E, ID::R, ID::D}, {ID::Q}, features); + // for (auto c1 : list_np) + // for (auto c2 : list_np) + // for (auto c3 : list_np) + // setup_type(std::string("$_DLATCHSR_") + c1 + c2 + c3 + "_", {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_NNN_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_NNP_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_NPN_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_NPP_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_PNN_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_PNP_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_PPN_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + setup_type(ID($_DLATCHSR_PPP_), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}, features); + } + constexpr CellTableBuilder() { + setup_internals_other(); + setup_internals_eval(); + setup_internals_ff(); + setup_internals_anyinit(); + setup_internals_mem_noff(); + setup_stdcells_tristate(); + setup_stdcells_eval(); + setup_stdcells_ff(); + } + +}; + +constexpr CellTableBuilder builder{}; + +struct PortInfo { + struct PortLists { + std::array data{}; + constexpr CellTableBuilder::PortList operator()(IdString type) const { + return data[type.index_]; + } + constexpr CellTableBuilder::PortList& operator[](size_t idx) { + return data[idx]; + } + constexpr size_t size() const { return data.size(); } + }; + PortLists inputs {}; + PortLists outputs {}; + constexpr PortInfo() { + for (size_t i = 0; i < builder.count; ++i) { + auto& cell = builder.cells[i]; + size_t idx = cell.type.index_; + inputs[idx] = cell.inputs; + outputs[idx] = cell.outputs; + } + } +}; + +struct Categories { + struct Category { + std::array data{}; + constexpr bool operator()(IdString type) const { + size_t idx = type.index_; + if (idx >= MAX_CELLS) + return false; + return data[idx]; + } + constexpr bool operator[](size_t idx) { + return data[idx]; + } + constexpr void set_id(IdString type, bool val = true) { + size_t idx = type.index_; + if (idx >= MAX_CELLS) + return; // TODO should be an assert but then it's not constexpr + data[idx] = val; + } + constexpr void set(size_t idx, bool val = true) { + data[idx] = val; + } + constexpr size_t size() const { return data.size(); } + }; + Category empty {}; + Category is_known {}; + Category is_evaluable {}; + Category is_combinatorial {}; + Category is_synthesizable {}; + Category is_stdcell {}; + Category is_ff {}; + Category is_mem_noff {}; + Category is_anyinit {}; + Category is_tristate {}; + constexpr Categories() { + for (size_t i = 0; i < builder.count; ++i) { + auto& cell = builder.cells[i]; + size_t idx = cell.type.index_; + is_known.set(idx); + is_evaluable.set(idx, cell.features.is_evaluable); + is_combinatorial.set(idx, cell.features.is_combinatorial); + is_synthesizable.set(idx, cell.features.is_synthesizable); + is_stdcell.set(idx, cell.features.is_stdcell); + is_ff.set(idx, cell.features.is_ff); + is_mem_noff.set(idx, cell.features.is_mem_noff); + is_anyinit.set(idx, cell.features.is_anyinit); + is_tristate.set(idx, cell.features.is_tristate); + } + } + constexpr static Category join(Category left, Category right) { + Category c {}; + for (size_t i = 0; i < MAX_CELLS; ++i) { + c.set(i, left[i] || right[i]); + } + return c; + } + constexpr static Category meet(Category left, Category right) { + Category c {}; + for (size_t i = 0; i < MAX_CELLS; ++i) { + c.set(i, left[i] && right[i]); + } + return c; + } + // Sketchy! Make sure to always meet with only the known universe. + // In other words, no modus tollens allowed + constexpr static Category complement(Category arg) { + Category c {}; + for (size_t i = 0; i < MAX_CELLS; ++i) { + c.set(i, !arg[i]); + } + return c; + } +}; + +// Pure +static constexpr PortInfo port_info; +static constexpr Categories categories; + +// Legacy +namespace Compat { + static constexpr auto internals_all = Categories::meet(categories.is_known, Categories::complement(categories.is_stdcell)); + static constexpr auto mem_ff = Categories::join(categories.is_ff, categories.is_mem_noff); + // old setup_internals + setup_stdcells + static constexpr auto nomem_noff = Categories::meet(categories.is_known, Categories::complement(mem_ff)); + static constexpr auto internals_mem_ff = Categories::meet(internals_all, mem_ff); + // old setup_internals + static constexpr auto internals_nomem_noff = Categories::meet(internals_all, nomem_noff); + // old setup_stdcells + static constexpr auto stdcells_nomem_noff = Categories::meet(categories.is_stdcell, nomem_noff); + static constexpr auto stdcells_mem = Categories::meet(categories.is_stdcell, categories.is_mem_noff); + // old setup_internals_eval + // static constexpr auto internals_eval = Categories::meet(internals_all, categories.is_evaluable); +}; + +namespace { + static_assert(categories.is_evaluable(ID($and))); + static_assert(!categories.is_ff(ID($and))); + static_assert(Categories::join(categories.is_evaluable, categories.is_ff)(ID($and))); + static_assert(Categories::join(categories.is_evaluable, categories.is_ff)(ID($dffsr))); + static_assert(!Categories::join(categories.is_evaluable, categories.is_ff)(ID($anyinit))); +} + +}; + +struct NewCellType { + RTLIL::IdString type; + pool inputs, outputs; + bool is_evaluable; + bool is_combinatorial; + bool is_synthesizable; +}; + +struct NewCellTypes { + struct IdStringHash { + std::size_t operator()(const IdString id) const { + return static_cast(id.hash_top().yield()); + } + }; + StaticCellTypes::Categories::Category static_cell_types = StaticCellTypes::categories.empty; + std::unordered_map custom_cell_types {}; + + NewCellTypes() { + static_cell_types = StaticCellTypes::categories.empty; + } + + NewCellTypes(RTLIL::Design *design) { + static_cell_types = StaticCellTypes::categories.empty; + setup(design); + } + void setup(RTLIL::Design *design = NULL) { + if (design) + setup_design(design); + static_cell_types = StaticCellTypes::categories.is_known; + } + void setup_design(RTLIL::Design *design) { + for (auto module : design->modules()) + setup_module(module); + } + + void setup_module(RTLIL::Module *module) { + pool inputs, outputs; + for (RTLIL::IdString wire_name : module->ports) { + RTLIL::Wire *wire = module->wire(wire_name); + if (wire->port_input) + inputs.insert(wire->name); + if (wire->port_output) + outputs.insert(wire->name); + } + setup_type(module->name, inputs, outputs); + } + + void setup_type(RTLIL::IdString type, const pool &inputs, const pool &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false) { + NewCellType ct = {type, inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable}; + custom_cell_types[ct.type] = ct; + } + + void clear() { + custom_cell_types.clear(); + static_cell_types = StaticCellTypes::categories.empty; + } + + bool cell_known(const RTLIL::IdString &type) const { + return static_cell_types(type) || custom_cell_types.count(type) != 0; + } + + bool cell_output(const RTLIL::IdString &type, const RTLIL::IdString &port) const + { + if (static_cell_types(type) && StaticCellTypes::port_info.outputs(type).contains(port)) { + return true; + } + auto it = custom_cell_types.find(type); + return it != custom_cell_types.end() && it->second.outputs.count(port) != 0; + } + + bool cell_input(const RTLIL::IdString &type, const RTLIL::IdString &port) const + { + if (static_cell_types(type) && StaticCellTypes::port_info.inputs(type).contains(port)) { + return true; + } + auto it = custom_cell_types.find(type); + return it != custom_cell_types.end() && it->second.inputs.count(port) != 0; + } + + RTLIL::PortDir cell_port_dir(RTLIL::IdString type, RTLIL::IdString port) const + { + bool is_input, is_output; + if (static_cell_types(type)) { + is_input = StaticCellTypes::port_info.inputs(type).contains(port); + is_output = StaticCellTypes::port_info.outputs(type).contains(port); + } else { + auto it = custom_cell_types.find(type); + if (it == custom_cell_types.end()) + return RTLIL::PD_UNKNOWN; + is_input = it->second.inputs.count(port); + is_output = it->second.outputs.count(port); + } + return RTLIL::PortDir(is_input + is_output * 2); + } + bool cell_evaluable(const RTLIL::IdString &type) const + { + return static_cell_types(type) && StaticCellTypes::categories.is_evaluable(type); + } +}; + +extern NewCellTypes yosys_celltypes; + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/pattern.h b/kernel/pattern.h new file mode 100644 index 000000000..bb794e9fa --- /dev/null +++ b/kernel/pattern.h @@ -0,0 +1,102 @@ +#ifndef OPT_DFF_COMP_H +#define OPT_DFF_COMP_H + +#include "kernel/rtlil.h" +#include +#include + +YOSYS_NAMESPACE_BEGIN + +/** + * Pattern matching utilities for control signal analysis. + * + * A pattern_t maps control signals to required values, representing a + * product term (conjunction): {A=1, B=0} means "A AND !B". + * + * A patterns_t is a set of patterns representing a sum-of-products: + * {{A=1, B=0}, {A=0, C=1}} means "(A AND !B) OR (!A AND C)". + * + * Used for analyzing MUX tree control paths in DFF optimization. + */ + +// Pattern matching for clock enable +// A pattern maps control signals to their required values for a MUX path +typedef std::map pattern_t; // Set of control signals that must ALL match required vals +typedef std::set patterns_t; // Alternative patterns (OR) +typedef std::pair ctrl_t; // Control signal +typedef std::set ctrls_t; // Set of control signals that must ALL be active + +/** + * Find if two patterns differ in exactly one variable. + * Example: {A=1,B=1} vs {A=1,B=0} returns B, allows simplification: (A&B) | (A&!B) => A + */ +inline std::optional find_complementary_pattern_var( + const pattern_t& left, + const pattern_t& right +) { + std::optional ret; + for (const auto &pt : left) { + // Left requires signal that right doesn't constrain - incompatible domains + if (right.count(pt.first) == 0) + return std::nullopt; + // Signal has same required value in both - not the complement variable + if (right.at(pt.first) == pt.second) + continue; + // Already found one differing signal, now found another - not simplifiable + if (ret) + return std::nullopt; + // First differing signal - candidate complement variable + ret = pt.first; + } + return ret; +} + +/** + * Simplify a sum-of-products by merging complementary patterns: (A&B) | (A&!B) => A, + * and removing redundant patterns: A | (A&B) => A + */ +inline void simplify_patterns(patterns_t& patterns) { + auto new_patterns = patterns; + + // Merge complementary patterns + bool optimized; + do { + optimized = false; + for (auto i = patterns.begin(); i != patterns.end(); i++) { + for (auto j = std::next(i, 1); j != patterns.end(); j++) { + const auto& left = (GetSize(*j) <= GetSize(*i)) ? *j : *i; + auto right = (GetSize(*i) < GetSize(*j)) ? *j : *i; + const auto complementary_var = find_complementary_pattern_var(left, right); + + if (complementary_var && new_patterns.count(right)) { + new_patterns.erase(right); + right.erase(complementary_var.value()); + new_patterns.insert(right); + optimized = true; + } + } + } + patterns = new_patterns; + } while(optimized); + + // Remove redundant patterns + for (auto i = patterns.begin(); i != patterns.end(); ++i) { + for (auto j = std::next(i, 1); j != patterns.end(); ++j) { + const auto& left = (GetSize(*j) <= GetSize(*i)) ? *j : *i; + const auto& right = (GetSize(*i) < GetSize(*j)) ? *j : *i; + bool redundant = true; + + for (const auto& pt : left) + if (right.count(pt.first) == 0 || right.at(pt.first) != pt.second) + redundant = false; + if (redundant) + new_patterns.erase(right); + } + } + + patterns = std::move(new_patterns); +} + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/register.cc b/kernel/register.cc index 3f5aa49ca..cba6d5f99 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -22,6 +22,7 @@ #include "kernel/json.h" #include "kernel/gzip.h" #include "kernel/log_help.h" +#include "kernel/newcelltypes.h" #include #include @@ -975,16 +976,18 @@ struct HelpPass : public Pass { json.entry("generator", yosys_maybe_version()); dict> groups; - dict> cells; + dict> cells; // iterate over cells bool raise_error = false; - for (auto &it : yosys_celltypes.cell_types) { - auto name = it.first.str(); + for (auto it : StaticCellTypes::builder.cells) { + if (!StaticCellTypes::categories.is_known(it.type)) + continue; + auto name = it.type.str(); if (cell_help_messages.contains(name)) { auto cell_help = cell_help_messages.get(name); groups[cell_help.group].emplace_back(name); - auto cell_pair = pair(cell_help, it.second); + auto cell_pair = pair(cell_help, it); cells.emplace(name, cell_pair); } else { log("ERROR: Missing cell help for cell '%s'.\n", name); @@ -1025,9 +1028,9 @@ struct HelpPass : public Pass { json.name("outputs"); json.value(outputs); vector properties; // CellType properties - if (ct.is_evaluable) properties.push_back("is_evaluable"); - if (ct.is_combinatorial) properties.push_back("is_combinatorial"); - if (ct.is_synthesizable) properties.push_back("is_synthesizable"); + if (ct.features.is_evaluable) properties.push_back("is_evaluable"); + if (ct.features.is_combinatorial) properties.push_back("is_combinatorial"); + if (ct.features.is_synthesizable) properties.push_back("is_synthesizable"); // SimHelper properties size_t last = 0; size_t next = 0; while ((next = ch.tags.find(", ", last)) != string::npos) { @@ -1204,7 +1207,7 @@ struct LicensePass : public Pass { log(" | |\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); log(" | |\n"); - log(" | Copyright (C) 2012 - 2025 Claire Xenia Wolf |\n"); + log(" | Copyright (C) 2012 - 2026 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.cc b/kernel/rtlil.cc index cdaaa97bb..a99f0803e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -19,9 +19,10 @@ #include "kernel/yosys.h" #include "kernel/macc.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/binding.h" #include "kernel/sigtools.h" +#include "kernel/threading.h" #include "frontends/verilog/verilog_frontend.h" #include "frontends/verilog/preproc.h" #include "backends/rtlil/rtlil_backend.h" @@ -31,6 +32,7 @@ #include #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -141,9 +143,17 @@ static constexpr bool check_well_known_id_order() // and in sorted ascii order, as required by the ID macro. static_assert(check_well_known_id_order()); +constexpr int STATIC_ID_END = static_cast(RTLIL::StaticId::STATIC_ID_END); + struct IdStringCollector { + IdStringCollector(std::vector &live_ids) + : live_ids(live_ids) {} + void trace(IdString id) { - live.insert(id.index_); + if (id.index_ >= STATIC_ID_END) + live_ids[id.index_ - STATIC_ID_END].set(); + else if (id.index_ < 0) + live_autoidx_ids.push_back(id.index_); } template void trace(const T* v) { trace(*v); @@ -177,27 +187,14 @@ struct IdStringCollector { trace(element); } - void trace(const RTLIL::Design &design) { - trace_values(design.modules_); - trace(design.selection_vars); - } void trace(const RTLIL::Selection &selection_var) { trace(selection_var.selected_modules); trace(selection_var.selected_members); } - void trace_named(const RTLIL::NamedObject named) { + void trace_named(const RTLIL::NamedObject &named) { trace_keys(named.attributes); trace(named.name); } - void trace(const RTLIL::Module &module) { - trace_named(module); - trace_values(module.wires_); - trace_values(module.cells_); - trace(module.avail_parameters); - trace_keys(module.parameter_default_values); - trace_values(module.memories); - trace_values(module.processes); - } void trace(const RTLIL::Wire &wire) { trace_named(wire); if (wire.known_driver()) @@ -233,7 +230,8 @@ struct IdStringCollector { trace(action.memid); } - std::unordered_set live; + std::vector &live_ids; + std::vector live_autoidx_ids; }; int64_t RTLIL::OwningIdString::gc_ns; @@ -242,20 +240,55 @@ int RTLIL::OwningIdString::gc_count; void RTLIL::OwningIdString::collect_garbage() { int64_t start = PerformanceTimer::query(); - IdStringCollector collector; - for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) { - collector.trace(*design); - } - int size = GetSize(global_id_storage_); - for (int i = static_cast(StaticId::STATIC_ID_END); i < size; ++i) { - RTLIL::IdString::Storage &storage = global_id_storage_.at(i); - if (storage.buf == nullptr) - continue; - if (collector.live.find(i) != collector.live.end()) - continue; - if (global_refcount_storage_.find(i) != global_refcount_storage_.end()) - continue; + int pool_size = 0; + for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) + for (RTLIL::Module *module : design->modules()) + pool_size = std::max(pool_size, ThreadPool::work_pool_size(0, module->cells_size(), 1000)); + ParallelDispatchThreadPool thread_pool(pool_size); + + int size = GetSize(global_id_storage_); + std::vector live_ids(size - STATIC_ID_END); + std::vector collectors; + int num_threads = thread_pool.num_threads(); + collectors.reserve(num_threads); + for (int i = 0; i < num_threads; ++i) + collectors.emplace_back(live_ids); + + for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) { + for (RTLIL::Module *module : design->modules()) { + collectors[0].trace_named(*module); + ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000)); + subpool.run([&collectors, module](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(module->cells_size())) + collectors[ctx.thread_num].trace(module->cell_at(i)); + for (int i : ctx.item_range(module->wires_size())) + collectors[ctx.thread_num].trace(module->wire_at(i)); + }); + collectors[0].trace(module->avail_parameters); + collectors[0].trace_keys(module->parameter_default_values); + collectors[0].trace_values(module->memories); + collectors[0].trace_values(module->processes); + } + collectors[0].trace(design->selection_vars); + } + + ShardedVector free_ids(thread_pool); + thread_pool.run([&live_ids, size, &free_ids](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(size - STATIC_ID_END)) { + int index = i + STATIC_ID_END; + RTLIL::IdString::Storage &storage = global_id_storage_.at(index); + if (storage.buf == nullptr) + continue; + if (live_ids[i].load()) + continue; + if (global_refcount_storage_.find(index) != global_refcount_storage_.end()) + continue; + free_ids.insert(ctx, index); + } + }); + for (int i : free_ids) { + RTLIL::IdString::Storage &storage = global_id_storage_.at(i); if (yosys_xtrace) { log("#X# Removed IdString '%s' with index %d.\n", storage.buf, i); log_backtrace("-X- ", yosys_xtrace-1); @@ -267,8 +300,13 @@ void RTLIL::OwningIdString::collect_garbage() global_free_idx_list_.push_back(i); } + std::unordered_set live_autoidx_ids; + for (IdStringCollector &collector : collectors) + for (int id : collector.live_autoidx_ids) + live_autoidx_ids.insert(id); + for (auto it = global_autoidx_id_storage_.begin(); it != global_autoidx_id_storage_.end();) { - if (collector.live.find(it->first) != collector.live.end()) { + if (live_autoidx_ids.find(it->first) != live_autoidx_ids.end()) { ++it; continue; } @@ -287,159 +325,17 @@ void RTLIL::OwningIdString::collect_garbage() dict RTLIL::constpad; -static const pool &builtin_ff_cell_types_internal() { - static const pool res = { - ID($sr), - ID($ff), - ID($dff), - ID($dffe), - ID($dffsr), - ID($dffsre), - ID($adff), - ID($adffe), - ID($aldff), - ID($aldffe), - ID($sdff), - ID($sdffe), - ID($sdffce), - ID($dlatch), - ID($adlatch), - ID($dlatchsr), - ID($_DFFE_NN_), - ID($_DFFE_NP_), - ID($_DFFE_PN_), - ID($_DFFE_PP_), - ID($_DFFSR_NNN_), - ID($_DFFSR_NNP_), - ID($_DFFSR_NPN_), - ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), - ID($_DFFSR_PNP_), - ID($_DFFSR_PPN_), - ID($_DFFSR_PPP_), - ID($_DFFSRE_NNNN_), - ID($_DFFSRE_NNNP_), - ID($_DFFSRE_NNPN_), - ID($_DFFSRE_NNPP_), - ID($_DFFSRE_NPNN_), - ID($_DFFSRE_NPNP_), - ID($_DFFSRE_NPPN_), - ID($_DFFSRE_NPPP_), - ID($_DFFSRE_PNNN_), - ID($_DFFSRE_PNNP_), - ID($_DFFSRE_PNPN_), - ID($_DFFSRE_PNPP_), - ID($_DFFSRE_PPNN_), - ID($_DFFSRE_PPNP_), - ID($_DFFSRE_PPPN_), - ID($_DFFSRE_PPPP_), - ID($_DFF_N_), - ID($_DFF_P_), - ID($_DFF_NN0_), - ID($_DFF_NN1_), - ID($_DFF_NP0_), - ID($_DFF_NP1_), - ID($_DFF_PN0_), - ID($_DFF_PN1_), - ID($_DFF_PP0_), - ID($_DFF_PP1_), - ID($_DFFE_NN0N_), - ID($_DFFE_NN0P_), - ID($_DFFE_NN1N_), - ID($_DFFE_NN1P_), - ID($_DFFE_NP0N_), - ID($_DFFE_NP0P_), - ID($_DFFE_NP1N_), - ID($_DFFE_NP1P_), - ID($_DFFE_PN0N_), - ID($_DFFE_PN0P_), - ID($_DFFE_PN1N_), - ID($_DFFE_PN1P_), - ID($_DFFE_PP0N_), - ID($_DFFE_PP0P_), - ID($_DFFE_PP1N_), - ID($_DFFE_PP1P_), - ID($_ALDFF_NN_), - ID($_ALDFF_NP_), - ID($_ALDFF_PN_), - ID($_ALDFF_PP_), - ID($_ALDFFE_NNN_), - ID($_ALDFFE_NNP_), - ID($_ALDFFE_NPN_), - ID($_ALDFFE_NPP_), - ID($_ALDFFE_PNN_), - ID($_ALDFFE_PNP_), - ID($_ALDFFE_PPN_), - ID($_ALDFFE_PPP_), - ID($_SDFF_NN0_), - ID($_SDFF_NN1_), - ID($_SDFF_NP0_), - ID($_SDFF_NP1_), - ID($_SDFF_PN0_), - ID($_SDFF_PN1_), - ID($_SDFF_PP0_), - ID($_SDFF_PP1_), - ID($_SDFFE_NN0N_), - ID($_SDFFE_NN0P_), - ID($_SDFFE_NN1N_), - ID($_SDFFE_NN1P_), - ID($_SDFFE_NP0N_), - ID($_SDFFE_NP0P_), - ID($_SDFFE_NP1N_), - ID($_SDFFE_NP1P_), - ID($_SDFFE_PN0N_), - ID($_SDFFE_PN0P_), - ID($_SDFFE_PN1N_), - ID($_SDFFE_PN1P_), - ID($_SDFFE_PP0N_), - ID($_SDFFE_PP0P_), - ID($_SDFFE_PP1N_), - ID($_SDFFE_PP1P_), - ID($_SDFFCE_NN0N_), - ID($_SDFFCE_NN0P_), - ID($_SDFFCE_NN1N_), - ID($_SDFFCE_NN1P_), - ID($_SDFFCE_NP0N_), - ID($_SDFFCE_NP0P_), - ID($_SDFFCE_NP1N_), - ID($_SDFFCE_NP1P_), - ID($_SDFFCE_PN0N_), - ID($_SDFFCE_PN0P_), - ID($_SDFFCE_PN1N_), - ID($_SDFFCE_PN1P_), - ID($_SDFFCE_PP0N_), - ID($_SDFFCE_PP0P_), - ID($_SDFFCE_PP1N_), - ID($_SDFFCE_PP1P_), - ID($_SR_NN_), - ID($_SR_NP_), - ID($_SR_PN_), - ID($_SR_PP_), - ID($_DLATCH_N_), - ID($_DLATCH_P_), - ID($_DLATCH_NN0_), - ID($_DLATCH_NN1_), - ID($_DLATCH_NP0_), - ID($_DLATCH_NP1_), - ID($_DLATCH_PN0_), - ID($_DLATCH_PN1_), - ID($_DLATCH_PP0_), - ID($_DLATCH_PP1_), - ID($_DLATCHSR_NNN_), - ID($_DLATCHSR_NNP_), - ID($_DLATCHSR_NPN_), - ID($_DLATCHSR_NPP_), - ID($_DLATCHSR_PNN_), - ID($_DLATCHSR_PNP_), - ID($_DLATCHSR_PPN_), - ID($_DLATCHSR_PPP_), - ID($_FF_), - }; - return res; -} - const pool &RTLIL::builtin_ff_cell_types() { - return builtin_ff_cell_types_internal(); + static const pool res = []() { + pool r; + for (size_t i = 0; i < StaticCellTypes::builder.count; i++) { + auto &cell = StaticCellTypes::builder.cells[i]; + if (cell.features.is_ff) + r.insert(cell.type); + } + return r; + }(); + return res; } #define check(condition) log_assert(condition && "malformed Const union") @@ -1465,15 +1361,21 @@ void RTLIL::Design::sort_modules() modules_.sort(sort_by_id_str()); } +void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool); + void RTLIL::Design::check() { #ifndef NDEBUG log_assert(!selection_stack.empty()); + int pool_size = 0; + for (auto &it : modules_) + pool_size = std::max(pool_size, ThreadPool::work_pool_size(0, it.second->cells_size(), 1000)); + ParallelDispatchThreadPool thread_pool(pool_size); for (auto &it : modules_) { log_assert(this == it.second->design); log_assert(it.first == it.second->name); log_assert(!it.first.empty()); - it.second->check(); + check_module(it.second, thread_pool); } #endif } @@ -1548,6 +1450,13 @@ void RTLIL::Design::pop_selection() push_full_selection(); } +std::string RTLIL::Design::to_rtlil_str(bool only_selected) const +{ + std::ostringstream f; + RTLIL_BACKEND::dump_design(f, const_cast(this), only_selected); + return f.str(); +} + std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { bool include_partials = partials == RTLIL::SELECT_ALL; @@ -1702,11 +1611,11 @@ size_t RTLIL::Module::count_id(RTLIL::IdString id) namespace { struct InternalCellChecker { - RTLIL::Module *module; + const RTLIL::Module *module; RTLIL::Cell *cell; pool expected_params, expected_ports; - InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { } + InternalCellChecker(const RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { } void error(int linenr) { @@ -2682,88 +2591,96 @@ void RTLIL::Module::sort() it.second->attributes.sort(sort_by_id_str()); } -void RTLIL::Module::check() +void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool) { #ifndef NDEBUG - std::vector ports_declared; - for (auto &it : wires_) { - log_assert(this == it.second->module); - log_assert(it.first == it.second->name); - log_assert(!it.first.empty()); - log_assert(it.second->width >= 0); - log_assert(it.second->port_id >= 0); - for (auto &it2 : it.second->attributes) - log_assert(!it2.first.empty()); - if (it.second->port_id) { - log_assert(GetSize(ports) >= it.second->port_id); - log_assert(ports.at(it.second->port_id-1) == it.first); - log_assert(it.second->port_input || it.second->port_output); - if (GetSize(ports_declared) < it.second->port_id) - ports_declared.resize(it.second->port_id); - log_assert(ports_declared[it.second->port_id-1] == false); - ports_declared[it.second->port_id-1] = true; - } else - log_assert(!it.second->port_input && !it.second->port_output); - } - for (auto port_declared : ports_declared) - log_assert(port_declared == true); - log_assert(GetSize(ports) == GetSize(ports_declared)); + ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000)); + const RTLIL::Module *const_module = module; - for (auto &it : memories) { + pool memory_strings; + for (auto &it : module->memories) { log_assert(it.first == it.second->name); log_assert(!it.first.empty()); log_assert(it.second->width >= 0); log_assert(it.second->size >= 0); for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); + memory_strings.insert(it.second->name.str()); } - pool packed_memids; + std::vector ports_declared(GetSize(module->ports)); + ShardedVector memids(subpool); + subpool.run([const_module, &ports_declared, &memory_strings, &memids](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(const_module->cells_size())) { + auto it = *const_module->cells_.element(i); + log_assert(const_module == it.second->module); + log_assert(it.first == it.second->name); + log_assert(!it.first.empty()); + log_assert(!it.second->type.empty()); + for (auto &it2 : it.second->connections()) { + log_assert(!it2.first.empty()); + it2.second.check(const_module); + } + for (auto &it2 : it.second->attributes) + log_assert(!it2.first.empty()); + for (auto &it2 : it.second->parameters) + log_assert(!it2.first.empty()); + InternalCellChecker checker(const_module, it.second); + checker.check(); + if (it.second->has_memid()) { + log_assert(memory_strings.count(it.second->parameters.at(ID::MEMID).decode_string())); + } else if (it.second->is_mem_cell()) { + std::string memid = it.second->parameters.at(ID::MEMID).decode_string(); + log_assert(!memory_strings.count(memid)); + memids.insert(ctx, std::move(memid)); + } + auto cell_mod = const_module->design->module(it.first); + if (cell_mod != nullptr) { + // assertion check below to make sure that there are no + // cases where a cell has a blackbox attribute since + // that is deprecated + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #endif + log_assert(!it.second->get_blackbox_attribute()); + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif + } + } - for (auto &it : cells_) { - log_assert(this == it.second->module); - log_assert(it.first == it.second->name); - log_assert(!it.first.empty()); - log_assert(!it.second->type.empty()); - for (auto &it2 : it.second->connections()) { - log_assert(!it2.first.empty()); - it2.second.check(this); + for (int i : ctx.item_range(const_module->wires_size())) { + auto it = *const_module->wires_.element(i); + log_assert(const_module == it.second->module); + log_assert(it.first == it.second->name); + log_assert(!it.first.empty()); + log_assert(it.second->width >= 0); + log_assert(it.second->port_id >= 0); + for (auto &it2 : it.second->attributes) + log_assert(!it2.first.empty()); + if (it.second->port_id) { + log_assert(GetSize(const_module->ports) >= it.second->port_id); + log_assert(const_module->ports.at(it.second->port_id-1) == it.first); + log_assert(it.second->port_input || it.second->port_output); + log_assert(it.second->port_id <= GetSize(ports_declared)); + bool previously_declared = ports_declared[it.second->port_id-1].set_and_return_old(); + log_assert(previously_declared == false); + } else + log_assert(!it.second->port_input && !it.second->port_output); } - for (auto &it2 : it.second->attributes) - log_assert(!it2.first.empty()); - for (auto &it2 : it.second->parameters) - log_assert(!it2.first.empty()); - InternalCellChecker checker(this, it.second); - checker.check(); - if (it.second->has_memid()) { - log_assert(memories.count(it.second->parameters.at(ID::MEMID).decode_string())); - } else if (it.second->is_mem_cell()) { - IdString memid = it.second->parameters.at(ID::MEMID).decode_string(); - log_assert(!memories.count(memid)); - log_assert(!packed_memids.count(memid)); - packed_memids.insert(memid); - } - auto cell_mod = design->module(it.first); - if (cell_mod != nullptr) { - // assertion check below to make sure that there are no - // cases where a cell has a blackbox attribute since - // that is deprecated - #ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #endif - log_assert(!it.second->get_blackbox_attribute()); - #ifdef __GNUC__ - #pragma GCC diagnostic pop - #endif - } - } + }); + for (const MonotonicFlag &port_declared : ports_declared) + log_assert(port_declared.load() == true); + pool memids_pool; + for (std::string &memid : memids) + log_assert(memids_pool.insert(memid).second); - for (auto &it : processes) { + for (auto &it : module->processes) { log_assert(it.first == it.second->name); log_assert(!it.first.empty()); log_assert(it.second->root_case.compare.empty()); - std::vector all_cases = {&it.second->root_case}; + std::vector all_cases = {&it.second->root_case}; for (size_t i = 0; i < all_cases.size(); i++) { for (auto &switch_it : all_cases[i]->switches) { for (auto &case_it : switch_it->cases) { @@ -2776,34 +2693,41 @@ void RTLIL::Module::check() } for (auto &sync_it : it.second->syncs) { switch (sync_it->type) { - case SyncType::ST0: - case SyncType::ST1: - case SyncType::STp: - case SyncType::STn: - case SyncType::STe: + case RTLIL::SyncType::ST0: + case RTLIL::SyncType::ST1: + case RTLIL::SyncType::STp: + case RTLIL::SyncType::STn: + case RTLIL::SyncType::STe: log_assert(!sync_it->signal.empty()); break; - case SyncType::STa: - case SyncType::STg: - case SyncType::STi: + case RTLIL::SyncType::STa: + case RTLIL::SyncType::STg: + case RTLIL::SyncType::STi: log_assert(sync_it->signal.empty()); break; } } } - for (auto &it : connections_) { + for (auto &it : module->connections_) { log_assert(it.first.size() == it.second.size()); log_assert(!it.first.has_const()); - it.first.check(this); - it.second.check(this); + it.first.check(module); + it.second.check(module); } - for (auto &it : attributes) + for (auto &it : module->attributes) log_assert(!it.first.empty()); #endif } +void RTLIL::Module::check() +{ + int pool_size = ThreadPool::work_pool_size(0, cells_size(), 1000); + ParallelDispatchThreadPool thread_pool(pool_size); + check_module(this, thread_pool); +} + void RTLIL::Module::optimize() { } @@ -2982,6 +2906,8 @@ void RTLIL::Module::add(RTLIL::Binding *binding) void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); + if (wires.empty()) + return; struct DeleteWireWorker { @@ -3039,6 +2965,13 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) } } +void RTLIL::Module::remove(RTLIL::Memory *memory) +{ + log_assert(memories.count(memory->name) != 0); + memories.erase(memory->name); + delete memory; +} + void RTLIL::Module::remove(RTLIL::Process *process) { log_assert(processes.count(process->name) != 0); @@ -4281,6 +4214,13 @@ RTLIL::SigSpec RTLIL::Module::FutureFF(RTLIL::IdString name, const RTLIL::SigSpe return sig; } +std::string RTLIL::Module::to_rtlil_str() const +{ + std::ostringstream f; + RTLIL_BACKEND::dump_module(f, "", const_cast(this), design, false); + return f.str(); +} + RTLIL::Wire::Wire() { static unsigned int hashidx_count = 123456789; @@ -4308,6 +4248,13 @@ RTLIL::Wire::~Wire() #endif } +std::string RTLIL::Wire::to_rtlil_str() const +{ + std::ostringstream f; + RTLIL_BACKEND::dump_wire(f, "", this); + return f.str(); +} + #ifdef YOSYS_ENABLE_PYTHON static std::map all_wires; std::map *RTLIL::Wire::get_all_wires(void) @@ -4330,6 +4277,13 @@ RTLIL::Memory::Memory() #endif } +std::string RTLIL::Memory::to_rtlil_str() const +{ + std::ostringstream f; + RTLIL_BACKEND::dump_memory(f, "", this); + return f.str(); +} + RTLIL::Process::Process() : module(nullptr) { static unsigned int hashidx_count = 123456789; @@ -4337,6 +4291,13 @@ RTLIL::Process::Process() : module(nullptr) hashidx_ = hashidx_count; } +std::string RTLIL::Process::to_rtlil_str() const +{ + std::ostringstream f; + RTLIL_BACKEND::dump_proc(f, "", this); + return f.str(); +} + RTLIL::Cell::Cell() : module(nullptr) { static unsigned int hashidx_count = 123456789; @@ -4358,6 +4319,13 @@ RTLIL::Cell::~Cell() #endif } +std::string RTLIL::Cell::to_rtlil_str() const +{ + std::ostringstream f; + RTLIL_BACKEND::dump_cell(f, "", this); + return f.str(); +} + #ifdef YOSYS_ENABLE_PYTHON static std::map all_cells; std::map *RTLIL::Cell::get_all_cells(void) @@ -4558,7 +4526,7 @@ bool RTLIL::Cell::is_mem_cell() const } bool RTLIL::Cell::is_builtin_ff() const { - return builtin_ff_cell_types_internal().count(type) > 0; + return StaticCellTypes::categories.is_ff(type); } RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit) @@ -5022,31 +4990,35 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe other->unpack(); } - bool modified = false; - bool other_modified = false; - for (int i = GetSize(bits_) - 1; i >= 0; i--) - { - if (bits_[i].wire == NULL) continue; + // Convert pattern to pool for O(1) lookup, avoiding O(n*m) chunk iteration + pool pattern_bits; + pattern_bits.reserve(pattern.size()); + for (auto &bit : pattern) + if (bit.wire != NULL) + pattern_bits.insert(bit); - for (auto &pattern_chunk : pattern.chunks()) - if (bits_[i].wire == pattern_chunk.wire && - bits_[i].offset >= pattern_chunk.offset && - bits_[i].offset < pattern_chunk.offset + pattern_chunk.width) { - modified = true; - bits_.erase(bits_.begin() + i); - if (other != NULL) { - other_modified = true; - other->bits_.erase(other->bits_.begin() + i); - } - break; + // Compact in-place to avoid O(n^2) erase operations + size_t write_idx = 0; + for (size_t read_idx = 0; read_idx < bits_.size(); read_idx++) + { + if (!(bits_[read_idx].wire != NULL && pattern_bits.count(bits_[read_idx]))) { + if (write_idx != read_idx) { + bits_[write_idx] = bits_[read_idx]; + if (other != NULL) + other->bits_[write_idx] = other->bits_[read_idx]; } + write_idx++; + } } + bool modified = (write_idx < bits_.size()); if (modified) { + bits_.resize(write_idx); hash_.clear(); try_repack(); } - if (other_modified) { + if (other != NULL && modified) { + other->bits_.resize(write_idx); other->hash_.clear(); other->try_repack(); } @@ -5073,24 +5045,27 @@ void RTLIL::SigSpec::remove2(const pool &pattern, RTLIL::SigSpec other->unpack(); } - bool modified = false; - bool other_modified = false; - for (int i = GetSize(bits_) - 1; i >= 0; i--) { - if (bits_[i].wire != NULL && pattern.count(bits_[i])) { - modified = true; - bits_.erase(bits_.begin() + i); - if (other != NULL) { - other_modified = true; - other->bits_.erase(other->bits_.begin() + i); + // Avoid O(n^2) complexity by compacting in-place + size_t write_idx = 0; + for (size_t read_idx = 0; read_idx < bits_.size(); read_idx++) { + if (!(bits_[read_idx].wire != NULL && pattern.count(bits_[read_idx]))) { + if (write_idx != read_idx) { + bits_[write_idx] = bits_[read_idx]; + if (other != NULL) + other->bits_[write_idx] = other->bits_[read_idx]; } + write_idx++; } } + bool modified = (write_idx < bits_.size()); if (modified) { + bits_.resize(write_idx); hash_.clear(); try_repack(); } - if (other_modified) { + if (other != NULL && modified) { + other->bits_.resize(write_idx); other->hash_.clear(); other->try_repack(); } @@ -5106,24 +5081,27 @@ void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigS other->unpack(); } - bool modified = false; - bool other_modified = false; - for (int i = GetSize(bits_) - 1; i >= 0; i--) { - if (bits_[i].wire != NULL && pattern.count(bits_[i])) { - modified = true; - bits_.erase(bits_.begin() + i); - if (other != NULL) { - other_modified = true; - other->bits_.erase(other->bits_.begin() + i); + // Avoid O(n^2) complexity by compacting in-place + size_t write_idx = 0; + for (size_t read_idx = 0; read_idx < bits_.size(); read_idx++) { + if (!(bits_[read_idx].wire != NULL && pattern.count(bits_[read_idx]))) { + if (write_idx != read_idx) { + bits_[write_idx] = bits_[read_idx]; + if (other != NULL) + other->bits_[write_idx] = other->bits_[read_idx]; } + write_idx++; } } + bool modified = (write_idx < bits_.size()); if (modified) { + bits_.resize(write_idx); hash_.clear(); try_repack(); } - if (other_modified) { + if (other != NULL && modified) { + other->bits_.resize(write_idx); other->hash_.clear(); other->try_repack(); } @@ -5294,26 +5272,32 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const log_assert(length >= 0); log_assert(offset + length <= size()); - SigSpec extracted; - Chunks cs = chunks(); - auto it = cs.begin(); - for (; offset; offset -= it->width, ++it) { - if (offset < it->width) { - int chunk_length = min(it->width - offset, length); - extracted.append(it->extract(offset, chunk_length)); - length -= chunk_length; - ++it; - break; - } - } - for (; length; length -= it->width, ++it) { - if (length >= it->width) { - extracted.append(*it); + std::vector extracted; + SigBit first; + bool is_packing = true; + for (int i = offset; i < offset + length; i++) { + bool was_packing_before = is_packing; + SigBit bit = (*this)[i]; + if (i == offset) { + first = bit; + if (!bit.wire) + is_packing = false; } else { - extracted.append(it->extract(0, length)); - break; + if (bit.wire != first.wire) + is_packing = false; + if (bit.wire) + if (bit.offset != first.offset + (i - offset)) + is_packing = false; } + if (was_packing_before && !is_packing) + for (int j = offset; j < i; j++) + extracted.push_back((*this)[j]); + if (!is_packing) + extracted.push_back((*this)[i]); } + if (is_packing) + return SigChunk(first.wire, first.offset, length); + return extracted; } @@ -5418,7 +5402,7 @@ RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const } #ifndef NDEBUG -void RTLIL::SigSpec::check(Module *mod) const +void RTLIL::SigSpec::check(const Module *mod) const { if (rep_ == CHUNK) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ec47adb0e..b32f9ea76 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -223,8 +223,8 @@ struct RTLIL::IdString constexpr inline IdString() : index_(0) { } inline IdString(const char *str) : index_(insert(std::string_view(str))) { } - constexpr inline IdString(const IdString &str) : index_(str.index_) { } - inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; } + constexpr IdString(const IdString &str) = default; + IdString(IdString &&str) = default; inline IdString(const std::string &str) : index_(insert(std::string_view(str))) { } inline IdString(std::string_view str) : index_(insert(str)) { } constexpr inline IdString(StaticId id) : index_(static_cast(id)) {} @@ -275,6 +275,17 @@ struct RTLIL::IdString *out += std::to_string(-index_); } + std::string unescape() const { + if (index_ < 0) { + // Must start with "$auto$" so no unescaping required. + return str(); + } + std::string_view str = global_id_storage_.at(index_).str_view(); + if (str.size() < 2 || str[0] != '\\' || str[1] == '$' || str[1] == '\\' || (str[1] >= '0' && str[1] <= '9')) + return std::string(str); + return std::string(str.substr(1)); + } + class Substrings { std::string_view first_; int suffix_number; @@ -737,6 +748,7 @@ template <> struct IDMacroHelper<-1> { namespace RTLIL { extern dict constpad; + [[deprecated("use StaticCellTypes::categories.is_ff() instead")]] const pool &builtin_ff_cell_types(); static inline std::string escape_id(const std::string &str) { @@ -758,7 +770,7 @@ namespace RTLIL { } static inline std::string unescape_id(RTLIL::IdString str) { - return unescape_id(str.str()); + return str.unescape(); } static inline const char *id2cstr(RTLIL::IdString str) { @@ -1388,6 +1400,8 @@ struct RTLIL::SigSpecConstIterator struct RTLIL::SigSpec { private: + friend class SigSpecRepTest; + FRIEND_TEST(SigSpecRepTest, Extract); enum Representation : char { CHUNK, BITS, @@ -1748,9 +1762,9 @@ public: } #ifndef NDEBUG - void check(Module *mod = nullptr) const; + void check(const Module *mod = nullptr) const; #else - void check(Module *mod = nullptr) const { (void)mod; } + void check(const Module *mod = nullptr) const { (void)mod; } #endif }; @@ -2031,7 +2045,10 @@ struct RTLIL::Design // returns all selected unboxed whole modules, warning the user if any // partially selected or boxed modules have been ignored std::vector selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); } + static std::map *get_all_designs(void); + + std::string to_rtlil_str(bool only_selected = true) const; }; struct RTLIL::Module : public RTLIL::NamedObject @@ -2137,13 +2154,18 @@ public: } RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } + int wires_size() const { return wires_.size(); } + RTLIL::Wire* wire_at(int index) const { return wires_.element(index)->second; } RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } + int cells_size() const { return cells_.size(); } + RTLIL::Cell* cell_at(int index) const { return cells_.element(index)->second; } void add(RTLIL::Binding *binding); // Removing wires is expensive. If you have to remove wires, remove them all at once. void remove(const pool &wires); void remove(RTLIL::Cell *cell); + void remove(RTLIL::Memory *memory); void remove(RTLIL::Process *process); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); @@ -2390,6 +2412,7 @@ public: RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = ""); RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + std::string to_rtlil_str() const; #ifdef YOSYS_ENABLE_PYTHON static std::map *get_all_modules(void); #endif @@ -2443,6 +2466,7 @@ public: return zero_index + start_offset; } + std::string to_rtlil_str() const; #ifdef YOSYS_ENABLE_PYTHON static std::map *get_all_wires(void); #endif @@ -2460,6 +2484,8 @@ struct RTLIL::Memory : public RTLIL::NamedObject Memory(); int width, start_offset, size; + + std::string to_rtlil_str() const; #ifdef YOSYS_ENABLE_PYTHON ~Memory(); static std::map *get_all_memorys(void); @@ -2518,6 +2544,8 @@ public: template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); + std::string to_rtlil_str() const; + #ifdef YOSYS_ENABLE_PYTHON static std::map *get_all_cells(void); #endif @@ -2596,6 +2624,7 @@ public: template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); RTLIL::Process *clone() const; + std::string to_rtlil_str() const; }; diff --git a/kernel/satgen.cc b/kernel/satgen.cc index f2c1e00c2..7fbcba1b2 100644 --- a/kernel/satgen.cc +++ b/kernel/satgen.cc @@ -19,6 +19,7 @@ #include "kernel/satgen.h" #include "kernel/ff.h" +#include "kernel/yosys_common.h" USING_YOSYS_NAMESPACE @@ -1378,7 +1379,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) return true; } - if (cell->type == ID($scopeinfo)) + if (cell->type == ID($scopeinfo) || cell->type == ID($input_port)) { return true; } @@ -1387,3 +1388,22 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep) // .. and all sequential cells with asynchronous inputs return false; } + +namespace Yosys { + +void report_missing_model(bool warn_only, RTLIL::Cell* cell) +{ + std::string s; + if (cell->is_builtin_ff()) + s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); + else + s = stringf("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); + + if (warn_only) { + log_formatted_warning_noprefix(s); + } else { + log_formatted_error(s); + } +} + +} diff --git a/kernel/satgen.h b/kernel/satgen.h index 7815847b3..c11d480a4 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -59,6 +59,7 @@ struct SatSolver struct ezSatPtr : public std::unique_ptr { ezSatPtr() : unique_ptr(yosys_satsolver->create()) { } + explicit ezSatPtr(SatSolver *solver) : unique_ptr((solver ? solver : yosys_satsolver)->create()) { } }; struct SatGen @@ -292,6 +293,8 @@ struct SatGen bool importCell(RTLIL::Cell *cell, int timestep = -1); }; +void report_missing_model(bool warn_only, RTLIL::Cell* cell); + YOSYS_NAMESPACE_END #endif diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index ec0483a4a..9866f5c98 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -279,7 +279,7 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar ERROR("object not found") if (string_flag) { - Tcl_SetResult(interp, (char *) obj->get_string_attribute(attr_id).c_str(), TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(obj->get_string_attribute(attr_id).c_str(), -1)); } else if (int_flag || uint_flag || sint_flag) { if (!obj->has_attribute(attr_id)) ERROR("attribute missing (required for -int)"); @@ -295,7 +295,7 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar if (!obj->has_attribute(attr_id)) ERROR("attribute missing (required unless -bool or -string)") - Tcl_SetResult(interp, (char *) obj->attributes.at(attr_id).as_string().c_str(), TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(obj->attributes.at(attr_id).as_string().c_str(), -1)); } return TCL_OK; @@ -341,7 +341,7 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar if (!obj) ERROR("object not found") - Tcl_SetResult(interp, (char *) std::to_string(obj->has_attribute(attr_id)).c_str(), TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(std::to_string(obj->has_attribute(attr_id)).c_str(), -1)); return TCL_OK; } @@ -465,14 +465,14 @@ static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *a const RTLIL::Const &value = cell->getParam(param_id); if (string_flag) { - Tcl_SetResult(interp, (char *) value.decode_string().c_str(), TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(value.decode_string().c_str(), -1)); } else if (int_flag || uint_flag || sint_flag) { mp_int value_mp; if (!const_to_mp_int(value, &value_mp, sint_flag, uint_flag)) ERROR("bignum manipulation failed"); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&value_mp)); } else { - Tcl_SetResult(interp, (char *) value.as_string().c_str(), TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(value.as_string().c_str(), -1)); } return TCL_OK; } diff --git a/kernel/threading.cc b/kernel/threading.cc index dcc044c89..eda6bb4cb 100644 --- a/kernel/threading.cc +++ b/kernel/threading.cc @@ -17,6 +17,20 @@ static int get_max_threads() return max_threads; } +static int init_work_units_per_thread_override() +{ + const char *v = getenv("YOSYS_WORK_UNITS_PER_THREAD"); + if (v == nullptr) + return 0; + return atoi(v); +} + +static int get_work_units_per_thread_override() +{ + static int work_units_per_thread = init_work_units_per_thread_override(); + return work_units_per_thread; +} + void DeferredLogs::flush() { for (auto &m : logs) @@ -31,12 +45,23 @@ int ThreadPool::pool_size(int reserved_cores, int max_worker_threads) #ifdef YOSYS_ENABLE_THREADS int available_threads = std::min(std::thread::hardware_concurrency(), get_max_threads()); int num_threads = std::min(available_threads - reserved_cores, max_worker_threads); - return std::max(0, num_threads); + return std::max(0, num_threads); #else - return 0; + (void)reserved_cores; + (void)max_worker_threads; + (void)get_max_threads(); + return 0; #endif } +int ThreadPool::work_pool_size(int reserved_cores, int work_units, int work_units_per_thread) +{ + int work_units_per_thread_override = get_work_units_per_thread_override(); + if (work_units_per_thread_override > 0) + work_units_per_thread = work_units_per_thread_override; + return pool_size(reserved_cores, work_units / work_units_per_thread); +} + ThreadPool::ThreadPool(int pool_size, std::function b) : body(std::move(b)) { @@ -57,4 +82,76 @@ ThreadPool::~ThreadPool() #endif } +IntRange item_range_for_worker(int num_items, int thread_num, int num_threads) +{ + if (num_threads <= 1) { + return {0, num_items}; + } + int items_per_thread = num_items / num_threads; + int extra_items = num_items % num_threads; + // The first `extra_items` threads get one extra item. + int start = thread_num * items_per_thread + std::min(thread_num, extra_items); + int end = (thread_num + 1) * items_per_thread + std::min(thread_num + 1, extra_items); + return {start, end}; +} + +ParallelDispatchThreadPool::ParallelDispatchThreadPool(int pool_size) + : num_worker_threads_(std::max(1, pool_size) - 1) +{ +#ifdef YOSYS_ENABLE_THREADS + main_to_workers_signal.resize(num_worker_threads_, 0); +#endif + // Don't start the threads until we've constructed all our data members. + thread_pool = std::make_unique(num_worker_threads_, [this](int thread_num){ + run_worker(thread_num); + }); +} + +ParallelDispatchThreadPool::~ParallelDispatchThreadPool() +{ +#ifdef YOSYS_ENABLE_THREADS + if (num_worker_threads_ == 0) + return; + current_work = nullptr; + num_active_worker_threads_.store(num_worker_threads_, std::memory_order_relaxed); + signal_workers_start(); + wait_for_workers_done(); +#endif +} + +void ParallelDispatchThreadPool::run(std::function work, int max_threads) +{ + Multithreading multithreading; + int num_active_worker_threads = num_threads(max_threads) - 1; + if (num_active_worker_threads == 0) { + work({{0}, 1}); + return; + } +#ifdef YOSYS_ENABLE_THREADS + num_active_worker_threads_.store(num_active_worker_threads, std::memory_order_relaxed); + current_work = &work; + signal_workers_start(); + work({{0}, num_active_worker_threads + 1}); + wait_for_workers_done(); +#endif +} + +void ParallelDispatchThreadPool::run_worker(int thread_num) +{ +#ifdef YOSYS_ENABLE_THREADS + while (true) + { + worker_wait_for_start(thread_num); + if (current_work == nullptr) + break; + int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); + (*current_work)({{thread_num + 1}, num_active_worker_threads + 1}); + signal_worker_done(); + } + signal_worker_done(); +#else + (void)current_work; +#endif +} + YOSYS_NAMESPACE_END diff --git a/kernel/threading.h b/kernel/threading.h index b8cd62f87..3a31b0633 100644 --- a/kernel/threading.h +++ b/kernel/threading.h @@ -8,6 +8,7 @@ #include "kernel/yosys_common.h" #include "kernel/log.h" +#include "kernel/utils.h" #ifndef YOSYS_THREADING_H #define YOSYS_THREADING_H @@ -131,6 +132,11 @@ public: // The result may be 0. static int pool_size(int reserved_cores, int max_worker_threads); + // Computes the number of worker threads to use, by dividing work_units among threads. + // For testing purposes you can set YOSYS_WORK_UNITS_PER_THREAD to override `work_units_per_thread`. + // The result may be 0. + static int work_pool_size(int reserved_cores, int work_units, int work_units_per_thread); + // Create a pool of threads running the given closure (parameterized by thread number). // `pool_size` must be the result of a `pool_size()` call. ThreadPool(int pool_size, std::function b); @@ -154,6 +160,142 @@ private: #endif }; +// Divides some number of items into `num_threads` subranges and returns the +// `thread_num`'th subrange. If `num_threads` is zero, returns the whole range. +IntRange item_range_for_worker(int num_items, int thread_num, int num_threads); + +// A type that encapsulates the index of a thread in some list of threads. Useful for +// stronger typechecking and code readability. +struct ThreadIndex { + int thread_num; +}; + +// A set of threads with a `run()` API that runs a closure on all of the threads +// and wait for all those closures to complete. This is a convenient way to implement +// parallel algorithms that use barrier synchronization. +class ParallelDispatchThreadPool +{ +public: + // Create a pool of threads running the given closure (parameterized by thread number). + // `pool_size` must be the result of a `pool_size()` call. + // `pool_size` can be zero, which we treat as 1. + ParallelDispatchThreadPool(int pool_size); + ~ParallelDispatchThreadPool(); + + // For each thread running a closure, a `RunCtx` is passed to the closure. Currently + // it contains the thread index and the total number of threads. It can be passed + // directly to any APIs requiring a `ThreadIndex`. + struct RunCtx : public ThreadIndex { + int num_threads; + IntRange item_range(int num_items) const { + return item_range_for_worker(num_items, thread_num, num_threads); + } + }; + // Sometimes we only want to activate a subset of the threads in the pool. This + // class provides a way to do that. It provides the same `num_threads()` + // and `run()` APIs as a `ParallelDispatchThreadPool`. + class Subpool { + public: + Subpool(ParallelDispatchThreadPool &parent, int max_threads) + : parent(parent), max_threads(max_threads) {} + // Returns the number of threads that will be used when calling `run()`. + int num_threads() const { + return parent.num_threads(max_threads); + } + void run(std::function work) { + parent.run(std::move(work), max_threads); + } + ParallelDispatchThreadPool &thread_pool() { return parent; } + private: + ParallelDispatchThreadPool &parent; + int max_threads; + }; + + // Run the `work` function in parallel on each thread in the pool (parameterized by + // thread number). Waits for all work functions to complete. Only one `run()` can be + // active at a time. + // Uses no more than `max_threads` threads (but at least one). + void run(std::function work) { + run(std::move(work), INT_MAX); + } + + // Returns the number of threads that will be used when calling `run()`. + int num_threads() const { + return num_threads(INT_MAX); + } +private: + friend class Subpool; + + void run(std::function work, int max_threads); + int num_threads(int max_threads) const { + return std::min(num_worker_threads_ + 1, std::max(1, max_threads)); + } + void run_worker(int thread_num); + + std::function *current_work = nullptr; + // Keeps a correct count even when threads are exiting. + int num_worker_threads_; + // The count of active worker threads for the current `run()`. + // This is only written by the main thread, and only written when + // no other worker threads are running (i.e. all worker threads have + // passed the increment of `done_workers` in `signal_worker_done()` + // and not passed the release of the lock in `worker_wait_for_start()`. + // Although there can't be any races, we still need to make it atomic + // to prevent the compiler reordering accesses so the above invariant + // is maintained. + std::atomic num_active_worker_threads_ = 0; + +#ifdef YOSYS_ENABLE_THREADS + // Not especially efficient for large numbers of threads. Worker wakeup could scale + // better by conceptually organising workers into a tree and having workers wake + // up their children. + std::mutex main_to_workers_signal_mutex; + std::condition_variable main_to_workers_signal_cv; + std::vector main_to_workers_signal; + void signal_workers_start() { + std::unique_lock lock(main_to_workers_signal_mutex); + int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); + std::fill(main_to_workers_signal.begin(), main_to_workers_signal.begin() + num_active_worker_threads, 1); + // When `num_active_worker_threads_` is small compared to `num_worker_threads_`, we have a "thundering herd" + // problem here. Fixing that would add complexity so don't worry about it for now. + main_to_workers_signal_cv.notify_all(); + } + void worker_wait_for_start(int thread_num) { + std::unique_lock lock(main_to_workers_signal_mutex); + main_to_workers_signal_cv.wait(lock, [this, thread_num] { return main_to_workers_signal[thread_num] > 0; }); + main_to_workers_signal[thread_num] = 0; + } + + std::atomic done_workers = 0; + std::mutex workers_to_main_signal_mutex; + std::condition_variable workers_to_main_signal_cv; + void signal_worker_done() { + // Must read `num_active_worker_threads_` before we increment `d`! Otherwise + // it is possible we would increment `d`, and then another worker signals the + // main thread that all workers are done, and the main thread writes to + // `num_active_worker_threads_` before we check it. + int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); + int d = done_workers.fetch_add(1, std::memory_order_release); + if (d + 1 == num_active_worker_threads) { + std::unique_lock lock(workers_to_main_signal_mutex); + workers_to_main_signal_cv.notify_all(); + } + } + void wait_for_workers_done() { + std::unique_lock lock(workers_to_main_signal_mutex); + workers_to_main_signal_cv.wait(lock, [this] { + int num_active_worker_threads = num_active_worker_threads_.load(std::memory_order_relaxed); + return done_workers.load(std::memory_order_acquire) == num_active_worker_threads; + }); + done_workers.store(0, std::memory_order_relaxed); + } +#endif + // Ensure `thread_pool` is destroyed before any other members, + // forcing all threads to be joined before destroying the + // members (e.g. workers_to_main_signal_mutex) they might be using. + std::unique_ptr thread_pool; +}; + template class ConcurrentStack { @@ -181,6 +323,382 @@ private: std::vector contents; }; +// A vector that is sharded into buckets, one per thread. This lets multiple threads write +// efficiently to the vector without synchronization overhead. After all writers have +// finished writing, the vector can be iterated over. The iteration order is deterministic: +// all the elements written by thread 0 in the order it inserted them, followed by all elements +// written by thread 1, etc. +template +class ShardedVector { +public: + ShardedVector(const ParallelDispatchThreadPool &thread_pool) { + init(thread_pool.num_threads()); + } + ShardedVector(const ParallelDispatchThreadPool::Subpool &thread_pool) { + init(thread_pool.num_threads()); + } + + // Insert a value, passing the `ThreadIndex` of the writer thread. + // Parallel inserts with different `ThreadIndex` values are fine. + // Inserts must not run concurrently with any other methods (e.g. + // iteration or `empty()`.) + void insert(const ThreadIndex &thread, T value) { + buckets[thread.thread_num].emplace_back(std::move(value)); + } + + bool empty() const { + for (const std::vector &bucket : buckets) + if (!bucket.empty()) + return false; + return true; + } + + using Buckets = std::vector>; + class iterator { + public: + iterator(typename Buckets::iterator bucket_it, typename Buckets::iterator bucket_end) + : bucket_it(std::move(bucket_it)), bucket_end(std::move(bucket_end)) { + if (bucket_it != bucket_end) + inner_it = bucket_it->begin(); + normalize(); + } + T& operator*() const { return *inner_it.value(); } + iterator &operator++() { + ++*inner_it; + normalize(); + return *this; + } + bool operator!=(const iterator &other) const { + return bucket_it != other.bucket_it || inner_it != other.inner_it; + } + private: + void normalize() { + if (bucket_it == bucket_end) + return; + while (inner_it == bucket_it->end()) { + ++bucket_it; + if (bucket_it == bucket_end) { + inner_it.reset(); + return; + } + inner_it = bucket_it->begin(); + } + } + std::optional::iterator> inner_it; + typename Buckets::iterator bucket_it; + typename Buckets::iterator bucket_end; + }; + iterator begin() { return iterator(buckets.begin(), buckets.end()); } + iterator end() { return iterator(buckets.end(), buckets.end()); } +private: + void init(int num_threads) { + buckets.resize(num_threads); + } + Buckets buckets; +}; + +// This collision handler for `ShardedHashtable` resolves collisions by keeping +// the current value and discarding the other. This is correct when all values with the +// same key are interchangeable, i.e. when the hashtable is being used as a set instead +// of a map. +template +struct SetCollisionHandler { + void operator()(typename V::Accumulated &, typename V::Accumulated &) const {} +}; + +// A hashtable that can be efficiently built in parallel and then looked up concurrently. +// `V` is the type of elements that will be added to the hashtable. It must have a +// member type `Accumulated` representing the combination of multiple `V` elements. This +// can be the same as `V`, but for example `V` could contain a Wire* and `V::Accumulated` +// could contain a `pool`. `KeyEquality` is a class containing an `operator()` that +// returns true of two `V` elements have equal keys. +// `CollisionHandler` is used to reduce two `V::Accumulated` values into a single value. +// +// To use this, first construct a `Builder` and fill it in (in parallel), then construct +// a `ShardedHashtable` from the `Builder`. +template +class ShardedHashtable { +public: + // A combination of a `V` and its hash value. + struct Value { + Value(V value, unsigned int hash) : value(std::move(value)), hash(hash) {} + Value(Value &&) = default; + Value(const Value &) = delete; + Value &operator=(const Value &) = delete; + V value; + unsigned int hash; + }; + // A combination of a `V::Accumulated` and its hash value. + struct AccumulatedValue { + AccumulatedValue(typename V::Accumulated value, unsigned int hash) : value(std::move(value)), hash(hash) {} + AccumulatedValue(AccumulatedValue &&) = default; +#if defined(_MSC_VER) + AccumulatedValue(const AccumulatedValue &) { + log_error("Copy constructor called on AccumulatedValue"); + } + AccumulatedValue &operator=(const AccumulatedValue &) { + log_error("Copy assignment called on AccumulatedValue"); + return *this; + } +#else + AccumulatedValue(const AccumulatedValue &) = delete; + AccumulatedValue &operator=(const AccumulatedValue &) = delete; +#endif + typename V::Accumulated value; + unsigned int hash; + }; + // A class containing an `operator()` that returns true of two `AccumulatedValue` + // elements have equal keys. + // Required to insert `AccumulatedValue`s into an `std::unordered_set`. + struct AccumulatedValueEquality { + KeyEquality inner; + AccumulatedValueEquality(const KeyEquality &inner) : inner(inner) {} + bool operator()(const AccumulatedValue &v1, const AccumulatedValue &v2) const { + return inner(v1.value, v2.value); + } + }; + // A class containing an `operator()` that returns the hash value of an `AccumulatedValue`. + // Required to insert `AccumulatedValue`s into an `std::unordered_set`. + struct AccumulatedValueHashOp { + size_t operator()(const AccumulatedValue &v) const { + return static_cast(v.hash); + } + }; + using Shard = std::unordered_set; + + // First construct one of these. Then populate it in parallel by calling `insert()` from many threads. + // Then do another parallel phase calling `process()` from many threads. + class Builder { + public: + Builder(const ParallelDispatchThreadPool &thread_pool, KeyEquality equality = KeyEquality(), CollisionHandler collision_handler = CollisionHandler()) + : collision_handler(std::move(collision_handler)) { + init(thread_pool.num_threads(), std::move(equality)); + } + Builder(const ParallelDispatchThreadPool::Subpool &thread_pool, KeyEquality equality = KeyEquality(), CollisionHandler collision_handler = CollisionHandler()) + : collision_handler(std::move(collision_handler)) { + init(thread_pool.num_threads(), std::move(equality)); + } + // First call `insert` to insert all elements. All inserts must finish + // before calling any `process()`. + void insert(const ThreadIndex &thread, Value v) { + // You might think that for the single-threaded case, we can optimize by + // inserting directly into the `std::unordered_set` here. But that slows things down + // a lot and I never got around to figuring out why. + std::vector> &buckets = all_buckets[thread.thread_num]; + size_t bucket = static_cast(v.hash) % buckets.size(); + buckets[bucket].emplace_back(std::move(v)); + } + // Then call `process` for each thread. All `process()`s must finish before using + // the `Builder` to construct a `ShardedHashtable`. + void process(const ThreadIndex &thread) { + int size = 0; + for (std::vector> &buckets : all_buckets) + size += GetSize(buckets[thread.thread_num]); + Shard &shard = shards[thread.thread_num]; + shard.reserve(size); + for (std::vector> &buckets : all_buckets) { + for (Value &value : buckets[thread.thread_num]) + accumulate(value, shard); + // Free as much memory as we can during the parallel phase. + std::vector().swap(buckets[thread.thread_num]); + } + } + private: + friend class ShardedHashtable; + void accumulate(Value &value, Shard &shard) { + // With C++20 we could make this more efficient using heterogenous lookup + AccumulatedValue accumulated_value{std::move(value.value), value.hash}; + auto [it, inserted] = shard.insert(std::move(accumulated_value)); + if (!inserted) + collision_handler(const_cast(it->value), accumulated_value.value); + } + void init(int num_threads, KeyEquality equality) { + all_buckets.resize(num_threads); + for (std::vector> &buckets : all_buckets) + buckets.resize(num_threads); + for (int i = 0; i < num_threads; ++i) + shards.emplace_back(0, AccumulatedValueHashOp(), AccumulatedValueEquality(equality)); + } + const CollisionHandler collision_handler; + // A num_threads x num_threads matrix of buckets. + // In the first phase, each thread i gemerates elements and writes them to + // bucket [i][j] where j = hash(element) % num_threads. + // In the second phase, thread i reads from bucket [j][i] for all j, collecting + // all elements where i = hash(element) % num_threads. + std::vector>> all_buckets; + std::vector shards; + }; + + // Then finally construct the hashtable: + ShardedHashtable(Builder &builder) : shards(std::move(builder.shards)) { + // Check that all necessary 'process()' calls were made. + for (std::vector> &buckets : builder.all_buckets) + for (std::vector &bucket : buckets) + log_assert(bucket.empty()); + // Free memory. + std::vector>>().swap(builder.all_buckets); + } + ShardedHashtable(ShardedHashtable &&other) = default; + ShardedHashtable() {} + + ShardedHashtable &operator=(ShardedHashtable &&other) = default; + + // Look up by `AccumulatedValue`. If we switch to C++20 then we could use + // heterogenous lookup to support looking up by `Value` here. Returns nullptr + // if the key is not found. + const typename V::Accumulated *find(const AccumulatedValue &v) const { + size_t num_shards = shards.size(); + if (num_shards == 0) + return nullptr; + size_t shard = static_cast(v.hash) % num_shards; + auto it = shards[shard].find(v); + if (it == shards[shard].end()) + return nullptr; + return &it->value; + } + + // Insert an element into the table. The caller is responsible for ensuring this does not + // happen concurrently with any other method calls. + void insert(AccumulatedValue v) { + size_t num_shards = shards.size(); + if (num_shards == 0) + return; + size_t shard = static_cast(v.hash) % num_shards; + shards[shard].insert(v); + } + + // Call this for each shard to implement parallel destruction. For very large `ShardedHashtable`s, + // deleting all elements of all shards on a single thread can be a performance bottleneck. + void clear(const ThreadIndex &shard) { + AccumulatedValueEquality equality = shards[shard.thread_num].key_eq(); + shards[shard.thread_num] = Shard(0, AccumulatedValueHashOp(), equality); + } +private: + std::vector shards; +}; + +// A concurrent work-queue that can share batches of work across threads. +// Uses a naive implementation of work-stealing. +template +class ConcurrentWorkQueue { +public: + // Create a queue that supports the given number of threads and + // groups work into `batch_size` units. + ConcurrentWorkQueue(int num_threads, int batch_size = 100) + : batch_size(batch_size), thread_states(num_threads) {} + int num_threads() const { return GetSize(thread_states); } + // Push some work to do. Pushes and pops with the same `thread` must + // not happen concurrently. + void push(const ThreadIndex &thread, T work) { + ThreadState &thread_state = thread_states[thread.thread_num]; + thread_state.next_batch.emplace_back(std::move(work)); + if (GetSize(thread_state.next_batch) < batch_size) + return; + bool was_empty; + { + std::unique_lock lock(thread_state.batches_lock); + was_empty = thread_state.batches.empty(); + thread_state.batches.push_back(std::move(thread_state.next_batch)); + } + if (was_empty) { + std::unique_lock lock(waiters_lock); + if (num_waiters > 0) { + waiters_cv.notify_one(); + } + } + } + // Grab some work to do. + // If all threads enter `pop_batch()`, then instead of deadlocking the + // queue will return no work. That is the only case in which it will + // return no work. + std::vector pop_batch(const ThreadIndex &thread) { + ThreadState &thread_state = thread_states[thread.thread_num]; + if (!thread_state.next_batch.empty()) + return std::move(thread_state.next_batch); + // Empty our own work queue first. + { + std::unique_lock lock(thread_state.batches_lock); + if (!thread_state.batches.empty()) { + std::vector batch = std::move(thread_state.batches.back()); + thread_state.batches.pop_back(); + return batch; + } + } + // From here on in this function, our work queue is empty. + while (true) { + std::vector batch = try_steal(thread); + if (!batch.empty()) { + return std::move(batch); + } + // Termination: if all threads run out of work, then all of + // them will eventually enter this loop and there will be no further + // notifications on waiters_cv, so all will eventually increment + // num_waiters and wait, so num_waiters == num_threads() + // will become true. + std::unique_lock lock(waiters_lock); + ++num_waiters; + if (num_waiters == num_threads()) { + waiters_cv.notify_all(); + return {}; + } + // As above, it's possible that we'll wait here even when there + // are work batches posted by other threads. That's OK. + waiters_cv.wait(lock); + if (num_waiters == num_threads()) + return {}; + --num_waiters; + } + } +private: + std::vector try_steal(const ThreadIndex &thread) { + for (int i = 1; i < num_threads(); i++) { + int other_thread_num = (thread.thread_num + i) % num_threads(); + ThreadState &other_thread_state = thread_states[other_thread_num]; + std::unique_lock lock(other_thread_state.batches_lock); + if (!other_thread_state.batches.empty()) { + std::vector batch = std::move(other_thread_state.batches.front()); + other_thread_state.batches.pop_front(); + return batch; + } + } + return {}; + } + + int batch_size; + + struct ThreadState { + // Entirely thread-local. + std::vector next_batch; + + std::mutex batches_lock; + // Only the associated thread ever adds to this, and only at the back. + // Other threads can remove elements from the front. + std::deque> batches; + }; + std::vector thread_states; + + std::mutex waiters_lock; + std::condition_variable waiters_cv; + // Number of threads waiting for work. Their queues are empty. + int num_waiters = 0; +}; + +// A monotonic flag. Starts false, and can be set to true in a thread-safe way. +// Once `load()` returns true, it will always return true. +// Uses relaxed atomics so there are no memory ordering guarantees. Do not use this +// to guard access to shared memory. +class MonotonicFlag { +public: + MonotonicFlag() : value(false) {} + bool load() const { return value.load(std::memory_order_relaxed); } + void set() { value.store(true, std::memory_order_relaxed); } + bool set_and_return_old() { + return value.exchange(true, std::memory_order_relaxed); + } +private: + std::atomic value; +}; + YOSYS_NAMESPACE_END #endif // YOSYS_THREADING_H diff --git a/kernel/utils.h b/kernel/utils.h index e90ba09d8..e71fb4911 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -125,20 +125,22 @@ public: }; -// ------------------------------------------------ -// A simple class for topological sorting -// ------------------------------------------------ +// --------------------------------------------------- +// Best-effort topological sorting with loop detection +// --------------------------------------------------- template > class TopoSort { - public: + static_assert(!(std::is_pointer::value && std::is_same>::value), + "std::less is run-to-run unstable for pointers"); +public: // We use this ordering of the edges in the adjacency matrix for // exact compatibility with an older implementation. struct IndirectCmp { - IndirectCmp(const std::vector &nodes) : node_cmp_(), nodes_(nodes) {} + IndirectCmp(const std::vector &nodes) : node_cmp_(), nodes_(nodes) {} bool operator()(int a, int b) const { - log_assert(static_cast(a) < nodes_.size()); + log_assert(static_cast(a) < nodes_.size()); log_assert(static_cast(b) < nodes_.size()); return node_cmp_(nodes_[a], nodes_[b]); } @@ -147,7 +149,9 @@ template > class TopoSort }; bool analyze_loops; + // The stability doesn't rely on std::less of T, so pointers are safe std::map node_to_index; + // edges[i] is the set of nodes with an edge into node i std::vector> edges; std::vector sorted; std::set> loops; @@ -160,10 +164,10 @@ template > class TopoSort int node(T n) { - auto rv = node_to_index.emplace(n, static_cast(nodes.size())); - if (rv.second) { - nodes.push_back(n); - edges.push_back(std::set(indirect_cmp)); + auto rv = node_to_index.emplace(n, static_cast(nodes.size())); + if (rv.second) { + nodes.push_back(n); + edges.push_back(std::set(indirect_cmp)); } return rv.first->second; } @@ -183,13 +187,14 @@ template > class TopoSort sorted.clear(); found_loops = false; - std::vector marked_cells(edges.size(), false); - std::vector active_cells(edges.size(), false); - std::vector active_stack; + std::vector node_is_sorted(edges.size(), false); + std::vector node_is_on_stack(edges.size(), false); + // Only used with analyze_loops + std::vector stack; sorted.reserve(edges.size()); for (const auto &it : node_to_index) - sort_worker(it.second, marked_cells, active_cells, active_stack); + sort_worker(it.second, node_is_sorted, node_is_on_stack, stack); log_assert(GetSize(sorted) == GetSize(nodes)); @@ -211,19 +216,20 @@ template > class TopoSort return database; } - private: +private: bool found_loops; std::vector nodes; const IndirectCmp indirect_cmp; - void sort_worker(const int root_index, std::vector &marked_cells, std::vector &active_cells, std::vector &active_stack) + void sort_worker(const int root_index, std::vector &node_is_sorted, std::vector &node_is_on_stack, std::vector &stack) { - if (active_cells[root_index]) { + if (node_is_on_stack[root_index]) { + // We've been here before, meaning we have a loop found_loops = true; if (analyze_loops) { std::vector loop; - for (int i = GetSize(active_stack) - 1; i >= 0; i--) { - const int index = active_stack[i]; + for (int i = GetSize(stack) - 1; i >= 0; i--) { + const int index = stack[i]; loop.push_back(nodes[index]); if (index == root_index) break; @@ -233,23 +239,24 @@ template > class TopoSort return; } - if (marked_cells[root_index]) + // We're done if we've already sorted this subgraph + if (node_is_sorted[root_index]) return; if (!edges[root_index].empty()) { if (analyze_loops) - active_stack.push_back(root_index); - active_cells[root_index] = true; + stack.push_back(root_index); + node_is_on_stack[root_index] = true; for (int left_n : edges[root_index]) - sort_worker(left_n, marked_cells, active_cells, active_stack); + sort_worker(left_n, node_is_sorted, node_is_on_stack, stack); if (analyze_loops) - active_stack.pop_back(); - active_cells[root_index] = false; + stack.pop_back(); + node_is_on_stack[root_index] = false; } - marked_cells[root_index] = true; + node_is_sorted[root_index] = true; sorted.push_back(nodes[root_index]); } }; @@ -299,6 +306,24 @@ auto reversed(const T& container) { return reverse_view{container}; } +// A range of integers [start_, end_) that can be iterated over with a +// C++ range-based for loop. +struct IntRange { + int start_; + int end_; + struct Int { + int v; + int operator*() const { return v; } + Int &operator++() { ++v; return *this; } + bool operator!=(const Int &other) const { return v != other.v; } + }; + Int begin() const { return {start_}; } + Int end() const { return {end_}; } + + bool operator==(const IntRange &other) const { return start_ == other.start_ && end_ == other.end_; } + bool operator!=(const IntRange &other) const { return !(*this == other); } +}; + YOSYS_NAMESPACE_END #endif diff --git a/kernel/wallace_tree.h b/kernel/wallace_tree.h new file mode 100644 index 000000000..eb3513803 --- /dev/null +++ b/kernel/wallace_tree.h @@ -0,0 +1,112 @@ +/** + * Wallace tree utilities for multi-operand addition using carry-save adders + * + * Terminology: + * - compressor: $fa viewed as reducing 3 inputs to 2 outputs (sum + shifted carry) (3:2 compressor) + * - level: A stage of parallel compression operations + * - depth: Maximum number of 3:2 compressor levels from any input to a signal + * + * References: + * - "Binary Adder Architectures for Cell-Based VLSI and their Synthesis" (https://iis-people.ee.ethz.ch/~zimmi/publications/adder_arch.pdf) + * - "A Suggestion for a Fast Multiplier" (https://www.ece.ucdavis.edu/~vojin/CLASSES/EEC280/Web-page/papers/Arithmetic/Wallace_mult.pdf) + */ + +#ifndef WALLACE_TREE_H +#define WALLACE_TREE_H + +#include "kernel/sigtools.h" +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +inline std::pair emit_fa(Module *module, SigSpec a, SigSpec b, SigSpec c, int width) +{ + SigSpec sum = module->addWire(NEW_ID, width); + SigSpec cout = module->addWire(NEW_ID, width); + + module->addFa(NEW_ID, a, b, c, cout, sum); + + SigSpec carry; + carry.append(State::S0); + carry.append(cout.extract(0, width - 1)); + return {sum, carry}; +} + +/** + * wallace_reduce_scheduled() - Reduce multiple operands to two using a Wallace tree + * @module: The Yosys module to which the compressors will be added + * @sigs: Vector of input signals (operands) to be reduced + * @width: Target bit-width to which all operands will be zero-extended + * @compressor_count: Optional pointer to return the number of $fa cells emitted + * + * Return: The final two reduced operands, that are to be fed into an adder + */ +inline std::pair wallace_reduce_scheduled(Module *module, std::vector &sigs, int width, int *compressor_count = nullptr) +{ + struct DepthSig { + SigSpec sig; + int depth; + }; + + for (auto &s : sigs) + s.extend_u0(width); + + std::vector operands; + operands.reserve(sigs.size()); + for (auto &s : sigs) + operands.push_back({s, 0}); + + // Number of $fa's emitted + if (compressor_count) + *compressor_count = 0; + + // Only compress operands ready at current level + for (int level = 0; operands.size() > 2; level++) { + // Partition operands into ready and waiting + std::vector ready, waiting; + for (auto &op : operands) { + if (op.depth <= level) + ready.push_back(op); + else + waiting.push_back(op); + } + + if (ready.size() < 3) + continue; + + // Apply compressors to ready operands + std::vector compressed; + size_t i = 0; + while (i + 2 < ready.size()) { + auto [sum, carry] = emit_fa(module, ready[i].sig, ready[i + 1].sig, ready[i + 2].sig, width); + int new_depth = std::max({ready[i].depth, ready[i + 1].depth, ready[i + 2].depth}) + 1; + compressed.push_back({sum, new_depth}); + compressed.push_back({carry, new_depth}); + if (compressor_count) + (*compressor_count)++; + i += 3; + } + // Uncompressed operands pass through to next level + for (; i < ready.size(); i++) + compressed.push_back(ready[i]); + // Merge compressed with waiting operands + for (auto &op : waiting) + compressed.push_back(op); + + operands = std::move(compressed); + } + + if (operands.size() == 0) + return {SigSpec(State::S0, width), SigSpec(State::S0, width)}; + else if (operands.size() == 1) + return {operands[0].sig, SigSpec(State::S0, width)}; + else { + log_assert(operands.size() == 2); + log(" Wallace tree depth: %d levels of $fa + 1 final $add\n", std::max(operands[0].depth, operands[1].depth)); + return {operands[0].sig, operands[1].sig}; + } +} + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 2c9b8304d..b3688b77b 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -18,8 +18,8 @@ */ #include "kernel/yosys.h" -#include "kernel/celltypes.h" #include "kernel/log.h" +#include "kernel/newcelltypes.h" #ifdef YOSYS_ENABLE_READLINE # include @@ -92,7 +92,7 @@ const char* yosys_maybe_version() { } RTLIL::Design *yosys_design = NULL; -CellTypes yosys_celltypes; +NewCellTypes yosys_celltypes; #ifdef YOSYS_ENABLE_TCL Tcl_Interp *yosys_tcl_interp = NULL; @@ -173,7 +173,7 @@ void yosys_banner() log("\n"); log(" /----------------------------------------------------------------------------\\\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); - log(" | Copyright (C) 2012 - 2025 Claire Xenia Wolf |\n"); + log(" | Copyright (C) 2012 - 2026 Claire Xenia Wolf |\n"); log(" | Distributed under an ISC-like license, type \"license\" to see terms |\n"); log(" \\----------------------------------------------------------------------------/\n"); log(" %s\n", yosys_maybe_version()); @@ -262,7 +262,7 @@ void yosys_setup() Pass::init_register(); yosys_design = new RTLIL::Design; - yosys_celltypes.setup(); + yosys_celltypes.static_cell_types = StaticCellTypes::categories.is_known; log_push(); } @@ -291,8 +291,6 @@ void yosys_shutdown() log_errfile = NULL; log_files.clear(); - yosys_celltypes.clear(); - #ifdef YOSYS_ENABLE_TCL if (yosys_tcl_interp != NULL) { if (!Tcl_InterpDeleted(yosys_tcl_interp)) { @@ -473,17 +471,30 @@ struct TclPass : public Pass { #endif -#if defined(__linux__) || defined(__CYGWIN__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) std::string proc_self_dirname() { - char path[PATH_MAX]; - ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); + std::string path(4096, '\0'); + ssize_t buflen = -1; + // Double until sucess, while avoiding endless loop. Give up + // when symlink is longer than 4096*(2^30) = 4398046511104 + // bytes. + for (int tries = 30; 0 < tries; tries--) { + buflen = readlink("/proc/self/exe", path.data(), path.size()); + if (buflen < (ssize_t)path.size()) + break; + else + path.resize(path.size() * 2); + } if (buflen < 0) { log_error("readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno)); + path.resize(0); + } else { + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + path.resize(buflen); } - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); + return path; } #elif defined(__FreeBSD__) || defined(__NetBSD__) std::string proc_self_dirname() diff --git a/libs/ezsat/ezcmdline.cc b/libs/ezsat/ezcmdline.cc new file mode 100644 index 000000000..57800591c --- /dev/null +++ b/libs/ezsat/ezcmdline.cc @@ -0,0 +1,92 @@ + +#include "ezcmdline.h" + +#include "../../kernel/yosys.h" + +ezCmdlineSAT::ezCmdlineSAT(const std::string &cmd) : command(cmd) {} + +ezCmdlineSAT::~ezCmdlineSAT() {} + +bool ezCmdlineSAT::solver(const std::vector &modelExpressions, std::vector &modelValues, const std::vector &assumptions) +{ +#if !defined(YOSYS_DISABLE_SPAWN) + const std::string tempdir_name = Yosys::make_temp_dir(Yosys::get_base_tmpdir() + "/yosys-sat-XXXXXX"); + const std::string cnf_filename = Yosys::stringf("%s/problem.cnf", tempdir_name.c_str()); + const std::string sat_command = Yosys::stringf("%s %s", command.c_str(), cnf_filename.c_str()); + FILE *dimacs = fopen(cnf_filename.c_str(), "w"); + if (dimacs == nullptr) { + Yosys::log_cmd_error("Failed to create CNF file `%s`.\n", cnf_filename.c_str()); + } + + std::vector modelIdx; + for (auto id : modelExpressions) + modelIdx.push_back(bind(id)); + std::vector> extraClauses; + for (auto id : assumptions) + extraClauses.push_back({bind(id)}); + + printDIMACS(dimacs, false, extraClauses); + fclose(dimacs); + + bool status_sat = false; + bool status_unsat = false; + std::vector values; + + auto line_callback = [&](const std::string &line) { + if (line.empty()) { + return; + } + if (line[0] == 's') { + if (line.substr(0, 5) == "s SAT") { + status_sat = true; + } + if (line.substr(0, 7) == "s UNSAT") { + status_unsat = true; + } + return; + } + if (line[0] == 'v') { + std::stringstream ss(line.substr(1)); + int lit; + while (ss >> lit) { + if (lit == 0) { + return; + } + bool val = lit >= 0; + int ind = lit >= 0 ? lit - 1 : -lit - 1; + if (Yosys::GetSize(values) <= ind) { + values.resize(ind + 1); + } + values[ind] = val; + } + } + }; + int return_code = Yosys::run_command(sat_command, line_callback); + if (return_code != 0 && return_code != 10 && return_code != 20) { + Yosys::log_cmd_error("Shell command failed!\n"); + } + + modelValues.clear(); + modelValues.resize(modelIdx.size()); + + if (!status_sat && !status_unsat) { + solverTimeoutStatus = true; + } + if (!status_sat) { + return false; + } + + for (size_t i = 0; i < modelIdx.size(); i++) { + int idx = modelIdx[i]; + bool refvalue = true; + + if (idx < 0) + idx = -idx, refvalue = false; + + modelValues[i] = (values.at(idx - 1) == refvalue); + } + return true; +#else + Yosys::log_error("SAT solver command not available in this build!\n"); +#endif +} diff --git a/libs/ezsat/ezcmdline.h b/libs/ezsat/ezcmdline.h new file mode 100644 index 000000000..8ec8c7043 --- /dev/null +++ b/libs/ezsat/ezcmdline.h @@ -0,0 +1,36 @@ +/* + * ezSAT -- A simple and easy to use CNF generator for SAT solvers + * + * Copyright (C) 2013 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef EZSATCOMMAND_H +#define EZSATCOMMAND_H + +#include "ezsat.h" + +class ezCmdlineSAT : public ezSAT +{ +private: + std::string command; + +public: + ezCmdlineSAT(const std::string &cmd); + virtual ~ezCmdlineSAT(); + bool solver(const std::vector &modelExpressions, std::vector &modelValues, const std::vector &assumptions) override; +}; + +#endif diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 30df625cb..1f4b8855f 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -103,7 +103,7 @@ bool ezMiniSAT::solver(const std::vector &modelExpressions, std::vector 0) { if (alarmHandlerTimeout == 0) - solverTimoutStatus = true; + solverTimeoutStatus = true; alarm(0); sigaction(SIGALRM, &old_sig_action, NULL); alarm(old_alarm_timeout); diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 20a210abe..8e3114705 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -54,7 +54,7 @@ ezSAT::ezSAT() cnfClausesCount = 0; solverTimeout = 0; - solverTimoutStatus = false; + solverTimeoutStatus = false; literal("CONST_TRUE"); literal("CONST_FALSE"); @@ -1222,10 +1222,15 @@ ezSATvec ezSAT::vec(const std::vector &vec) return ezSATvec(*this, vec); } -void ezSAT::printDIMACS(FILE *f, bool verbose) const +void ezSAT::printDIMACS(FILE *f, bool verbose, const std::vector> &extraClauses) const { + if (f == nullptr) { + fprintf(stderr, "Usage error: printDIMACS() must not be called with a null FILE pointer\n"); + abort(); + } + if (cnfConsumed) { - fprintf(stderr, "Usage error: printDIMACS() must not be called after cnfConsumed()!"); + fprintf(stderr, "Usage error: printDIMACS() must not be called after cnfConsumed()!\n"); abort(); } @@ -1259,8 +1264,10 @@ void ezSAT::printDIMACS(FILE *f, bool verbose) const std::vector> all_clauses; getFullCnf(all_clauses); assert(cnfClausesCount == int(all_clauses.size())); + for (auto c : extraClauses) + all_clauses.push_back(c); - fprintf(f, "p cnf %d %d\n", cnfVariableCount, cnfClausesCount); + fprintf(f, "p cnf %d %d\n", cnfVariableCount, (int) all_clauses.size()); int maxClauseLen = 0; for (auto &clause : all_clauses) maxClauseLen = std::max(int(clause.size()), maxClauseLen); diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 7f3bdf68d..445c8edba 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -78,7 +78,7 @@ protected: public: int solverTimeout; - bool solverTimoutStatus; + bool solverTimeoutStatus; ezSAT(); virtual ~ezSAT(); @@ -153,8 +153,8 @@ public: solverTimeout = newTimeoutSeconds; } - bool getSolverTimoutStatus() { - return solverTimoutStatus; + bool getSolverTimeoutStatus() { + return solverTimeoutStatus; } // manage CNF (usually only accessed by SAT solvers) @@ -295,7 +295,7 @@ public: // printing CNF and internal state - void printDIMACS(FILE *f, bool verbose = false) const; + void printDIMACS(FILE *f, bool verbose = false, const std::vector> &extraClauses = std::vector>()) const; void printInternalState(FILE *f) const; // more sophisticated constraints (designed to be used directly with assume(..)) diff --git a/misc/create_vcxsrc.sh b/misc/create_vcxsrc.sh index 42a690ce6..98c1817bd 100644 --- a/misc/create_vcxsrc.sh +++ b/misc/create_vcxsrc.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex vcxsrc="$1" diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index b1b1383b1..5e2994a53 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -5,6 +5,7 @@ endif OBJS += passes/cmds/add.o OBJS += passes/cmds/delete.o OBJS += passes/cmds/design.o +OBJS += passes/cmds/design_equal.o OBJS += passes/cmds/select.o OBJS += passes/cmds/show.o OBJS += passes/cmds/viz.o @@ -36,6 +37,7 @@ OBJS += passes/cmds/chformal.o OBJS += passes/cmds/chtype.o OBJS += passes/cmds/blackbox.o OBJS += passes/cmds/ltp.o +OBJS += passes/cmds/linux_perf.o ifeq ($(DISABLE_SPAWN),0) OBJS += passes/cmds/bugpoint.o endif diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index b7a5feb57..1019c2955 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -20,7 +20,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celledges.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/utils.h" #include "kernel/log_help.h" diff --git a/passes/cmds/design_equal.cc b/passes/cmds/design_equal.cc new file mode 100644 index 000000000..d5f0d617a --- /dev/null +++ b/passes/cmds/design_equal.cc @@ -0,0 +1,367 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/rtlil.h" + +YOSYS_NAMESPACE_BEGIN + +class ModuleComparator +{ + RTLIL::Module *mod_a; + RTLIL::Module *mod_b; + +public: + ModuleComparator(RTLIL::Module *mod_a, RTLIL::Module *mod_b) : mod_a(mod_a), mod_b(mod_b) {} + + template + [[noreturn]] void error(FmtString...> fmt, const Args &... args) + { + formatted_error(fmt.format(args...)); + } + [[noreturn]] + void formatted_error(std::string err) + { + log("Module A: %s\n", log_id(mod_a->name)); + log_module(mod_a, " "); + log("Module B: %s\n", log_id(mod_b->name)); + log_module(mod_b, " "); + log_cmd_error("Designs are different: %s\n", err); + } + + bool compare_sigbit(const RTLIL::SigBit &a, const RTLIL::SigBit &b) + { + if (a.wire == nullptr && b.wire == nullptr) + return a.data == b.data; + if (a.wire != nullptr && b.wire != nullptr) + return a.wire->name == b.wire->name && a.offset == b.offset; + return false; + } + + bool compare_sigspec(const RTLIL::SigSpec &a, const RTLIL::SigSpec &b) + { + if (a.size() != b.size()) return false; + auto it_a = a.begin(), it_b = b.begin(); + for (; it_a != a.end(); ++it_a, ++it_b) { + if (!compare_sigbit(*it_a, *it_b)) return false; + } + return true; + } + + std::string compare_attributes(const RTLIL::AttrObject *a, const RTLIL::AttrObject *b) + { + for (const auto &it : a->attributes) { + if (b->attributes.count(it.first) == 0) + return "missing attribute " + std::string(log_id(it.first)) + " in second design"; + if (it.second != b->attributes.at(it.first)) + return "attribute " + std::string(log_id(it.first)) + " mismatch: " + log_const(it.second) + " != " + log_const(b->attributes.at(it.first)); + } + for (const auto &it : b->attributes) + if (a->attributes.count(it.first) == 0) + return "missing attribute " + std::string(log_id(it.first)) + " in first design"; + return ""; + } + + std::string compare_wires(const RTLIL::Wire *a, const RTLIL::Wire *b) + { + if (a->name != b->name) + return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + if (a->width != b->width) + return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width); + if (a->start_offset != b->start_offset) + return "start_offset mismatch: " + std::to_string(a->start_offset) + " != " + std::to_string(b->start_offset); + if (a->port_id != b->port_id) + return "port_id mismatch: " + std::to_string(a->port_id) + " != " + std::to_string(b->port_id); + if (a->port_input != b->port_input) + return "port_input mismatch: " + std::to_string(a->port_input) + " != " + std::to_string(b->port_input); + if (a->port_output != b->port_output) + return "port_output mismatch: " + std::to_string(a->port_output) + " != " + std::to_string(b->port_output); + if (a->upto != b->upto) + return "upto mismatch: " + std::to_string(a->upto) + " != " + std::to_string(b->upto); + if (a->is_signed != b->is_signed) + return "is_signed mismatch: " + std::to_string(a->is_signed) + " != " + std::to_string(b->is_signed); + if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) + return mismatch; + return ""; + } + + void check_wires() + { + for (const auto &it : mod_a->wires_) { + if (mod_b->wires_.count(it.first) == 0) + error("Module %s missing wire %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + if (std::string mismatch = compare_wires(it.second, mod_b->wires_.at(it.first)); !mismatch.empty()) + error("Module %s wire %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch); + } + for (const auto &it : mod_b->wires_) + if (mod_a->wires_.count(it.first) == 0) + error("Module %s missing wire %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + } + + std::string compare_memories(const RTLIL::Memory *a, const RTLIL::Memory *b) + { + if (a->name != b->name) + return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + if (a->width != b->width) + return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width); + if (a->start_offset != b->start_offset) + return "start_offset mismatch: " + std::to_string(a->start_offset) + " != " + std::to_string(b->start_offset); + if (a->size != b->size) + return "size mismatch: " + std::to_string(a->size) + " != " + std::to_string(b->size); + if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) + return mismatch; + return ""; + } + + std::string compare_cells(const RTLIL::Cell *a, const RTLIL::Cell *b) + { + if (a->name != b->name) + return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + if (a->type != b->type) + return "type mismatch: " + std::string(log_id(a->type)) + " != " + log_id(b->type); + if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) + return mismatch; + + for (const auto &it : a->parameters) { + if (b->parameters.count(it.first) == 0) + return "parameter mismatch: missing parameter " + std::string(log_id(it.first)) + " in second design"; + if (it.second != b->parameters.at(it.first)) + return "parameter mismatch: " + std::string(log_id(it.first)) + " mismatch: " + log_const(it.second) + " != " + log_const(b->parameters.at(it.first)); + } + for (const auto &it : b->parameters) + if (a->parameters.count(it.first) == 0) + return "parameter mismatch: missing parameter " + std::string(log_id(it.first)) + " in first design"; + + for (const auto &it : a->connections()) { + if (b->connections().count(it.first) == 0) + return "connection mismatch: missing connection " + std::string(log_id(it.first)) + " in second design"; + if (!compare_sigspec(it.second, b->connections().at(it.first))) + return "connection " + std::string(log_id(it.first)) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(it.first)); + } + for (const auto &it : b->connections()) + if (a->connections().count(it.first) == 0) + return "connection mismatch: missing connection " + std::string(log_id(it.first)) + " in first design"; + + return ""; + } + + void check_cells() + { + for (const auto &it : mod_a->cells_) { + if (mod_b->cells_.count(it.first) == 0) + error("Module %s missing cell %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + if (std::string mismatch = compare_cells(it.second, mod_b->cells_.at(it.first)); !mismatch.empty()) + error("Module %s cell %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch); + } + for (const auto &it : mod_b->cells_) + if (mod_a->cells_.count(it.first) == 0) + error("Module %s missing cell %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + } + + void check_memories() + { + for (const auto &it : mod_a->memories) { + if (mod_b->memories.count(it.first) == 0) + error("Module %s missing memory %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + if (std::string mismatch = compare_memories(it.second, mod_b->memories.at(it.first)); !mismatch.empty()) + error("Module %s memory %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch); + } + for (const auto &it : mod_b->memories) + if (mod_a->memories.count(it.first) == 0) + error("Module %s missing memory %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + } + + std::string compare_case_rules(const RTLIL::CaseRule *a, const RTLIL::CaseRule *b) + { + if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) return mismatch; + + if (a->compare.size() != b->compare.size()) + return "compare size mismatch: " + std::to_string(a->compare.size()) + " != " + std::to_string(b->compare.size()); + for (size_t i = 0; i < a->compare.size(); i++) + if (!compare_sigspec(a->compare[i], b->compare[i])) + return "compare " + std::to_string(i) + " mismatch: " + log_signal(a->compare[i]) + " != " + log_signal(b->compare[i]); + + if (a->actions.size() != b->actions.size()) + return "actions size mismatch: " + std::to_string(a->actions.size()) + " != " + std::to_string(b->actions.size()); + for (size_t i = 0; i < a->actions.size(); i++) { + if (!compare_sigspec(a->actions[i].first, b->actions[i].first)) + return "action " + std::to_string(i) + " first mismatch: " + log_signal(a->actions[i].first) + " != " + log_signal(b->actions[i].first); + if (!compare_sigspec(a->actions[i].second, b->actions[i].second)) + return "action " + std::to_string(i) + " second mismatch: " + log_signal(a->actions[i].second) + " != " + log_signal(b->actions[i].second); + } + + if (a->switches.size() != b->switches.size()) + return "switches size mismatch: " + std::to_string(a->switches.size()) + " != " + std::to_string(b->switches.size()); + for (size_t i = 0; i < a->switches.size(); i++) + if (std::string mismatch = compare_switch_rules(a->switches[i], b->switches[i]); !mismatch.empty()) + return "switch " + std::to_string(i) + " " + mismatch; + + return ""; + } + + std::string compare_switch_rules(const RTLIL::SwitchRule *a, const RTLIL::SwitchRule *b) + { + if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) + return mismatch; + if (!compare_sigspec(a->signal, b->signal)) + return "signal mismatch: " + log_signal(a->signal) + " != " + log_signal(b->signal); + + if (a->cases.size() != b->cases.size()) + return "cases size mismatch: " + std::to_string(a->cases.size()) + " != " + std::to_string(b->cases.size()); + for (size_t i = 0; i < a->cases.size(); i++) + if (std::string mismatch = compare_case_rules(a->cases[i], b->cases[i]); !mismatch.empty()) + return "case " + std::to_string(i) + " " + mismatch; + + return ""; + } + + std::string compare_sync_rules(const RTLIL::SyncRule *a, const RTLIL::SyncRule *b) + { + if (a->type != b->type) + return "type mismatch: " + std::to_string(a->type) + " != " + std::to_string(b->type); + if (!compare_sigspec(a->signal, b->signal)) + return "signal mismatch: " + log_signal(a->signal) + " != " + log_signal(b->signal); + if (a->actions.size() != b->actions.size()) + return "actions size mismatch: " + std::to_string(a->actions.size()) + " != " + std::to_string(b->actions.size()); + for (size_t i = 0; i < a->actions.size(); i++) { + if (!compare_sigspec(a->actions[i].first, b->actions[i].first)) + return "action " + std::to_string(i) + " first mismatch: " + log_signal(a->actions[i].first) + " != " + log_signal(b->actions[i].first); + if (!compare_sigspec(a->actions[i].second, b->actions[i].second)) + return "action " + std::to_string(i) + " second mismatch: " + log_signal(a->actions[i].second) + " != " + log_signal(b->actions[i].second); + } + if (a->mem_write_actions.size() != b->mem_write_actions.size()) + return "mem_write_actions size mismatch: " + std::to_string(a->mem_write_actions.size()) + " != " + std::to_string(b->mem_write_actions.size()); + for (size_t i = 0; i < a->mem_write_actions.size(); i++) { + const auto &ma = a->mem_write_actions[i]; + const auto &mb = b->mem_write_actions[i]; + if (ma.memid != mb.memid) + return "mem_write_actions " + std::to_string(i) + " memid mismatch: " + log_id(ma.memid) + " != " + log_id(mb.memid); + if (!compare_sigspec(ma.address, mb.address)) + return "mem_write_actions " + std::to_string(i) + " address mismatch: " + log_signal(ma.address) + " != " + log_signal(mb.address); + if (!compare_sigspec(ma.data, mb.data)) + return "mem_write_actions " + std::to_string(i) + " data mismatch: " + log_signal(ma.data) + " != " + log_signal(mb.data); + if (!compare_sigspec(ma.enable, mb.enable)) + return "mem_write_actions " + std::to_string(i) + " enable mismatch: " + log_signal(ma.enable) + " != " + log_signal(mb.enable); + if (ma.priority_mask != mb.priority_mask) + return "mem_write_actions " + std::to_string(i) + " priority_mask mismatch: " + log_const(ma.priority_mask) + " != " + log_const(mb.priority_mask); + if (std::string mismatch = compare_attributes(&ma, &mb); !mismatch.empty()) + return "mem_write_actions " + std::to_string(i) + " " + mismatch; + } + return ""; + } + + std::string compare_processes(const RTLIL::Process *a, const RTLIL::Process *b) + { + if (a->name != b->name) return "name mismatch: " + std::string(log_id(a->name)) + " != " + log_id(b->name); + if (std::string mismatch = compare_attributes(a, b); !mismatch.empty()) + return mismatch; + if (std::string mismatch = compare_case_rules(&a->root_case, &b->root_case); !mismatch.empty()) + return "case rule " + mismatch; + if (a->syncs.size() != b->syncs.size()) + return "sync count mismatch: " + std::to_string(a->syncs.size()) + " != " + std::to_string(b->syncs.size()); + for (size_t i = 0; i < a->syncs.size(); i++) + if (std::string mismatch = compare_sync_rules(a->syncs[i], b->syncs[i]); !mismatch.empty()) + return "sync " + std::to_string(i) + " " + mismatch; + return ""; + } + + void check_processes() + { + for (auto &it : mod_a->processes) { + if (mod_b->processes.count(it.first) == 0) + error("Module %s missing process %s in second design.\n", log_id(mod_a->name), log_id(it.first)); + if (std::string mismatch = compare_processes(it.second, mod_b->processes.at(it.first)); !mismatch.empty()) + error("Module %s process %s %s.\n", log_id(mod_a->name), log_id(it.first), mismatch.c_str()); + } + for (auto &it : mod_b->processes) + if (mod_a->processes.count(it.first) == 0) + error("Module %s missing process %s in first design.\n", log_id(mod_b->name), log_id(it.first)); + } + + void check_connections() + { + const auto &conns_a = mod_a->connections(); + const auto &conns_b = mod_b->connections(); + if (conns_a.size() != conns_b.size()) { + error("Module %s connection count differs: %zu != %zu\n", log_id(mod_a->name), conns_a.size(), conns_b.size()); + } else { + for (size_t i = 0; i < conns_a.size(); i++) { + if (!compare_sigspec(conns_a[i].first, conns_b[i].first)) + error("Module %s connection %zu LHS %s != %s.\n", log_id(mod_a->name), i, log_signal(conns_a[i].first), log_signal(conns_b[i].first)); + if (!compare_sigspec(conns_a[i].second, conns_b[i].second)) + error("Module %s connection %zu RHS %s != %s.\n", log_id(mod_a->name), i, log_signal(conns_a[i].second), log_signal(conns_b[i].second)); + } + } + } + + void check() + { + if (mod_a->name != mod_b->name) + error("Modules have different names: %s != %s\n", log_id(mod_a->name), log_id(mod_b->name)); + if (std::string mismatch = compare_attributes(mod_a, mod_b); !mismatch.empty()) + error("Module %s %s.\n", log_id(mod_a->name), mismatch); + check_wires(); + check_cells(); + check_memories(); + check_connections(); + check_processes(); + } +}; + +struct DesignEqualPass : public Pass { + DesignEqualPass() : Pass("design_equal", "check if two designs are the same") { } + void help() override + { + log("\n"); + log(" design_equal \n"); + log("\n"); + log("Compare the current design with the design previously saved under the given\n"); + log("name. Abort with an error if the designs are different.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + if (args.size() != 2) + log_cmd_error("Missing argument.\n"); + + std::string check_name = args[1]; + if (saved_designs.count(check_name) == 0) + log_cmd_error("No saved design '%s' found!\n", check_name.c_str()); + + RTLIL::Design *other = saved_designs.at(check_name); + + for (auto &it : design->modules_) { + RTLIL::Module *mod = it.second; + if (!other->has(mod->name)) + log_error("Second design missing module %s.\n", log_id(mod->name)); + + ModuleComparator cmp(mod, other->module(mod->name)); + cmp.check(); + } + for (auto &it : other->modules_) { + RTLIL::Module *mod = it.second; + if (!design->has(mod->name)) + log_error("First design missing module %s.\n", log_id(mod->name)); + } + + log("Designs are identical.\n"); + } +} DesignEqualPass; + +YOSYS_NAMESPACE_END diff --git a/passes/cmds/icell_liberty.cc b/passes/cmds/icell_liberty.cc index a928e5d58..1d3628f1f 100644 --- a/passes/cmds/icell_liberty.cc +++ b/passes/cmds/icell_liberty.cc @@ -1,5 +1,6 @@ #include "kernel/yosys.h" #include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/ff.h" USING_YOSYS_NAMESPACE @@ -123,7 +124,7 @@ struct LibertyStubber { return; } - if (RTLIL::builtin_ff_cell_types().count(base_name)) + if (StaticCellTypes::categories.is_ff(base_name)) return liberty_flop(base, derived, f); auto& base_type = ct.cell_types[base_name]; diff --git a/passes/cmds/linux_perf.cc b/passes/cmds/linux_perf.cc new file mode 100644 index 000000000..2b75a3a79 --- /dev/null +++ b/passes/cmds/linux_perf.cc @@ -0,0 +1,102 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 Claire Xenia Wolf + * Copyright (C) 2014 Johann Glaser + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/log_help.h" + +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#ifdef __linux__ +#include +struct LinuxPerf : public Pass { + LinuxPerf() : Pass("linux_perf", "turn linux perf recording off or on") { + internal(); + } + bool formatted_help() override + { + auto *help = PrettyHelp::get_current(); + + auto content_root = help->get_root(); + + content_root->usage("linux_perf [on|off]"); + + content_root->paragraph( + "This pass turns Linux 'perf' profiling on or off, when it has been configured to use control FIFOs." + "YOSYS_PERF_CTL and YOSYS_PERF_ACK must point to Linux perf control FIFOs." + ); + content_root->paragraph("Example shell command line:"); + content_root->codeblock( + "mkfifo /tmp/perf.fifo /tmp/perf-ack.fifo\n" + "YOSYS_PERF_CTL=/tmp/perf.fifo YOSYS_PERF_ACK=/tmp/perf-ack.fifo \\\n" + " perf record --latency --delay=-1 \\\n" + " --control=fifo:/tmp/perf.fifo,/tmp/perf-ack.fifo --call-graph=dwarf ./yosys \\\n" + " -dt -p \"read_rtlil design.rtlil; linux_perf on; opt_clean; linux_perf off\"\n" + ); + + return true; + } + void execute(std::vector args, RTLIL::Design *) override + { + if (args.size() > 2) + cmd_error(args, 2, "Unexpected argument."); + + std::string_view ctl_msg; + if (args.size() == 2) { + if (args[1] == "on") + ctl_msg = "enable\n"; + else if (args[1] == "off") + ctl_msg = "disable\n"; + else + cmd_error(args, 1, "Unexpected argument."); + } + + const char *ctl_fifo = std::getenv("YOSYS_PERF_CTL"); + if (!ctl_fifo) + log_error("YOSYS_PERF_CTL environment variable not set."); + const char *ack_fifo = std::getenv("YOSYS_PERF_ACK"); + if (!ack_fifo) + log_error("YOSYS_PERF_ACK environment variable not set."); + + int ctl_fd = open(ctl_fifo, O_WRONLY); + if (ctl_fd < 0) + log_error("Failed to open YOSYS_PERF_CTL."); + int ack_fd = open(ack_fifo, O_RDONLY); + if (ack_fd < 0) + log_error("Failed to open YOSYS_PERF_ACK."); + int result = write(ctl_fd, ctl_msg.data(), ctl_msg.size()); + if (result != static_cast(ctl_msg.size())) + log_error("Failed to write to YOSYS_PERF_CTL."); + char buffer[64]; + result = read(ack_fd, buffer, sizeof(buffer)); + close(ctl_fd); + close(ack_fd); + if (result <= 0) + log_error("Failed to read from YOSYS_PERF_ACK."); + if (strcmp(buffer, "ack\n") != 0) + log_error("YOSYS_PERF_ACK did not return 'ack'."); + } +} LinuxPerf; +#endif + +PRIVATE_NAMESPACE_END diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 078ffb769..a07d588c4 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -254,18 +254,17 @@ struct RenamePass : public Pass { log("\n"); log(" rename -enumerate [-pattern ] [selection]\n"); log("\n"); - log("Assign short auto-generated names to all selected wires and cells with private\n"); - log("names. The -pattern option can be used to set the pattern for the new names.\n"); - log("The character %% in the pattern is replaced with a integer number. The default\n"); - log("pattern is '_%%_'.\n"); + log("Assigns auto-generated names to objects used in formal verification\n"); + log("that do not have a public name. This applies to all formal property\n"); + log("cells, $any*/$all* output wires, and their containing cells.\n"); log("\n"); log("\n"); log(" rename -witness\n"); log("\n"); - log("Assigns auto-generated names to all $any*/$all* output wires and containing\n"); - log("cells that do not have a public name. This ensures that, during formal\n"); - log("verification, a solver-found trace can be fully specified using a public\n"); - log("hierarchical names.\n"); + log("Assigns auto-generated names to objects used in formal verification\n"); + log("that do not have a public name. This applies to all formal property\n"); + log("cells ($assert, $assume, $cover, $live, $fair, $check), $any*/$all*\n"); + log("output wires, and their containing cells.\n"); log("\n"); log("\n"); log(" rename -hide [selection]\n"); diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index f64ce943c..24ab5cfd8 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -37,7 +37,7 @@ struct ScratchpadPass : public Pass { log("\n"); log(" scratchpad [options]\n"); log("\n"); - log("This pass allows to read and modify values from the scratchpad of the current\n"); + log("This pass allows reading and modifying values from the scratchpad of the current\n"); log("design. Options:\n"); log("\n"); log(" -get \n"); diff --git a/passes/cmds/sdc/sdc.cc b/passes/cmds/sdc/sdc.cc index fad001e50..635aad016 100644 --- a/passes/cmds/sdc/sdc.cc +++ b/passes/cmds/sdc/sdc.cc @@ -165,7 +165,12 @@ struct SdcObjects { if (!top) log_error("Top module couldn't be determined. Check 'top' attribute usage"); for (auto port : top->ports) { - design_ports.push_back(std::make_pair(port.str().substr(1), top->wire(port))); + RTLIL::Wire *wire = top->wire(port); + if (!wire) { + // This should not be possible. See https://github.com/YosysHQ/yosys/pull/5594#issue-3791198573 + log_error("Port %s doesn't exist", log_id(port)); + } + design_ports.push_back(std::make_pair(port.str().substr(1), wire)); } std::list hierarchy{}; sniff_module(hierarchy, top); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 6da15c19a..2359efe03 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -18,7 +18,7 @@ */ #include "kernel/yosys.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/sigtools.h" #include "kernel/log_help.h" @@ -488,7 +488,7 @@ static int parse_comma_list(std::set &tokens, const std::string } } -static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector &rules, std::set &limits, int max_objects, char mode, CellTypes &ct, bool eval_only) +static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector &rules, std::set &limits, int max_objects, char mode, NewCellTypes &ct, bool eval_only) { int sel_objects = 0; bool is_input, is_output; @@ -564,13 +564,13 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char std::vector rules; std::set limits; - CellTypes ct; + NewCellTypes ct; if (mode != 'x') ct.setup(design); if (pos < int(arg.size()) && arg[pos] == '*') { - levels = 1000000; + levels = 1'000'000; pos++; } else if (pos < int(arg.size()) && '0' <= arg[pos] && arg[pos] <= '9') { diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 5d2ccfcc8..99a223bdc 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -310,6 +310,8 @@ struct SetundefPass : public Pass { RTLIL::SigSpec sig = undriven_signals.export_all(); for (auto &c : sig.chunks()) { + if (!design->selected(module, c.wire)) + continue; RTLIL::Wire * wire; if (c.wire->width == c.width) { wire = c.wire; @@ -328,12 +330,12 @@ struct SetundefPass : public Pass { SigMap sigmap(module); SigPool undriven_signals; - for (auto &it : module->wires_) - undriven_signals.add(sigmap(it.second)); + for (auto wire : module->selected_wires()) + undriven_signals.add(sigmap(wire)); - for (auto &it : module->wires_) - if (it.second->port_input) - undriven_signals.del(sigmap(it.second)); + for (auto wire : module->selected_wires()) + if (wire->port_input) + undriven_signals.del(sigmap(wire)); CellTypes ct(design); for (auto &it : module->cells_) @@ -367,6 +369,14 @@ struct SetundefPass : public Pass { if (!cell->is_builtin_ff()) continue; + bool cell_selected = design->selected(module, cell); + bool wire_selected = false; + for (auto bit : sigmap(cell->getPort(ID::Q))) + if (bit.wire && design->selected(module, bit.wire)) + wire_selected = true; + if (!cell_selected && !wire_selected) + continue; + for (auto bit : sigmap(cell->getPort(ID::Q))) ffbits.insert(bit); } @@ -502,14 +512,21 @@ struct SetundefPass : public Pass { } } - for (auto &it : module->cells_) - if (!it.second->get_bool_attribute(ID::xprop_decoder)) - it.second->rewrite_sigspecs(worker); - for (auto &it : module->processes) - it.second->rewrite_sigspecs(worker); + for (auto cell : module->selected_cells()) + if (!cell->get_bool_attribute(ID::xprop_decoder)) + cell->rewrite_sigspecs(worker); + for (auto proc : module->selected_processes()) + proc->rewrite_sigspecs(worker); for (auto &it : module->connections_) { - worker(it.first); - worker(it.second); + SigSpec lhs = it.first; + bool selected = false; + for (auto &chunk : lhs.chunks()) + if (chunk.wire && module->design->selected(module, chunk.wire)) + selected = true; + if (selected) { + worker(it.first); + worker(it.second); + } } if (worker.next_bit_mode == MODE_ANYSEQ || worker.next_bit_mode == MODE_ANYCONST) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 61135e066..9494d6032 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -561,7 +561,7 @@ struct statdata_t { } } - if (tech == "xilinx") { + if (tech == "xilinx" || tech == "analogdevices") { log("\n"); log(" Estimated number of LCs: %10u\n", estimate_xilinx_lc()); } @@ -628,7 +628,7 @@ struct statdata_t { first_line = false; } log("\n }\n"); - if (tech == "xilinx") { + if (tech == "xilinx" || tech == "analogdevices") { log(" \"estimated_num_lc\": %u,\n", estimate_xilinx_lc()); } if (tech == "cmos") { @@ -710,7 +710,7 @@ struct statdata_t { log("\n"); log(" }"); } - if (tech == "xilinx") { + if (tech == "xilinx" || tech == "analogdevices") { log(",\n"); log(" \"estimated_num_lc\": %u", estimate_xilinx_lc()); } @@ -908,7 +908,7 @@ struct StatPass : public Pass { log("\n"); log(" -tech \n"); log(" print area estimate for the specified technology. Currently supported\n"); - log(" values for : xilinx, cmos\n"); + log(" values for : xilinx, analogdevices, cmos\n"); log("\n"); log(" -width\n"); log(" annotate internal cell types with their word width.\n"); @@ -968,7 +968,7 @@ struct StatPass : public Pass { if (!json_mode) log_header(design, "Printing statistics.\n"); - if (techname != "" && techname != "xilinx" && techname != "cmos" && !json_mode) + if (techname != "" && techname != "xilinx" && techname != "analogdevices" && techname != "cmos" && !json_mode) log_cmd_error("Unsupported technology: '%s'\n", techname); if (json_mode) { diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 537b6793d..52c00072f 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -18,7 +18,7 @@ */ #include "kernel/yosys.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/sigtools.h" #include "kernel/utils.h" #include "kernel/log_help.h" diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index df7b665d5..222fecaca 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -115,16 +115,45 @@ struct DebugPass : public Pass { log("\n"); log("Execute the specified command with debug log messages enabled\n"); log("\n"); + log(" debug -on\n"); + log(" debug -off\n"); + log("\n"); + log("Enable or disable debug log messages globally\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { size_t argidx; + bool mode_on = false; + bool mode_off = false; + for (argidx = 1; argidx < args.size(); argidx++) { - // .. parse options .. + if (args[argidx] == "-on") { + mode_on = true; + continue; + } + if (args[argidx] == "-off") { + mode_off = true; + continue; + } break; } + if (mode_on && mode_off) + log_cmd_error("Cannot specify both -on and -off\n"); + + if (mode_on) { + log_force_debug++; + return; + } + + if (mode_off) { + if (log_force_debug > 0) + log_force_debug--; + return; + } + log_force_debug++; try { diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 7291bb859..3f40e72ab 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -463,6 +463,10 @@ struct XpropWorker return; } + if (cell->type.in(ID($scopeinfo))) { + return; + } + log_warning("Unhandled cell %s (%s) during maybe-x marking\n", log_id(cell), log_id(cell->type)); mark_outputs_maybe_x(cell); } diff --git a/passes/equiv/equiv.h b/passes/equiv/equiv.h new file mode 100644 index 000000000..055dc440b --- /dev/null +++ b/passes/equiv/equiv.h @@ -0,0 +1,68 @@ +#ifndef EQUIV_H +#define EQUIV_H + +#include "kernel/log.h" +#include "kernel/yosys_common.h" +#include "kernel/sigtools.h" +#include "kernel/satgen.h" +#include "kernel/newcelltypes.h" + +YOSYS_NAMESPACE_BEGIN + +struct EquivBasicConfig { + bool model_undef = false; + int max_seq = 1; + bool set_assumes = false; + bool ignore_unknown_cells = false; + + bool parse(const std::vector& args, size_t& idx) { + if (args[idx] == "-undef") { + model_undef = true; + return true; + } + if (args[idx] == "-seq" && idx+1 < args.size()) { + max_seq = atoi(args[++idx].c_str()); + return true; + } + if (args[idx] == "-set-assumes") { + set_assumes = true; + return true; + } + if (args[idx] == "-ignore-unknown-cells") { + ignore_unknown_cells = true; + return true; + } + return false; + } + static std::string help(const char* default_seq) { + return stringf( + " -undef\n" + " enable modelling of undef states\n" + "\n" + " -seq \n" + " the max. number of time steps to be considered (default = %s)\n" + "\n" + " -set-assumes\n" + " set all assumptions provided via $assume cells\n" + "\n" + " -ignore-unknown-cells\n" + " ignore all cells that can not be matched to a SAT model\n" + , default_seq); + } +}; + +template +struct EquivWorker { + RTLIL::Module *module; + + ezSatPtr ez; + SatGen satgen; + Config cfg; + + EquivWorker(RTLIL::Module *module, const SigMap *sigmap, Config cfg) : module(module), satgen(ez.get(), sigmap), cfg(cfg) { + satgen.model_undef = cfg.model_undef; + } +}; + +YOSYS_NAMESPACE_END +#endif // EQUIV_H diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index e1a3a7990..e4480c893 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -18,49 +18,34 @@ */ #include "kernel/yosys.h" -#include "kernel/satgen.h" -#include "kernel/sigtools.h" +#include "passes/equiv/equiv.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct EquivInductWorker +struct EquivInductWorker : public EquivWorker<> { - Module *module; SigMap sigmap; vector cells; pool workset; - ezSatPtr ez; - SatGen satgen; - - int max_seq; int success_counter; - bool set_assumes; dict ez_step_is_consistent; - pool cell_warn_cache; SigPool undriven_signals; - EquivInductWorker(Module *module, const pool &unproven_equiv_cells, bool model_undef, int max_seq, bool set_assumes) : module(module), sigmap(module), + EquivInductWorker(Module *module, const pool &unproven_equiv_cells, EquivBasicConfig cfg) : EquivWorker<>(module, &sigmap, cfg), sigmap(module), cells(module->selected_cells()), workset(unproven_equiv_cells), - satgen(ez.get(), &sigmap), max_seq(max_seq), success_counter(0), set_assumes(set_assumes) - { - satgen.model_undef = model_undef; - } + success_counter(0) {} void create_timestep(int step) { vector ez_equal_terms; for (auto cell : cells) { - if (!satgen.importCell(cell, step) && !cell_warn_cache.count(cell)) { - if (cell->is_builtin_ff()) - log_warning("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); - else - log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); - cell_warn_cache.insert(cell); + if (!satgen.importCell(cell, step)) { + report_missing_model(cfg.ignore_unknown_cells, cell); } if (cell->type == ID($equiv)) { SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit(); @@ -78,7 +63,7 @@ struct EquivInductWorker } } - if (set_assumes) { + if (cfg.set_assumes) { if (step == 1) { RTLIL::SigSpec assumes_a, assumes_en; satgen.getAssumes(assumes_a, assumes_en, step); @@ -123,7 +108,7 @@ struct EquivInductWorker GetSize(satgen.initial_state), GetSize(undriven_signals)); } - for (int step = 1; step <= max_seq; step++) + for (int step = 1; step <= cfg.max_seq; step++) { ez->assume(ez_step_is_consistent[step]); @@ -146,7 +131,7 @@ struct EquivInductWorker return; } - log(" Proof for induction step failed. %s\n", step != max_seq ? "Extending to next time step." : "Trying to prove individual $equiv from workset."); + log(" Proof for induction step failed. %s\n", step != cfg.max_seq ? "Extending to next time step." : "Trying to prove individual $equiv from workset."); } workset.sort(); @@ -158,12 +143,12 @@ struct EquivInductWorker log(" Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort(ID::Y)))); - int ez_a = satgen.importSigBit(bit_a, max_seq+1); - int ez_b = satgen.importSigBit(bit_b, max_seq+1); + int ez_a = satgen.importSigBit(bit_a, cfg.max_seq+1); + int ez_b = satgen.importSigBit(bit_b, cfg.max_seq+1); int cond = ez->XOR(ez_a, ez_b); if (satgen.model_undef) - cond = ez->AND(cond, ez->NOT(satgen.importUndefSigBit(bit_a, max_seq+1))); + cond = ez->AND(cond, ez->NOT(satgen.importUndefSigBit(bit_a, cfg.max_seq+1))); if (!ez->solve(cond)) { log(" success!\n"); @@ -189,14 +174,7 @@ struct EquivInductPass : public Pass { log("Only selected $equiv cells are proven and only selected cells are used to\n"); log("perform the proof.\n"); log("\n"); - log(" -undef\n"); - log(" enable modelling of undef states\n"); - log("\n"); - log(" -seq \n"); - log(" the max. number of time steps to be considered (default = 4)\n"); - log("\n"); - log(" -set-assumes\n"); - log(" set all assumptions provided via $assume cells\n"); + log("%s", EquivBasicConfig::help("4")); log("\n"); log("This command is very effective in proving complex sequential circuits, when\n"); log("the internal state of the circuit quickly propagates to $equiv cells.\n"); @@ -214,25 +192,15 @@ struct EquivInductPass : public Pass { void execute(std::vector args, Design *design) override { int success_counter = 0; - bool model_undef = false, set_assumes = false; - int max_seq = 4; + EquivBasicConfig cfg {}; + cfg.max_seq = 4; log_header(design, "Executing EQUIV_INDUCT pass.\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-undef") { - model_undef = true; + if (cfg.parse(args, argidx)) continue; - } - if (args[argidx] == "-seq" && argidx+1 < args.size()) { - max_seq = atoi(args[++argidx].c_str()); - continue; - } - if (args[argidx] == "-set-assumes") { - set_assumes = true; - continue; - } break; } extra_args(args, argidx, design); @@ -253,7 +221,7 @@ struct EquivInductPass : public Pass { continue; } - EquivInductWorker worker(module, unproven_equiv_cells, model_undef, max_seq, set_assumes); + EquivInductWorker worker(module, unproven_equiv_cells, cfg); worker.run(); success_counter += worker.success_counter; } diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index bae7452f7..a9a728f94 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -79,6 +79,7 @@ struct EquivMakeWorker if (token == ".fsm") { IdString modname = RTLIL::escape_id(next_token(line)); + (void)modname; IdString signame = RTLIL::escape_id(next_token(line)); if (encdata.count(signame)) log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn); diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index 97f95ac63..e498928c3 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -17,15 +17,51 @@ * */ +#include "kernel/log.h" #include "kernel/yosys.h" -#include "kernel/satgen.h" +#include "passes/equiv/equiv.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct EquivSimpleWorker +struct EquivSimpleConfig : EquivBasicConfig { + bool verbose = false; + bool short_cones = false; + bool group = true; + bool parse(const std::vector& args, size_t& idx) { + if (EquivBasicConfig::parse(args, idx)) + return true; + if (args[idx] == "-v") { + verbose = true; + return true; + } + if (args[idx] == "-short") { + short_cones = true; + return true; + } + if (args[idx] == "-nogroup") { + group = false; + return true; + } + return false; + } + static std::string help(const char* default_seq) { + return EquivBasicConfig::help(default_seq) + + " -v\n" + " verbose output\n" + "\n" + " -short\n" + " create shorter input cones that stop at shared nodes. This yields\n" + " simpler SAT problems but sometimes fails to prove equivalence.\n" + "\n" + " -nogroup\n" + " disabling grouping of $equiv cells by output wire\n" + "\n"; + } +}; + +struct EquivSimpleWorker : public EquivWorker { - Module *module; const vector &equiv_cells; const vector &assume_cells; struct Cone { @@ -43,27 +79,11 @@ struct EquivSimpleWorker }; DesignModel model; - ezSatPtr ez; - SatGen satgen; - - struct Config { - bool verbose = false; - bool short_cones = false; - bool model_undef = false; - bool nogroup = false; - bool set_assumes = false; - int max_seq = 1; - }; - Config cfg; - pool> imported_cells_cache; - EquivSimpleWorker(const vector &equiv_cells, const vector &assume_cells, DesignModel model, Config cfg) : - module(equiv_cells.front()->module), equiv_cells(equiv_cells), assume_cells(assume_cells), - model(model), satgen(ez.get(), &model.sigmap), cfg(cfg) - { - satgen.model_undef = cfg.model_undef; - } + EquivSimpleWorker(const vector &equiv_cells, const vector &assume_cells, DesignModel model, EquivSimpleConfig cfg) : + EquivWorker(equiv_cells.front()->module, &model.sigmap, cfg), equiv_cells(equiv_cells), assume_cells(assume_cells), + model(model) {} struct ConeFinder { DesignModel model; @@ -229,14 +249,6 @@ struct EquivSimpleWorker return extra_problem_cells; } - static void report_missing_model(Cell* cell) - { - if (cell->is_builtin_ff()) - log_cmd_error("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type)); - else - log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type)); - } - void prepare_ezsat(int ez_context, SigBit bit_a, SigBit bit_b) { if (satgen.model_undef) @@ -257,7 +269,9 @@ struct EquivSimpleWorker } void construct_ezsat(const pool& input_bits, int step) { + log("ezsat\n"); if (cfg.set_assumes) { + log("yep assume\n"); if (cfg.verbose && step == cfg.max_seq) { RTLIL::SigSpec assumes_a, assumes_en; satgen.getAssumes(assumes_a, assumes_en, step+1); @@ -323,7 +337,7 @@ struct EquivSimpleWorker for (auto cell : problem_cells) { auto key = pair(cell, step+1); if (!imported_cells_cache.count(key) && !satgen.importCell(cell, step+1)) { - report_missing_model(cell); + report_missing_model(cfg.ignore_unknown_cells, cell); } imported_cells_cache.insert(key); } @@ -414,59 +428,20 @@ struct EquivSimplePass : public Pass { log("\n"); log("This command tries to prove $equiv cells using a simple direct SAT approach.\n"); log("\n"); - log(" -v\n"); - log(" verbose output\n"); - log("\n"); - log(" -undef\n"); - log(" enable modelling of undef states\n"); - log("\n"); - log(" -short\n"); - log(" create shorter input cones that stop at shared nodes. This yields\n"); - log(" simpler SAT problems but sometimes fails to prove equivalence.\n"); - log("\n"); - log(" -nogroup\n"); - log(" disabling grouping of $equiv cells by output wire\n"); - log("\n"); - log(" -seq \n"); - log(" the max. number of time steps to be considered (default = 1)\n"); - log("\n"); - log(" -set-assumes\n"); - log(" set all assumptions provided via $assume cells\n"); + log("%s", EquivSimpleConfig::help("1")); log("\n"); } void execute(std::vector args, Design *design) override { - EquivSimpleWorker::Config cfg = {}; + EquivSimpleConfig cfg {}; int success_counter = 0; log_header(design, "Executing EQUIV_SIMPLE pass.\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-v") { - cfg.verbose = true; + if (cfg.parse(args, argidx)) continue; - } - if (args[argidx] == "-short") { - cfg.short_cones = true; - continue; - } - if (args[argidx] == "-undef") { - cfg.model_undef = true; - continue; - } - if (args[argidx] == "-nogroup") { - cfg.nogroup = true; - continue; - } - if (args[argidx] == "-seq" && argidx+1 < args.size()) { - cfg.max_seq = atoi(args[++argidx].c_str()); - continue; - } - if (args[argidx] == "-set-assumes") { - cfg.set_assumes = true; - continue; - } break; } extra_args(args, argidx, design); @@ -489,7 +464,7 @@ struct EquivSimplePass : public Pass { if (cell->type == ID($equiv) && cell->getPort(ID::A) != cell->getPort(ID::B)) { auto bit = sigmap(cell->getPort(ID::Y).as_bit()); auto bit_group = bit; - if (!cfg.nogroup && bit_group.wire) + if (cfg.group && bit_group.wire) bit_group.offset = 0; unproven_equiv_cells[bit_group][bit] = cell; unproven_cells_counter++; diff --git a/passes/memory/memlib.md b/passes/memory/memlib.md index f3c0dd937..5ad3f7777 100644 --- a/passes/memory/memlib.md +++ b/passes/memory/memlib.md @@ -310,7 +310,7 @@ The port clock is always provided on the memory cell as `PORT__CLK` signal (even if it is also shared). Shared clocks are also provided as `CLK_` signals. -For `anyedge` clocks, the cell gets a `PORT__CLKPOL` parameter that is set +For `anyedge` clocks, the cell gets a `PORT__CLK_POL` parameter that is set to 1 for `posedge` clocks and 0 for `negedge` clocks. If the clock is shared, the same information will also be provided as `CLK__POL` parameter. diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index c3c10363b..87adaa26d 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -39,6 +39,7 @@ struct PassOptions { bool no_auto_distributed; bool no_auto_block; bool no_auto_huge; + bool force_params; double logic_cost_rom; double logic_cost_ram; }; @@ -1859,7 +1860,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector &cells, cons cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren)); } else { cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren); - if (cfg.def->byte != 0 && cfg.def->width_mode != WidthMode::Single) + if (cfg.def->byte != 0 && (cfg.def->width_mode != WidthMode::Single || opts.force_params)) cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren)); } } @@ -2068,8 +2069,10 @@ void MemMapping::emit(const MemConfig &cfg) { std::vector cells; for (int rd = 0; rd < cfg.repl_d; rd++) { Cell *cell = mem.module->addCell(stringf("%s.%d.%d", mem.memid, rp, rd), cfg.def->id); - if (cfg.def->width_mode == WidthMode::Global) + if (cfg.def->width_mode == WidthMode::Global || opts.force_params) cell->setParam(ID::WIDTH, cfg.def->dbits[cfg.base_width_log2]); + if (opts.force_params) + cell->setParam(ID::ABITS, cfg.def->abits); if (cfg.def->widthscale) { std::vector val; for (auto &bit: init_swz.bits[rd]) @@ -2179,6 +2182,9 @@ struct MemoryLibMapPass : public Pass { log(" Disables automatic mapping of given kind of RAMs. Manual mapping\n"); log(" (using ram_style or other attributes) is still supported.\n"); log("\n"); + log(" -force-params\n"); + log(" Always generate memories with WIDTH and ABITS parameters.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { @@ -2188,6 +2194,7 @@ struct MemoryLibMapPass : public Pass { opts.no_auto_distributed = false; opts.no_auto_block = false; opts.no_auto_huge = false; + opts.force_params = false; opts.logic_cost_ram = 1.0; opts.logic_cost_rom = 1.0/16.0; log_header(design, "Executing MEMORY_LIBMAP pass (mapping memories to cells).\n"); @@ -2214,6 +2221,10 @@ struct MemoryLibMapPass : public Pass { opts.no_auto_huge = true; continue; } + if (args[argidx] == "-force-params") { + opts.force_params = true; + continue; + } if (args[argidx] == "-logic-cost-rom" && argidx+1 < args.size()) { opts.logic_cost_rom = strtod(args[++argidx].c_str(), nullptr); continue; diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index 426d9a79a..e7b62fc6a 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -9,7 +9,6 @@ OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_dff.o OBJS += passes/opt/opt_share.o -OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_expr.o OBJS += passes/opt/opt_hier.o @@ -23,6 +22,7 @@ OBJS += passes/opt/opt_lut_ins.o OBJS += passes/opt/opt_ffinv.o OBJS += passes/opt/pmux2shiftx.o OBJS += passes/opt/muxpack.o +OBJS += passes/opt/opt_balance_tree.o OBJS += passes/opt/peepopt.o GENFILES += passes/opt/peepopt_pm.h @@ -39,3 +39,5 @@ PEEPOPT_PATTERN += passes/opt/peepopt_formal_clockgateff.pmg passes/opt/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN) $(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^) endif + +include $(YOSYS_SRC)/passes/opt/opt_clean/Makefile.inc \ No newline at end of file diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 6efeefb3c..c13790edf 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -38,6 +38,9 @@ struct ExclusiveDatabase pool reduce_or; for (auto cell : module->cells()) { if (cell->type == ID($eq)) { + SigSpec y_sig = sigmap(cell->getPort(ID::Y)); + if (GetSize(y_sig) == 0) + continue; nonconst_sig = sigmap(cell->getPort(ID::A)); const_sig = sigmap(cell->getPort(ID::B)); if (!const_sig.is_fully_const()) { @@ -45,12 +48,15 @@ struct ExclusiveDatabase continue; std::swap(nonconst_sig, const_sig); } - y_port = sigmap(cell->getPort(ID::Y)); + y_port = y_sig[0]; } else if (cell->type == ID($logic_not)) { + SigSpec y_sig = sigmap(cell->getPort(ID::Y)); + if (GetSize(y_sig) == 0) + continue; nonconst_sig = sigmap(cell->getPort(ID::A)); const_sig = Const(State::S0, GetSize(nonconst_sig)); - y_port = sigmap(cell->getPort(ID::Y)); + y_port = y_sig[0]; } else if (cell->type == ID($reduce_or)) { reduce_or.insert(cell); @@ -84,7 +90,10 @@ struct ExclusiveDatabase } if (nonconst_sig.empty()) continue; - y_port = sigmap(cell->getPort(ID::Y)); + SigSpec y_sig = sigmap(cell->getPort(ID::Y)); + if (GetSize(y_sig) == 0) + continue; + y_port = y_sig[0]; sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values)); } } @@ -254,7 +263,6 @@ struct MuxpackWorker int cases = GetSize(chain) - cursor; Cell *first_cell = chain[cursor]; - dict taps_dict; if (cases < 2) { cursor++; diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index ec5760cd9..983437e64 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -193,7 +193,6 @@ struct OptPass : public Pass { } design->optimize(); - design->sort(); design->check(); log_header(design, "Finished fast OPT passes.%s\n", fast_mode ? "" : " (There is nothing left to do.)"); diff --git a/passes/opt/opt_balance_tree.cc b/passes/opt/opt_balance_tree.cc new file mode 100644 index 000000000..129a27376 --- /dev/null +++ b/passes/opt/opt_balance_tree.cc @@ -0,0 +1,379 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 Eddie Hung + * 2024 Akash Levy + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + + +struct OptBalanceTreeWorker { + // Module and signal map + Module *module; + SigMap sigmap; + + // Counts of each cell type that are getting balanced + dict cell_count; + + // Check if cell is of the right type and has matching input/output widths + // Only allow cells with "natural" output widths (no truncation) to prevent + // equivalence issues when rebalancing (see YosysHQ/yosys#5605) + bool is_right_type(Cell* cell, IdString cell_type) { + if (cell->type != cell_type) + return false; + + int y_width = cell->getParam(ID::Y_WIDTH).as_int(); + int a_width = cell->getParam(ID::A_WIDTH).as_int(); + int b_width = cell->getParam(ID::B_WIDTH).as_int(); + + // Calculate the "natural" output width for this operation + int natural_width; + if (cell_type == ID($add)) { + // Addition produces max(A_WIDTH, B_WIDTH) + 1 (for carry bit) + natural_width = std::max(a_width, b_width) + 1; + } else if (cell_type == ID($mul)) { + // Multiplication produces A_WIDTH + B_WIDTH + natural_width = a_width + b_width; + } else { + // Logic operations ($and/$or/$xor) produce max(A_WIDTH, B_WIDTH) + natural_width = std::max(a_width, b_width); + } + + // Only allow cells where Y_WIDTH >= natural width (no truncation) + // This prevents rebalancing chains where truncation semantics matter + return y_width >= natural_width; + } + + // Create a balanced binary tree from a vector of source signals + SigSpec create_balanced_tree(vector &sources, IdString cell_type, Cell* cell) { + // Base case: if we have no sources, return an empty signal + if (sources.size() == 0) + return SigSpec(); + + // Base case: if we have only one source, return it + if (sources.size() == 1) + return sources[0]; + + // Base case: if we have two sources, create a single cell + if (sources.size() == 2) { + // Create a new cell of the same type + Cell* new_cell = module->addCell(NEW_ID, cell_type); + + // Copy attributes from reference cell + new_cell->attributes = cell->attributes; + + // Create output wire + int out_width = cell->getParam(ID::Y_WIDTH).as_int(); + if (cell_type == ID($add)) + out_width = max(sources[0].size(), sources[1].size()) + 1; + else if (cell_type == ID($mul)) + out_width = sources[0].size() + sources[1].size(); + Wire* out_wire = module->addWire(NEW_ID, out_width); + + // Connect ports and fix up parameters + new_cell->setPort(ID::A, sources[0]); + new_cell->setPort(ID::B, sources[1]); + new_cell->setPort(ID::Y, out_wire); + new_cell->fixup_parameters(); + new_cell->setParam(ID::A_SIGNED, cell->getParam(ID::A_SIGNED)); + new_cell->setParam(ID::B_SIGNED, cell->getParam(ID::B_SIGNED)); + + // Update count and return output wire + cell_count[cell_type]++; + return out_wire; + } + + // Recursive case: split sources into two groups and create subtrees + int mid = (sources.size() + 1) / 2; + vector left_sources(sources.begin(), sources.begin() + mid); + vector right_sources(sources.begin() + mid, sources.end()); + + SigSpec left_tree = create_balanced_tree(left_sources, cell_type, cell); + SigSpec right_tree = create_balanced_tree(right_sources, cell_type, cell); + + // Create a cell to combine the two subtrees + Cell* new_cell = module->addCell(NEW_ID, cell_type); + + // Copy attributes from reference cell + new_cell->attributes = cell->attributes; + + // Create output wire + int out_width = cell->getParam(ID::Y_WIDTH).as_int(); + if (cell_type == ID($add)) + out_width = max(left_tree.size(), right_tree.size()) + 1; + else if (cell_type == ID($mul)) + out_width = left_tree.size() + right_tree.size(); + Wire* out_wire = module->addWire(NEW_ID, out_width); + + // Connect ports and fix up parameters + new_cell->setPort(ID::A, left_tree); + new_cell->setPort(ID::B, right_tree); + new_cell->setPort(ID::Y, out_wire); + new_cell->fixup_parameters(); + new_cell->setParam(ID::A_SIGNED, cell->getParam(ID::A_SIGNED)); + new_cell->setParam(ID::B_SIGNED, cell->getParam(ID::B_SIGNED)); + + // Update count and return output wire + cell_count[cell_type]++; + return out_wire; + } + + OptBalanceTreeWorker(Module *module, const vector cell_types) : module(module), sigmap(module) { + // Do for each cell type + for (auto cell_type : cell_types) { + // Index all of the nets in the module + dict sig_to_driver; + dict> sig_to_sink; + for (auto cell : module->selected_cells()) + { + for (auto &conn : cell->connections()) + { + if (cell->output(conn.first)) + sig_to_driver[sigmap(conn.second)] = cell; + + if (cell->input(conn.first)) + { + SigSpec sig = sigmap(conn.second); + if (sig_to_sink.count(sig) == 0) + sig_to_sink[sig] = pool(); + sig_to_sink[sig].insert(cell); + } + } + } + + // Need to check if any wires connect to module ports + pool input_port_sigs; + pool output_port_sigs; + for (auto wire : module->selected_wires()) + if (wire->port_input || wire->port_output) { + SigSpec sig = sigmap(wire); + for (auto bit : sig) { + if (wire->port_input) + input_port_sigs.insert(bit); + if (wire->port_output) + output_port_sigs.insert(bit); + } + } + + // Actual logic starts here + pool consumed_cells; + for (auto cell : module->selected_cells()) + { + // If consumed or not the correct type, skip + if (consumed_cells.count(cell) || !is_right_type(cell, cell_type)) + continue; + + // BFS, following all chains until they hit a cell of a different type + // Pick the longest one + auto y = sigmap(cell->getPort(ID::Y)); + pool sinks; + pool current_loads = sig_to_sink[y]; + pool next_loads; + while (!current_loads.empty()) + { + // Find each sink and see what they are + for (auto x : current_loads) + { + // If not the correct type, don't follow any further + // (but add the originating cell to the list of sinks) + if (!is_right_type(x, cell_type)) + { + sinks.insert(cell); + continue; + } + + auto xy = sigmap(x->getPort(ID::Y)); + + // If this signal drives a port, add it to the sinks + // (even though it may not be the end of a chain) + for (auto bit : xy) { + if (output_port_sigs.count(bit) && !consumed_cells.count(x)) { + sinks.insert(x); + break; + } + } + + // Search signal's fanout + auto& next = sig_to_sink[xy]; + for (auto z : next) + next_loads.insert(z); + } + + // If we couldn't find any downstream loads, stop. + // Create a reduction for each of the max-length chains we found + if (next_loads.empty()) + { + for (auto s : current_loads) + { + // Not one of our gates? Don't follow any further + if (!is_right_type(s, cell_type)) + continue; + + sinks.insert(s); + } + break; + } + + // Otherwise, continue down the chain + current_loads = next_loads; + next_loads.clear(); + } + + // We have our list of sinks, now go tree balance the chains + for (auto head_cell : sinks) + { + // Avoid duplication if we already were covered + if (consumed_cells.count(head_cell)) + continue; + + // Get sources of the chain + dict sources; + dict signeds; + int inner_cells = 0; + std::deque bfs_queue = {head_cell}; + while (bfs_queue.size()) + { + Cell* x = bfs_queue.front(); + bfs_queue.pop_front(); + + for (IdString port: {ID::A, ID::B}) { + auto sig = sigmap(x->getPort(port)); + Cell* drv = sig_to_driver[sig]; + bool drv_ok = drv && is_right_type(drv, cell_type); + for (auto bit : sig) { + if (input_port_sigs.count(bit) && !consumed_cells.count(drv)) { + drv_ok = false; + break; + } + } + if (drv_ok) { + inner_cells++; + bfs_queue.push_back(drv); + } else { + sources[sig]++; + signeds[sig] = x->getParam(port == ID::A ? ID::A_SIGNED : ID::B_SIGNED).as_bool(); + } + } + } + + if (inner_cells) + { + // Create a tree + log_debug(" Creating tree for %s with %d sources and %d inner cells...\n", log_id(head_cell), GetSize(sources), inner_cells); + + // Build a vector of all source signals + vector source_signals; + vector signed_flags; + for (auto &source : sources) { + for (int i = 0; i < source.second; i++) { + source_signals.push_back(source.first); + signed_flags.push_back(signeds[source.first]); + } + } + + // If not all signed flags are the same, do not balance + if (!std::all_of(signed_flags.begin(), signed_flags.end(), [&](bool flag) { return flag == signed_flags[0]; })) { + continue; + } + + // Create the balanced tree + SigSpec tree_output = create_balanced_tree(source_signals, cell_type, head_cell); + + // Connect the tree output to the head cell's output + SigSpec head_output = sigmap(head_cell->getPort(ID::Y)); + int connect_width = std::min(head_output.size(), tree_output.size()); + module->connect(head_output.extract(0, connect_width), tree_output.extract(0, connect_width)); + if (head_output.size() > tree_output.size()) { + SigBit sext_bit = head_cell->getParam(ID::A_SIGNED).as_bool() ? head_output[connect_width - 1] : State::S0; + module->connect(head_output.extract(connect_width, head_output.size() - connect_width), SigSpec(sext_bit, head_output.size() - connect_width)); + } + + // Mark consumed cell for removal + consumed_cells.insert(head_cell); + } + } + } + + // Remove all consumed cells, which now have been replaced by trees + for (auto cell : consumed_cells) + module->remove(cell); + } + } +}; + +struct OptBalanceTreePass : public Pass { + OptBalanceTreePass() : Pass("opt_balance_tree", "$and/$or/$xor/$add/$mul cascades to trees") { } + void help() override { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_balance_tree [options] [selection]\n"); + log("\n"); + log("This pass converts cascaded chains of $and/$or/$xor/$add/$mul cells into\n"); + log("trees of cells to improve timing.\n"); + log("\n"); + log(" -arith\n"); + log(" only convert arithmetic cells.\n"); + log("\n"); + log(" -logic\n"); + log(" only convert logic cells.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override { + log_header(design, "Executing OPT_BALANCE_TREE pass (cell cascades to trees).\n"); + log_experimental("open_balance_tree"); + + // Handle arguments + size_t argidx; + vector cell_types = {ID($and), ID($or), ID($xor), ID($add), ID($mul)}; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-arith") { + cell_types = {ID($add), ID($mul)}; + continue; + } + if (args[argidx] == "-logic") { + cell_types = {ID($and), ID($or), ID($xor)}; + continue; + } + break; + } + extra_args(args, argidx, design); + + // Count of all cells that were packed + dict cell_count; + for (auto module : design->selected_modules()) { + OptBalanceTreeWorker worker(module, cell_types); + for (auto cell : worker.cell_count) { + cell_count[cell.first] += cell.second; + } + } + + // Log stats + for (auto cell_type : cell_types) + log("Converted %d %s cells into trees.\n", cell_count[cell_type], log_id(cell_type)); + + // Clean up + Yosys::run_pass("clean -purge"); + } +} OptBalanceTreePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc deleted file mode 100644 index 3892c7581..000000000 --- a/passes/opt/opt_clean.cc +++ /dev/null @@ -1,794 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 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 - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/log.h" -#include "kernel/celltypes.h" -#include "kernel/ffinit.h" -#include -#include -#include - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -using RTLIL::id2cstr; - -struct keep_cache_t -{ - Design *design; - dict cache; - bool purge_mode = false; - - void reset(Design *design = nullptr, bool purge_mode = false) - { - this->design = design; - this->purge_mode = purge_mode; - cache.clear(); - } - - bool query(Module *module) - { - log_assert(design != nullptr); - - if (module == nullptr) - return false; - - if (cache.count(module)) - return cache.at(module); - - cache[module] = true; - if (!module->get_bool_attribute(ID::keep)) { - bool found_keep = false; - for (auto cell : module->cells()) - if (query(cell, true /* ignore_specify */)) { - found_keep = true; - break; - } - for (auto wire : module->wires()) - if (wire->get_bool_attribute(ID::keep)) { - found_keep = true; - break; - } - cache[module] = found_keep; - } - - return cache[module]; - } - - bool query(Cell *cell, bool ignore_specify = false) - { - if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) - return true; - - if (cell->type.in(ID($overwrite_tag))) - return true; - - if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule))) - return true; - - if (cell->type == ID($print) || cell->type == ID($check)) - return true; - - if (cell->has_keep_attr()) - return true; - - if (!purge_mode && cell->type == ID($scopeinfo)) - return true; - - if (cell->module && cell->module->design) - return query(cell->module->design->module(cell->type)); - - return false; - } -}; - -keep_cache_t keep_cache; -CellTypes ct_reg, ct_all; -int count_rm_cells, count_rm_wires; - -void rmunused_module_cells(Module *module, bool verbose) -{ - SigMap sigmap(module); - dict> mem2cells; - pool mem_unused; - pool queue, unused; - pool used_raw_bits; - dict> wire2driver; - dict> driver_driver_logs; - FfInitVals ffinit(&sigmap, module); - - SigMap raw_sigmap; - for (auto &it : module->connections_) { - for (int i = 0; i < GetSize(it.second); i++) { - if (it.second[i].wire != nullptr) - raw_sigmap.add(it.first[i], it.second[i]); - } - } - - for (auto &it : module->memories) { - mem_unused.insert(it.first); - } - - for (Cell *cell : module->cells()) { - if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2))) { - IdString mem_id = cell->getParam(ID::MEMID).decode_string(); - mem2cells[mem_id].insert(cell); - } - } - - for (auto &it : module->cells_) { - Cell *cell = it.second; - for (auto &it2 : cell->connections()) { - if (ct_all.cell_known(cell->type) && !ct_all.cell_output(cell->type, it2.first)) - continue; - for (auto raw_bit : it2.second) { - if (raw_bit.wire == nullptr) - continue; - auto bit = sigmap(raw_bit); - if (bit.wire == nullptr && ct_all.cell_known(cell->type)) - driver_driver_logs[raw_sigmap(raw_bit)].push_back(stringf("Driver-driver conflict " - "for %s between cell %s.%s and constant %s in %s: Resolved using constant.", - log_signal(raw_bit), log_id(cell), log_id(it2.first), log_signal(bit), log_id(module))); - if (bit.wire != nullptr) - wire2driver[bit].insert(cell); - } - } - if (keep_cache.query(cell)) - queue.insert(cell); - else - unused.insert(cell); - } - - for (auto &it : module->wires_) { - Wire *wire = it.second; - if (wire->port_output || wire->get_bool_attribute(ID::keep)) { - for (auto bit : sigmap(wire)) - for (auto c : wire2driver[bit]) - queue.insert(c), unused.erase(c); - for (auto raw_bit : SigSpec(wire)) - used_raw_bits.insert(raw_sigmap(raw_bit)); - } - } - - while (!queue.empty()) - { - pool bits; - pool mems; - for (auto cell : queue) { - for (auto &it : cell->connections()) - if (!ct_all.cell_known(cell->type) || ct_all.cell_input(cell->type, it.first)) - for (auto bit : sigmap(it.second)) - bits.insert(bit); - - if (cell->type.in(ID($memrd), ID($memrd_v2))) { - IdString mem_id = cell->getParam(ID::MEMID).decode_string(); - if (mem_unused.count(mem_id)) { - mem_unused.erase(mem_id); - mems.insert(mem_id); - } - } - } - - queue.clear(); - - for (auto bit : bits) - for (auto c : wire2driver[bit]) - if (unused.count(c)) - queue.insert(c), unused.erase(c); - - for (auto mem : mems) - for (auto c : mem2cells[mem]) - if (unused.count(c)) - queue.insert(c), unused.erase(c); - } - - unused.sort(RTLIL::sort_by_name_id()); - - for (auto cell : unused) { - if (verbose) - log_debug(" removing unused `%s' cell `%s'.\n", cell->type, cell->name); - module->design->scratchpad_set_bool("opt.did_something", true); - if (cell->is_builtin_ff()) - ffinit.remove_init(cell->getPort(ID::Q)); - module->remove(cell); - count_rm_cells++; - } - - for (auto it : mem_unused) - { - if (verbose) - log_debug(" removing unused memory `%s'.\n", it); - delete module->memories.at(it); - module->memories.erase(it); - } - - for (auto &it : module->cells_) { - Cell *cell = it.second; - for (auto &it2 : cell->connections()) { - if (ct_all.cell_known(cell->type) && !ct_all.cell_input(cell->type, it2.first)) - continue; - for (auto raw_bit : raw_sigmap(it2.second)) - used_raw_bits.insert(raw_bit); - } - } - - for (auto it : driver_driver_logs) { - if (used_raw_bits.count(it.first)) - for (auto msg : it.second) - log_warning("%s\n", msg); - } -} - -int count_nontrivial_wire_attrs(RTLIL::Wire *w) -{ - int count = w->attributes.size(); - count -= w->attributes.count(ID::src); - count -= w->attributes.count(ID::hdlname); - count -= w->attributes.count(ID(scopename)); - count -= w->attributes.count(ID::unused_bits); - 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; - RTLIL::Wire *w2 = s2.wire; - - if (w1 == NULL || w2 == NULL) - return w2 == NULL; - - if (w1->port_input != w2->port_input) - return w2->port_input; - - if ((w1->port_input && w1->port_output) != (w2->port_input && w2->port_output)) - return !(w2->port_input && w2->port_output); - - if (w1->name.isPublic() && w2->name.isPublic()) { - if (regs.check(s1) != regs.check(s2)) - return regs.check(s2); - if (direct_wires.count(w1) != direct_wires.count(w2)) - return direct_wires.count(w2) != 0; - if (conns.check_any(s1) != conns.check_any(s2)) - return conns.check_any(s2); - } - - if (w1->port_output != w2->port_output) - return w2->port_output; - - if (w1->name[0] != w2->name[0]) - return w2->name.isPublic(); - - int attrs1 = count_nontrivial_wire_attrs(w1); - int attrs2 = count_nontrivial_wire_attrs(w2); - - if (attrs1 != attrs2) - return attrs2 > attrs1; - - return w2->name.lt_by_name(w1->name); -} - -bool check_public_name(RTLIL::IdString id) -{ - if (id.begins_with("$")) - return false; - const std::string &id_str = id.str(); - if (id.begins_with("\\_") && (id.ends_with("_") || id_str.find("_[") != std::string::npos)) - return false; - if (id_str.find(".$") != std::string::npos) - return false; - return true; -} - -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; - if (ct_reg.cell_known(cell->type)) { - bool clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic)); - for (auto &it2 : cell->connections()) - if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output(cell->type, it2.first)) - register_signals.add(it2.second); - } - for (auto &it2 : cell->connections()) - connected_signals.add(it2.second); - } - - SigMap assign_map(module); - - // construct a pool of wires which are directly driven by a known celltype, - // this will influence our choice of representatives - pool direct_wires; - { - 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++) { - RTLIL::SigBit s1 = RTLIL::SigBit(wire, i), s2 = assign_map(s1); - if (!compare_signals(s1, s2, register_signals, connected_signals, direct_wires)) - assign_map.add(s1); - } - } - - // 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); // 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; - if (wire->port_id > 0) { - RTLIL::SigSpec sig = RTLIL::SigSpec(wire); - raw_used_signals.add(sig); - assign_map.apply(sig); - used_signals.add(sig); - if (!wire->port_input) - used_signals_nodrivers.add(sig); - } - if (wire->get_bool_attribute(ID::keep)) { - RTLIL::SigSpec sig = RTLIL::SigSpec(wire); - assign_map.apply(sig); - used_signals.add(sig); - } - auto it2 = wire->attributes.find(ID::init); - if (it2 != wire->attributes.end()) { - RTLIL::Const &val = it2->second; - SigSpec sig = assign_map(wire); - for (int i = 0; i < GetSize(val) && i < GetSize(sig); i++) - if (val[i] != State::Sx) - init_bits[sig[i]] = val[i]; - wire->attributes.erase(it2); - } - } - - // set init attributes on all wires of a connected group - for (auto wire : module->wires()) { - bool found = false; - Const val(State::Sx, wire->width); - for (int i = 0; i < wire->width; i++) { - auto it = init_bits.find(RTLIL::SigBit(wire, i)); - if (it != init_bits.end()) { - val.set(i, it->second); - found = true; - } - } - if (found) - 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()) - { - SigSpec s1 = SigSpec(wire), s2 = assign_map(s1); - log_assert(GetSize(s1) == GetSize(s2)); - - Const initval; - if (wire->attributes.count(ID::init)) - initval = wire->attributes.at(ID::init); - if (GetSize(initval) != GetSize(wire)) - initval.resize(GetSize(wire), State::Sx); - if (initval.is_fully_undef()) - wire->attributes.erase(ID::init); - - if (GetSize(wire) == 0) { - // delete zero-width wires, unless they are module ports - if (wire->port_id == 0) - goto delete_this_wire; - } else - if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) { - // do not delete anything with "keep" or module ports or initialized wires - } else - if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) { - // do not get rid of public names unless in purge mode or if the wire is entirely unused, not even aliased - } else - if (!raw_used_signals.check_any(s1)) { - // delete wires that aren't used by anything directly - goto delete_this_wire; - } - - if (0) - { - delete_this_wire: - del_wires_queue.insert(wire); - } - else - { - RTLIL::SigSig new_conn; - for (int i = 0; i < GetSize(s1); i++) - if (s1[i] != s2[i]) { - if (s2[i] == State::Sx && (initval[i] == State::S0 || initval[i] == State::S1)) { - s2[i] = initval[i]; - initval.set(i, State::Sx); - } - new_conn.first.append(s1[i]); - new_conn.second.append(s2[i]); - } - if (new_conn.first.size() > 0) { - if (initval.is_fully_undef()) - wire->attributes.erase(ID::init); - else - wire->attributes.at(ID::init) = initval; - used_signals.add(new_conn.first); - used_signals.add(new_conn.second); - module->connect(new_conn); - } - - if (!used_signals_nodrivers.check_all(s2)) { - std::string unused_bits; - for (int i = 0; i < GetSize(s2); i++) { - if (s2[i].wire == NULL) - continue; - if (!used_signals_nodrivers.check(s2[i])) { - if (!unused_bits.empty()) - unused_bits += " "; - unused_bits += stringf("%d", i); - } - } - if (unused_bits.empty() || wire->port_id != 0) - wire->attributes.erase(ID::unused_bits); - else - wire->attributes[ID::unused_bits] = RTLIL::Const(unused_bits); - } else { - wire->attributes.erase(ID::unused_bits); - } - } - } - - int del_temp_wires_count = 0; - for (auto wire : del_wires_queue) { - if (ys_debug() || (check_public_name(wire->name) && verbose)) - log_debug(" removing unused non-port wire %s.\n", wire->name); - else - del_temp_wires_count++; - } - - module->remove(del_wires_queue); - count_rm_wires += GetSize(del_wires_queue); - - if (verbose && del_temp_wires_count) - log_debug(" removed %d unused temporary wires.\n", del_temp_wires_count); - - if (!del_wires_queue.empty()) - module->design->scratchpad_set_bool("opt.did_something", true); - - return !del_wires_queue.empty(); -} - -bool rmunused_module_init(RTLIL::Module *module, bool verbose) -{ - bool did_something = false; - CellTypes fftypes; - fftypes.setup_internals_mem(); - - SigMap sigmap(module); - dict qbits; - - for (auto cell : module->cells()) - if (fftypes.cell_known(cell->type) && cell->hasPort(ID::Q)) - { - SigSpec sig = cell->getPort(ID::Q); - - for (int i = 0; i < GetSize(sig); i++) - { - SigBit bit = sig[i]; - - if (bit.wire == nullptr || bit.wire->attributes.count(ID::init) == 0) - continue; - - Const init = bit.wire->attributes.at(ID::init); - - if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz) - continue; - - sigmap.add(bit); - qbits[bit] = init[i]; - } - } - - for (auto wire : module->wires()) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - Const init = wire->attributes.at(ID::init); - - for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++) - { - if (init[i] == State::Sx || init[i] == State::Sz) - continue; - - SigBit wire_bit = SigBit(wire, i); - SigBit mapped_wire_bit = sigmap(wire_bit); - - if (wire_bit == mapped_wire_bit) - goto next_wire; - - if (mapped_wire_bit.wire) { - if (qbits.count(mapped_wire_bit) == 0) - goto next_wire; - - if (qbits.at(mapped_wire_bit) != init[i]) - goto next_wire; - } - else { - if (mapped_wire_bit == State::Sx || mapped_wire_bit == State::Sz) - goto next_wire; - - if (mapped_wire_bit != init[i]) { - log_warning("Initial value conflict for %s resolving to %s but with init %s.\n", log_signal(wire_bit), log_signal(mapped_wire_bit), log_signal(init[i])); - goto next_wire; - } - } - } - - if (verbose) - log_debug(" removing redundant init attribute on %s.\n", log_id(wire)); - - wire->attributes.erase(ID::init); - did_something = true; - next_wire:; - } - - if (did_something) - module->design->scratchpad_set_bool("opt.did_something", true); - - return did_something; -} - -void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool rminit) -{ - if (verbose) - log("Finding unused cells or wires in module %s..\n", module->name); - - std::vector delcells; - for (auto cell : module->cells()) { - if (cell->type.in(ID($pos), ID($_BUF_), ID($buf)) && !cell->has_keep_attr()) { - bool is_signed = cell->type == ID($pos) && cell->getParam(ID::A_SIGNED).as_bool(); - RTLIL::SigSpec a = cell->getPort(ID::A); - RTLIL::SigSpec y = cell->getPort(ID::Y); - a.extend_u0(GetSize(y), is_signed); - - if (a.has_const(State::Sz)) { - SigSpec new_a; - SigSpec new_y; - for (int i = 0; i < GetSize(a); ++i) { - SigBit b = a[i]; - if (b == State::Sz) - continue; - new_a.append(b); - new_y.append(y[i]); - } - a = std::move(new_a); - y = std::move(new_y); - } - if (!y.empty()) - module->connect(y, a); - delcells.push_back(cell); - } else if (cell->type.in(ID($connect)) && !cell->has_keep_attr()) { - RTLIL::SigSpec a = cell->getPort(ID::A); - RTLIL::SigSpec b = cell->getPort(ID::B); - if (a.has_const() && !b.has_const()) - std::swap(a, b); - module->connect(a, b); - delcells.push_back(cell); - } else if (cell->type.in(ID($input_port)) && !cell->has_keep_attr()) { - delcells.push_back(cell); - } - } - for (auto cell : delcells) { - if (verbose) { - if (cell->type == ID($connect)) - log_debug(" removing connect cell `%s': %s <-> %s\n", cell->name, - log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B))); - else if (cell->type == ID($input_port)) - log_debug(" removing input port marker cell `%s': %s\n", cell->name, - log_signal(cell->getPort(ID::Y))); - else - log_debug(" removing buffer cell `%s': %s = %s\n", cell->name, - log_signal(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::A))); - } - module->remove(cell); - } - if (!delcells.empty()) - module->design->scratchpad_set_bool("opt.did_something", true); - - rmunused_module_cells(module, verbose); - while (rmunused_module_signals(module, purge_mode, verbose)) { } - - if (rminit && rmunused_module_init(module, verbose)) - while (rmunused_module_signals(module, purge_mode, verbose)) { } -} - -struct OptCleanPass : public Pass { - OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" opt_clean [options] [selection]\n"); - log("\n"); - log("This pass identifies wires and cells that are unused and removes them. Other\n"); - log("passes often remove cells but leave the wires in the design or reconnect the\n"); - log("wires but leave the old cells in the design. This pass can be used to clean up\n"); - log("after the passes that do the actual work.\n"); - log("\n"); - log("This pass only operates on completely selected modules without processes.\n"); - log("\n"); - log(" -purge\n"); - log(" also remove internal nets if they have a public name\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - bool purge_mode = false; - - log_header(design, "Executing OPT_CLEAN pass (remove unused cells and wires).\n"); - log_push(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-purge") { - purge_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - keep_cache.reset(design, purge_mode); - - ct_reg.setup_internals_mem(); - ct_reg.setup_internals_anyinit(); - ct_reg.setup_stdcells_mem(); - - ct_all.setup(design); - - count_rm_cells = 0; - count_rm_wires = 0; - - for (auto module : design->selected_whole_modules_warn()) { - if (module->has_processes_warn()) - continue; - rmunused_module(module, purge_mode, true, true); - } - - if (count_rm_cells > 0 || count_rm_wires > 0) - log("Removed %d unused cells and %d unused wires.\n", count_rm_cells, count_rm_wires); - - design->optimize(); - design->sort(); - design->check(); - - keep_cache.reset(); - ct_reg.clear(); - ct_all.clear(); - log_pop(); - - request_garbage_collection(); - } -} OptCleanPass; - -struct CleanPass : public Pass { - CleanPass() : Pass("clean", "remove unused cells and wires") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" clean [options] [selection]\n"); - log("\n"); - log("This is identical to 'opt_clean', but less verbose.\n"); - log("\n"); - log("When commands are separated using the ';;' token, this command will be executed\n"); - log("between the commands.\n"); - log("\n"); - log("When commands are separated using the ';;;' token, this command will be executed\n"); - log("in -purge mode between the commands.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - bool purge_mode = false; - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-purge") { - purge_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - keep_cache.reset(design); - - ct_reg.setup_internals_mem(); - ct_reg.setup_internals_anyinit(); - ct_reg.setup_stdcells_mem(); - - ct_all.setup(design); - - count_rm_cells = 0; - count_rm_wires = 0; - - for (auto module : design->selected_unboxed_whole_modules()) { - if (module->has_processes()) - continue; - rmunused_module(module, purge_mode, ys_debug(), true); - } - - log_suppressed(); - if (count_rm_cells > 0 || count_rm_wires > 0) - log("Removed %d unused cells and %d unused wires.\n", count_rm_cells, count_rm_wires); - - design->optimize(); - design->sort(); - design->check(); - - keep_cache.reset(); - ct_reg.clear(); - ct_all.clear(); - - request_garbage_collection(); - } -} CleanPass; - -PRIVATE_NAMESPACE_END diff --git a/passes/opt/opt_clean/Makefile.inc b/passes/opt/opt_clean/Makefile.inc new file mode 100644 index 000000000..b4bb5b070 --- /dev/null +++ b/passes/opt/opt_clean/Makefile.inc @@ -0,0 +1,10 @@ +OPT_CLEAN_OBJS = +OPT_CLEAN_OBJS += passes/opt/opt_clean/cells_all.o +OPT_CLEAN_OBJS += passes/opt/opt_clean/cells_temp.o +OPT_CLEAN_OBJS += passes/opt/opt_clean/wires.o +OPT_CLEAN_OBJS += passes/opt/opt_clean/inits.o +OPT_CLEAN_OBJS += passes/opt/opt_clean/opt_clean.o + +$(OPT_CLEAN_OBJS): passes/opt/opt_clean/opt_clean.h + +OBJS += $(OPT_CLEAN_OBJS) diff --git a/passes/opt/opt_clean/cells_all.cc b/passes/opt/opt_clean/cells_all.cc new file mode 100644 index 000000000..aa97851e3 --- /dev/null +++ b/passes/opt/opt_clean/cells_all.cc @@ -0,0 +1,373 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/ffinit.h" +#include "kernel/yosys_common.h" +#include "passes/opt/opt_clean/opt_clean.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +unsigned int hash_bit(const SigBit &bit) { + return static_cast(hash_ops::hash(bit).yield()); +} + +SigMap wire_sigmap(const RTLIL::Module* mod) { + SigMap map; + for (auto &it : mod->connections_) { + for (int i = 0; i < GetSize(it.second); i++) { + if (it.second[i].wire != nullptr) + map.add(it.first[i], it.second[i]); + } + } + return map; +} + +struct WireDrivers; +// Maps from a SigBit to a unique driver cell. +struct WireDriver { + using Accumulated = WireDrivers; + SigBit bit; + int driver_cell; +}; +// Maps from a SigBit to one or more driver cells. +struct WireDrivers { + WireDrivers() : driver_cell(0) {} + WireDrivers(WireDriver driver) : bit(driver.bit), driver_cell(driver.driver_cell) {} + WireDrivers(SigBit bit) : bit(bit), driver_cell(0) {} + WireDrivers(WireDrivers &&other) = default; + + class const_iterator { + public: + const_iterator(const WireDrivers &drivers, bool end) + : driver_cell(drivers.driver_cell), in_extra_cells(end) { + if (drivers.extra_driver_cells) { + if (end) { + extra_it = drivers.extra_driver_cells->end(); + } else { + extra_it = drivers.extra_driver_cells->begin(); + } + } + } + int operator*() const { + if (in_extra_cells) + return **extra_it; + return driver_cell; + } + const_iterator& operator++() { + if (in_extra_cells) + ++*extra_it; + else + in_extra_cells = true; + return *this; + } + bool operator!=(const const_iterator &other) const { + return !(*this == other); + } + bool operator==(const const_iterator &other) const { + return in_extra_cells == other.in_extra_cells && + extra_it == other.extra_it; + } + private: + std::optional::iterator> extra_it; + int driver_cell; + bool in_extra_cells; + }; + + const_iterator begin() const { return const_iterator(*this, false); } + const_iterator end() const { return const_iterator(*this, true); } + + SigBit bit; + int driver_cell; + std::unique_ptr> extra_driver_cells; +}; +struct WireDriversKeyEquality { + bool operator()(const WireDrivers &a, const WireDrivers &b) const { + return a.bit == b.bit; + } +}; +struct WireDriversCollisionHandler { + void operator()(WireDrivers &incumbent, WireDrivers &new_value) const { + log_assert(new_value.extra_driver_cells == nullptr); + if (!incumbent.extra_driver_cells) + incumbent.extra_driver_cells.reset(new pool()); + incumbent.extra_driver_cells->insert(new_value.driver_cell); + } +}; +using Wire2Drivers = ShardedHashtable; + +struct ConflictLogs { + ShardedVector> logs; + ConflictLogs(ParallelDispatchThreadPool::Subpool &subpool) : logs(subpool) {} + void print_warnings(pool& used_raw_bits, const SigMap& wire_map, const RTLIL::Module* mod, CleanRunContext &clean_ctx) { + if (!logs.empty()) { + // We could do this in parallel but hopefully this is rare. + for (auto [_, cell] : mod->cells_) { + for (auto &[port, sig] : cell->connections()) { + if (clean_ctx.ct_all.cell_known(cell->type) && !clean_ctx.ct_all.cell_input(cell->type, port)) + continue; + for (auto raw_bit : wire_map(sig)) + used_raw_bits.insert(raw_bit); + } + } + for (std::pair &it : logs) { + if (used_raw_bits.count(it.first)) + log_warning("%s\n", it.second); + } + } + } +}; + +struct CellTraversal { + ConcurrentWorkQueue queue; + Wire2Drivers wire2driver; + dict> mem2cells; + CellTraversal(int num_threads) : queue(num_threads), wire2driver(), mem2cells() {} +}; + +struct CellAnalysis { + ShardedVector keep_wires; + std::vector> unused; + + CellAnalysis(AnalysisContext& actx) + : keep_wires(actx.subpool), unused(actx.mod->cells_size()) {} + + pool analyze_kept_wires(CellTraversal& traversal, const SigMap& sigmap, const SigMap& wire_map, int num_threads) { + // Also enqueue cells that drive kept wires into cell_queue + // and mark those cells as used + // and mark all bits of those wires as used + pool used_raw_bits; + int i = 0; + for (Wire *wire : keep_wires) { + for (auto bit : sigmap(wire)) { + const WireDrivers *drivers = traversal.wire2driver.find({{bit}, hash_bit(bit)}); + if (drivers != nullptr) + for (int cell_index : *drivers) + if (unused[cell_index].exchange(false, std::memory_order_relaxed)) { + ThreadIndex fake_thread_index = {i++ % num_threads}; + traversal.queue.push(fake_thread_index, cell_index); + } + } + for (auto raw_bit : SigSpec(wire)) + used_raw_bits.insert(wire_map(raw_bit)); + } + return used_raw_bits; + } + + void mark_used_and_enqueue(int cell_idx, ConcurrentWorkQueue& queue, const ParallelDispatchThreadPool::RunCtx &ctx) { + if (unused[cell_idx].exchange(false, std::memory_order_relaxed)) + queue.push(ctx, cell_idx); + } +}; + +ConflictLogs explore(CellAnalysis& analysis, CellTraversal& traversal, const SigMap& wire_map, AnalysisContext& actx, CleanRunContext &clean_ctx) { + ConflictLogs logs(actx.subpool); + Wire2Drivers::Builder wire2driver_builder(actx.subpool); + ShardedVector> mem2cells_vector(actx.subpool); + + // Enqueue kept cells into traversal.queue + // Prepare input cone traversal into traversal.wire2driver + // Prepare "input cone" traversal from memory to write port or meminit as analysis.mem2cells + // Also check driver conflicts + // Also mark cells unused to true unless keep (we override this later) + actx.subpool.run([&analysis, &traversal, &logs, &wire_map, &mem2cells_vector, &wire2driver_builder, &actx, &clean_ctx](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(actx.mod->cells_size())) { + Cell *cell = actx.mod->cell_at(i); + if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2))) + mem2cells_vector.insert(ctx, {cell->getParam(ID::MEMID).decode_string(), i}); + + for (auto &it2 : cell->connections()) { + if (clean_ctx.ct_all.cell_known(cell->type) && !clean_ctx.ct_all.cell_output(cell->type, it2.first)) + continue; + for (auto raw_bit : it2.second) { + if (raw_bit.wire == nullptr) + continue; + auto bit = actx.assign_map(raw_bit); + if (bit.wire == nullptr && clean_ctx.ct_all.cell_known(cell->type)) { + std::string msg = stringf("Driver-driver conflict " + "for %s between cell %s.%s and constant %s in %s: Resolved using constant.", + log_signal(raw_bit), cell->name.unescape(), it2.first.unescape(), log_signal(bit), actx.mod->name.unescape()); + logs.logs.insert(ctx, {wire_map(raw_bit), msg}); + } + if (bit.wire != nullptr) + wire2driver_builder.insert(ctx, {{bit, i}, hash_bit(bit)}); + } + } + bool keep = clean_ctx.keep_cache.query(cell); + analysis.unused[i].store(!keep, std::memory_order_relaxed); + if (keep) + traversal.queue.push(ctx, i); + } + for (int i : ctx.item_range(actx.mod->wires_size())) { + Wire *wire = actx.mod->wire_at(i); + if (wire->port_output || wire->get_bool_attribute(ID::keep)) + analysis.keep_wires.insert(ctx, wire); + } + }); + // Finish by merging per-thread collected data + actx.subpool.run([&wire2driver_builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + wire2driver_builder.process(ctx); + }); + traversal.wire2driver = wire2driver_builder; + + for (std::pair &mem2cell : mem2cells_vector) + traversal.mem2cells[mem2cell.first].insert(mem2cell.second); + + return logs; +} + +struct MemAnalysis { + std::vector> unused; + dict indices; + MemAnalysis(const RTLIL::Module* mod) : unused(mod->memories.size()), indices() { + for (int i = 0; i < GetSize(mod->memories); ++i) { + indices[mod->memories.element(i)->first.str()] = i; + unused[i].store(true, std::memory_order_relaxed); + } + } +}; + +void fixup_unused_cells_and_mems(CellAnalysis& analysis, MemAnalysis& mem_analysis, CellTraversal& traversal, AnalysisContext& actx, CleanRunContext &clean_ctx) { + // Processes the cell queue in batches, traversing input cones by enqueuing more cells + // Discover and mark used memories and cells + actx.subpool.run([&analysis, &mem_analysis, &traversal, &actx, &clean_ctx](const ParallelDispatchThreadPool::RunCtx &ctx) { + pool bits; + pool mems; + while (true) { + std::vector cell_indices = traversal.queue.pop_batch(ctx); + if (cell_indices.empty()) + return; + for (auto cell_index : cell_indices) { + Cell *cell = actx.mod->cell_at(cell_index); + for (auto &it : cell->connections()) + if (!clean_ctx.ct_all.cell_known(cell->type) || clean_ctx.ct_all.cell_input(cell->type, it.first)) + for (auto bit : actx.assign_map(it.second)) + bits.insert(bit); + + if (cell->type.in(ID($memrd), ID($memrd_v2))) { + std::string mem_id = cell->getParam(ID::MEMID).decode_string(); + if (mem_analysis.indices.count(mem_id)) { + int mem_index = mem_analysis.indices[mem_id]; + // Memory fixup + if (mem_analysis.unused[mem_index].exchange(false, std::memory_order_relaxed)) + mems.insert(mem_id); + } + } + } + + for (auto bit : bits) { + // Cells fixup + const WireDrivers *drivers = traversal.wire2driver.find({{bit}, hash_bit(bit)}); + if (drivers != nullptr) + for (int cell_idx : *drivers) + analysis.mark_used_and_enqueue(cell_idx, traversal.queue, ctx); + } + bits.clear(); + + for (auto mem : mems) { + if (traversal.mem2cells.count(mem) == 0) + continue; + // Cells fixup + for (int cell_idx : traversal.mem2cells.at(mem)) + analysis.mark_used_and_enqueue(cell_idx, traversal.queue, ctx); + } + mems.clear(); + } + }); +} + +pool all_unused_cells(const Module *mod, const CellAnalysis& analysis, Wire2Drivers& wire2driver, ParallelDispatchThreadPool::Subpool &subpool) { + pool unused_cells; + ShardedVector sharded_unused_cells(subpool); + subpool.run([mod, &analysis, &wire2driver, &sharded_unused_cells](const ParallelDispatchThreadPool::RunCtx &ctx) { + // Parallel destruction of `wire2driver` + wire2driver.clear(ctx); + for (int i : ctx.item_range(mod->cells_size())) + if (analysis.unused[i].load(std::memory_order_relaxed)) + sharded_unused_cells.insert(ctx, i); + }); + for (int cell_index : sharded_unused_cells) + unused_cells.insert(mod->cell_at(cell_index)); + unused_cells.sort(RTLIL::sort_by_name_id()); + return unused_cells; +} + +void remove_cells(RTLIL::Module* mod, FfInitVals& ffinit, const pool& cells, bool verbose, RmStats& stats) { + for (auto cell : cells) { + if (verbose) + log_debug(" removing unused `%s' cell `%s'.\n", cell->type, cell->name); + mod->design->scratchpad_set_bool("opt.did_something", true); + if (cell->is_builtin_ff()) + ffinit.remove_init(cell->getPort(ID::Q)); + mod->remove(cell); + stats.count_rm_cells++; + } +} + +void remove_mems(RTLIL::Module* mod, const MemAnalysis& mem_analysis, bool verbose) { + for (const auto &it : mem_analysis.indices) { + if (!mem_analysis.unused[it.second].load(std::memory_order_relaxed)) + continue; + RTLIL::IdString id(it.first); + if (verbose) + log_debug(" removing unused memory `%s'.\n", id.unescape()); + delete mod->memories.at(id); + mod->memories.erase(id); + } +} + +PRIVATE_NAMESPACE_END + +YOSYS_NAMESPACE_BEGIN + +void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx) +{ + AnalysisContext actx(module, subpool); + + // Used for logging warnings only + SigMap wire_map = wire_sigmap(module); + + CellAnalysis analysis(actx); + CellTraversal traversal(subpool.num_threads()); + // Mark all unkept cells as unused initially + // and queue up cell traversal from those cells + auto logs = explore(analysis, traversal, wire_map, actx, clean_ctx); + // Mark cells that drive kept wires into cell_queue and those bits as used + // and queue up cell traversal from those cells + pool used_raw_bits = analysis.analyze_kept_wires(traversal, actx.assign_map, wire_map, subpool.num_threads()); + + // Mark all memories as unused initially + MemAnalysis mem_analysis(module); + // Marked all used cells and mems as used by traversing with cell queue + fixup_unused_cells_and_mems(analysis, mem_analysis, traversal, actx, clean_ctx); + // Analyses are now fully correct + + // unused_cells.contains(foo) iff analysis.used[foo] == true + // wire2driver is passed in only to destroy it + pool unused_cells = all_unused_cells(module, analysis, traversal.wire2driver, subpool); + + FfInitVals ffinit; + ffinit.set_parallel(&actx.assign_map, subpool.thread_pool(), module); + // Now we know what to kill + remove_cells(module, ffinit, unused_cells, clean_ctx.flags.verbose, clean_ctx.stats); + remove_mems(module, mem_analysis, clean_ctx.flags.verbose); + logs.print_warnings(used_raw_bits, wire_map, module, clean_ctx); +} + +YOSYS_NAMESPACE_END diff --git a/passes/opt/opt_clean/cells_temp.cc b/passes/opt/opt_clean/cells_temp.cc new file mode 100644 index 000000000..b325b68d9 --- /dev/null +++ b/passes/opt/opt_clean/cells_temp.cc @@ -0,0 +1,104 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "passes/opt/opt_clean/opt_clean.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +bool is_signed(RTLIL::Cell* cell) { + return cell->type == ID($pos) && cell->getParam(ID::A_SIGNED).as_bool(); +} + +bool trim_buf(RTLIL::Cell* cell, ShardedVector& new_connections, const ParallelDispatchThreadPool::RunCtx &ctx) { + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec y = cell->getPort(ID::Y); + a.extend_u0(GetSize(y), is_signed(cell)); + + if (a.has_const(State::Sz)) { + RTLIL::SigSpec new_a; + RTLIL::SigSpec new_y; + for (int i = 0; i < GetSize(a); ++i) { + RTLIL::SigBit b = a[i]; + if (b == State::Sz) + return false; + new_a.append(b); + new_y.append(y[i]); + } + a = std::move(new_a); + y = std::move(new_y); + } + if (!y.empty()) + new_connections.insert(ctx, {y, a}); + return true; +} + +bool remove(ShardedVector& cells, RTLIL::Module* mod, bool verbose) { + bool did_something = false; + for (RTLIL::Cell *cell : cells) { + if (verbose) { + if (cell->type == ID($connect)) + log_debug(" removing connect cell `%s': %s <-> %s\n", cell->name, + log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B))); + else if (cell->type == ID($input_port)) + log_debug(" removing input port marker cell `%s': %s\n", cell->name, + log_signal(cell->getPort(ID::Y))); + else + log_debug(" removing buffer cell `%s': %s = %s\n", cell->name, + log_signal(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::A))); + } + mod->remove(cell); + did_something = true; + } + return did_something; +} +PRIVATE_NAMESPACE_END +YOSYS_NAMESPACE_BEGIN + +void remove_temporary_cells(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose) +{ + ShardedVector delcells(subpool); + ShardedVector new_connections(subpool); + const RTLIL::Module *const_module = module; + subpool.run([const_module, &delcells, &new_connections](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(const_module->cells_size())) { + RTLIL::Cell *cell = const_module->cell_at(i); + if (cell->type.in(ID($pos), ID($_BUF_), ID($buf)) && !cell->has_keep_attr()) { + if (trim_buf(cell, new_connections, ctx)) + delcells.insert(ctx, cell); + } else if (cell->type.in(ID($connect)) && !cell->has_keep_attr()) { + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec b = cell->getPort(ID::B); + if (a.has_const() && !b.has_const()) + std::swap(a, b); + new_connections.insert(ctx, {a, b}); + delcells.insert(ctx, cell); + } else if (cell->type.in(ID($input_port)) && !cell->has_keep_attr()) { + delcells.insert(ctx, cell); + } + } + }); + for (RTLIL::SigSig &connection : new_connections) { + module->connect(connection); + } + if (remove(delcells, module, verbose)) + module->design->scratchpad_set_bool("opt.did_something", true); +} + +YOSYS_NAMESPACE_END diff --git a/passes/opt/opt_clean/inits.cc b/passes/opt/opt_clean/inits.cc new file mode 100644 index 000000000..70c2ef9e2 --- /dev/null +++ b/passes/opt/opt_clean/inits.cc @@ -0,0 +1,137 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "passes/opt/opt_clean/opt_clean.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +ShardedVector> build_inits(AnalysisContext& actx) { + ShardedVector> results(actx.subpool); + actx.subpool.run([&results, &actx](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(actx.mod->cells_size())) { + RTLIL::Cell *cell = actx.mod->cell_at(i); + if (StaticCellTypes::Compat::internals_mem_ff(cell->type) && cell->hasPort(ID::Q)) + { + SigSpec sig = cell->getPort(ID::Q); + + for (int i = 0; i < GetSize(sig); i++) + { + SigBit bit = sig[i]; + + if (bit.wire == nullptr || bit.wire->attributes.count(ID::init) == 0) + continue; + + Const init = bit.wire->attributes.at(ID::init); + + if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz) + continue; + + results.insert(ctx, {bit, init[i]}); + } + } + } + }); + return results; +} + +dict qbits_from_inits(ShardedVector>& inits, SigMap& assign_map) { + dict qbits; + for (std::pair &p : inits) { + assign_map.add(p.first); + qbits[p.first] = p.second; + } + return qbits; +} + +ShardedVector deferred_init_transfer(const dict& qbits, AnalysisContext& actx) { + ShardedVector wire_results(actx.subpool); + actx.subpool.run([&actx, &qbits, &wire_results](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int j : ctx.item_range(actx.mod->wires_size())) { + RTLIL::Wire *wire = actx.mod->wire_at(j); + if (wire->attributes.count(ID::init) == 0) + continue; + Const init = wire->attributes.at(ID::init); + + for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++) + { + if (init[i] == State::Sx || init[i] == State::Sz) + continue; + + SigBit wire_bit = SigBit(wire, i); + SigBit mapped_wire_bit = actx.assign_map(wire_bit); + + if (wire_bit == mapped_wire_bit) + goto next_wire; + + if (mapped_wire_bit.wire) { + if (qbits.count(mapped_wire_bit) == 0) + goto next_wire; + + if (qbits.at(mapped_wire_bit) != init[i]) + goto next_wire; + } + else { + if (mapped_wire_bit == State::Sx || mapped_wire_bit == State::Sz) + goto next_wire; + + if (mapped_wire_bit != init[i]) { + log_warning("Initial value conflict for %s resolving to %s but with init %s.\n", log_signal(wire_bit), log_signal(mapped_wire_bit), log_signal(init[i])); + goto next_wire; + } + } + } + wire_results.insert(ctx, wire); + + next_wire:; + } + }); + return wire_results; +} + +bool remove_redundant_inits(ShardedVector wires, bool verbose) { + bool did_something = false; + for (RTLIL::Wire *wire : wires) { + if (verbose) + log_debug(" removing redundant init attribute on %s.\n", log_id(wire)); + wire->attributes.erase(ID::init); + did_something = true; + } + return did_something; +} + +PRIVATE_NAMESPACE_END +YOSYS_NAMESPACE_BEGIN + +bool rmunused_module_init(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose) +{ + AnalysisContext actx(module, subpool); + + ShardedVector> inits = build_inits(actx); + dict qbits = qbits_from_inits(inits, actx.assign_map); + ShardedVector inits_to_transfer = deferred_init_transfer(qbits, actx); + + bool did_something = remove_redundant_inits(inits_to_transfer, verbose); + if (did_something) + module->design->scratchpad_set_bool("opt.did_something", true); + + return did_something; +} + +YOSYS_NAMESPACE_END diff --git a/passes/opt/opt_clean/keep_cache.h b/passes/opt/opt_clean/keep_cache.h new file mode 100644 index 000000000..7405f24fc --- /dev/null +++ b/passes/opt/opt_clean/keep_cache.h @@ -0,0 +1,167 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/rtlil.h" +#include "kernel/sigtools.h" +#include "kernel/threading.h" +#include "kernel/celltypes.h" +#include "kernel/yosys_common.h" + +#ifndef OPT_CLEAN_KEEP_CACHE_H +#define OPT_CLEAN_KEEP_CACHE_H + +YOSYS_NAMESPACE_BEGIN + +struct KeepCache +{ + dict keep_modules; + bool purge_mode; + + KeepCache(bool purge_mode, ParallelDispatchThreadPool &thread_pool, const std::vector &selected_modules) + : purge_mode(purge_mode) { + + std::vector scan_modules_worklist; + dict> dependents; + std::vector propagate_kept_modules_worklist; + for (RTLIL::Module *module : selected_modules) { + if (keep_modules.count(module)) + continue; + bool keep = scan_module(module, thread_pool, dependents, ALL_CELLS, scan_modules_worklist); + keep_modules[module] = keep; + if (keep) + propagate_kept_modules_worklist.push_back(module); + } + + while (!scan_modules_worklist.empty()) { + RTLIL::Module *module = scan_modules_worklist.back(); + scan_modules_worklist.pop_back(); + if (keep_modules.count(module)) + continue; + bool keep = scan_module(module, thread_pool, dependents, MINIMUM_CELLS, scan_modules_worklist); + keep_modules[module] = keep; + if (keep) + propagate_kept_modules_worklist.push_back(module); + } + + while (!propagate_kept_modules_worklist.empty()) { + RTLIL::Module *module = propagate_kept_modules_worklist.back(); + propagate_kept_modules_worklist.pop_back(); + for (RTLIL::Module *dependent : dependents[module]) { + if (keep_modules[dependent]) + continue; + keep_modules[dependent] = true; + propagate_kept_modules_worklist.push_back(dependent); + } + } + } + + bool query(Cell *cell) const + { + if (keep_cell(cell, purge_mode)) + return true; + if (cell->type.in(ID($specify2), ID($specify3), ID($specrule))) + return true; + if (cell->module && cell->module->design) { + RTLIL::Module *cell_module = cell->module->design->module(cell->type); + return cell_module != nullptr && keep_modules.at(cell_module); + } + return false; + } + +private: + enum ScanCells { + // Scan every cell to see if it uses a module that is kept. + ALL_CELLS, + // Stop scanning cells if we determine early that this module is kept. + MINIMUM_CELLS, + }; + bool scan_module(Module *module, ParallelDispatchThreadPool &thread_pool, dict> &dependents, + ScanCells scan_cells, std::vector &worklist) const + { + MonotonicFlag keep_module; + if (module->get_bool_attribute(ID::keep)) { + if (scan_cells == MINIMUM_CELLS) + return true; + keep_module.set(); + } + + ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000)); + ShardedVector deps(subpool); + const RTLIL::Module *const_module = module; + bool purge_mode = this->purge_mode; + subpool.run([purge_mode, const_module, scan_cells, &deps, &keep_module](const ParallelDispatchThreadPool::RunCtx &ctx) { + bool keep = false; + for (int i : ctx.item_range(const_module->cells_size())) { + Cell *cell = const_module->cell_at(i); + if (keep_cell(cell, purge_mode)) { + if (scan_cells == MINIMUM_CELLS) { + keep_module.set(); + return; + } + keep = true; + } + if (const_module->design) { + RTLIL::Module *cell_module = const_module->design->module(cell->type); + if (cell_module != nullptr) + deps.insert(ctx, cell_module); + } + } + if (keep) { + keep_module.set(); + return; + } + for (int i : ctx.item_range(const_module->wires_size())) { + Wire *wire = const_module->wire_at(i); + if (wire->get_bool_attribute(ID::keep)) { + keep_module.set(); + return; + } + } + }); + if (scan_cells == MINIMUM_CELLS && keep_module.load()) + return true; + for (Module *dep : deps) { + dependents[dep].push_back(module); + worklist.push_back(dep); + } + return keep_module.load(); + } + + static bool keep_cell(Cell *cell, bool purge_mode) + { + if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) + return true; + + if (cell->type.in(ID($overwrite_tag))) + return true; + + if (cell->type == ID($print) || cell->type == ID($check)) + return true; + + if (cell->has_keep_attr()) + return true; + + if (!purge_mode && cell->type == ID($scopeinfo)) + return true; + return false; + } +}; + +YOSYS_NAMESPACE_END +#endif /* OPT_CLEAN_KEEP_CACHE_H */ diff --git a/passes/opt/opt_clean/opt_clean.cc b/passes/opt/opt_clean/opt_clean.cc new file mode 100644 index 000000000..87597d721 --- /dev/null +++ b/passes/opt/opt_clean/opt_clean.cc @@ -0,0 +1,151 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/log.h" +#include "passes/opt/opt_clean/opt_clean.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +void rmunused_module(RTLIL::Module *module, bool rminit, CleanRunContext &clean_ctx) +{ + if (clean_ctx.flags.verbose) + log("Finding unused cells or wires in module %s..\n", module->name); + + // Use no more than one worker per thousand cells, rounded down, so + // we only start multithreading with at least 2000 cells. + int num_worker_threads = ThreadPool::work_pool_size(0, module->cells_size(), 10000); + ParallelDispatchThreadPool::Subpool subpool(clean_ctx.thread_pool, num_worker_threads); + remove_temporary_cells(module, subpool, clean_ctx.flags.verbose); + rmunused_module_cells(module, subpool, clean_ctx); + while (rmunused_module_signals(module, subpool, clean_ctx)) { } + + if (rminit && rmunused_module_init(module, subpool, clean_ctx.flags.verbose)) + while (rmunused_module_signals(module, subpool, clean_ctx)) { } +} + +struct OptCleanPass : public Pass { + OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_clean [options] [selection]\n"); + log("\n"); + log("This pass identifies wires and cells that are unused and removes them. Other\n"); + log("passes often remove cells but leave the wires in the design or reconnect the\n"); + log("wires but leave the old cells in the design. This pass can be used to clean up\n"); + log("after the passes that do the actual work.\n"); + log("\n"); + log("This pass only operates on completely selected modules without processes.\n"); + log("\n"); + log(" -purge\n"); + log(" also remove internal nets if they have a public name\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + bool purge_mode = false; + + log_header(design, "Executing OPT_CLEAN pass (remove unused cells and wires).\n"); + log_push(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-purge") { + purge_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + { + std::vector selected_modules; + for (auto module : design->selected_whole_modules_warn()) + if (!module->has_processes_warn()) + selected_modules.push_back(module); + CleanRunContext clean_ctx(design, selected_modules, {purge_mode, true}); + for (auto module : selected_modules) + rmunused_module(module, true, clean_ctx); + clean_ctx.stats.log(); + + design->optimize(); + design->check(); + } + + log_pop(); + + request_garbage_collection(); + } +} OptCleanPass; + +struct CleanPass : public Pass { + CleanPass() : Pass("clean", "remove unused cells and wires") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" clean [options] [selection]\n"); + log("\n"); + log("This is identical to 'opt_clean', but less verbose.\n"); + log("\n"); + log("When commands are separated using the ';;' token, this command will be executed\n"); + log("between the commands.\n"); + log("\n"); + log("When commands are separated using the ';;;' token, this command will be executed\n"); + log("in -purge mode between the commands.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + bool purge_mode = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-purge") { + purge_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + { + std::vector selected_modules; + for (auto module : design->selected_unboxed_whole_modules()) + if (!module->has_processes()) + selected_modules.push_back(module); + CleanRunContext clean_ctx(design, selected_modules, {purge_mode, ys_debug()}); + for (auto module : selected_modules) + rmunused_module(module, true, clean_ctx); + + log_suppressed(); + clean_ctx.stats.log(); + + design->optimize(); + design->check(); + } + + request_garbage_collection(); + } +} CleanPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/opt/opt_clean/opt_clean.h b/passes/opt/opt_clean/opt_clean.h new file mode 100644 index 000000000..c48a8188a --- /dev/null +++ b/passes/opt/opt_clean/opt_clean.h @@ -0,0 +1,92 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/rtlil.h" +#include "kernel/threading.h" +#include "passes/opt/opt_clean/keep_cache.h" + +#ifndef OPT_CLEAN_SHARED_H +#define OPT_CLEAN_SHARED_H + +YOSYS_NAMESPACE_BEGIN + +struct AnalysisContext { + SigMap assign_map; + const RTLIL::Module *mod; + ParallelDispatchThreadPool::Subpool &subpool; + AnalysisContext(RTLIL::Module* m, ParallelDispatchThreadPool::Subpool &p) : assign_map(m), mod(m), subpool(p) {} +}; + +struct RmStats { + int count_rm_cells = 0; + int count_rm_wires = 0; + + void log() + { + if (count_rm_cells > 0 || count_rm_wires > 0) + YOSYS_NAMESPACE_PREFIX log("Removed %d unused cells and %d unused wires.\n", count_rm_cells, count_rm_wires); + } +}; + +struct Flags { + bool purge = false; + bool verbose = false; +}; +struct CleanRunContext { + static constexpr auto ct_reg = StaticCellTypes::Categories::join( + StaticCellTypes::Compat::mem_ff, + StaticCellTypes::categories.is_anyinit); + NewCellTypes ct_all; + RmStats stats; + ParallelDispatchThreadPool thread_pool; + KeepCache keep_cache; + Flags flags; + +private: + // Helper to compute thread pool size + static int compute_thread_pool_size(const std::vector& selected_modules) { + int thread_pool_size = 0; + for (auto module : selected_modules) + thread_pool_size = std::max(thread_pool_size, + ThreadPool::work_pool_size(0, module->cells_size(), 10000)); + return thread_pool_size; + } + +public: + CleanRunContext(RTLIL::Design* design, const std::vector& selected_modules, Flags f) + : thread_pool(compute_thread_pool_size(selected_modules)), + keep_cache(f.purge, thread_pool, selected_modules), + flags(f) + { + ct_all.setup(design); + } + + ~CleanRunContext() { + ct_all.clear(); + } +}; + +void remove_temporary_cells(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose); +void rmunused_module_cells(Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx); +bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx); +bool rmunused_module_init(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, bool verbose); + +YOSYS_NAMESPACE_END + +#endif /* OPT_CLEAN_SHARED_H */ diff --git a/passes/opt/opt_clean/wires.cc b/passes/opt/opt_clean/wires.cc new file mode 100644 index 000000000..28c792936 --- /dev/null +++ b/passes/opt/opt_clean/wires.cc @@ -0,0 +1,585 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "passes/opt/opt_clean/opt_clean.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +// No collision handler for these, since we will use them such that collisions don't happen +struct ShardedSigBit { + using Accumulated = ShardedSigBit; + RTLIL::SigBit bit; + ShardedSigBit() = default; + ShardedSigBit(const RTLIL::SigBit &bit) : bit(bit) {} +}; +struct ShardedSigBitEquality { + bool operator()(const ShardedSigBit &b1, const ShardedSigBit &b2) const { + return b1.bit == b2.bit; + } +}; +using ShardedSigPool = ShardedHashtable>; + +struct ShardedSigSpec { + using Accumulated = ShardedSigSpec; + RTLIL::SigSpec spec; + ShardedSigSpec() = default; + ShardedSigSpec(RTLIL::SigSpec spec) : spec(std::move(spec)) {} + ShardedSigSpec(ShardedSigSpec &&) = default; +}; +struct ShardedSigSpecEquality { + bool operator()(const ShardedSigSpec &s1, const ShardedSigSpec &s2) const { + return s1.spec == s2.spec; + } +}; +using ShardedSigSpecPool = ShardedHashtable>; + +struct ExactCellWires { + const ShardedSigSpecPool &exact_cells; + const SigMap &assign_map; + dict cache; + + ExactCellWires(const ShardedSigSpecPool &exact_cells, const SigMap &assign_map) : exact_cells(exact_cells), assign_map(assign_map) {} + void cache_result_for_bit(const SigBit &bit) { + if (bit.wire != nullptr) + (void)is_exactly_cell_driven(bit.wire); + } + bool is_exactly_cell_driven(RTLIL::Wire *wire) { + if (wire->port_input) + return true; + auto it = cache.find(wire); + if (it != cache.end()) + return it->second; + SigSpec sig = assign_map(wire); + bool direct = exact_cells.find({sig, sig.hash_into(Hasher()).yield()}) != nullptr; + cache.insert({wire, direct}); + return direct; + } + void cache_all(ShardedVector &bits) { + for (RTLIL::SigBit candidate : bits) { + cache_result_for_bit(candidate); + cache_result_for_bit(assign_map(candidate)); + } + + } +}; + +int count_nontrivial_wire_attrs(RTLIL::Wire *w) +{ + int count = w->attributes.size(); + count -= w->attributes.count(ID::src); + count -= w->attributes.count(ID::hdlname); + count -= w->attributes.count(ID::scopename); + count -= w->attributes.count(ID::unused_bits); + return count; +} + +// Should we pick `s2` over `s1` to represent a signal? +bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const ShardedSigPool ®s, const ShardedSigPool &conns, ExactCellWires &cell_wires) +{ + if (s1 == s2) + return false; + + RTLIL::Wire *w1 = s1.wire; + RTLIL::Wire *w2 = s2.wire; + + if (w1 == NULL || w2 == NULL) + return w2 == NULL; + + if (w1->port_input != w2->port_input) + return w2->port_input; + + if ((w1->port_input && w1->port_output) != (w2->port_input && w2->port_output)) + return !(w2->port_input && w2->port_output); + + if (w1->name.isPublic() && w2->name.isPublic()) { + ShardedSigPool::AccumulatedValue s1_val = {s1, s1.hash_top().yield()}; + ShardedSigPool::AccumulatedValue s2_val = {s2, s2.hash_top().yield()}; + bool regs1 = regs.find(s1_val) != nullptr; + bool regs2 = regs.find(s2_val) != nullptr; + if (regs1 != regs2) + return regs2; + bool w1_exact = cell_wires.is_exactly_cell_driven(w1); + bool w2_exact = cell_wires.is_exactly_cell_driven(w2); + if (w1_exact != w2_exact) + return w2_exact; + bool conns1 = conns.find(s1_val) != nullptr; + bool conns2 = conns.find(s2_val) != nullptr; + if (conns1 != conns2) + return conns2; + } + + if (w1 == w2) + return s2.offset < s1.offset; + + if (w1->port_output != w2->port_output) + return w2->port_output; + + if (w1->name[0] != w2->name[0]) + return w2->name.isPublic(); + + int attrs1 = count_nontrivial_wire_attrs(w1); + int attrs2 = count_nontrivial_wire_attrs(w2); + + if (attrs1 != attrs2) + return attrs2 > attrs1; + + return w2->name.lt_by_name(w1->name); +} + +bool check_public_name(RTLIL::IdString id) +{ + if (id.begins_with("$")) + return false; + const std::string &id_str = id.str(); + if (id.begins_with("\\_") && (id.ends_with("_") || id_str.find("_[") != std::string::npos)) + return false; + if (id_str.find(".$") != std::string::npos) + return false; + return true; +} + +void add_spec(ShardedSigPool::Builder &builder, const ThreadIndex &thread, const RTLIL::SigSpec &spec) { + for (SigBit bit : spec) + if (bit.wire != nullptr) + builder.insert(thread, {bit, bit.hash_top().yield()}); +} + +bool check_any(const ShardedSigPool &sigs, const RTLIL::SigSpec &spec) { + for (SigBit b : spec) + if (sigs.find({b, b.hash_top().yield()}) != nullptr) + return true; + return false; +} + +bool check_all(const ShardedSigPool &sigs, const RTLIL::SigSpec &spec) { + for (SigBit b : spec) + if (sigs.find({b, b.hash_top().yield()}) == nullptr) + return false; + return true; +} + +struct UpdateConnection { + RTLIL::Cell *cell; + RTLIL::IdString port; + RTLIL::SigSpec spec; +}; +void fixup_cell_ports(ShardedVector &update_connections) +{ + for (UpdateConnection &update : update_connections) + update.cell->connections_.at(update.port) = std::move(update.spec); +} + +struct InitBits { + dict values; + // Wires that appear in the keys of the `values` dict + pool wires; + + // Set init attributes on all wires of a connected group + void apply_normalised_inits() { + for (RTLIL::Wire *wire : wires) { + bool found = false; + Const val(State::Sx, wire->width); + for (int i = 0; i < wire->width; i++) { + auto it = values.find(RTLIL::SigBit(wire, i)); + if (it != values.end()) { + val.set(i, it->second); + found = true; + } + } + if (found) + wire->attributes[ID::init] = val; + } + } +}; +static InitBits consume_inits(ShardedVector &initialized_wires, const SigMap &assign_map) +{ + InitBits init_bits; + for (RTLIL::Wire *initialized_wire : initialized_wires) { + auto it = initialized_wire->attributes.find(ID::init); + RTLIL::Const &val = it->second; + SigSpec sig = assign_map(initialized_wire); + for (int i = 0; i < GetSize(val) && i < GetSize(sig); i++) + if (val[i] != State::Sx && sig[i].wire != nullptr) { + init_bits.values[sig[i]] = val[i]; + init_bits.wires.insert(sig[i].wire); + } + initialized_wire->attributes.erase(it); + } + return init_bits; +} + +/** + * What kinds of things are signals connected to? + * Helps pick representatives out of groups of connected signals */ +struct SigConnKinds { + // Wire bits directly driven by registers (with clk2fflogic exception) + ShardedSigPool raw_registers; + // Wire bits directly connected to any cell port + ShardedSigPool raw_cell_connected; + + // Signals exactly driven by a known cell output, + // this will influence only our choice of representatives. + // A signal is exactly driven by a cell output iff all its bits are driven by this output + // and all bits of this output drive a bit of this signal. + // Additionally, all signals that sigmap to this signal are exactly driven by the port, too + ShardedSigSpecPool exact_cells; + + SigConnKinds(bool purge_mode, const AnalysisContext& actx, CleanRunContext& clean_ctx) { + ShardedSigPool::Builder raw_register_builder(actx.subpool); + ShardedSigPool::Builder raw_cell_connected_builder(actx.subpool); + ShardedSigSpecPool::Builder exact_cell_output_builder(actx.subpool); + actx.subpool.run([&exact_cell_output_builder, &raw_register_builder, &raw_cell_connected_builder, purge_mode, &actx, &clean_ctx](const ParallelDispatchThreadPool::RunCtx &ctx) { + + for (int i : ctx.item_range(actx.mod->cells_size())) { + RTLIL::Cell *cell = actx.mod->cell_at(i); + if (!purge_mode) { + if (clean_ctx.ct_reg(cell->type)) { + // Improve witness signal naming when clk2fflogic used + // see commit message e36c71b5 + bool clk2fflogic = cell->get_bool_attribute(ID::clk2fflogic); + for (auto &[port, sig] : cell->connections()) + if (clk2fflogic ? port == ID::D : clean_ctx.ct_all.cell_output(cell->type, port)) + add_spec(raw_register_builder, ctx, sig); + } + for (auto &[_, sig] : cell->connections()) + add_spec(raw_cell_connected_builder, ctx, sig); + } + if (clean_ctx.ct_all.cell_known(cell->type)) + for (auto &[port, sig] : cell->connections()) + if (clean_ctx.ct_all.cell_output(cell->type, port)) { + RTLIL::SigSpec spec = actx.assign_map(sig); + unsigned int hash = spec.hash_into(Hasher()).yield(); + exact_cell_output_builder.insert(ctx, {std::move(spec), hash}); + } + } + }); + actx.subpool.run([&raw_register_builder, &raw_cell_connected_builder, &exact_cell_output_builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + raw_register_builder.process(ctx); + raw_cell_connected_builder.process(ctx); + exact_cell_output_builder.process(ctx); + }); + raw_registers = raw_register_builder; + raw_cell_connected = raw_cell_connected_builder; + exact_cells = exact_cell_output_builder; + } + void clear(const ParallelDispatchThreadPool::RunCtx &ctx) { + raw_registers.clear(ctx); + raw_cell_connected.clear(ctx); + exact_cells.clear(ctx); + } +}; + +ShardedVector build_candidates(ExactCellWires& cell_wires, const SigConnKinds& sig_analysis, const AnalysisContext& actx) { + ShardedVector candidates(actx.subpool); + actx.subpool.run([&actx, &sig_analysis, &candidates, &cell_wires](const ParallelDispatchThreadPool::RunCtx &ctx) { + std::optional local_cell_wires; + ExactCellWires *this_thread_cell_wires = &cell_wires; + if (ctx.thread_num > 0) { + local_cell_wires.emplace(sig_analysis.exact_cells, actx.assign_map); + this_thread_cell_wires = &local_cell_wires.value(); + } + for (int i : ctx.item_range(actx.mod->wires_size())) { + RTLIL::Wire *wire = actx.mod->wire_at(i); + for (int j = 0; j < wire->width; ++j) { + RTLIL::SigBit s1(wire, j); + RTLIL::SigBit s2 = actx.assign_map(s1); + if (compare_signals(s2, s1, sig_analysis.raw_registers, sig_analysis.raw_cell_connected, *this_thread_cell_wires)) + candidates.insert(ctx, s1); + } + } + }); + return candidates; +} + +void update_assign_map(SigMap& assign_map, ShardedVector& sigmap_canonical_candidates, ExactCellWires& cell_wires, const SigConnKinds& sig_analysis) { + for (RTLIL::SigBit candidate : sigmap_canonical_candidates) { + RTLIL::SigBit current_canonical = assign_map(candidate); + // Resolves if two threads in build_candidates found different candidates + // for the same set + // TODO adds effort for single-threaded? + if (compare_signals(current_canonical, candidate, sig_analysis.raw_registers, sig_analysis.raw_cell_connected, cell_wires)) + assign_map.add(candidate); + } +} + +struct DeferredUpdates { + // Deferred updates to the assign_map + ShardedVector update_connections; + // Wires we should remove init from + ShardedVector initialized_wires; + DeferredUpdates(ParallelDispatchThreadPool::Subpool &subpool) : update_connections(subpool), initialized_wires(subpool) {} +}; +struct UsedSignals { + // here, "connected" means "driven or driving something" + // meanwhile, "used" means "driving something" + // sigmapped + ShardedSigPool connected; + // pre-sigmapped + ShardedSigPool raw_connected; + // sigmapped + ShardedSigPool used; + + void clear(ParallelDispatchThreadPool::Subpool &subpool) { + subpool.run([this](const ParallelDispatchThreadPool::RunCtx &ctx) { + connected.clear(ctx); + raw_connected.clear(ctx); + used.clear(ctx); + }); + } +}; + +DeferredUpdates analyse_connectivity(UsedSignals& used, SigConnKinds& sig_analysis, const AnalysisContext& actx, CleanRunContext &clean_ctx) { + DeferredUpdates deferred(actx.subpool); + ShardedSigPool::Builder conn_builder(actx.subpool); + ShardedSigPool::Builder raw_conn_builder(actx.subpool); + ShardedSigPool::Builder used_builder(actx.subpool); + + // gather the usage information for cells and update cell connections with the altered sigmap + // also gather the usage information for ports, wires with `keep` + // also gather init bits + actx.subpool.run([&deferred, &conn_builder, &raw_conn_builder, &used_builder, &sig_analysis, &actx, &clean_ctx](const ParallelDispatchThreadPool::RunCtx &ctx) { + // Parallel destruction of these sharded structures + sig_analysis.clear(ctx); + + for (int i : ctx.item_range(actx.mod->cells_size())) { + RTLIL::Cell *cell = actx.mod->cell_at(i); + for (const auto &[port, sig] : cell->connections_) { + SigSpec spec = actx.assign_map(sig); + if (spec != sig) + deferred.update_connections.insert(ctx, {cell, port, spec}); + add_spec(raw_conn_builder, ctx, spec); + add_spec(conn_builder, ctx, spec); + if (!clean_ctx.ct_all.cell_output(cell->type, port)) + add_spec(used_builder, ctx, spec); + } + } + for (int i : ctx.item_range(actx.mod->wires_size())) { + RTLIL::Wire *wire = actx.mod->wire_at(i); + if (wire->port_id > 0) { + RTLIL::SigSpec sig = RTLIL::SigSpec(wire); + add_spec(raw_conn_builder, ctx, sig); + actx.assign_map.apply(sig); + add_spec(conn_builder, ctx, sig); + if (!wire->port_input) + add_spec(used_builder, ctx, sig); + } + if (wire->get_bool_attribute(ID::keep)) { + RTLIL::SigSpec sig = RTLIL::SigSpec(wire); + actx.assign_map.apply(sig); + add_spec(conn_builder, ctx, sig); + } + auto it = wire->attributes.find(ID::init); + if (it != wire->attributes.end()) + deferred.initialized_wires.insert(ctx, wire); + } + }); + actx.subpool.run([&conn_builder, &raw_conn_builder, &used_builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + conn_builder.process(ctx); + raw_conn_builder.process(ctx); + used_builder.process(ctx); + }); + used = {conn_builder, raw_conn_builder, used_builder}; + return deferred; +} + +struct WireDeleter { + pool del_wires_queue; + ShardedVector remove_init; + ShardedVector> set_init; + ShardedVector new_connections; + ShardedVector remove_unused_bits; + ShardedVector> set_unused_bits; + WireDeleter(UsedSignals& used_sig_analysis, bool purge_mode, const AnalysisContext& actx) : + remove_init(actx.subpool), + set_init(actx.subpool), + new_connections(actx.subpool), + remove_unused_bits(actx.subpool), + set_unused_bits(actx.subpool) { + ShardedVector del_wires(actx.subpool); + actx.subpool.run([&actx, purge_mode, &del_wires, &used_sig_analysis, this](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(actx.mod->wires_size())) { + RTLIL::Wire *wire = actx.mod->wire_at(i); + SigSpec s1 = SigSpec(wire), s2 = actx.assign_map(s1); + log_assert(GetSize(s1) == GetSize(s2)); + + Const initval; + bool has_init_attribute = wire->attributes.count(ID::init); + bool init_changed = false; + if (has_init_attribute) + initval = wire->attributes.at(ID::init); + if (GetSize(initval) != GetSize(wire)) { + initval.resize(GetSize(wire), State::Sx); + init_changed = true; + } + + if (GetSize(wire) == 0) { + // delete zero-width wires, unless they are module ports + if (wire->port_id == 0) + goto delete_this_wire; + } else + if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) { + // do not delete anything with "keep" or module ports or initialized wires + } else + if (!purge_mode && check_public_name(wire->name) && (check_any(used_sig_analysis.raw_connected, s1) || check_any(used_sig_analysis.connected, s2) || s1 != s2)) { + // do not get rid of public names unless in purge mode or if the wire is entirely unused, not even aliased + } else + if (!check_any(used_sig_analysis.raw_connected, s1)) { + // delete wires that aren't used by anything directly + goto delete_this_wire; + } + + if (0) + { + delete_this_wire: + del_wires.insert(ctx, wire); + } + else + { + RTLIL::SigSig new_conn; + for (int i = 0; i < GetSize(s1); i++) + if (s1[i] != s2[i]) { + if (s2[i] == State::Sx && (initval[i] == State::S0 || initval[i] == State::S1)) { + s2[i] = initval[i]; + initval.set(i, State::Sx); + init_changed = true; + } + new_conn.first.append(s1[i]); + new_conn.second.append(s2[i]); + } + if (new_conn.first.size() > 0) + new_connections.insert(ctx, std::move(new_conn)); + if (initval.is_fully_undef()) { + if (has_init_attribute) + remove_init.insert(ctx, wire); + } else + if (init_changed) + set_init.insert(ctx, {wire, std::move(initval)}); + + std::string unused_bits; + if (!check_all(used_sig_analysis.used, s2)) { + for (int i = 0; i < GetSize(s2); i++) { + if (s2[i].wire == NULL) + continue; + SigBit b = s2[i]; + if (used_sig_analysis.used.find({b, b.hash_top().yield()}) == nullptr) { + if (!unused_bits.empty()) + unused_bits += " "; + unused_bits += stringf("%d", i); + } + } + } + if (unused_bits.empty() || wire->port_id != 0) { + if (wire->attributes.count(ID::unused_bits)) + remove_unused_bits.insert(ctx, wire); + } else { + RTLIL::Const unused_bits_const(std::move(unused_bits)); + if (wire->attributes.count(ID::unused_bits)) { + RTLIL::Const &unused_bits_attr = wire->attributes.at(ID::unused_bits); + if (unused_bits_attr != unused_bits_const) + set_unused_bits.insert(ctx, {wire, std::move(unused_bits_const)}); + } else + set_unused_bits.insert(ctx, {wire, std::move(unused_bits_const)}); + } + } + } + }); + del_wires_queue.insert(del_wires.begin(), del_wires.end()); + } + // Decide for each wire if we should be deleting it + // and fix up attributes + void commit_changes(RTLIL::Module* mod) { + for (RTLIL::Wire *wire : remove_init) + wire->attributes.erase(ID::init); + for (auto &p : set_init) + p.first->attributes[ID::init] = std::move(p.second); + for (auto &conn : new_connections) + mod->connect(std::move(conn)); + for (RTLIL::Wire *wire : remove_unused_bits) + wire->attributes.erase(ID::unused_bits); + for (auto &p : set_unused_bits) + p.first->attributes[ID::unused_bits] = std::move(p.second); + } + int delete_wires(RTLIL::Module* mod, bool verbose) { + int deleted_and_unreported = 0; + for (auto wire : del_wires_queue) { + if (ys_debug() || (check_public_name(wire->name) && verbose)) + log_debug(" removing unused non-port wire %s.\n", wire->name); + else + deleted_and_unreported++; + } + mod->remove(del_wires_queue); + return deleted_and_unreported; + } +}; + +PRIVATE_NAMESPACE_END + +YOSYS_NAMESPACE_BEGIN + +bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::Subpool &subpool, CleanRunContext &clean_ctx) +{ + // Passing actx to function == function does parallel work + // Not passing module as function argument == function does not modify module + // The above sentence signals intent; it's not enforced due to constness laundering in wire_at / cell_at + AnalysisContext actx(module, subpool); + SigConnKinds conn_kinds(clean_ctx.flags.purge, actx, clean_ctx); + + ExactCellWires cell_wires(conn_kinds.exact_cells, actx.assign_map); + // Collect sigmap representative candidates as built in parallel + // With parallel runs, this creates redundant candidates that have to resolve in update_assign_map + ShardedVector new_sigmap_rep_candidates = build_candidates(cell_wires, conn_kinds, actx); + + // Cache all the cell_wires results that we might possible need. This avoids the results + // changing when we update `assign_map` below. + cell_wires.cache_all(new_sigmap_rep_candidates); + // Modify assign_map to reflect the connectivity we want, not the one we have + // this changes representative selection in assign_map + update_assign_map(actx.assign_map, new_sigmap_rep_candidates, cell_wires, conn_kinds); + + // Remove all wire-wire connections + module->connections_.clear(); + + UsedSignals used; + DeferredUpdates deferred = analyse_connectivity(used, conn_kinds, actx, clean_ctx); + fixup_cell_ports(deferred.update_connections); + // Rip up and re-apply init attributes onto representative wires with x-bits + // in place of unset init bits + consume_inits(deferred.initialized_wires, actx.assign_map).apply_normalised_inits(); + + WireDeleter deleter(used, clean_ctx.flags.purge, actx); + + used.clear(subpool); + + deleter.commit_changes(module); + int deleted_and_unreported = deleter.delete_wires(module, clean_ctx.flags.verbose); + int deleted_total = GetSize(deleter.del_wires_queue); + + clean_ctx.stats.count_rm_wires += deleted_total; + + if (clean_ctx.flags.verbose && deleted_and_unreported) + log_debug(" removed %d unused temporary wires.\n", deleted_and_unreported); + + if (deleted_total) + module->design->scratchpad_set_bool("opt.did_something", true); + + return deleted_total != 0; +} + +YOSYS_NAMESPACE_END diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 04bcec835..90ace69e5 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -26,6 +26,7 @@ #include "kernel/sigtools.h" #include "kernel/ffinit.h" #include "kernel/ff.h" +#include "kernel/pattern.h" #include "passes/techmap/simplemap.h" #include #include @@ -45,34 +46,80 @@ struct OptDffOptions struct OptDffWorker { const OptDffOptions &opt; - Module *module; + + // Cell to port bit index typedef std::pair cell_int_t; - SigMap sigmap; + + SigMap sigmap; // Signal aliasing FfInitVals initvals; - dict bitusers; - dict bit2mux; + dict bitusers; // Signal sink count + dict bit2mux; // Signal bit to driving MUX - typedef std::map pattern_t; - typedef std::set patterns_t; - typedef std::pair ctrl_t; - typedef std::set ctrls_t; - - // Used as a queue. std::vector dff_cells; - OptDffWorker(const OptDffOptions &opt, Module *mod) : opt(opt), module(mod), sigmap(mod), initvals(&sigmap, mod) { + bool is_active(SigBit sig, bool pol) const { + return sig == (pol ? State::S1 : State::S0); + } + + bool is_inactive(SigBit sig, bool pol) const { + return sig == (pol ? State::S0 : State::S1); + } + + bool is_always_active(SigBit sig, bool pol) const { + return is_active(sig, pol) || (!opt.keepdc && sig == State::Sx); + } + + bool is_always_inactive(SigBit sig, bool pol) const { + return is_inactive(sig, pol) || (!opt.keepdc && sig == State::Sx); + } + + SigSpec create_not(SigSpec a, bool is_fine) { + if (is_fine) + return module->NotGate(NEW_ID, a); + else + return module->Not(NEW_ID, a); + } + + SigSpec create_and(SigSpec a, SigSpec b, bool is_fine) { + if (is_fine) + return module->AndGate(NEW_ID, a, b); + else + return module->And(NEW_ID, a, b); + } + + void create_mux_to_output(SigSpec a, SigSpec b, SigSpec sel, SigSpec y, bool pol, bool is_fine) { + if (is_fine) { + if (pol) + module->addMuxGate(NEW_ID, a, b, sel, y); + else + module->addMuxGate(NEW_ID, b, a, sel, y); + } else { + if (pol) + module->addMux(NEW_ID, a, b, sel, y); + else + module->addMux(NEW_ID, b, a, sel, y); + } + } + + void maybe_simplemap(Cell *c, bool make_gates) { + if (make_gates) { + simplemap(module, c); + module->remove(c); + } + } + + OptDffWorker(const OptDffOptions &opt, Module *mod) + : opt(opt), module(mod), sigmap(mod), initvals(&sigmap, mod) + { // Gathering two kinds of information here for every sigmapped SigBit: - // - // - bitusers: how many users it has (muxes will only be merged into FFs if this is 1, making the FF the only user) + // - bitusers: how many users it has (muxes will only be merged into FFs if the FF is the only user) // - bit2mux: the mux cell and bit index that drives it, if any for (auto wire : module->wires()) - { if (wire->port_output) for (auto bit : sigmap(wire)) bitusers[bit]++; - } for (auto cell : module->cells()) { if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) { @@ -83,39 +130,36 @@ struct OptDffWorker for (auto conn : cell->connections()) { bool is_output = cell->output(conn.first); - if (!is_output || !cell->known()) { + if (!is_output || !cell->known()) for (auto bit : sigmap(conn.second)) bitusers[bit]++; - } } if (module->design->selected(module, cell) && cell->is_builtin_ff()) dff_cells.push_back(cell); } - } State combine_const(State a, State b) { - if (a == State::Sx && !opt.keepdc) - return b; - if (b == State::Sx && !opt.keepdc) - return a; - if (a == b) - return a; + // Combine constants: returns Sm if values conflict + if (a == State::Sx && !opt.keepdc) return b; + if (b == State::Sx && !opt.keepdc) return a; + if (a == b) return a; return State::Sm; } patterns_t find_muxtree_feedback_patterns(RTLIL::SigBit d, RTLIL::SigBit q, pattern_t path) { + // Find feedback paths D->Q through mux tree, replacing found paths with Sx patterns_t ret; if (d == q) { ret.insert(path); - return ret; + return ret; // Feedback found } if (bit2mux.count(d) == 0 || bitusers[d] > 1) - return ret; + return ret; // D not driven by MUX / MUX drives multiple loads cell_int_t mbit = bit2mux.at(d); RTLIL::SigSpec sig_a = sigmap(mbit.first->getPort(ID::A)); @@ -123,11 +167,10 @@ struct OptDffWorker RTLIL::SigSpec sig_s = sigmap(mbit.first->getPort(ID::S)); int width = GetSize(sig_a), index = mbit.second; - for (int i = 0; i < GetSize(sig_s); i++) - if (path.count(sig_s[i]) && path.at(sig_s[i])) - { + // Traverse MUX tree + for (int i = 0; i < GetSize(sig_s); i++) { + if (path.count(sig_s[i]) && path.at(sig_s[i])) { ret = find_muxtree_feedback_patterns(sig_b[i*width + index], q, path); - if (sig_b[i*width + index] == q) { RTLIL::SigSpec s = mbit.first->getPort(ID::B); s[i*width + index] = RTLIL::Sx; @@ -136,18 +179,19 @@ struct OptDffWorker return ret; } + } + // Specific path wasn't forced, explore the 0 branch pattern_t path_else = path; - - for (int i = 0; i < GetSize(sig_s); i++) - { + for (int i = 0; i < GetSize(sig_s); i++) { if (path.count(sig_s[i])) continue; pattern_t path_this = path; - path_else[sig_s[i]] = false; - path_this[sig_s[i]] = true; + path_else[sig_s[i]] = false; // Assume S=0 for 'else' path + path_this[sig_s[i]] = true; // Assume S=1 for 'this' path + // Selected when S=1 for (auto &pat : find_muxtree_feedback_patterns(sig_b[i*width + index], q, path_this)) ret.insert(pat); @@ -158,6 +202,7 @@ struct OptDffWorker } } + // Selected when S=0 for (auto &pat : find_muxtree_feedback_patterns(sig_a[index], q, path_else)) ret.insert(pat); @@ -170,75 +215,17 @@ struct OptDffWorker return ret; } - void simplify_patterns(patterns_t& patterns) - { - auto new_patterns = patterns; - auto find_comp = [](const auto& left, const auto& right) -> std::optional { - std::optional ret; - for (const auto &pt: left) - if (right.count(pt.first) == 0) - return {}; - else if (right.at(pt.first) == pt.second) - continue; - else - if (ret) - return {}; - else - ret = pt.first; - return ret; - }; - - // remove complimentary patterns - bool optimized; - do { - optimized = false; - for (auto i = patterns.begin(); i != patterns.end(); i++) { - for (auto j = std::next(i, 1); j != patterns.end(); j++) { - const auto& left = (GetSize(*j) <= GetSize(*i)) ? *j : *i; - auto right = (GetSize(*i) < GetSize(*j)) ? *j : *i; - - const auto complimentary_var = find_comp(left, right); - - if (complimentary_var && new_patterns.count(right)) { - new_patterns.erase(right); - right.erase(complimentary_var.value()); - new_patterns.insert(right); - optimized = true; - } - } - } - patterns = new_patterns; - } while(optimized); - - // remove redundant patterns - for (auto i = patterns.begin(); i != patterns.end(); ++i) { - for (auto j = std::next(i, 1); j != patterns.end(); ++j) { - const auto& left = (GetSize(*j) <= GetSize(*i)) ? *j : *i; - const auto& right = (GetSize(*i) < GetSize(*j)) ? *j : *i; - - bool redundant = true; - - for (const auto& pt : left) - if (right.count(pt.first) == 0 || right.at(pt.first) != pt.second) - redundant = false; - if (redundant) - new_patterns.erase(right); - } - } - patterns = std::move(new_patterns); - } - ctrl_t make_patterns_logic(const patterns_t &patterns, const ctrls_t &ctrls, bool make_gates) { - if (patterns.empty() && GetSize(ctrls) == 1) { + if (patterns.empty() && GetSize(ctrls) == 1) return *ctrls.begin(); - } RTLIL::SigSpec or_input; - for (auto pat : patterns) - { + // Build logic for each feedback pattern + for (auto pat : patterns) { RTLIL::SigSpec s1, s2; + for (auto it : pat) { s1.append(it.first); s2.append(it.second); @@ -246,81 +233,500 @@ struct OptDffWorker RTLIL::SigSpec y = module->addWire(NEW_ID); RTLIL::Cell *c = module->addNe(NEW_ID, s1, s2, y); - - if (make_gates) { - simplemap(module, c); - module->remove(c); - } - + maybe_simplemap(c, make_gates); or_input.append(y); } + + // Add existing control signals for (auto item : ctrls) { if (item.second) or_input.append(item.first); - else if (make_gates) - or_input.append(module->NotGate(NEW_ID, item.first)); else - or_input.append(module->Not(NEW_ID, item.first)); + or_input.append(create_not(item.first, make_gates)); } - if (GetSize(or_input) == 0) - return ctrl_t(State::S1, true); - - if (GetSize(or_input) == 1) - return ctrl_t(or_input, true); + if (GetSize(or_input) == 0) return ctrl_t(State::S1, true); + if (GetSize(or_input) == 1) return ctrl_t(or_input, true); RTLIL::SigSpec y = module->addWire(NEW_ID); RTLIL::Cell *c = module->addReduceAnd(NEW_ID, or_input, y); - - if (make_gates) { - simplemap(module, c); - module->remove(c); - } - + maybe_simplemap(c, make_gates); return ctrl_t(y, true); } ctrl_t combine_resets(const ctrls_t &ctrls, bool make_gates) { - if (GetSize(ctrls) == 1) { + if (GetSize(ctrls) == 1) return *ctrls.begin(); - } - - RTLIL::SigSpec or_input; bool final_pol = false; - for (auto item : ctrls) { + for (auto item : ctrls) if (item.second) final_pol = true; - } + RTLIL::SigSpec or_input; for (auto item : ctrls) { if (item.second == final_pol) or_input.append(item.first); - else if (make_gates) - or_input.append(module->NotGate(NEW_ID, item.first)); else - or_input.append(module->Not(NEW_ID, item.first)); + or_input.append(create_not(item.first, make_gates)); } RTLIL::SigSpec y = module->addWire(NEW_ID); - RTLIL::Cell *c = final_pol ? module->addReduceOr(NEW_ID, or_input, y) : module->addReduceAnd(NEW_ID, or_input, y); - - if (make_gates) { - simplemap(module, c); - module->remove(c); - } - + RTLIL::Cell *c = final_pol + ? module->addReduceOr(NEW_ID, or_input, y) + : module->addReduceAnd(NEW_ID, or_input, y); + maybe_simplemap(c, make_gates); return ctrl_t(y, final_pol); } - bool run() { - // We have all the information we need, and the list of FFs to process as well. Do it. + bool signal_all_same(const SigSpec &sig) { + for (int i = 1; i < GetSize(sig); i++) + if (sig[i] != sig[0]) + return false; + return true; + } + + bool optimize_sr(FfData &ff, Cell *cell, bool &changed) + { + // Removes SR if CLR/SET are always active + // Converts SR to ARST if one pin is never active + // Converts SR to ARST if SET/CLR are inverses of eachother + bool sr_removed = false; + std::vector keep_bits; + + // Check for constant Set/Clear inputs + for (int i = 0; i < ff.width; i++) { + if (is_always_active(ff.sig_clr[i], ff.pol_clr)) { + initvals.remove_init(ff.sig_q[i]); + module->connect(ff.sig_q[i], State::S0); + log("Handling always-active CLR at position %d on %s (%s) from module %s (changing to const driver).\n", + i, log_id(cell), log_id(cell->type), log_id(module)); + sr_removed = true; + } else if (is_always_active(ff.sig_set[i], ff.pol_set)) { + initvals.remove_init(ff.sig_q[i]); + if (!ff.pol_clr) + module->connect(ff.sig_q[i], ff.sig_clr[i]); + else if (ff.is_fine) + module->addNotGate(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); + else + module->addNot(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); + log("Handling always-active SET at position %d on %s (%s) from module %s (changing to combinatorial circuit).\n", + i, log_id(cell), log_id(cell->type), log_id(module)); + sr_removed = true; + } else { + keep_bits.push_back(i); + } + } + + if (sr_removed) { + if (keep_bits.empty()) { + module->remove(cell); + return true; // FF fully removed + } + ff = ff.slice(keep_bits); + ff.cell = cell; + changed = true; + } + + // Try SR -> ARST conversion + bool clr_inactive = ff.pol_clr ? ff.sig_clr.is_fully_zero() : ff.sig_clr.is_fully_ones(); + bool set_inactive = ff.pol_set ? ff.sig_set.is_fully_zero() : ff.sig_set.is_fully_ones(); + + if (clr_inactive && signal_all_same(ff.sig_set)) { + log("Removing never-active CLR on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_sr = false; + ff.has_arst = true; + ff.pol_arst = ff.pol_set; + ff.sig_arst = ff.sig_set[0]; + ff.val_arst = Const(State::S1, ff.width); + changed = true; + } else if (set_inactive && signal_all_same(ff.sig_clr)) { + log("Removing never-active SET on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_sr = false; + ff.has_arst = true; + ff.pol_arst = ff.pol_clr; + ff.sig_arst = ff.sig_clr[0]; + ff.val_arst = Const(State::S0, ff.width); + changed = true; + } else if (ff.pol_clr == ff.pol_set) { + State val_neutral = ff.pol_set ? State::S0 : State::S1; + SigBit sig_arst = (ff.sig_clr[0] == val_neutral) ? ff.sig_set[0] : ff.sig_clr[0]; + + bool failed = false; + Const::Builder val_arst_builder(ff.width); + for (int i = 0; i < ff.width; i++) { + if (ff.sig_clr[i] == sig_arst && ff.sig_set[i] == val_neutral) + val_arst_builder.push_back(State::S0); + else if (ff.sig_set[i] == sig_arst && ff.sig_clr[i] == val_neutral) + val_arst_builder.push_back(State::S1); + else { + failed = true; + break; + } + } + + if (!failed) { + log("Converting CLR/SET to ARST on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_sr = false; + ff.has_arst = true; + ff.val_arst = val_arst_builder.build(); + ff.sig_arst = sig_arst; + ff.pol_arst = ff.pol_clr; + changed = true; + } + } + + return false; + } + + bool optimize_aload(FfData &ff, Cell *cell, bool &changed) + { + // Removes unused Async Load + // Converts constant Async Load to ARST + if (is_always_inactive(ff.sig_aload, ff.pol_aload)) { + log("Removing never-active async load on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_aload = false; + changed = true; + return false; + } + + if (is_active(ff.sig_aload, ff.pol_aload)) { + // ALOAD always active + log("Handling always-active async load on %s (%s) from module %s (changing to combinatorial circuit).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.remove(); + + if (ff.has_sr) { + SigSpec tmp; + if (ff.is_fine) { + tmp = ff.pol_set + ? module->MuxGate(NEW_ID, ff.sig_ad, State::S1, ff.sig_set) + : module->MuxGate(NEW_ID, State::S1, ff.sig_ad, ff.sig_set); + + if (ff.pol_clr) + module->addMuxGate(NEW_ID, tmp, State::S0, ff.sig_clr, ff.sig_q); + else + module->addMuxGate(NEW_ID, State::S0, tmp, ff.sig_clr, ff.sig_q); + } else { + tmp = ff.pol_set + ? module->Or(NEW_ID, ff.sig_ad, ff.sig_set) + : module->Or(NEW_ID, ff.sig_ad, module->Not(NEW_ID, ff.sig_set)); + + if (ff.pol_clr) + module->addAnd(NEW_ID, tmp, module->Not(NEW_ID, ff.sig_clr), ff.sig_q); + else + module->addAnd(NEW_ID, tmp, ff.sig_clr, ff.sig_q); + } + } else if (ff.has_arst) { + create_mux_to_output(ff.sig_ad, ff.val_arst, ff.sig_arst, ff.sig_q, ff.pol_arst, ff.is_fine); + } else { + module->connect(ff.sig_q, ff.sig_ad); + } + return true; + } + + // AD is constant -> ARST + if (ff.sig_ad.is_fully_const() && !ff.has_arst && !ff.has_sr) { + log("Changing const-value async load to async reset on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_arst = true; + ff.has_aload = false; + ff.sig_arst = ff.sig_aload; + ff.pol_arst = ff.pol_aload; + ff.val_arst = ff.sig_ad.as_const(); + changed = true; + } + + return false; + } + + bool optimize_arst(FfData &ff, Cell *cell, bool &changed) + { + // Removes ARST if never active or replaces FF if always active + if (is_inactive(ff.sig_arst, ff.pol_arst)) { + log("Removing never-active ARST on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_arst = false; + changed = true; + } else if (is_always_active(ff.sig_arst, ff.pol_arst)) { + log("Handling always-active ARST on %s (%s) from module %s (changing to const driver).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.remove(); + module->connect(ff.sig_q, ff.val_arst); + return true; + } + + return false; + } + + void optimize_srst(FfData &ff, Cell *cell, bool &changed) + { + // Removes SRST if never active or forces D to reset value if always active + if (is_inactive(ff.sig_srst, ff.pol_srst)) { + log("Removing never-active SRST on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_srst = false; + changed = true; + } else if (is_always_active(ff.sig_srst, ff.pol_srst)) { + log("Handling always-active SRST on %s (%s) from module %s (changing to const D).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_srst = false; + if (!ff.ce_over_srst) + ff.has_ce = false; + + ff.sig_d = ff.val_srst; + changed = true; + } + } + + void optimize_ce(FfData &ff, Cell *cell, bool &changed) + { + if (is_always_inactive(ff.sig_ce, ff.pol_ce)) { + if (ff.has_srst && !ff.ce_over_srst) { + log("Handling never-active EN on %s (%s) from module %s (connecting SRST instead).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.pol_ce = ff.pol_srst; + ff.sig_ce = ff.sig_srst; + ff.has_srst = false; + ff.sig_d = ff.val_srst; + changed = true; + } else if (!opt.keepdc || ff.val_init.is_fully_def()) { + log("Handling never-active EN on %s (%s) from module %s (removing D path).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_ce = ff.has_clk = ff.has_srst = false; + changed = true; + } else { + ff.sig_d = ff.sig_q; + ff.has_ce = ff.has_srst = false; + changed = true; + } + } else if (is_active(ff.sig_ce, ff.pol_ce)) { + log("Removing always-active EN on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_ce = false; + changed = true; + } + } + + void optimize_const_clk(FfData &ff, Cell *cell, bool &changed) + { + if (!opt.keepdc || ff.val_init.is_fully_def()) { + log("Handling const CLK on %s (%s) from module %s (removing D path).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_ce = ff.has_clk = ff.has_srst = false; + changed = true; + } else if (ff.has_ce || ff.has_srst || ff.sig_d != ff.sig_q) { + ff.sig_d = ff.sig_q; + ff.has_ce = ff.has_srst = false; + changed = true; + } + } + + void optimize_d_equals_q(FfData &ff, Cell *cell, bool &changed) + { + // Detect feedback loops where D is hardwired to Q + if (ff.has_clk && ff.has_srst) { + log("Handling D = Q on %s (%s) from module %s (conecting SRST instead).\n", + log_id(cell), log_id(cell->type), log_id(module)); + if (ff.has_ce && ff.ce_over_srst) { + SigSpec ce = ff.pol_ce ? ff.sig_ce : create_not(ff.sig_ce, ff.is_fine); + SigSpec srst = ff.pol_srst ? ff.sig_srst : create_not(ff.sig_srst, ff.is_fine); + ff.sig_ce = create_and(ce, srst, ff.is_fine); + ff.pol_ce = true; + } else { + ff.pol_ce = ff.pol_srst; + ff.sig_ce = ff.sig_srst; + } + + ff.has_ce = true; + ff.has_srst = false; + ff.sig_d = ff.val_srst; + changed = true; + } else if (!opt.keepdc || ff.val_init.is_fully_def()) { + log("Handling D = Q on %s (%s) from module %s (removing D path).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_gclk = ff.has_clk = ff.has_ce = false; + changed = true; + } + } + + bool try_merge_srst(FfData &ff, Cell *cell, bool &changed) + { + std::map> groups; + std::vector remaining_indices; + Const::Builder val_srst_builder(ff.width); + + for (int i = 0; i < ff.width; i++) { + ctrls_t resets; + State reset_val = ff.has_srst ? ff.val_srst[i] : State::Sx; + + while (bit2mux.count(ff.sig_d[i]) && bitusers[ff.sig_d[i]] == 1) { + cell_int_t mbit = bit2mux.at(ff.sig_d[i]); + if (GetSize(mbit.first->getPort(ID::S)) != 1) + break; + + SigBit s = mbit.first->getPort(ID::S); + SigBit a = mbit.first->getPort(ID::A)[mbit.second]; + SigBit b = mbit.first->getPort(ID::B)[mbit.second]; + + if ((a == State::S0 || a == State::S1) && (b == State::S0 || b == State::S1)) + break; + + bool b_const = (b == State::S0 || b == State::S1); + bool a_const = (a == State::S0 || a == State::S1); + + if (b_const && (b == reset_val || reset_val == State::Sx) && a != ff.sig_q[i]) { + reset_val = b.data; + resets.insert(ctrl_t(s, true)); + ff.sig_d[i] = a; + } else if (a_const && (a == reset_val || reset_val == State::Sx) && b != ff.sig_q[i]) { + reset_val = a.data; + resets.insert(ctrl_t(s, false)); + ff.sig_d[i] = b; + } else { + break; + } + } + + if (!resets.empty()) { + if (ff.has_srst) + resets.insert(ctrl_t(ff.sig_srst, ff.pol_srst)); + + groups[resets].push_back(i); + } else { + remaining_indices.push_back(i); + } + + val_srst_builder.push_back(reset_val); + } + + Const val_srst = val_srst_builder.build(); + + for (auto &it : groups) { + FfData new_ff = ff.slice(it.second); + Const::Builder new_val_srst_builder(new_ff.width); + for (int i = 0; i < new_ff.width; i++) + new_val_srst_builder.push_back(val_srst[it.second[i]]); + + new_ff.val_srst = new_val_srst_builder.build(); + + ctrl_t srst = combine_resets(it.first, ff.is_fine); + new_ff.has_srst = true; + new_ff.sig_srst = srst.first; + new_ff.pol_srst = srst.second; + if (new_ff.has_ce) + new_ff.ce_over_srst = true; + + Cell *new_cell = new_ff.emit(); + if (new_cell) + dff_cells.push_back(new_cell); + + log("Adding SRST signal on %s (%s) from module %s (D = %s, Q = %s, rval = %s).\n", + log_id(cell), log_id(cell->type), log_id(module), + log_signal(new_ff.sig_d), log_signal(new_ff.sig_q), log_signal(new_ff.val_srst)); + } + + if (remaining_indices.empty()) { + module->remove(cell); + return true; + } + + if (GetSize(remaining_indices) != ff.width) { + ff = ff.slice(remaining_indices); + ff.cell = cell; + changed = true; + } + + return false; + } + + bool try_merge_ce(FfData &ff, Cell *cell, bool &changed) + { + std::map, std::vector> groups; + std::vector remaining_indices; + + for (int i = 0; i < ff.width; i++) { + ctrls_t enables; + + while (bit2mux.count(ff.sig_d[i]) && bitusers[ff.sig_d[i]] == 1) { + cell_int_t mbit = bit2mux.at(ff.sig_d[i]); + if (GetSize(mbit.first->getPort(ID::S)) != 1) + break; + + SigBit s = mbit.first->getPort(ID::S); + SigBit a = mbit.first->getPort(ID::A)[mbit.second]; + SigBit b = mbit.first->getPort(ID::B)[mbit.second]; + + if (a == ff.sig_q[i]) { + enables.insert(ctrl_t(s, true)); + ff.sig_d[i] = b; + } else if (b == ff.sig_q[i]) { + enables.insert(ctrl_t(s, false)); + ff.sig_d[i] = a; + } else { + break; + } + } + + patterns_t patterns; + if (!opt.simple_dffe) + patterns = find_muxtree_feedback_patterns(ff.sig_d[i], ff.sig_q[i], pattern_t()); + + if (!patterns.empty() || !enables.empty()) { + if (ff.has_ce) + enables.insert(ctrl_t(ff.sig_ce, ff.pol_ce)); + simplify_patterns(patterns); + groups[std::make_pair(patterns, enables)].push_back(i); + } else { + remaining_indices.push_back(i); + } + } + + for (auto &it : groups) { + FfData new_ff = ff.slice(it.second); + ctrl_t en = make_patterns_logic(it.first.first, it.first.second, ff.is_fine); + + new_ff.has_ce = true; + new_ff.sig_ce = en.first; + new_ff.pol_ce = en.second; + new_ff.ce_over_srst = false; + + Cell *new_cell = new_ff.emit(); + if (new_cell) + dff_cells.push_back(new_cell); + + log("Adding EN signal on %s (%s) from module %s (D = %s, Q = %s).\n", + log_id(cell), log_id(cell->type), log_id(module), + log_signal(new_ff.sig_d), log_signal(new_ff.sig_q)); + } + + if (remaining_indices.empty()) { + module->remove(cell); + return true; + } + + if (GetSize(remaining_indices) != ff.width) { + ff = ff.slice(remaining_indices); + ff.cell = cell; + changed = true; + } + + return false; + } + + bool run() + { bool did_something = false; + while (!dff_cells.empty()) { Cell *cell = dff_cells.back(); dff_cells.pop_back(); - // Break down the FF into pieces. + FfData ff(&initvals, cell); bool changed = false; @@ -330,301 +736,35 @@ struct OptDffWorker continue; } - if (ff.has_sr) { - bool sr_removed = false; - std::vector keep_bits; - // Check for always-active S/R bits. - for (int i = 0; i < ff.width; i++) { - if (ff.sig_clr[i] == (ff.pol_clr ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_clr[i] == State::Sx)) { - // Always-active clear — connect Q bit to 0. - initvals.remove_init(ff.sig_q[i]); - module->connect(ff.sig_q[i], State::S0); - log("Handling always-active CLR at position %d on %s (%s) from module %s (changing to const driver).\n", - i, log_id(cell), log_id(cell->type), log_id(module)); - sr_removed = true; - } else if (ff.sig_set[i] == (ff.pol_set ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_set[i] == State::Sx)) { - // Always-active set — connect Q bit to 1 if clear inactive, 0 if reset active. - initvals.remove_init(ff.sig_q[i]); - if (!ff.pol_clr) { - module->connect(ff.sig_q[i], ff.sig_clr[i]); - } else if (ff.is_fine) { - module->addNotGate(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); - } else { - module->addNot(NEW_ID, ff.sig_clr[i], ff.sig_q[i]); - } - log("Handling always-active SET at position %d on %s (%s) from module %s (changing to combinatorial circuit).\n", - i, log_id(cell), log_id(cell->type), log_id(module)); - sr_removed = true; - } else { - keep_bits.push_back(i); - } - } - if (sr_removed) { - if (keep_bits.empty()) { - module->remove(cell); - did_something = true; - continue; - } - ff = ff.slice(keep_bits); - ff.cell = cell; - changed = true; - } - - if (ff.pol_clr ? ff.sig_clr.is_fully_zero() : ff.sig_clr.is_fully_ones()) { - // CLR is useless, try to kill it. - bool failed = false; - for (int i = 0; i < ff.width; i++) - if (ff.sig_set[i] != ff.sig_set[0]) - failed = true; - if (!failed) { - log("Removing never-active CLR on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_sr = false; - ff.has_arst = true; - ff.pol_arst = ff.pol_set; - ff.sig_arst = ff.sig_set[0]; - ff.val_arst = Const(State::S1, ff.width); - changed = true; - } - } else if (ff.pol_set ? ff.sig_set.is_fully_zero() : ff.sig_set.is_fully_ones()) { - // SET is useless, try to kill it. - bool failed = false; - for (int i = 0; i < ff.width; i++) - if (ff.sig_clr[i] != ff.sig_clr[0]) - failed = true; - if (!failed) { - log("Removing never-active SET on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_sr = false; - ff.has_arst = true; - ff.pol_arst = ff.pol_clr; - ff.sig_arst = ff.sig_clr[0]; - ff.val_arst = Const(State::S0, ff.width); - changed = true; - } - } else if (ff.pol_clr == ff.pol_set) { - // Try a more complex conversion to plain async reset. - State val_neutral = ff.pol_set ? State::S0 : State::S1; - SigBit sig_arst; - if (ff.sig_clr[0] == val_neutral) - sig_arst = ff.sig_set[0]; - else - sig_arst = ff.sig_clr[0]; - bool failed = false; - Const::Builder val_arst_builder(ff.width); - for (int i = 0; i < ff.width; i++) { - if (ff.sig_clr[i] == sig_arst && ff.sig_set[i] == val_neutral) - val_arst_builder.push_back(State::S0); - else if (ff.sig_set[i] == sig_arst && ff.sig_clr[i] == val_neutral) - val_arst_builder.push_back(State::S1); - else { - failed = true; - break; - } - } - if (!failed) { - log("Converting CLR/SET to ARST on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_sr = false; - ff.has_arst = true; - ff.val_arst = val_arst_builder.build(); - ff.sig_arst = sig_arst; - ff.pol_arst = ff.pol_clr; - changed = true; - } - } + // Async control signal opt + if (ff.has_sr && optimize_sr(ff, cell, changed)) { + did_something = true; + continue; } - if (ff.has_aload) { - if (ff.sig_aload == (ff.pol_aload ? State::S0 : State::S1) || (!opt.keepdc && ff.sig_aload == State::Sx)) { - // Always-inactive enable — remove. - log("Removing never-active async load on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_aload = false; - changed = true; - } else if (ff.sig_aload == (ff.pol_aload ? State::S1 : State::S0)) { - // Always-active enable. Make a comb circuit, nuke the FF/latch. - log("Handling always-active async load on %s (%s) from module %s (changing to combinatorial circuit).\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.remove(); - if (ff.has_sr) { - SigSpec tmp; - if (ff.is_fine) { - if (ff.pol_set) - tmp = module->MuxGate(NEW_ID, ff.sig_ad, State::S1, ff.sig_set); - else - tmp = module->MuxGate(NEW_ID, State::S1, ff.sig_ad, ff.sig_set); - if (ff.pol_clr) - module->addMuxGate(NEW_ID, tmp, State::S0, ff.sig_clr, ff.sig_q); - else - module->addMuxGate(NEW_ID, State::S0, tmp, ff.sig_clr, ff.sig_q); - } else { - if (ff.pol_set) - tmp = module->Or(NEW_ID, ff.sig_ad, ff.sig_set); - else - tmp = module->Or(NEW_ID, ff.sig_ad, module->Not(NEW_ID, ff.sig_set)); - if (ff.pol_clr) - module->addAnd(NEW_ID, tmp, module->Not(NEW_ID, ff.sig_clr), ff.sig_q); - else - module->addAnd(NEW_ID, tmp, ff.sig_clr, ff.sig_q); - } - } else if (ff.has_arst) { - if (ff.is_fine) { - if (ff.pol_arst) - module->addMuxGate(NEW_ID, ff.sig_ad, ff.val_arst[0], ff.sig_arst, ff.sig_q); - else - module->addMuxGate(NEW_ID, ff.val_arst[0], ff.sig_ad, ff.sig_arst, ff.sig_q); - } else { - if (ff.pol_arst) - module->addMux(NEW_ID, ff.sig_ad, ff.val_arst, ff.sig_arst, ff.sig_q); - else - module->addMux(NEW_ID, ff.val_arst, ff.sig_ad, ff.sig_arst, ff.sig_q); - } - } else { - module->connect(ff.sig_q, ff.sig_ad); - } - did_something = true; - continue; - } else if (ff.sig_ad.is_fully_const() && !ff.has_arst && !ff.has_sr) { - log("Changing const-value async load to async reset on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_arst = true; - ff.has_aload = false; - ff.sig_arst = ff.sig_aload; - ff.pol_arst = ff.pol_aload; - ff.val_arst = ff.sig_ad.as_const(); - changed = true; - } + if (ff.has_aload && optimize_aload(ff, cell, changed)) { + did_something = true; + continue; } - if (ff.has_arst) { - if (ff.sig_arst == (ff.pol_arst ? State::S0 : State::S1)) { - // Always-inactive reset — remove. - log("Removing never-active ARST on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_arst = false; - changed = true; - } else if (ff.sig_arst == (ff.pol_arst ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_arst == State::Sx)) { - // Always-active async reset — change to const driver. - log("Handling always-active ARST on %s (%s) from module %s (changing to const driver).\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.remove(); - module->connect(ff.sig_q, ff.val_arst); - did_something = true; - continue; - } + if (ff.has_arst && optimize_arst(ff, cell, changed)) { + did_something = true; + continue; } - if (ff.has_srst) { - if (ff.sig_srst == (ff.pol_srst ? State::S0 : State::S1)) { - // Always-inactive reset — remove. - log("Removing never-active SRST on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_srst = false; - changed = true; - } else if (ff.sig_srst == (ff.pol_srst ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_srst == State::Sx)) { - // Always-active sync reset — connect to D instead. - log("Handling always-active SRST on %s (%s) from module %s (changing to const D).\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_srst = false; - if (!ff.ce_over_srst) - ff.has_ce = false; - ff.sig_d = ff.val_srst; - changed = true; - } - } + // Sync control signal opt + if (ff.has_srst) + optimize_srst(ff, cell, changed); - if (ff.has_ce) { - if (ff.sig_ce == (ff.pol_ce ? State::S0 : State::S1) || (!opt.keepdc && ff.sig_ce == State::Sx)) { - // Always-inactive enable — remove. - if (ff.has_srst && !ff.ce_over_srst) { - log("Handling never-active EN on %s (%s) from module %s (connecting SRST instead).\n", - log_id(cell), log_id(cell->type), log_id(module)); - // FF with sync reset — connect the sync reset to D instead. - ff.pol_ce = ff.pol_srst; - ff.sig_ce = ff.sig_srst; - ff.has_srst = false; - ff.sig_d = ff.val_srst; - changed = true; - } else if (!opt.keepdc || ff.val_init.is_fully_def()) { - log("Handling never-active EN on %s (%s) from module %s (removing D path).\n", - log_id(cell), log_id(cell->type), log_id(module)); - // The D input path is effectively useless, so remove it (this will be a D latch, SR latch, or a const driver). - ff.has_ce = ff.has_clk = ff.has_srst = false; - changed = true; - } else { - // We need to keep the undefined initival around as such - ff.sig_d = ff.sig_q; - ff.has_ce = ff.has_srst = false; - changed = true; - } - } else if (ff.sig_ce == (ff.pol_ce ? State::S1 : State::S0)) { - // Always-active enable. Just remove it. - // For FF, just remove the useless enable. - log("Removing always-active EN on %s (%s) from module %s.\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_ce = false; - changed = true; - } - } + if (ff.has_ce) + optimize_ce(ff, cell, changed); - if (ff.has_clk && ff.sig_clk.is_fully_const()) { - if (!opt.keepdc || ff.val_init.is_fully_def()) { - // Const clock — the D input path is effectively useless, so remove it (this will be a D latch, SR latch, or a const driver). - log("Handling const CLK on %s (%s) from module %s (removing D path).\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_ce = ff.has_clk = ff.has_srst = false; - changed = true; - } else { - // Const clock, but we need to keep the undefined initval around as such - if (ff.has_ce || ff.has_srst || ff.sig_d != ff.sig_q) { - ff.sig_d = ff.sig_q; - ff.has_ce = ff.has_srst = false; - changed = true; - } - } - } + if (ff.has_clk && ff.sig_clk.is_fully_const()) + optimize_const_clk(ff, cell, changed); - if ((ff.has_clk || ff.has_gclk) && ff.sig_d == ff.sig_q) { - // Q wrapped back to D, can be removed. - if (ff.has_clk && ff.has_srst) { - // FF with sync reset — connect the sync reset to D instead. - log("Handling D = Q on %s (%s) from module %s (conecting SRST instead).\n", - log_id(cell), log_id(cell->type), log_id(module)); - if (ff.has_ce && ff.ce_over_srst) { - if (!ff.pol_ce) { - if (ff.is_fine) - ff.sig_ce = module->NotGate(NEW_ID, ff.sig_ce); - else - ff.sig_ce = module->Not(NEW_ID, ff.sig_ce); - } - if (!ff.pol_srst) { - if (ff.is_fine) - ff.sig_srst = module->NotGate(NEW_ID, ff.sig_srst); - else - ff.sig_srst = module->Not(NEW_ID, ff.sig_srst); - } - if (ff.is_fine) - ff.sig_ce = module->AndGate(NEW_ID, ff.sig_ce, ff.sig_srst); - else - ff.sig_ce = module->And(NEW_ID, ff.sig_ce, ff.sig_srst); - ff.pol_ce = true; - } else { - ff.pol_ce = ff.pol_srst; - ff.sig_ce = ff.sig_srst; - } - ff.has_ce = true; - ff.has_srst = false; - ff.sig_d = ff.val_srst; - changed = true; - } else if (!opt.keepdc || ff.val_init.is_fully_def()) { - // The D input path is effectively useless, so remove it (this will be a const-input D latch, SR latch, or a const driver). - log("Handling D = Q on %s (%s) from module %s (removing D path).\n", - log_id(cell), log_id(cell->type), log_id(module)); - ff.has_gclk = ff.has_clk = ff.has_ce = false; - changed = true; - } - } + // Feedback (D=Q) opt + if ((ff.has_clk || ff.has_gclk) && ff.sig_d == ff.sig_q) + optimize_d_equals_q(ff, cell, changed); if (ff.has_aload && !ff.has_clk && ff.sig_ad == ff.sig_q) { log("Handling AD = Q on %s (%s) from module %s (removing async load path).\n", @@ -633,284 +773,157 @@ struct OptDffWorker changed = true; } - // The cell has been simplified as much as possible already. Now try to spice it up with enables / sync resets. + // Mux merging if (ff.has_clk && ff.sig_d != ff.sig_q) { - if (!ff.has_arst && !ff.has_sr && (!ff.has_srst || !ff.has_ce || ff.ce_over_srst) && !opt.nosdff) { - // Try to merge sync resets. - std::map> groups; - std::vector remaining_indices; - Const::Builder val_srst_builder(ff.width); + bool can_merge_srst = !ff.has_arst && !ff.has_sr && + (!ff.has_srst || !ff.has_ce || ff.ce_over_srst) && !opt.nosdff; - for (int i = 0 ; i < ff.width; i++) { - ctrls_t resets; - State reset_val = State::Sx; - if (ff.has_srst) - reset_val = ff.val_srst[i]; - while (bit2mux.count(ff.sig_d[i]) && bitusers[ff.sig_d[i]] == 1) { - cell_int_t mbit = bit2mux.at(ff.sig_d[i]); - if (GetSize(mbit.first->getPort(ID::S)) != 1) - break; - SigBit s = mbit.first->getPort(ID::S); - SigBit a = mbit.first->getPort(ID::A)[mbit.second]; - SigBit b = mbit.first->getPort(ID::B)[mbit.second]; - // Workaround for funny memory WE pattern. - if ((a == State::S0 || a == State::S1) && (b == State::S0 || b == State::S1)) - break; - if ((b == State::S0 || b == State::S1) && (b == reset_val || reset_val == State::Sx)) { - // This is better handled by CE pattern. - if (a == ff.sig_q[i]) - break; - reset_val = b.data; - resets.insert(ctrl_t(s, true)); - ff.sig_d[i] = a; - } else if ((a == State::S0 || a == State::S1) && (a == reset_val || reset_val == State::Sx)) { - // This is better handled by CE pattern. - if (b == ff.sig_q[i]) - break; - reset_val = a.data; - resets.insert(ctrl_t(s, false)); - ff.sig_d[i] = b; - } else { - break; - } - } - - if (!resets.empty()) { - if (ff.has_srst) - resets.insert(ctrl_t(ff.sig_srst, ff.pol_srst)); - groups[resets].push_back(i); - } else - remaining_indices.push_back(i); - val_srst_builder.push_back(reset_val); - } - Const val_srst = val_srst_builder.build(); - - for (auto &it : groups) { - FfData new_ff = ff.slice(it.second); - Const::Builder new_val_srst_builder(new_ff.width); - for (int i = 0; i < new_ff.width; i++) { - int j = it.second[i]; - new_val_srst_builder.push_back(val_srst[j]); - } - new_ff.val_srst = new_val_srst_builder.build(); - ctrl_t srst = combine_resets(it.first, ff.is_fine); - - new_ff.has_srst = true; - new_ff.sig_srst = srst.first; - new_ff.pol_srst = srst.second; - if (new_ff.has_ce) - new_ff.ce_over_srst = true; - Cell *new_cell = new_ff.emit(); - if (new_cell) - dff_cells.push_back(new_cell); - log("Adding SRST signal on %s (%s) from module %s (D = %s, Q = %s, rval = %s).\n", - log_id(cell), log_id(cell->type), log_id(module), log_signal(new_ff.sig_d), log_signal(new_ff.sig_q), log_signal(new_ff.val_srst)); - } - - if (remaining_indices.empty()) { - module->remove(cell); - did_something = true; - continue; - } else if (GetSize(remaining_indices) != ff.width) { - ff = ff.slice(remaining_indices); - ff.cell = cell; - changed = true; - } + if (can_merge_srst && try_merge_srst(ff, cell, changed)) { + did_something = true; + continue; } - if ((!ff.has_srst || !ff.has_ce || !ff.ce_over_srst) && !opt.nodffe) { - // Try to merge enables. - std::map, std::vector> groups; - std::vector remaining_indices; - for (int i = 0 ; i < ff.width; i++) { - // First, eat up as many simple muxes as possible. - ctrls_t enables; - while (bit2mux.count(ff.sig_d[i]) && bitusers[ff.sig_d[i]] == 1) { - cell_int_t mbit = bit2mux.at(ff.sig_d[i]); - if (GetSize(mbit.first->getPort(ID::S)) != 1) - break; - SigBit s = mbit.first->getPort(ID::S); - SigBit a = mbit.first->getPort(ID::A)[mbit.second]; - SigBit b = mbit.first->getPort(ID::B)[mbit.second]; - if (a == ff.sig_q[i]) { - enables.insert(ctrl_t(s, true)); - ff.sig_d[i] = b; - } else if (b == ff.sig_q[i]) { - enables.insert(ctrl_t(s, false)); - ff.sig_d[i] = a; - } else { - break; - } - } + bool can_merge_ce = (!ff.has_srst || !ff.has_ce || !ff.ce_over_srst) && !opt.nodffe; - patterns_t patterns; - if (!opt.simple_dffe) - patterns = find_muxtree_feedback_patterns(ff.sig_d[i], ff.sig_q[i], pattern_t()); - if (!patterns.empty() || !enables.empty()) { - if (ff.has_ce) - enables.insert(ctrl_t(ff.sig_ce, ff.pol_ce)); - simplify_patterns(patterns); - groups[std::make_pair(patterns, enables)].push_back(i); - } else - remaining_indices.push_back(i); - } - - for (auto &it : groups) { - FfData new_ff = ff.slice(it.second); - ctrl_t en = make_patterns_logic(it.first.first, it.first.second, ff.is_fine); - - new_ff.has_ce = true; - new_ff.sig_ce = en.first; - new_ff.pol_ce = en.second; - new_ff.ce_over_srst = false; - Cell *new_cell = new_ff.emit(); - if (new_cell) - dff_cells.push_back(new_cell); - log("Adding EN signal on %s (%s) from module %s (D = %s, Q = %s).\n", - log_id(cell), log_id(cell->type), log_id(module), log_signal(new_ff.sig_d), log_signal(new_ff.sig_q)); - } - - if (remaining_indices.empty()) { - module->remove(cell); - did_something = true; - continue; - } else if (GetSize(remaining_indices) != ff.width) { - ff = ff.slice(remaining_indices); - ff.cell = cell; - changed = true; - } + if (can_merge_ce && try_merge_ce(ff, cell, changed)) { + did_something = true; + continue; } } if (changed) { - // Rebuild the FF. ff.emit(); did_something = true; } } + return did_something; } - bool run_constbits() { + bool prove_const_with_sat(QuickConeSat &qcsat, ModWalker &modwalker, SigBit q, SigBit d, State val) + { + // Trivial non-const cases + if (!modwalker.has_drivers(d)) + return false; + if (val != State::S0 && val != State::S1) + return false; + + int init_sat_pi = qcsat.importSigBit(val); + int q_sat_pi = qcsat.importSigBit(q); + int d_sat_pi = qcsat.importSigBit(d); + qcsat.prepare(); + + // If no counterexample exists, FF is constant + return !qcsat.ez->solve( + qcsat.ez->IFF(q_sat_pi, init_sat_pi), + qcsat.ez->NOT(qcsat.ez->IFF(d_sat_pi, init_sat_pi))); + } + + State check_constbit(FfData &ff, int i) + { + State val = ff.val_init[i]; + if (ff.has_arst) val = combine_const(val, ff.val_arst[i]); + if (ff.has_srst) val = combine_const(val, ff.val_srst[i]); + if (ff.has_sr) { + if (ff.sig_clr[i] != (ff.pol_clr ? State::S0 : State::S1)) + val = combine_const(val, State::S0); + if (ff.sig_set[i] != (ff.pol_set ? State::S0 : State::S1)) + val = combine_const(val, State::S1); + } + + return val; + } + + bool run_constbits() + { + // Find FFs that are provably constant ModWalker modwalker(module->design, module); QuickConeSat qcsat(modwalker); - // Defer mutating cells by removing them/emiting new flip flops so that - // cell references in modwalker are not invalidated std::vector cells_to_remove; std::vector ffs_to_emit; - bool did_something = false; + for (auto cell : module->selected_cells()) { if (!cell->is_builtin_ff()) continue; - FfData ff(&initvals, cell); - // Now check if any bit can be replaced by a constant. + FfData ff(&initvals, cell); pool removed_sigbits; + for (int i = 0; i < ff.width; i++) { - State val = ff.val_init[i]; - if (ff.has_arst) - val = combine_const(val, ff.val_arst[i]); - if (ff.has_srst) - val = combine_const(val, ff.val_srst[i]); - if (ff.has_sr) { - if (ff.sig_clr[i] != (ff.pol_clr ? State::S0 : State::S1)) - val = combine_const(val, State::S0); - if (ff.sig_set[i] != (ff.pol_set ? State::S0 : State::S1)) - val = combine_const(val, State::S1); - } + State val = check_constbit(ff, i); if (val == State::Sm) continue; + + // Check Synchronous input D if (ff.has_clk || ff.has_gclk) { if (!ff.sig_d[i].wire) { + // D is already a constant val = combine_const(val, ff.sig_d[i].data); - if (val == State::Sm) + if (val == State::Sm) continue; + } else if (opt.sat) { + // Try SAT proof for non-constant D wires + if (!prove_const_with_sat(qcsat, modwalker, ff.sig_q[i], ff.sig_d[i], val)) continue; } else { - if (!opt.sat) - continue; - // For each register bit, try to prove that it cannot change from the initial value. If so, remove it - if (!modwalker.has_drivers(ff.sig_d.extract(i))) - continue; - if (val != State::S0 && val != State::S1) - continue; - - int init_sat_pi = qcsat.importSigBit(val); - int q_sat_pi = qcsat.importSigBit(ff.sig_q[i]); - int d_sat_pi = qcsat.importSigBit(ff.sig_d[i]); - - qcsat.prepare(); - - // Try to find out whether the register bit can change under some circumstances - bool counter_example_found = qcsat.ez->solve(qcsat.ez->IFF(q_sat_pi, init_sat_pi), qcsat.ez->NOT(qcsat.ez->IFF(d_sat_pi, init_sat_pi))); - - // If the register bit cannot change, we can replace it with a constant - if (counter_example_found) - continue; + continue; } } + + // Check Async Load input AD if (ff.has_aload) { if (!ff.sig_ad[i].wire) { val = combine_const(val, ff.sig_ad[i].data); - if (val == State::Sm) + if (val == State::Sm) continue; + } else if (opt.sat) { + if (!prove_const_with_sat(qcsat, modwalker, ff.sig_q[i], ff.sig_ad[i], val)) continue; } else { - if (!opt.sat) - continue; - // For each register bit, try to prove that it cannot change from the initial value. If so, remove it - if (!modwalker.has_drivers(ff.sig_ad.extract(i))) - continue; - if (val != State::S0 && val != State::S1) - continue; - - int init_sat_pi = qcsat.importSigBit(val); - int q_sat_pi = qcsat.importSigBit(ff.sig_q[i]); - int d_sat_pi = qcsat.importSigBit(ff.sig_ad[i]); - - qcsat.prepare(); - - // Try to find out whether the register bit can change under some circumstances - bool counter_example_found = qcsat.ez->solve(qcsat.ez->IFF(q_sat_pi, init_sat_pi), qcsat.ez->NOT(qcsat.ez->IFF(d_sat_pi, init_sat_pi))); - - // If the register bit cannot change, we can replace it with a constant - if (counter_example_found) - continue; + continue; } } - log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", val ? 1 : 0, - i, log_id(cell), log_id(cell->type), log_id(module)); + log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", + val ? 1 : 0, i, log_id(cell), log_id(cell->type), log_id(module)); + + // Replace the Q output with the constant value initvals.remove_init(ff.sig_q[i]); module->connect(ff.sig_q[i], val); removed_sigbits.insert(i); } + + // Reconstruct FF with constant bits removed if (!removed_sigbits.empty()) { std::vector keep_bits; for (int i = 0; i < ff.width; i++) if (!removed_sigbits.count(i)) keep_bits.push_back(i); + if (keep_bits.empty()) { - cells_to_remove.emplace_back(cell); - did_something = true; - continue; + cells_to_remove.push_back(cell); + } else { + ff = ff.slice(keep_bits); + ff.cell = cell; + ffs_to_emit.push_back(ff); } - ff = ff.slice(keep_bits); - ff.cell = cell; - ffs_to_emit.emplace_back(ff); did_something = true; } } + for (auto* cell : cells_to_remove) module->remove(cell); + for (auto& ff : ffs_to_emit) ff.emit(); + return did_something; } }; struct OptDffPass : public Pass { OptDffPass() : Pass("opt_dff", "perform DFF optimizations") { } + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -948,6 +961,7 @@ struct OptDffPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { log_header(design, "Executing OPT_DFF pass (perform DFF optimizations).\n"); + OptDffOptions opt; opt.nodffe = false; opt.nosdff = false; @@ -957,26 +971,11 @@ struct OptDffPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-nodffe") { - opt.nodffe = true; - continue; - } - if (args[argidx] == "-nosdff") { - opt.nosdff = true; - continue; - } - if (args[argidx] == "-simple-dffe") { - opt.simple_dffe = true; - continue; - } - if (args[argidx] == "-keepdc") { - opt.keepdc = true; - continue; - } - if (args[argidx] == "-sat") { - opt.sat = true; - continue; - } + if (args[argidx] == "-nodffe") { opt.nodffe = true; continue; } + if (args[argidx] == "-nosdff") { opt.nosdff = true; continue; } + if (args[argidx] == "-simple-dffe") { opt.simple_dffe = true; continue; } + if (args[argidx] == "-keepdc") { opt.keepdc = true; continue; } + if (args[argidx] == "-sat") { opt.sat = true; continue; } break; } extra_args(args, argidx, design); diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index ffe678d2f..2c040b09d 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -20,6 +20,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/utils.h" #include "kernel/log.h" #include @@ -31,7 +32,7 @@ PRIVATE_NAMESPACE_BEGIN bool did_something; -void replace_undriven(RTLIL::Module *module, const CellTypes &ct) +void replace_undriven(RTLIL::Module *module, const NewCellTypes &ct) { SigMap sigmap(module); SigPool driven_signals; @@ -407,9 +408,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - CellTypes ct_memcells; - ct_memcells.setup_stdcells_mem(); - if (!noclkinv) for (auto cell : module->cells()) if (design->selected(module, cell)) { @@ -433,7 +431,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($dffe), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce), ID($dffsre), ID($dlatch), ID($adlatch), ID($dlatchsr))) handle_polarity_inv(cell, ID::EN, ID::EN_POLARITY, assign_map, invert_map); - if (!ct_memcells.cell_known(cell->type)) + if (!StaticCellTypes::Compat::stdcells_mem(cell->type)) continue; handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID::S, assign_map, invert_map); @@ -1667,7 +1665,11 @@ skip_identity: int bit_idx; const auto onehot = sig_a.is_onehot(&bit_idx); - if (onehot) { + // Power of two + // A is unsigned or positive + if (onehot && (!cell->parameters[ID::A_SIGNED].as_bool() || bit_idx < sig_a.size() - 1)) { + cell->parameters[ID::A_SIGNED] = 0; + // 2^B = 1<name.c_str(), module->name.c_str()); @@ -1679,7 +1681,6 @@ skip_identity: log_debug("Replacing pow cell `%s' in module `%s' with multiply and left-shift\n", cell->name.c_str(), module->name.c_str()); cell->type = ID($mul); - cell->parameters[ID::A_SIGNED] = 0; cell->setPort(ID::A, Const(bit_idx, cell->parameters[ID::A_WIDTH].as_int())); SigSpec y_wire = module->addWire(NEW_ID, y_size); @@ -2291,7 +2292,7 @@ struct OptExprPass : public Pass { } extra_args(args, argidx, design); - CellTypes ct(design); + NewCellTypes ct(design); for (auto module : design->selected_modules()) { log("Optimizing module %s.\n", log_id(module)); diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index c0a017748..81a7e5a43 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -421,13 +421,12 @@ struct OptLutWorker } RTLIL::Cell *lutM, *lutR; - pool lutM_inputs, lutR_inputs; + pool lutR_inputs; pool lutM_dlogic_inputs; if (combine == COMBINE_A) { log_debug(" Combining LUTs into cell A.\n"); lutM = lutA; - lutM_inputs = lutA_inputs; lutM_dlogic_inputs = lutA_dlogic_inputs; lutR = lutB; lutR_inputs = lutB_inputs; @@ -436,7 +435,6 @@ struct OptLutWorker { log_debug(" Combining LUTs into cell B.\n"); lutM = lutB; - lutM_inputs = lutB_inputs; lutM_dlogic_inputs = lutB_dlogic_inputs; lutR = lutA; lutR_inputs = lutA_inputs; diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index fa8eb563b..580853b51 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -39,7 +39,8 @@ struct OptLutInsPass : public Pass { log("\n"); log(" -tech \n"); log(" Instead of generic $lut cells, operate on LUT cells specific\n"); - log(" to the given technology. Valid values are: xilinx, lattice, gowin.\n"); + log(" to the given technology. Valid values are: xilinx, lattice,\n"); + log(" gowin, analogdevices.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -58,7 +59,7 @@ struct OptLutInsPass : public Pass { } extra_args(args, argidx, design); - if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "ecp5" && techname != "gowin") + if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "analogdevices" && techname != "gowin") log_cmd_error("Unsupported technology: '%s'\n", techname); for (auto module : design->selected_modules()) @@ -81,7 +82,7 @@ struct OptLutInsPass : public Pass { inputs = cell->getPort(ID::A); output = cell->getPort(ID::Y); lut = cell->getParam(ID::LUT); - } else if (techname == "xilinx" || techname == "gowin") { + } else if (techname == "xilinx" || techname == "gowin" || techname == "analogdevices") { if (cell->type == ID(LUT1)) { inputs = { cell->getPort(ID(I0)), @@ -126,11 +127,11 @@ struct OptLutInsPass : public Pass { continue; } lut = cell->getParam(ID::INIT); - if (techname == "xilinx") + if (techname == "xilinx" || techname == "analogdevices") output = cell->getPort(ID::O); else output = cell->getPort(ID::F); - } else if (techname == "lattice" || techname == "ecp5") { + } else if (techname == "lattice") { if (cell->type == ID(LUT4)) { inputs = { cell->getPort(ID::A), @@ -236,7 +237,7 @@ struct OptLutInsPass : public Pass { } else { // xilinx, gowin cell->setParam(ID::INIT, new_lut); - if (techname == "xilinx") + if (techname == "xilinx" || techname == "analogdevices") log_assert(GetSize(new_inputs) <= 6); else log_assert(GetSize(new_inputs) <= 4); diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 307c2bcd3..a6121b268 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -22,6 +22,7 @@ #include "kernel/sigtools.h" #include "kernel/log.h" #include "kernel/celltypes.h" +#include "kernel/threading.h" #include "libs/sha1/sha1.h" #include #include @@ -37,16 +38,73 @@ PRIVATE_NAMESPACE_BEGIN template inline Hasher hash_pair(const T &t, const U &u) { return hash_ops>::hash(t, u); } -struct OptMergeWorker +// Some cell and its hash value. +struct CellHash { - RTLIL::Design *design; - RTLIL::Module *module; - SigMap assign_map; - FfInitVals initvals; - bool mode_share_all; + // Index of a cell in the module + int cell_index; + Hasher::hash_t hash_value; +}; - CellTypes ct; - int total_count; +// The algorithm: +// 1) Compute and store the hashes of all relevant cells, in parallel. +// 2) Given N = the number of threads, partition the cells into N buckets by hash value: +// bucket k contains the cells whose hash value mod N = k. +// 3) For each bucket in parallel, build a hashtable of that bucket’s cells (using the +// precomputed hashes) and record the duplicates found. +// 4) On the main thread, process the list of duplicates to remove cells. +// For efficiency we fuse the second step into the first step by having the parallel +// threads write the cells into buckets directly. +// To avoid synchronization overhead, we divide each bucket into N shards. Each +// thread j adds a cell to bucket k by writing to shard j of bucket k — +// no synchronization required. In the next phase, thread k builds the hashtable for +// bucket k by iterating over all shards of the bucket. + +// The input to each thread in the "compute cell hashes" phase. +struct CellRange +{ + int begin; + int end; +}; + +// The output from each thread in the "compute cell hashes" phase. +struct CellHashes +{ + // Entry i contains the hashes where hash_value % bucketed_cell_hashes.size() == i + std::vector> bucketed_cell_hashes; +}; + +// A duplicate cell that has been found. +struct DuplicateCell +{ + // Remove this cell from the design + int remove_cell; + // ... and use this cell instead. + int keep_cell; +}; + +// The input to each thread in the "find duplicate cells" phase. +// Shards of buckets of cell hashes +struct Shards +{ + std::vector>> &bucketed_cell_hashes; +}; + +// The output from each thread in the "find duplicate cells" phase. +struct FoundDuplicates +{ + std::vector duplicates; +}; + +struct OptMergeThreadWorker +{ + const RTLIL::Module *module; + const SigMap &assign_map; + const FfInitVals &initvals; + const CellTypes &ct; + int workers; + bool mode_share_all; + bool mode_keepdc; static Hasher hash_pmux_in(const SigSpec& sig_s, const SigSpec& sig_b, Hasher h) { @@ -62,8 +120,8 @@ struct OptMergeWorker static void sort_pmux_conn(dict &conn) { - SigSpec sig_s = conn.at(ID::S); - SigSpec sig_b = conn.at(ID::B); + const SigSpec &sig_s = conn.at(ID::S); + const SigSpec &sig_b = conn.at(ID::B); int s_width = GetSize(sig_s); int width = GetSize(sig_b) / s_width; @@ -144,7 +202,6 @@ struct OptMergeWorker if (cell1->parameters != cell2->parameters) return false; - if (cell1->connections_.size() != cell2->connections_.size()) return false; for (const auto &it : cell1->connections_) @@ -199,7 +256,7 @@ struct OptMergeWorker return conn1 == conn2; } - bool has_dont_care_initval(const RTLIL::Cell *cell) + bool has_dont_care_initval(const RTLIL::Cell *cell) const { if (!cell->is_builtin_ff()) return false; @@ -207,36 +264,134 @@ struct OptMergeWorker return !initvals(cell->getPort(ID::Q)).is_fully_def(); } - OptMergeWorker(RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux, bool mode_share_all, bool mode_keepdc) : - design(design), module(module), mode_share_all(mode_share_all) + OptMergeThreadWorker(const RTLIL::Module *module, const FfInitVals &initvals, + const SigMap &assign_map, const CellTypes &ct, int workers, + bool mode_share_all, bool mode_keepdc) : + module(module), assign_map(assign_map), initvals(initvals), ct(ct), + workers(workers), mode_share_all(mode_share_all), mode_keepdc(mode_keepdc) { - total_count = 0; - ct.setup_internals(); - ct.setup_internals_mem(); - ct.setup_stdcells(); - ct.setup_stdcells_mem(); + } - if (mode_nomux) { - ct.cell_types.erase(ID($mux)); - ct.cell_types.erase(ID($pmux)); + CellHashes compute_cell_hashes(const CellRange &cell_range) const + { + std::vector> bucketed_cell_hashes(workers); + for (int cell_index = cell_range.begin; cell_index < cell_range.end; ++cell_index) { + const RTLIL::Cell *cell = module->cell_at(cell_index); + if (!module->selected(cell)) + continue; + if (cell->type.in(ID($meminit), ID($meminit_v2), ID($mem), ID($mem_v2))) { + // Ignore those for performance: meminit can have an excessively large port, + // mem can have an excessively large parameter holding the init data + continue; + } + if (cell->type == ID($scopeinfo)) + continue; + if (mode_keepdc && has_dont_care_initval(cell)) + continue; + if (!cell->known()) + continue; + if (!mode_share_all && !ct.cell_known(cell->type)) + continue; + + Hasher::hash_t h = hash_cell_function(cell, Hasher()).yield(); + int bucket_index = h % workers; + bucketed_cell_hashes[bucket_index].push_back({cell_index, h}); } + return {std::move(bucketed_cell_hashes)}; + } - ct.cell_types.erase(ID($tribuf)); - ct.cell_types.erase(ID($_TBUF_)); - ct.cell_types.erase(ID($anyseq)); - ct.cell_types.erase(ID($anyconst)); - ct.cell_types.erase(ID($allseq)); - ct.cell_types.erase(ID($allconst)); - ct.cell_types.erase(ID($check)); - ct.cell_types.erase(ID($assert)); - ct.cell_types.erase(ID($assume)); - ct.cell_types.erase(ID($live)); - ct.cell_types.erase(ID($cover)); + FoundDuplicates find_duplicate_cells(int index, const Shards &in) const + { + // We keep a set of known cells. They're hashed with our hash_cell_function + // and compared with our compare_cell_parameters_and_connections. + struct CellHashOp { + std::size_t operator()(const CellHash &c) const { + return (std::size_t)c.hash_value; + } + }; + struct CellEqualOp { + const OptMergeThreadWorker& worker; + CellEqualOp(const OptMergeThreadWorker& w) : worker(w) {} + bool operator()(const CellHash &lhs, const CellHash &rhs) const { + return worker.compare_cell_parameters_and_connections( + worker.module->cell_at(lhs.cell_index), + worker.module->cell_at(rhs.cell_index)); + } + }; + std::unordered_set< + CellHash, + CellHashOp, + CellEqualOp> known_cells(0, CellHashOp(), CellEqualOp(*this)); + + std::vector duplicates; + for (const std::vector> &buckets : in.bucketed_cell_hashes) { + // Clear out our buckets as we go. This keeps the work of deallocation + // off the main thread. + std::vector bucket = std::move(buckets[index]); + for (CellHash c : bucket) { + auto [cell_in_map, inserted] = known_cells.insert(c); + if (inserted) + continue; + CellHash map_c = *cell_in_map; + if (module->cell_at(c.cell_index)->has_keep_attr()) { + if (module->cell_at(map_c.cell_index)->has_keep_attr()) + continue; + known_cells.erase(map_c); + known_cells.insert(c); + std::swap(c, map_c); + } + duplicates.push_back({c.cell_index, map_c.cell_index}); + } + } + return {duplicates}; + } +}; + +template +void initialize_queues(std::vector> &queues, int size) { + queues.reserve(size); + for (int i = 0; i < size; ++i) + queues.emplace_back(1); +} + +struct OptMergeWorker +{ + int total_count; + + OptMergeWorker(RTLIL::Module *module, const CellTypes &ct, bool mode_share_all, bool mode_keepdc) : + total_count(0) + { + SigMap assign_map(module); + FfInitVals initvals; + initvals.set(&assign_map, module); log("Finding identical cells in module `%s'.\n", module->name); - assign_map.set(module); - initvals.set(&assign_map, module); + // Use no more than one worker per thousand cells, rounded down, so + // we only start multithreading with at least 2000 cells. + int num_worker_threads = ThreadPool::pool_size(0, module->cells_size()/1000); + int workers = std::max(1, num_worker_threads); + + // The main thread doesn't do any work, so if there is only one worker thread, + // just run everything on the main thread instead. + // This avoids creating and waiting on a thread, which is pretty high overhead + // for very small modules. + if (num_worker_threads == 1) + num_worker_threads = 0; + OptMergeThreadWorker thread_worker(module, initvals, assign_map, ct, workers, mode_share_all, mode_keepdc); + + std::vector> cell_ranges_queues(num_worker_threads); + std::vector> cell_hashes_queues(num_worker_threads); + std::vector> shards_queues(num_worker_threads); + std::vector> duplicates_queues(num_worker_threads); + + ThreadPool thread_pool(num_worker_threads, [&](int i) { + while (std::optional c = cell_ranges_queues[i].pop_front()) { + cell_hashes_queues[i].push_back(thread_worker.compute_cell_hashes(*c)); + std::optional shards = shards_queues[i].pop_front(); + duplicates_queues[i].push_back(thread_worker.find_duplicate_cells(i, *shards)); + } + }); bool did_something = true; // A cell may have to go through a lot of collisions if the hash @@ -244,87 +399,99 @@ struct OptMergeWorker // beyond the user's control. while (did_something) { - std::vector cells; - cells.reserve(module->cells().size()); - for (auto cell : module->cells()) { - if (!design->selected(module, cell)) - continue; - if (cell->type.in(ID($meminit), ID($meminit_v2), ID($mem), ID($mem_v2))) { - // Ignore those for performance: meminit can have an excessively large port, - // mem can have an excessively large parameter holding the init data - continue; - } - if (cell->type == ID($scopeinfo)) - continue; - if (mode_keepdc && has_dont_care_initval(cell)) - continue; - if (!cell->known()) - continue; - if (!mode_share_all && !ct.cell_known(cell->type)) - continue; - cells.push_back(cell); - } + int cells_size = module->cells_size(); + log("Computing hashes of %d cells of `%s'.\n", cells_size, module->name); + std::vector>> sharded_bucketed_cell_hashes(workers); - did_something = false; - - // We keep a set of known cells. They're hashed with our hash_cell_function - // and compared with our compare_cell_parameters_and_connections. - // Both need to capture OptMergeWorker to access initvals - struct CellPtrHash { - const OptMergeWorker& worker; - CellPtrHash(const OptMergeWorker& w) : worker(w) {} - std::size_t operator()(const Cell* c) const { - return (std::size_t)worker.hash_cell_function(c, Hasher()).yield(); - } - }; - struct CellPtrEqual { - const OptMergeWorker& worker; - CellPtrEqual(const OptMergeWorker& w) : worker(w) {} - bool operator()(const Cell* lhs, const Cell* rhs) const { - return worker.compare_cell_parameters_and_connections(lhs, rhs); - } - }; - std::unordered_set< - RTLIL::Cell*, - CellPtrHash, - CellPtrEqual> known_cells (0, CellPtrHash(*this), CellPtrEqual(*this)); - - for (auto cell : cells) + int cell_index = 0; + int cells_size_mod_workers = cells_size % workers; { - auto [cell_in_map, inserted] = known_cells.insert(cell); - if (!inserted) { - // We've failed to insert since we already have an equivalent cell - Cell* other_cell = *cell_in_map; - if (cell->has_keep_attr()) { - if (other_cell->has_keep_attr()) - continue; - known_cells.erase(other_cell); - known_cells.insert(cell); - std::swap(other_cell, cell); - } - - did_something = true; - log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name, other_cell->name); - for (auto &it : cell->connections()) { - if (cell->output(it.first)) { - RTLIL::SigSpec other_sig = other_cell->getPort(it.first); - log_debug(" Redirecting output %s: %s = %s\n", it.first, - log_signal(it.second), log_signal(other_sig)); - Const init = initvals(other_sig); - initvals.remove_init(it.second); - initvals.remove_init(other_sig); - module->connect(RTLIL::SigSig(it.second, other_sig)); - assign_map.add(it.second, other_sig); - initvals.set_init(other_sig, init); - } - } - log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type, cell->name, module->name); - module->remove(cell); - total_count++; + Multithreading multithreading; + for (int i = 0; i < workers; ++i) { + int num_cells = cells_size/workers + ((i < cells_size_mod_workers) ? 1 : 0); + CellRange c = { cell_index, cell_index + num_cells }; + cell_index += num_cells; + if (num_worker_threads > 0) + cell_ranges_queues[i].push_back(c); + else + sharded_bucketed_cell_hashes[i] = std::move(thread_worker.compute_cell_hashes(c).bucketed_cell_hashes); } + log_assert(cell_index == cells_size); + if (num_worker_threads > 0) + for (int i = 0; i < workers; ++i) + sharded_bucketed_cell_hashes[i] = std::move(cell_hashes_queues[i].pop_front()->bucketed_cell_hashes); } + + log("Finding duplicate cells in `%s'.\n", module->name); + std::vector merged_duplicates; + { + Multithreading multithreading; + for (int i = 0; i < workers; ++i) { + Shards thread_shards = { sharded_bucketed_cell_hashes }; + if (num_worker_threads > 0) + shards_queues[i].push_back(thread_shards); + else { + std::vector d = std::move(thread_worker.find_duplicate_cells(i, thread_shards).duplicates); + merged_duplicates.insert(merged_duplicates.end(), d.begin(), d.end()); + } + } + if (num_worker_threads > 0) + for (int i = 0; i < workers; ++i) { + std::vector d = std::move(duplicates_queues[i].pop_front()->duplicates); + merged_duplicates.insert(merged_duplicates.end(), d.begin(), d.end()); + } + } + std::sort(merged_duplicates.begin(), merged_duplicates.end(), [](const DuplicateCell &lhs, const DuplicateCell &rhs) { + // Sort them by the order in which duplicates would have been detected in a single-threaded + // run. The cell at which the duplicate would have been detected is the latter of the two + // cells involved. + return std::max(lhs.remove_cell, lhs.keep_cell) < std::max(rhs.remove_cell, rhs.keep_cell); + }); + + // Convert to cell pointers because removing cells will invalidate the indices. + std::vector> cell_ptrs; + for (DuplicateCell dup : merged_duplicates) + cell_ptrs.push_back({module->cell_at(dup.remove_cell), module->cell_at(dup.keep_cell)}); + + for (auto [remove_cell, keep_cell] : cell_ptrs) + { + log_debug(" Cell `%s' is identical to cell `%s'.\n", remove_cell->name, keep_cell->name); + for (auto &it : remove_cell->connections()) { + if (remove_cell->output(it.first)) { + RTLIL::SigSpec keep_sig = keep_cell->getPort(it.first); + log_debug(" Redirecting output %s: %s = %s\n", it.first, + log_signal(it.second), log_signal(keep_sig)); + Const init = initvals(keep_sig); + initvals.remove_init(it.second); + initvals.remove_init(keep_sig); + module->connect(RTLIL::SigSig(it.second, keep_sig)); + auto keep_sig_it = keep_sig.begin(); + for (SigBit remove_sig_bit : it.second) { + assign_map.add(remove_sig_bit, *keep_sig_it); + ++keep_sig_it; + } + initvals.set_init(keep_sig, init); + } + } + log_debug(" Removing %s cell `%s' from module `%s'.\n", remove_cell->type, remove_cell->name, module->name); + module->remove(remove_cell); + total_count++; + } + did_something = !merged_duplicates.empty(); } + for (ConcurrentQueue &q : cell_ranges_queues) + q.close(); + + for (ConcurrentQueue &q : shards_queues) + q.close(); + + for (ConcurrentQueue &q : cell_ranges_queues) + q.close(); + + for (ConcurrentQueue &q : shards_queues) + q.close(); + log_suppressed(); } }; @@ -377,9 +544,25 @@ struct OptMergePass : public Pass { } extra_args(args, argidx, design); + CellTypes ct; + ct.setup_internals(); + ct.setup_internals_mem(); + ct.setup_stdcells(); + ct.setup_stdcells_mem(); + if (mode_nomux) { + ct.cell_types.erase(ID($mux)); + ct.cell_types.erase(ID($pmux)); + } + ct.cell_types.erase(ID($tribuf)); + ct.cell_types.erase(ID($_TBUF_)); + ct.cell_types.erase(ID($anyseq)); + ct.cell_types.erase(ID($anyconst)); + ct.cell_types.erase(ID($allseq)); + ct.cell_types.erase(ID($allconst)); + int total_count = 0; for (auto module : design->selected_modules()) { - OptMergeWorker worker(design, module, mode_nomux, mode_share_all, mode_keepdc); + OptMergeWorker worker(module, ct, mode_share_all, mode_keepdc); total_count += worker.total_count; } diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 2f7d26dcf..8bf151e71 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -21,11 +21,9 @@ #include "kernel/sigtools.h" #include "kernel/log.h" #include "kernel/celltypes.h" +#include #include #include -#include -#include -#include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -64,7 +62,7 @@ struct OptMuxtreeWorker RTLIL::Module *module; SigMap assign_map; int removed_count; - int glob_evals_left = 10000000; + int glob_evals_left = 10'000'000; struct bitinfo_t { // Is bit directly used by non-mux cells or ports? @@ -128,7 +126,7 @@ struct OptMuxtreeWorker // In case of $pmux, port B is multiple slices, concatenated, one per bit of port S for (int i = 0; i < GetSize(sig_s); i++) { RTLIL::SigSpec sig = sig_b.extract(i*GetSize(sig_a), GetSize(sig_a)); - RTLIL::SigSpec ctrl_sig = assign_map(sig_s.extract(i, 1)); + RTLIL::SigSpec ctrl_sig = assign_map(SigSpec{sig_s[i]}); portinfo_t portinfo = used_port_bit(sig, this_mux_idx); portinfo.ctrl_sig = sig2bits(ctrl_sig, false).front(); portinfo.const_activated = ctrl_sig.is_fully_const() && ctrl_sig.as_bool(); @@ -342,14 +340,21 @@ struct OptMuxtreeWorker // The payload is a reference counter used to manage the list // When it is non-zero, the signal in known to be inactive // When it reaches zero, the map element is removed - std::unordered_map known_inactive; + std::vector known_inactive; // database of known active signals - std::unordered_map known_active; + std::vector known_active; // this is just used to keep track of visited muxes in order to prohibit // endless recursion in mux loops - std::unordered_set visited_muxes; + std::vector visited_muxes; + + // Initialize with the maximum possible sizes + knowledge_t(int num_bits, int num_muxes) { + known_inactive.assign(num_bits, 0); + known_active.assign(num_bits, 0); + visited_muxes.assign(num_muxes, false); + } }; static void activate_port(knowledge_t &knowledge, int port_idx, const muxinfo_t &muxinfo) { @@ -366,11 +371,10 @@ struct OptMuxtreeWorker } static void deactivate_port(knowledge_t &knowledge, int port_idx, const muxinfo_t &muxinfo) { - auto unlearn = [](std::unordered_map& knowns, int i) { - auto it = knowns.find(i); - if (it != knowns.end()) - if (--it->second == 0) - knowns.erase(it); + auto unlearn = [](std::vector& knowns, int bit_idx) { + if (knowns[bit_idx] > 0) { + --knowns[bit_idx]; + } }; if (port_idx < GetSize(muxinfo.ports)-1 && !muxinfo.ports[port_idx].const_activated) @@ -418,9 +422,9 @@ struct OptMuxtreeWorker vector input_mux_queue; for (int m : muxinfo.ports[port_idx].input_muxes) { - if (knowledge.visited_muxes.count(m)) + if (knowledge.visited_muxes[m]) continue; - knowledge.visited_muxes.insert(m); + knowledge.visited_muxes[m] = true; input_mux_queue.push_back(m); } for (int m : input_mux_queue) { @@ -453,7 +457,7 @@ struct OptMuxtreeWorker // Allow revisiting input muxes, since evaluating other ports should // revisit these input muxes with different activation assumptions for (int m : input_mux_queue) - knowledge.visited_muxes.erase(m); + knowledge.visited_muxes[m] = false; // Undo our assumptions that the port is active deactivate_port(knowledge, port_idx, muxinfo); @@ -475,11 +479,11 @@ struct OptMuxtreeWorker vector bits = sig2bits(sig, false); for (int i = 0; i < GetSize(bits); i++) { if (bits[i] >= 0) { - if (knowledge.known_inactive.count(bits[i]) > 0) { + if (knowledge.known_inactive[bits[i]] > 0) { sig[i] = State::S0; did_something = true; } else - if (knowledge.known_active.count(bits[i]) > 0) { + if (knowledge.known_active[bits[i]] > 0) { sig[i] = State::S1; did_something = true; } @@ -552,7 +556,7 @@ struct OptMuxtreeWorker portinfo_t &portinfo = muxinfo.ports[port_idx]; if (portinfo.const_deactivated) continue; - if (knowledge.known_active.count(portinfo.ctrl_sig) > 0) { + if (knowledge.known_active[portinfo.ctrl_sig] > 0) { eval_mux_port(knowledge, mux_idx, port_idx, limits); return; } @@ -566,7 +570,7 @@ struct OptMuxtreeWorker if (portinfo.const_deactivated) continue; if (port_idx < GetSize(muxinfo.ports)-1) - if (knowledge.known_inactive.count(portinfo.ctrl_sig) > 0) + if (knowledge.known_inactive[portinfo.ctrl_sig] > 0) continue; eval_mux_port(knowledge, mux_idx, port_idx, limits); @@ -578,8 +582,8 @@ struct OptMuxtreeWorker void eval_root_mux(int mux_idx) { log_assert(glob_evals_left > 0); - knowledge_t knowledge; - knowledge.visited_muxes.insert(mux_idx); + knowledge_t knowledge(GetSize(bit2info), GetSize(mux2info)); + knowledge.visited_muxes[mux_idx] = true; limits_t limits = {}; limits.do_mark_ports_observable = root_enable_muxes.at(mux_idx); eval_mux(knowledge, mux_idx, limits); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 6d6cadfe7..b4592038b 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -110,22 +110,20 @@ struct OptReduceWorker RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID::S)); RTLIL::SigSpec new_sig_b, new_sig_s; - pool handled_sig; + dict> grouped_b_to_s; - handled_sig.insert(sig_a); - for (int i = 0; i < sig_s.size(); i++) - { - RTLIL::SigSpec this_b = sig_b.extract(i*sig_a.size(), sig_a.size()); - if (handled_sig.count(this_b) > 0) - continue; - - RTLIL::SigSpec this_s = sig_s.extract(i, 1); - for (int j = i+1; j < sig_s.size(); j++) { - RTLIL::SigSpec that_b = sig_b.extract(j*sig_a.size(), sig_a.size()); - if (this_b == that_b) - this_s.append(sig_s.extract(j, 1)); + int port_width = sig_a.size(); + for (int i = 0; i < sig_s.size(); i++) { + RTLIL::SigSpec this_b = sig_b.extract(i*port_width, port_width); + if (grouped_b_to_s.count(this_b)) { + grouped_b_to_s[this_b].push_back(sig_s[i]); + } else { + grouped_b_to_s[this_b] = {sig_s[i]}; } + } + for (auto &[this_b, this_s_bit] : grouped_b_to_s) { + RTLIL::SigSpec this_s{this_s_bit}; if (this_s.size() > 1) { RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or)); @@ -141,7 +139,6 @@ struct OptReduceWorker new_sig_b.append(this_b); new_sig_s.append(this_s); - handled_sig.insert(this_b); } if (new_sig_s.size() == 0) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 307cd299b..bc363e251 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -23,6 +23,7 @@ #include "kernel/modtools.h" #include "kernel/utils.h" #include "kernel/macc.h" +#include "kernel/newcelltypes.h" #include USING_YOSYS_NAMESPACE @@ -35,22 +36,20 @@ struct ShareWorkerConfig { int limit; size_t pattern_limit; - bool opt_force; bool opt_aggressive; bool opt_fast; - pool generic_uni_ops, generic_bin_ops, generic_cbin_ops, generic_other_ops; + StaticCellTypes::Categories::Category generic_uni_ops, generic_bin_ops, generic_cbin_ops, generic_other_ops; }; struct ShareWorker { const ShareWorkerConfig config; int limit; - pool generic_ops; + StaticCellTypes::Categories::Category generic_ops; RTLIL::Design *design; RTLIL::Module *module; - CellTypes fwd_ct, cone_ct; ModWalker modwalker; pool cells_to_remove; @@ -75,7 +74,7 @@ struct ShareWorker queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); for (auto &it : module->cells_) - if (!fwd_ct.cell_known(it.second->type)) { + if (!StaticCellTypes::Compat::internals_nomem_noff(it.second->type)) { pool &bits = modwalker.cell_inputs[it.second]; queue_bits.insert(bits.begin(), bits.end()); } @@ -95,7 +94,7 @@ struct ShareWorker queue_bits.insert(bits.begin(), bits.end()); visited_cells.insert(pbit.cell); } - if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) { + if (StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) { pool &bits = modwalker.cell_inputs[pbit.cell]; terminal_bits.insert(bits.begin(), bits.end()); queue_bits.insert(bits.begin(), bits.end()); @@ -363,11 +362,6 @@ struct ShareWorker not_a_muxed_cell: continue; - if (config.opt_force) { - shareable_cells.insert(cell); - continue; - } - if (cell->type.in(ID($memrd), ID($memrd_v2))) { if (cell->parameters.at(ID::CLK_ENABLE).as_bool()) continue; @@ -388,7 +382,7 @@ struct ShareWorker continue; } - if (generic_ops.count(cell->type)) { + if (generic_ops(cell->type)) { if (config.opt_aggressive) shareable_cells.insert(cell); continue; @@ -412,7 +406,7 @@ struct ShareWorker return true; } - if (config.generic_uni_ops.count(c1->type)) + if (config.generic_uni_ops(c1->type)) { if (!config.opt_aggressive) { @@ -429,7 +423,7 @@ struct ShareWorker return true; } - if (config.generic_bin_ops.count(c1->type) || c1->type == ID($alu)) + if (config.generic_bin_ops(c1->type) || c1->type == ID($alu)) { if (!config.opt_aggressive) { @@ -449,7 +443,7 @@ struct ShareWorker return true; } - if (config.generic_cbin_ops.count(c1->type)) + if (config.generic_cbin_ops(c1->type)) { if (!config.opt_aggressive) { @@ -511,7 +505,7 @@ struct ShareWorker { log_assert(c1->type == c2->type); - if (config.generic_uni_ops.count(c1->type)) + if (config.generic_uni_ops(c1->type)) { if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool()) { @@ -560,11 +554,11 @@ struct ShareWorker return supercell; } - if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == ID($alu)) + if (config.generic_bin_ops(c1->type) || config.generic_cbin_ops(c1->type) || c1->type == ID($alu)) { bool modified_src_cells = false; - if (config.generic_cbin_ops.count(c1->type)) + if (config.generic_cbin_ops(c1->type)) { int score_unflipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int()) + max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int()); @@ -758,7 +752,7 @@ struct ShareWorker recursion_state.insert(cell); for (auto c : consumer_cells) - if (fwd_ct.cell_known(c->type)) { + if (StaticCellTypes::Compat::internals_nomem_noff(c->type)) { const pool &bits = find_forbidden_controls(c); forbidden_controls_cache[cell].insert(bits.begin(), bits.end()); } @@ -897,7 +891,7 @@ struct ShareWorker return activation_patterns_cache.at(cell); } for (auto &pbit : modwalker.signal_consumers[bit]) { - log_assert(fwd_ct.cell_known(pbit.cell->type)); + log_assert(StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type)); if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID::A || pbit.port == ID::B)) driven_data_muxes.insert(pbit.cell); else @@ -1214,24 +1208,10 @@ struct ShareWorker ShareWorker(ShareWorkerConfig config, RTLIL::Design* design) : config(config), design(design), modwalker(design) { - generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); - generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); - generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end()); - generic_ops.insert(config.generic_other_ops.begin(), config.generic_other_ops.end()); - - fwd_ct.setup_internals(); - - cone_ct.setup_internals(); - cone_ct.cell_types.erase(ID($mul)); - cone_ct.cell_types.erase(ID($mod)); - cone_ct.cell_types.erase(ID($div)); - cone_ct.cell_types.erase(ID($modfloor)); - cone_ct.cell_types.erase(ID($divfloor)); - cone_ct.cell_types.erase(ID($pow)); - cone_ct.cell_types.erase(ID($shl)); - cone_ct.cell_types.erase(ID($shr)); - cone_ct.cell_types.erase(ID($sshl)); - cone_ct.cell_types.erase(ID($sshr)); + generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_uni_ops); + generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_bin_ops); + generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_cbin_ops); + generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_other_ops); } void operator()(RTLIL::Module *module) { @@ -1523,14 +1503,6 @@ struct SharePass : public Pass { log("This pass merges shareable resources into a single resource. A SAT solver\n"); log("is used to determine if two resources are share-able.\n"); log("\n"); - log(" -force\n"); - log(" Per default the selection of cells that is considered for sharing is\n"); - log(" narrowed using a list of cell types. With this option all selected\n"); - log(" cells are considered for resource sharing.\n"); - log("\n"); - log(" IMPORTANT NOTE: If the -all option is used then no cells with internal\n"); - log(" state must be selected!\n"); - log("\n"); log(" -aggressive\n"); log(" Per default some heuristics are used to reduce the number of cells\n"); log(" considered for resource sharing to only large resources. This options\n"); @@ -1557,58 +1529,53 @@ struct SharePass : public Pass { config.limit = -1; config.pattern_limit = design->scratchpad_get_int("share.pattern_limit", 1000); - config.opt_force = false; config.opt_aggressive = false; config.opt_fast = false; - config.generic_uni_ops.insert(ID($not)); - // config.generic_uni_ops.insert(ID($pos)); - config.generic_uni_ops.insert(ID($neg)); + config.generic_uni_ops.set_id(ID($not)); + // config.generic_uni_ops.set_id(ID($pos)); + config.generic_uni_ops.set_id(ID($neg)); - config.generic_cbin_ops.insert(ID($and)); - config.generic_cbin_ops.insert(ID($or)); - config.generic_cbin_ops.insert(ID($xor)); - config.generic_cbin_ops.insert(ID($xnor)); + config.generic_cbin_ops.set_id(ID($and)); + config.generic_cbin_ops.set_id(ID($or)); + config.generic_cbin_ops.set_id(ID($xor)); + config.generic_cbin_ops.set_id(ID($xnor)); - config.generic_bin_ops.insert(ID($shl)); - config.generic_bin_ops.insert(ID($shr)); - config.generic_bin_ops.insert(ID($sshl)); - config.generic_bin_ops.insert(ID($sshr)); + config.generic_bin_ops.set_id(ID($shl)); + config.generic_bin_ops.set_id(ID($shr)); + config.generic_bin_ops.set_id(ID($sshl)); + config.generic_bin_ops.set_id(ID($sshr)); - config.generic_bin_ops.insert(ID($lt)); - config.generic_bin_ops.insert(ID($le)); - config.generic_bin_ops.insert(ID($eq)); - config.generic_bin_ops.insert(ID($ne)); - config.generic_bin_ops.insert(ID($eqx)); - config.generic_bin_ops.insert(ID($nex)); - config.generic_bin_ops.insert(ID($ge)); - config.generic_bin_ops.insert(ID($gt)); + config.generic_bin_ops.set_id(ID($lt)); + config.generic_bin_ops.set_id(ID($le)); + config.generic_bin_ops.set_id(ID($eq)); + config.generic_bin_ops.set_id(ID($ne)); + config.generic_bin_ops.set_id(ID($eqx)); + config.generic_bin_ops.set_id(ID($nex)); + config.generic_bin_ops.set_id(ID($ge)); + config.generic_bin_ops.set_id(ID($gt)); - config.generic_cbin_ops.insert(ID($add)); - config.generic_cbin_ops.insert(ID($mul)); + config.generic_cbin_ops.set_id(ID($add)); + config.generic_cbin_ops.set_id(ID($mul)); - config.generic_bin_ops.insert(ID($sub)); - config.generic_bin_ops.insert(ID($div)); - config.generic_bin_ops.insert(ID($mod)); - config.generic_bin_ops.insert(ID($divfloor)); - config.generic_bin_ops.insert(ID($modfloor)); - // config.generic_bin_ops.insert(ID($pow)); + config.generic_bin_ops.set_id(ID($sub)); + config.generic_bin_ops.set_id(ID($div)); + config.generic_bin_ops.set_id(ID($mod)); + config.generic_bin_ops.set_id(ID($divfloor)); + config.generic_bin_ops.set_id(ID($modfloor)); + // config.generic_bin_ops.set_id(ID($pow)); - config.generic_uni_ops.insert(ID($logic_not)); - config.generic_cbin_ops.insert(ID($logic_and)); - config.generic_cbin_ops.insert(ID($logic_or)); + config.generic_uni_ops.set_id(ID($logic_not)); + config.generic_cbin_ops.set_id(ID($logic_and)); + config.generic_cbin_ops.set_id(ID($logic_or)); - config.generic_other_ops.insert(ID($alu)); - config.generic_other_ops.insert(ID($macc)); + config.generic_other_ops.set_id(ID($alu)); + config.generic_other_ops.set_id(ID($macc)); log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-force") { - config.opt_force = true; - continue; - } if (args[argidx] == "-aggressive") { config.opt_aggressive = true; continue; diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index 15569ebfc..542c2c0e8 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -158,7 +158,7 @@ in `select` lines. Index lines are using the `index expr1 === expr2` syntax. `expr1` is evaluated during matcher initialization and the same restrictions apply as for -`select` expressions. `expr2` is evaluated when the match is calulated. It is a +`select` expressions. `expr2` is evaluated when the match is calculated. It is a function of any state variables assigned to by previous blocks. Both expression are converted to the given type and compared for equality. Only cells for which all `index` statements in the block pass are considered by the match. diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 19c2be4ca..8cccb96c4 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -97,6 +97,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did all_empty = false; if (all_empty) { + did_something = true; for (auto cs : sw->cases) delete cs; sw->cases.clear(); diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index eb3b154b2..086dd5278 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -157,6 +157,7 @@ struct Async2syncPass : public Pass { SigSpec sig_set = ff.sig_set; SigSpec sig_clr = ff.sig_clr; + SigSpec sig_clr_inv = ff.sig_clr; if (!ff.pol_set) { if (!ff.is_fine) @@ -166,24 +167,42 @@ struct Async2syncPass : public Pass { } if (ff.pol_clr) { + if (!ff.is_fine) + sig_clr_inv = module->Not(NEW_ID, sig_clr); + else + sig_clr_inv = module->NotGate(NEW_ID, sig_clr); + } else { if (!ff.is_fine) sig_clr = module->Not(NEW_ID, sig_clr); else sig_clr = module->NotGate(NEW_ID, sig_clr); } + // At this point, sig_set and sig_clr are now unconditionally + // active-high, and sig_clr_inv is inverted sig_clr + + SigSpec set_and_clr; + if (!ff.is_fine) + set_and_clr = module->And(NEW_ID, sig_set, sig_clr); + else + set_and_clr = module->AndGate(NEW_ID, sig_set, sig_clr); + if (!ff.is_fine) { SigSpec tmp = module->Or(NEW_ID, ff.sig_d, sig_set); - module->addAnd(NEW_ID, tmp, sig_clr, new_d); + tmp = module->And(NEW_ID, tmp, sig_clr_inv); + module->addBwmux(NEW_ID, tmp, Const(State::Sx, ff.width), set_and_clr, new_d); tmp = module->Or(NEW_ID, new_q, sig_set); - module->addAnd(NEW_ID, tmp, sig_clr, ff.sig_q); + tmp = module->And(NEW_ID, tmp, sig_clr_inv); + module->addBwmux(NEW_ID, tmp, Const(State::Sx, ff.width), set_and_clr, ff.sig_q); } else { SigSpec tmp = module->OrGate(NEW_ID, ff.sig_d, sig_set); - module->addAndGate(NEW_ID, tmp, sig_clr, new_d); + tmp = module->AndGate(NEW_ID, tmp, sig_clr_inv); + module->addMuxGate(NEW_ID, tmp, State::Sx, set_and_clr, new_d); tmp = module->OrGate(NEW_ID, new_q, sig_set); - module->addAndGate(NEW_ID, tmp, sig_clr, ff.sig_q); + tmp = module->AndGate(NEW_ID, tmp, sig_clr_inv); + module->addMuxGate(NEW_ID, tmp, State::Sx, set_and_clr, ff.sig_q); } ff.sig_d = new_d; diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index dd94dd0d7..b75c8aab1 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -123,10 +123,14 @@ struct Clk2fflogicPass : public Pass { return module->Mux(NEW_ID, a, b, s); } SigSpec bitwise_sr(Module *module, SigSpec a, SigSpec s, SigSpec r, bool is_fine) { - if (is_fine) - return module->AndGate(NEW_ID, module->OrGate(NEW_ID, a, s), module->NotGate(NEW_ID, r)); - else - return module->And(NEW_ID, module->Or(NEW_ID, a, s), module->Not(NEW_ID, r)); + if (is_fine) { + return module->MuxGate(NEW_ID, module->AndGate(NEW_ID, module->OrGate(NEW_ID, a, s), module->NotGate(NEW_ID, r)), RTLIL::State::Sx, module->AndGate(NEW_ID, s, r)); + } else { + std::vector y; + for (int i = 0; i < a.size(); i++) + y.push_back(module->MuxGate(NEW_ID, module->AndGate(NEW_ID, module->OrGate(NEW_ID, a[i], s[i]), module->NotGate(NEW_ID, r[i])), RTLIL::State::Sx, module->AndGate(NEW_ID, s[i], r[i]))); + return y; + } } void execute(std::vector args, RTLIL::Design *design) override { diff --git a/passes/sat/qbfsat.h b/passes/sat/qbfsat.h index 253cecce4..3441b7819 100644 --- a/passes/sat/qbfsat.h +++ b/passes/sat/qbfsat.h @@ -170,7 +170,6 @@ struct QbfSolutionType { std::smatch m; bool sat_regex_found = false; bool unsat_regex_found = false; - dict hole_value_recovered; for (const std::string &x : stdout_lines) { if(std::regex_search(x, m, hole_value_regex)) { std::string loc = m[1].str(); diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 90b85d709..9988eef62 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -31,6 +31,22 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +static SatSolver *find_satsolver(const std::string &name) +{ + for (auto solver = yosys_satsolver_list; solver != nullptr; solver = solver->next) + if (solver->name == name) + return solver; + return nullptr; +} + +static std::string list_satsolvers() +{ + std::string result; + for (auto solver = yosys_satsolver_list; solver != nullptr; solver = solver->next) + result += result.empty() ? solver->name : ", " + solver->name; + return result; +} + struct SatHelper { RTLIL::Design *design; @@ -60,8 +76,8 @@ struct SatHelper int max_timestep, timeout; bool gotTimeout; - SatHelper(RTLIL::Design *design, RTLIL::Module *module, bool enable_undef, bool set_def_formal) : - design(design), module(module), sigmap(module), ct(design), satgen(ez.get(), &sigmap) + SatHelper(RTLIL::Design *design, RTLIL::Module *module, SatSolver *solver, bool enable_undef, bool set_def_formal) : + design(design), module(module), sigmap(module), ct(design), ez(solver), satgen(ez.get(), &sigmap) { this->enable_undef = enable_undef; satgen.model_undef = enable_undef; @@ -227,16 +243,12 @@ struct SatHelper int import_cell_counter = 0; for (auto cell : module->cells()) if (design->selected(module, cell)) { - // log("Import cell: %s\n", RTLIL::id2cstr(cell->name)); if (satgen.importCell(cell, timestep)) { for (auto &p : cell->connections()) if (ct.cell_output(cell->type, p.first)) show_drivers.insert(sigmap(p.second), cell); import_cell_counter++; - } else if (ignore_unknown_cells) - log_warning("Failed to import cell %s (type %s) to SAT database.\n", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - else - log_error("Failed to import cell %s (type %s) to SAT database.\n", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + } else report_missing_model(ignore_unknown_cells, cell); } log("Imported %d cells to SAT database.\n", import_cell_counter); @@ -441,7 +453,7 @@ struct SatHelper log_assert(gotTimeout == false); ez->setSolverTimeout(timeout); bool success = ez->solve(modelExpressions, modelValues, assumptions); - if (ez->getSolverTimoutStatus()) + if (ez->getSolverTimeoutStatus()) gotTimeout = true; return success; } @@ -451,7 +463,7 @@ struct SatHelper log_assert(gotTimeout == false); ez->setSolverTimeout(timeout); bool success = ez->solve(modelExpressions, modelValues, a, b, c, d, e, f); - if (ez->getSolverTimoutStatus()) + if (ez->getSolverTimeoutStatus()) gotTimeout = true; return success; } @@ -961,10 +973,10 @@ struct SatPass : public Pass { log(" -show-regs, -show-public, -show-all\n"); log(" show all registers, show signals with 'public' names, show all signals\n"); log("\n"); - log(" -ignore_div_by_zero\n"); + log(" -ignore-div-by-zero\n"); log(" ignore all solutions that involve a division by zero\n"); log("\n"); - log(" -ignore_unknown_cells\n"); + log(" -ignore-unknown-cells\n"); log(" ignore all cells that can not be matched to a SAT model\n"); log("\n"); log("The following options can be used to set up a sequential problem:\n"); @@ -1066,6 +1078,10 @@ struct SatPass : public Pass { log(" -timeout \n"); log(" Maximum number of seconds a single SAT instance may take.\n"); log("\n"); + log(" -select-solver \n"); + log(" Select SAT solver implementation for this invocation.\n"); + log(" If not given, uses scratchpad key 'sat.solver' if set, otherwise default.\n"); + log("\n"); log(" -verify\n"); log(" Return an error and stop the synthesis script if the proof fails.\n"); log("\n"); @@ -1097,8 +1113,14 @@ struct SatPass : public Pass { log_header(design, "Executing SAT pass (solving SAT problems in the circuit).\n"); + std::string solver_name = design->scratchpad_get_string("sat.solver", ""); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-select-solver" && argidx+1 < args.size()) { + solver_name = args[++argidx]; + continue; + } if (args[argidx] == "-all") { loopcount = -1; continue; @@ -1141,7 +1163,7 @@ struct SatPass : public Pass { stepsize = max(1, atoi(args[++argidx].c_str())); continue; } - if (args[argidx] == "-ignore_div_by_zero") { + if (args[argidx] == "-ignore-div-by-zero" || args[argidx] == "-ignore_div_by_zero") { ignore_div_by_zero = true; continue; } @@ -1316,7 +1338,7 @@ struct SatPass : public Pass { show_all = true; continue; } - if (args[argidx] == "-ignore_unknown_cells") { + if (args[argidx] == "-ignore-unknown-cells" || args[argidx] == "-ignore_unknown_cells") { ignore_unknown_cells = true; continue; } @@ -1336,6 +1358,14 @@ struct SatPass : public Pass { } extra_args(args, argidx, design); + SatSolver *solver = yosys_satsolver; + if (!solver_name.empty()) { + solver = find_satsolver(solver_name); + if (solver == nullptr) + log_cmd_error("Unknown SAT solver '%s'. Available solvers: %s\n", + solver_name, list_satsolvers()); + } + RTLIL::Module *module = NULL; for (auto mod : design->selected_modules()) { if (module) @@ -1398,13 +1428,15 @@ struct SatPass : public Pass { shows.push_back(wire->name.str()); } + log("Using SAT solver `%s`.\n", solver->name.c_str()); + if (tempinduct) { if (loopcount > 0 || max_undef) log_cmd_error("The options -max, -all, and -max_undef are not supported for temporal induction proofs!\n"); - SatHelper basecase(design, module, enable_undef, set_def_formal); - SatHelper inductstep(design, module, enable_undef, set_def_formal); + SatHelper basecase(design, module, solver, enable_undef, set_def_formal); + SatHelper inductstep(design, module, solver, enable_undef, set_def_formal); basecase.sets = sets; basecase.set_assumes = set_assumes; @@ -1593,7 +1625,7 @@ struct SatPass : public Pass { if (maxsteps > 0) log_cmd_error("The options -maxsteps is only supported for temporal induction proofs!\n"); - SatHelper sathelper(design, module, enable_undef, set_def_formal); + SatHelper sathelper(design, module, solver, enable_undef, set_def_formal); sathelper.sets = sets; sathelper.set_assumes = set_assumes; diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index a29651653..1be993154 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/mem.h" #include "kernel/fstdata.h" #include "kernel/ff.h" @@ -52,9 +53,23 @@ static const std::map g_units = { "zs", -21 }, }; -static double stringToTime(std::string str) +struct scaled_time { + uint64_t time; + int scale; // exponent of 10, e.g. -6 = us, -9 = ns + bool end; +}; + +static uint64_t pow10(int n) { - if (str=="END") return -1; + int r = 1; + while (n--) + r *= 10; + return r; +} + +static scaled_time stringToTime(std::string str) +{ + if (str=="END") return {1, 0, true}; char *endptr; long value = strtol(str.c_str(), &endptr, 10); @@ -65,7 +80,7 @@ static double stringToTime(std::string str) if (value < 0) log_error("Time value '%s' must be positive\n", str); - return value * pow(10.0, g_units.at(endptr)); + return {(unsigned long)value, g_units.at(endptr), false}; } struct SimWorker; @@ -109,8 +124,8 @@ struct SimShared bool hdlname = false; int rstlen = 1; FstData *fst = nullptr; - double start_time = 0; - double stop_time = -1; + scaled_time start_time = {0, 0, false}; + scaled_time stop_time = {1, 0, true}; SimulationMode sim_mode = SimulationMode::sim; bool cycles_set = false; std::vector> outputfiles; @@ -215,7 +230,13 @@ struct SimInstance std::vector memories; - dict> signal_database; + struct signal_entry_t { + int id; + Const last_value; + SigSpec mapped_sig; + }; + + dict signal_database; dict>> trace_mem_database; dict, Const> trace_mem_init_database; dict fst_handles; @@ -412,11 +433,11 @@ struct SimInstance return result; } - Const get_state(SigSpec sig) + Const get_state_mapped(const SigSpec &mapped_sig) { - Const::Builder builder(GetSize(sig)); + Const::Builder builder(GetSize(mapped_sig)); - for (auto bit : sigmap(sig)) + for (auto bit : mapped_sig) if (bit.wire == nullptr) builder.push_back(bit.data); else if (state_nets.count(bit)) @@ -424,7 +445,12 @@ struct SimInstance else builder.push_back(State::Sz); - Const value = builder.build(); + return builder.build(); + } + + Const get_state(SigSpec sig) + { + Const value = get_state_mapped(sigmap(sig)); if (shared->debug) log("[%s] get %s: %s\n", hiername(), log_signal(sig), log_signal(value)); return value; @@ -549,31 +575,27 @@ struct SimInstance if (shared->debug) log("[%s] eval %s (%s)\n", hiername(), log_id(cell), log_id(cell->type)); - // Simple (A -> Y) and (A,B -> Y) cells - if (has_a && !has_c && !has_d && !has_s && has_y) { - set_state(sig_y, CellTypes::eval(cell, get_state(sig_a), get_state(sig_b))); - return; - } + bool err = false; + RTLIL::Const eval_state; + if (has_a && !has_c && !has_d && !has_s && has_y) + // Simple (A -> Y) and (A,B -> Y) cells + eval_state = CellTypes::eval(cell, get_state(sig_a), get_state(sig_b), &err); + else if (has_a && has_b && has_c && !has_d && !has_s && has_y) + // (A,B,C -> Y) cells + eval_state = CellTypes::eval(cell, get_state(sig_a), get_state(sig_b), get_state(sig_c), &err); + else if (has_a && !has_b && !has_c && !has_d && has_s && has_y) + // (A,S -> Y) cells + eval_state = CellTypes::eval(cell, get_state(sig_a), get_state(sig_s), &err); + else if (has_a && has_b && !has_c && !has_d && has_s && has_y) + // (A,B,S -> Y) cells + eval_state = CellTypes::eval(cell, get_state(sig_a), get_state(sig_b), get_state(sig_s), &err); + else + err = true; - // (A,B,C -> Y) cells - if (has_a && has_b && has_c && !has_d && !has_s && has_y) { - set_state(sig_y, CellTypes::eval(cell, get_state(sig_a), get_state(sig_b), get_state(sig_c))); - return; - } - - // (A,S -> Y) cells - if (has_a && !has_b && !has_c && !has_d && has_s && has_y) { - set_state(sig_y, CellTypes::eval(cell, get_state(sig_a), get_state(sig_s))); - return; - } - - // (A,B,S -> Y) cells - if (has_a && has_b && !has_c && !has_d && has_s && has_y) { - set_state(sig_y, CellTypes::eval(cell, get_state(sig_a), get_state(sig_b), get_state(sig_s))); - return; - } - - log_warning("Unsupported evaluable cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); + if (err) + log_warning("Unsupported evaluable cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); + else + set_state(sig_y, eval_state); return; } @@ -994,7 +1016,7 @@ struct SimInstance if (shared->hide_internal && wire->name[0] == '$') continue; - signal_database[wire] = make_pair(id, Const()); + signal_database[wire] = {id, Const(), sigmap(wire)}; id++; } @@ -1035,11 +1057,11 @@ struct SimInstance hdlname.pop_back(); for (auto name : hdlname) enter_scope("\\" + name); - register_signal(signal_name.c_str(), GetSize(signal.first), signal.first, signal.second.first, registers.count(signal.first)!=0); + register_signal(signal_name.c_str(), GetSize(signal.first), signal.first, signal.second.id, registers.count(signal.first)!=0); for (auto name : hdlname) exit_scope(); } else - register_signal(log_id(signal.first->name), GetSize(signal.first), signal.first, signal.second.first, registers.count(signal.first)!=0); + register_signal(log_id(signal.first->name), GetSize(signal.first), signal.first, signal.second.id, registers.count(signal.first)!=0); } for (auto &trace_mem : trace_mem_database) @@ -1111,15 +1133,14 @@ struct SimInstance { for (auto &it : signal_database) { - Wire *wire = it.first; - Const value = get_state(wire); - int id = it.second.first; + signal_entry_t &entry = it.second; + Const value = get_state_mapped(entry.mapped_sig); - if (it.second.second == value) + if (entry.last_value == value) continue; - it.second.second = value; - data->emplace(id, value); + entry.last_value = value; + data->emplace(entry.id, value); } for (auto &trace_mem : trace_mem_database) @@ -1238,6 +1259,10 @@ struct SimInstance bool checkSignals() { + // No checks performed when using stimulus + if (shared->sim_mode == SimulationMode::sim) + return false; + bool retVal = false; for(auto &item : fst_handles) { if (item.second==0) continue; // Ignore signals not found @@ -1247,9 +1272,7 @@ struct SimInstance log_warning("Signal '%s.%s' size is different in gold and gate.\n", scope, log_id(item.first)); continue; } - if (shared->sim_mode == SimulationMode::sim) { - // No checks performed when using stimulus - } else if (shared->sim_mode == SimulationMode::gate && !fst_val.is_fully_def()) { // FST data contains X + if (shared->sim_mode == SimulationMode::gate && !fst_val.is_fully_def()) { // FST data contains X for(int i=0;igetStartTime()) + if (start_time.time == 0) { + if (start_time.time < fst->getStartTime()) log_warning("Start time is before simulation file start time\n"); startCount = fst->getStartTime(); - } else if (start_time==-1) + } else if (start_time.end) startCount = fst->getEndTime(); else { - startCount = start_time / fst->getTimescale(); + startCount = start_time.time * pow10(start_time.scale - fst->getScale()); if (startCount > fst->getEndTime()) { startCount = fst->getEndTime(); log_warning("Start time is after simulation file end time\n"); } } - if (stop_time==0) { - if (stop_time < fst->getStartTime()) + if (stop_time.time == 0) { + if (stop_time.time < fst->getStartTime()) log_warning("Stop time is before simulation file start time\n"); stopCount = fst->getStartTime(); - } else if (stop_time==-1) + } else if (stop_time.end) stopCount = fst->getEndTime(); else { - stopCount = stop_time / fst->getTimescale(); + stopCount = stop_time.time * pow10(stop_time.scale - fst->getScale()); if (stopCount > fst->getEndTime()) { stopCount = fst->getEndTime(); log_warning("Stop time is after simulation file end time\n"); @@ -2165,27 +2188,27 @@ struct SimWorker : SimShared uint64_t startCount = 0; uint64_t stopCount = 0; - if (start_time==0) { - if (start_time < fst->getStartTime()) + if (start_time.time == 0) { + if (start_time.time < fst->getStartTime()) log_warning("Start time is before simulation file start time\n"); startCount = fst->getStartTime(); - } else if (start_time==-1) + } else if (start_time.end) startCount = fst->getEndTime(); else { - startCount = start_time / fst->getTimescale(); + startCount = start_time.time * pow10(start_time.scale - fst->getScale()); if (startCount > fst->getEndTime()) { startCount = fst->getEndTime(); log_warning("Start time is after simulation file end time\n"); } } - if (stop_time==0) { - if (stop_time < fst->getStartTime()) + if (stop_time.time == 0) { + if (stop_time.time < fst->getStartTime()) log_warning("Stop time is before simulation file start time\n"); stopCount = fst->getStartTime(); - } else if (stop_time==-1) + } else if (stop_time.end) stopCount = fst->getEndTime(); else { - stopCount = stop_time / fst->getTimescale(); + stopCount = stop_time.time * pow10(stop_time.scale - fst->getScale()); if (stopCount > fst->getEndTime()) { stopCount = fst->getEndTime(); log_warning("Stop time is after simulation file end time\n"); diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 91b3b563a..eccad8998 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -39,6 +39,7 @@ OBJS += passes/techmap/muxcover.o OBJS += passes/techmap/aigmap.o OBJS += passes/techmap/tribuf.o OBJS += passes/techmap/lut2mux.o +OBJS += passes/techmap/lut2bmux.o OBJS += passes/techmap/nlutmap.o OBJS += passes/techmap/shregmap.o OBJS += passes/techmap/deminout.o @@ -54,6 +55,7 @@ OBJS += passes/techmap/extractinv.o OBJS += passes/techmap/cellmatch.o OBJS += passes/techmap/clockgate.o OBJS += passes/techmap/constmap.o +OBJS += passes/techmap/arith_tree.o endif ifeq ($(DISABLE_SPAWN),0) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index e25a6facd..1ed0c867d 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -43,7 +43,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/ffinit.h" #include "kernel/ff.h" #include "kernel/cost.h" @@ -63,13 +63,19 @@ # include # include # include +# include #endif #ifndef _WIN32 # include # include +# include +#endif +#if defined(__wasm) +#include #endif #include "frontends/blif/blifparse.h" +#include "liberty_cache.h" #ifdef YOSYS_LINK_ABC namespace abc { @@ -125,11 +131,11 @@ struct AbcConfig std::vector liberty_files; std::vector genlib_files; std::string constr_file; + std::string abc_liberty_args; vector lut_costs; std::string delay_target; std::string sop_inputs; std::string sop_products; - std::string lutin_shared; std::vector dont_use_cells; bool cleanup = true; bool keepff = false; @@ -143,6 +149,14 @@ struct AbcConfig bool markgroups = false; pool enabled_gates; bool cmos_cost = false; + + bool is_yosys_abc() const { +#ifdef ABCEXTERNAL + return false; +#else + return exe_file == yosys_abc_executable; +#endif + } }; struct AbcSigVal { @@ -155,7 +169,12 @@ struct AbcSigVal { } }; -#if defined(__linux__) && !defined(YOSYS_DISABLE_SPAWN) +// REUSE_YOSYS_ABC_PROCESSES only works when ABC is built with ENABLE_READLINE. +#if defined(__linux__) && !defined(YOSYS_DISABLE_SPAWN) && defined(YOSYS_ENABLE_READLINE) +#define REUSE_YOSYS_ABC_PROCESSES +#endif + +#ifdef REUSE_YOSYS_ABC_PROCESSES struct AbcProcess { pid_t pid; @@ -188,10 +207,10 @@ struct AbcProcess int status; int ret = waitpid(pid, &status, 0); if (ret != pid) { - log_error("waitpid(%d) failed", pid); + log_error("waitpid(%d) failed\n", pid); } if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - log_error("ABC failed with status %X", status); + log_error("ABC failed with status %X\n", status); } if (from_child_pipe >= 0) close(from_child_pipe); @@ -203,12 +222,12 @@ std::optional spawn_abc(const char* abc_exe, DeferredLogs &logs) { // fork()s. int to_child_pipe[2]; if (pipe2(to_child_pipe, O_CLOEXEC) != 0) { - logs.log_error("pipe failed"); + logs.log_error("pipe failed\n"); return std::nullopt; } int from_child_pipe[2]; if (pipe2(from_child_pipe, O_CLOEXEC) != 0) { - logs.log_error("pipe failed"); + logs.log_error("pipe failed\n"); return std::nullopt; } @@ -221,39 +240,39 @@ std::optional spawn_abc(const char* abc_exe, DeferredLogs &logs) { posix_spawn_file_actions_t file_actions; if (posix_spawn_file_actions_init(&file_actions) != 0) { - logs.log_error("posix_spawn_file_actions_init failed"); + logs.log_error("posix_spawn_file_actions_init failed\n"); return std::nullopt; } if (posix_spawn_file_actions_addclose(&file_actions, to_child_pipe[1]) != 0) { - logs.log_error("posix_spawn_file_actions_addclose failed"); + logs.log_error("posix_spawn_file_actions_addclose failed\n"); return std::nullopt; } if (posix_spawn_file_actions_addclose(&file_actions, from_child_pipe[0]) != 0) { - logs.log_error("posix_spawn_file_actions_addclose failed"); + logs.log_error("posix_spawn_file_actions_addclose failed\n"); return std::nullopt; } if (posix_spawn_file_actions_adddup2(&file_actions, to_child_pipe[0], STDIN_FILENO) != 0) { - logs.log_error("posix_spawn_file_actions_adddup2 failed"); + logs.log_error("posix_spawn_file_actions_adddup2 failed\n"); return std::nullopt; } if (posix_spawn_file_actions_adddup2(&file_actions, from_child_pipe[1], STDOUT_FILENO) != 0) { - logs.log_error("posix_spawn_file_actions_adddup2 failed"); + logs.log_error("posix_spawn_file_actions_adddup2 failed\n"); return std::nullopt; } if (posix_spawn_file_actions_addclose(&file_actions, to_child_pipe[0]) != 0) { - logs.log_error("posix_spawn_file_actions_addclose failed"); + logs.log_error("posix_spawn_file_actions_addclose failed\n"); return std::nullopt; } if (posix_spawn_file_actions_addclose(&file_actions, from_child_pipe[1]) != 0) { - logs.log_error("posix_spawn_file_actions_addclose failed"); + logs.log_error("posix_spawn_file_actions_addclose failed\n"); return std::nullopt; } char arg1[] = "-s"; char* argv[] = { strdup(abc_exe), arg1, nullptr }; if (0 != posix_spawnp(&result.pid, abc_exe, &file_actions, nullptr, argv, environ)) { - logs.log_error("posix_spawnp %s failed (errno=%s)", abc_exe, strerrorname_np(errno)); + logs.log_error("posix_spawnp %s failed (errno=%s)\n", abc_exe, strerror(errno)); return std::nullopt; } free(argv[0]); @@ -272,12 +291,14 @@ using AbcSigMap = SigValMap; struct RunAbcState { const AbcConfig &config; - std::string tempdir_name; + std::string per_run_tempdir_name; std::vector signal_list; bool did_run = false; bool err = false; DeferredLogs logs; dict pi_map, po_map; + std::string abc_script; + std::string dont_use_args; RunAbcState(const AbcConfig &config) : config(config) {} void run(ConcurrentStack &process_pool); @@ -823,16 +844,23 @@ std::string fold_abc_cmd(std::string str) return new_str; } -std::string replace_tempdir(std::string text, std::string tempdir_name, bool show_tempdir) +std::string replace_tempdir(std::string text, std::string_view global_tempdir_name, std::string_view per_run_tempdir_name, bool show_tempdir) { if (show_tempdir) return text; while (1) { - size_t pos = text.find(tempdir_name); + size_t pos = text.find(global_tempdir_name); if (pos == std::string::npos) break; - text = text.substr(0, pos) + "" + text.substr(pos + GetSize(tempdir_name)); + text = text.substr(0, pos) + "" + text.substr(pos + GetSize(global_tempdir_name)); + } + + while (1) { + size_t pos = text.find(per_run_tempdir_name); + if (pos == std::string::npos) + break; + text = text.substr(0, pos) + "" + text.substr(pos + GetSize(per_run_tempdir_name)); } std::string selfdir_name = proc_self_dirname(); @@ -854,11 +882,12 @@ struct abc_output_filter bool got_cr; int escape_seq_state; std::string linebuf; - std::string tempdir_name; + std::string global_tempdir_name; + std::string per_run_tempdir_name; bool show_tempdir; - abc_output_filter(RunAbcState& state, std::string tempdir_name, bool show_tempdir) - : state(state), tempdir_name(tempdir_name), show_tempdir(show_tempdir) + abc_output_filter(RunAbcState& state, std::string global_tempdir_name, std::string per_run_tempdir_name, bool show_tempdir) + : state(state), global_tempdir_name(global_tempdir_name), per_run_tempdir_name(per_run_tempdir_name), show_tempdir(show_tempdir) { got_cr = false; escape_seq_state = 0; @@ -885,7 +914,7 @@ struct abc_output_filter return; } if (ch == '\n') { - state.logs.log("ABC: %s\n", replace_tempdir(linebuf, tempdir_name, show_tempdir)); + state.logs.log("ABC: %s\n", replace_tempdir(linebuf, global_tempdir_name, per_run_tempdir_name, show_tempdir)); got_cr = false, linebuf.clear(); return; } @@ -986,96 +1015,110 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module const AbcConfig &config = run_abc.config; if (config.cleanup) - run_abc.tempdir_name = get_base_tmpdir() + "/"; + run_abc.per_run_tempdir_name = get_base_tmpdir() + "/"; else - run_abc.tempdir_name = "_tmp_"; - run_abc.tempdir_name += proc_program_prefix() + "yosys-abc-XXXXXX"; - run_abc.tempdir_name = make_temp_dir(run_abc.tempdir_name); + run_abc.per_run_tempdir_name = "_tmp_"; + run_abc.per_run_tempdir_name += proc_program_prefix() + "yosys-abc-XXXXXX"; + run_abc.per_run_tempdir_name = make_temp_dir(run_abc.per_run_tempdir_name); log_header(design, "Extracting gate netlist of module `%s' to `%s/input.blif'..\n", - module->name.c_str(), replace_tempdir(run_abc.tempdir_name, run_abc.tempdir_name, config.show_tempdir).c_str()); + module->name.c_str(), replace_tempdir(run_abc.per_run_tempdir_name, config.global_tempdir_name, run_abc.per_run_tempdir_name, config.show_tempdir).c_str()); - std::string abc_script = stringf("read_blif \"%s/input.blif\"; ", run_abc.tempdir_name); + run_abc.abc_script = stringf("read_blif \"%s/input.blif\"; ", run_abc.per_run_tempdir_name); if (!config.liberty_files.empty() || !config.genlib_files.empty()) { - std::string dont_use_args; + run_abc.dont_use_args = ""; for (std::string dont_use_cell : config.dont_use_cells) { - dont_use_args += stringf("-X \"%s\" ", dont_use_cell); + run_abc.dont_use_args += stringf("-X \"%s\" ", dont_use_cell); } - bool first_lib = true; - for (std::string liberty_file : config.liberty_files) { - abc_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args, first_lib ? "" : "-m", liberty_file); - first_lib = false; + + std::string merged_scl; + if (config.abc_liberty_args.empty()) { + merged_scl = convert_liberty_files_to_merged_scl(config.liberty_files, run_abc.dont_use_args, config.exe_file); } + if (!merged_scl.empty()) { + run_abc.abc_script += stringf("read_scl \"%s\" ; ", merged_scl.c_str()); + } else if(!config.liberty_files.empty()) { + if (!config.abc_liberty_args.empty()) { + log("ABC: abc_liberty_args provided, using liberty format\n"); + } else { + log_warning("ABC: Merged scl conversion failed, using liberty format\n"); + } + bool first_lib = true; + for (std::string liberty_file : config.liberty_files) { + run_abc.abc_script += stringf("read_lib %s %s %s -w \"%s\" ; ", run_abc.dont_use_args, first_lib ? "" : "-m", config.abc_liberty_args, liberty_file); + first_lib = false; + } + } + for (std::string liberty_file : config.genlib_files) - abc_script += stringf("read_library \"%s\"; ", liberty_file); + run_abc.abc_script += stringf("read_library \"%s\"; ", liberty_file); if (!config.constr_file.empty()) - abc_script += stringf("read_constr -v \"%s\"; ", config.constr_file); + run_abc.abc_script += stringf("read_constr -v \"%s\"; ", config.constr_file); } else if (!config.lut_costs.empty()) - abc_script += stringf("read_lut %s/lutdefs.txt; ", config.global_tempdir_name); + run_abc.abc_script += stringf("read_lut %s/lutdefs.txt; ", config.global_tempdir_name); else - abc_script += stringf("read_library %s/stdcells.genlib; ", config.global_tempdir_name); + run_abc.abc_script += stringf("read_library %s/stdcells.genlib; ", config.global_tempdir_name); if (!config.script_file.empty()) { const std::string &script_file = config.script_file; if (script_file[0] == '+') { for (size_t i = 1; i < script_file.size(); i++) if (script_file[i] == '\'') - abc_script += "'\\''"; + run_abc.abc_script += "'\\''"; else if (script_file[i] == ',') - abc_script += " "; + run_abc.abc_script += " "; else - abc_script += script_file[i]; + run_abc.abc_script += script_file[i]; } else - abc_script += stringf("source %s", script_file); + run_abc.abc_script += stringf("source %s", script_file); } else if (!config.lut_costs.empty()) { bool all_luts_cost_same = true; for (int this_cost : config.lut_costs) if (this_cost != config.lut_costs.front()) all_luts_cost_same = false; - abc_script += config.fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; + run_abc.abc_script += config.fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; if (all_luts_cost_same && !config.fast_mode) - abc_script += "; lutpack {S}"; + run_abc.abc_script += "; lutpack -S 1"; } else if (!config.liberty_files.empty() || !config.genlib_files.empty()) - abc_script += config.constr_file.empty() ? + run_abc.abc_script += config.constr_file.empty() ? (config.fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (config.fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); else if (config.sop_mode) - abc_script += config.fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; + run_abc.abc_script += config.fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; else - abc_script += config.fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL; + run_abc.abc_script += config.fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL; if (config.script_file.empty() && !config.delay_target.empty()) - for (size_t pos = abc_script.find("dretime;"); pos != std::string::npos; pos = abc_script.find("dretime;", pos+1)) - abc_script = abc_script.substr(0, pos) + "dretime; retime -o {D};" + abc_script.substr(pos+8); + for (size_t pos = run_abc.abc_script.find("dretime;"); pos != std::string::npos; pos = run_abc.abc_script.find("dretime;", pos+1)) + run_abc.abc_script = run_abc.abc_script.substr(0, pos) + "dretime; retime -o {D};" + run_abc.abc_script.substr(pos+8); - for (size_t pos = abc_script.find("{D}"); pos != std::string::npos; pos = abc_script.find("{D}", pos)) - abc_script = abc_script.substr(0, pos) + config.delay_target + abc_script.substr(pos+3); + for (size_t pos = run_abc.abc_script.find("{D}"); pos != std::string::npos; pos = run_abc.abc_script.find("{D}", pos)) + run_abc.abc_script = run_abc.abc_script.substr(0, pos) + config.delay_target + run_abc.abc_script.substr(pos+3); - for (size_t pos = abc_script.find("{I}"); pos != std::string::npos; pos = abc_script.find("{I}", pos)) - abc_script = abc_script.substr(0, pos) + config.sop_inputs + abc_script.substr(pos+3); + for (size_t pos = run_abc.abc_script.find("{I}"); pos != std::string::npos; pos = run_abc.abc_script.find("{I}", pos)) + run_abc.abc_script = run_abc.abc_script.substr(0, pos) + config.sop_inputs + run_abc.abc_script.substr(pos+3); - for (size_t pos = abc_script.find("{P}"); pos != std::string::npos; pos = abc_script.find("{P}", pos)) - abc_script = abc_script.substr(0, pos) + config.sop_products + abc_script.substr(pos+3); + for (size_t pos = run_abc.abc_script.find("{P}"); pos != std::string::npos; pos = run_abc.abc_script.find("{P}", pos)) + run_abc.abc_script = run_abc.abc_script.substr(0, pos) + config.sop_products + run_abc.abc_script.substr(pos+3); - for (size_t pos = abc_script.find("{S}"); pos != std::string::npos; pos = abc_script.find("{S}", pos)) - abc_script = abc_script.substr(0, pos) + config.lutin_shared + abc_script.substr(pos+3); if (config.abc_dress) - abc_script += stringf("; dress \"%s/input.blif\"", run_abc.tempdir_name); - abc_script += stringf("; write_blif %s/output.blif", run_abc.tempdir_name); - abc_script = add_echos_to_abc_cmd(abc_script); -#if defined(__linux__) && !defined(YOSYS_DISABLE_SPAWN) - abc_script += "; echo; echo \"YOSYS_ABC_DONE\"\n"; + run_abc.abc_script += stringf("; dress \"%s/input.blif\"", run_abc.per_run_tempdir_name); + run_abc.abc_script += stringf("; write_blif %s/output.blif", run_abc.per_run_tempdir_name); + run_abc.abc_script = add_echos_to_abc_cmd(run_abc.abc_script); +#if defined(REUSE_YOSYS_ABC_PROCESSES) + if (config.is_yosys_abc()) + run_abc.abc_script += "; echo; echo \"YOSYS_ABC_DONE\"\n"; #endif - for (size_t i = 0; i+1 < abc_script.size(); i++) - if (abc_script[i] == ';' && abc_script[i+1] == ' ') - abc_script[i+1] = '\n'; + for (size_t i = 0; i+1 < run_abc.abc_script.size(); i++) + if (run_abc.abc_script[i] == ';' && run_abc.abc_script[i+1] == ' ') + run_abc.abc_script[i+1] = '\n'; - std::string buffer = stringf("%s/abc.script", run_abc.tempdir_name); + std::string buffer = stringf("%s/abc.script", run_abc.per_run_tempdir_name); FILE *f = fopen(buffer.c_str(), "wt"); if (f == nullptr) log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno)); - fprintf(f, "%s\n", abc_script.c_str()); + fprintf(f, "%s\n", run_abc.abc_script.c_str()); fclose(f); if (dff_mode || !clk_str.empty()) @@ -1127,42 +1170,86 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module handle_loops(assign_map, module); } +#if defined(REUSE_YOSYS_ABC_PROCESSES) +static bool is_abc_prompt(const std::string &line, std::string &rest) { + size_t pos = 0; + while (true) { + // The prompt may not start at the start of the line, because + // ABC can output progress and maybe other data that isn't + // newline-terminated. + size_t start = line.find("abc ", pos); + if (start == std::string::npos) + return false; + pos = start + 4; + + size_t digits = 0; + while (pos + digits < line.size() && line[pos + digits] >= '0' && line[pos + digits] <= '9') + ++digits; + if (digits < 2) + return false; + if (line.substr(pos + digits, 2) == "> ") { + rest = line.substr(pos + digits + 2); + return true; + } + } +} + bool read_until_abc_done(abc_output_filter &filt, int fd, DeferredLogs &logs) { std::string line; char buf[1024]; + bool seen_source_cmd = false; + bool seen_yosys_abc_done = false; while (true) { int ret = read(fd, buf, sizeof(buf) - 1); if (ret < 0) { - logs.log_error("Failed to read from ABC, errno=%d", errno); + logs.log_error("Failed to read from ABC, errno=%d\n", errno); return false; } if (ret == 0) { - logs.log_error("ABC exited prematurely"); + logs.log_error("ABC exited prematurely\n"); return false; } char *start = buf; char *end = buf + ret; while (start < end) { char *p = static_cast(memchr(start, '\n', end - start)); - if (p == nullptr) { - break; + char *upto = p == nullptr ? end : p + 1; + line.append(start, upto - start); + start = upto; + + std::string rest; + bool is_prompt = is_abc_prompt(line, rest); + if (is_prompt && seen_source_cmd) { + // This is the first prompt after we sourced the script. + // We are done here. + // We won't have seen a newline yet since ABC is waiting at the prompt. + if (!seen_yosys_abc_done) + logs.log_error("ABC script did not complete successfully\n"); + return seen_yosys_abc_done; } - line.append(start, p + 1 - start); - if (line.substr(0, 14) == "YOSYS_ABC_DONE") { - // Ignore any leftover output, there should only be a prompt perhaps - return true; + if (line.empty() || line[line.size() - 1] != '\n') { + // No newline yet, wait for more text + continue; } filt.next_line(line); + if (is_prompt && rest.substr(0, 7) == "source ") + seen_source_cmd = true; + if (line.substr(0, 14) == "YOSYS_ABC_DONE") + seen_yosys_abc_done = true; line.clear(); - start = p + 1; } line.append(start, end - start); } } +#endif +#if defined(REUSE_YOSYS_ABC_PROCESSES) void RunAbcState::run(ConcurrentStack &process_pool) +#else +void RunAbcState::run(ConcurrentStack &) +#endif { - std::string buffer = stringf("%s/input.blif", tempdir_name); + std::string buffer = stringf("%s/input.blif", per_run_tempdir_name); FILE *f = fopen(buffer.c_str(), "wt"); if (f == nullptr) { logs.log("Opening %s for writing failed: %s\n", buffer, strerror(errno)); @@ -1285,24 +1372,28 @@ void RunAbcState::run(ConcurrentStack &process_pool) logs.log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", count_gates, GetSize(signal_list), count_input, count_output); - if (count_output > 0) - { - std::string tmp_script_name = stringf("%s/abc.script", tempdir_name); - logs.log("Running ABC script: %s\n", replace_tempdir(tmp_script_name, tempdir_name, config.show_tempdir)); + if (count_output == 0) { + logs.log("Don't call ABC as there is nothing to map.\n"); + return; + } + int ret; + std::string tmp_script_name = stringf("%s/abc.script", per_run_tempdir_name); + do { + logs.log("Running ABC script: %s\n", replace_tempdir(tmp_script_name, config.global_tempdir_name, per_run_tempdir_name, config.show_tempdir)); errno = 0; - abc_output_filter filt(*this, tempdir_name, config.show_tempdir); + abc_output_filter filt(*this, config.global_tempdir_name, per_run_tempdir_name, config.show_tempdir); #ifdef YOSYS_LINK_ABC - string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name); + string temp_stdouterr_name = stringf("%s/stdouterr.txt", per_run_tempdir_name); FILE *temp_stdouterr_w = fopen(temp_stdouterr_name.c_str(), "w"); if (temp_stdouterr_w == NULL) - log_error("ABC: cannot open a temporary file for output redirection"); + logs.log_error("ABC: cannot open a temporary file for output redirection"); fflush(stdout); fflush(stderr); FILE *old_stdout = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering FILE *old_stderr = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering #if defined(__wasm) -#define fd_renumber(from, to) (void)__wasi_fd_renumber(from, to) +#define fd_renumber(from, to) (void)__wasilibc_fd_renumber(from, to) #else #define fd_renumber(from, to) dup2(from, to) #endif @@ -1318,7 +1409,7 @@ void RunAbcState::run(ConcurrentStack &process_pool) abc_argv[2] = strdup("-f"); abc_argv[3] = strdup(tmp_script_name.c_str()); abc_argv[4] = 0; - int ret = abc::Abc_RealMain(4, abc_argv); + ret = abc::Abc_RealMain(4, abc_argv); free(abc_argv[0]); free(abc_argv[1]); free(abc_argv[2]); @@ -1333,39 +1424,42 @@ void RunAbcState::run(ConcurrentStack &process_pool) for (std::string line; std::getline(temp_stdouterr_r, line); ) filt.next_line(line + "\n"); temp_stdouterr_r.close(); -#elif defined(__linux__) && !defined(YOSYS_DISABLE_SPAWN) - AbcProcess process; - if (std::optional process_opt = process_pool.try_pop_back()) { - process = std::move(process_opt.value()); - } else if (std::optional process_opt = spawn_abc(config.exe_file.c_str(), logs)) { - process = std::move(process_opt.value()); - } else { - return; - } - std::string cmd = stringf( - "empty\n" - "source %s\n", tmp_script_name); - int ret = write(process.to_child_pipe, cmd.c_str(), cmd.size()); - if (ret != static_cast(cmd.size())) { - logs.log_error("write failed"); - return; - } - ret = read_until_abc_done(filt, process.from_child_pipe, logs) ? 0 : 1; - if (ret == 0) { - process_pool.push_back(std::move(process)); - } + break; #else - std::string cmd = stringf("\"%s\" -s -f %s/abc.script 2>&1", config.exe_file.c_str(), tempdir_name.c_str()); - int ret = run_command(cmd, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1)); -#endif - if (ret != 0) { - logs.log_error("ABC: execution of script \"%s\" failed: return code %d (errno=%d).\n", tmp_script_name, ret, errno); - return; +#if defined(REUSE_YOSYS_ABC_PROCESSES) + if (config.is_yosys_abc()) { + AbcProcess process; + if (std::optional process_opt = process_pool.try_pop_back()) { + process = std::move(process_opt.value()); + } else if (std::optional process_opt = spawn_abc(config.exe_file.c_str(), logs)) { + process = std::move(process_opt.value()); + } else { + return; + } + std::string cmd = stringf( + "empty\n" + "source %s\n", tmp_script_name); + ret = write(process.to_child_pipe, cmd.c_str(), cmd.size()); + if (ret != static_cast(cmd.size())) { + logs.log_error("write failed"); + return; + } + ret = read_until_abc_done(filt, process.from_child_pipe, logs) ? 0 : 1; + if (ret == 0) { + process_pool.push_back(std::move(process)); + } + break; } - did_run = true; +#endif + std::string cmd = stringf("\"%s\" -s -f %s 2>&1", config.exe_file, tmp_script_name); + ret = run_command(cmd, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1)); +#endif + } while (false); + if (ret != 0) { + logs.log_error("ABC: execution of script \"%s\" failed: return code %d (errno=%d).\n", tmp_script_name, ret, errno); return; } - log("Don't call ABC as there is nothing to map.\n"); + did_run = true; } void emit_global_input_files(const AbcConfig &config) @@ -1437,7 +1531,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL return; } - std::string buffer = stringf("%s/%s", run_abc.tempdir_name, "output.blif"); + std::string buffer = stringf("%s/%s", run_abc.per_run_tempdir_name, "output.blif"); std::ifstream ifs; ifs.open(buffer); if (ifs.fail()) @@ -1724,7 +1818,7 @@ void AbcModuleState::finish() if (run_abc.config.cleanup) { log("Removing temp directory.\n"); - remove_directory(run_abc.tempdir_name); + remove_directory(run_abc.per_run_tempdir_name); } log_pop(); } @@ -1806,7 +1900,7 @@ struct AbcPass : public Pass { log("%s\n", fold_abc_cmd(ABC_COMMAND_CTR)); log("\n"); log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT "; lutpack {S}")); + log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT "; lutpack -S 1")); log("\n"); log(" for -lut/-luts (different LUT sizes):\n"); log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT)); @@ -1874,10 +1968,6 @@ struct AbcPass : public Pass { log(" maximum number of SOP products.\n"); log(" (replaces {P} in the default scripts above)\n"); log("\n"); - log(" -S \n"); - log(" maximum number of LUT inputs shared.\n"); - log(" (replaces {S} in the default scripts above, default: -S 1)\n"); - log("\n"); log(" -lut \n"); log(" generate netlist using luts of (max) the specified width.\n"); log("\n"); @@ -1953,6 +2043,10 @@ struct AbcPass : public Pass { log(" preserve naming by an equivalence check between the original and\n"); log(" post-ABC netlists (experimental).\n"); log("\n"); + log(" -liberty_args \n"); + log(" when -liberty is used, also pass the specified arguments to ABC\n"); + log(" command \"read_lib\". Example: -liberty_args \"-G 250\"\n"); + log("\n"); log("When no target cell library is specified the Yosys standard cell library is\n"); log("loaded into ABC before the ABC script is executed.\n"); log("\n"); @@ -1988,11 +2082,6 @@ struct AbcPass : public Pass { if (design->scratchpad.count("abc.P")) { config.sop_products = "-P " + design->scratchpad_get_string("abc.P"); } - if (design->scratchpad.count("abc.S")) { - config.lutin_shared = "-S " + design->scratchpad_get_string("abc.S"); - } else { - config.lutin_shared = "-S 1"; - } lut_arg = design->scratchpad_get_string("abc.lut", lut_arg); luts_arg = design->scratchpad_get_string("abc.luts", luts_arg); config.sop_mode = design->scratchpad_get_bool("abc.sop", false); @@ -2075,10 +2164,6 @@ struct AbcPass : public Pass { config.sop_products = "-P " + args[++argidx]; continue; } - if (arg == "-S" && argidx+1 < args.size()) { - config.lutin_shared = "-S " + args[++argidx]; - continue; - } if (arg == "-lut" && argidx+1 < args.size()) { lut_arg = args[++argidx]; continue; @@ -2144,6 +2229,14 @@ struct AbcPass : public Pass { config.markgroups = true; continue; } + if (arg == "-liberty_args" && argidx+1 < args.size()) { + config.abc_liberty_args = args[++argidx]; + if (!config.abc_liberty_args.empty()) { + if (config.abc_liberty_args[0] == '\"' && config.abc_liberty_args.back() == '\"') + config.abc_liberty_args = config.abc_liberty_args.substr(1, config.abc_liberty_args.size() - 2); + } + continue; + } break; } extra_args(args, argidx, design); @@ -2382,7 +2475,7 @@ struct AbcPass : public Pass { continue; } - CellTypes ct(design); + NewCellTypes ct(design); std::vector all_cells = mod->selected_cells(); pool unassigned_cells(all_cells.begin(), all_cells.end()); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8b61a9299..90c48ae34 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -38,53 +38,53 @@ struct Abc9Pass : public ScriptPass Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } void on_register() override { - RTLIL::constpad["abc9.script.default"] = "+&scorr; &sweep; &dc2; &dch -f -r; &ps; &if {C} {W} {D} {R} -v; &mfs"; - RTLIL::constpad["abc9.script.default.area"] = "+&scorr; &sweep; &dc2; &dch -f -r; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; - RTLIL::constpad["abc9.script.default.fast"] = "+&if {C} {W} {D} {R} -v"; + RTLIL::constpad["abc9.script.default"] = "+&scorr; &sweep; &dc2; &dch -f -r; &ps; &if {W} {D} {R} -v; &mfs"; + RTLIL::constpad["abc9.script.default.area"] = "+&scorr; &sweep; &dc2; &dch -f -r; &ps; &if {W} {D} {R} -a -v; &mfs"; + RTLIL::constpad["abc9.script.default.fast"] = "+&if {W} {D} {R} -v"; // Based on ABC's &flow RTLIL::constpad["abc9.script.flow"] = "+&scorr; &sweep;" \ "&dch -C 500;" \ /* Round 1 */ \ - /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 1 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &dsdb;" \ - /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 2 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &syn2 -m -R 10; &dsdb;" \ "&blut -a -K 6;" \ - /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 3 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ /* Round 2 */ \ "&st; &sopb;" \ - /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 1 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &dsdb;" \ - /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 2 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &syn2 -m -R 10; &dsdb;" \ "&blut -a -K 6;" \ - /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 3 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ /* Round 3 */ \ - /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 1 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &dsdb;" \ - /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Map 2 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;" \ "&st; &syn2 -m -R 10; &dsdb;" \ "&blut -a -K 6;" \ - /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;"; + /* Map 3 */ "&unmap; &if {W} {D} {R} -v; &save; &load; &mfs;"; // Based on ABC's &flow2 RTLIL::constpad["abc9.script.flow2"] = "+&scorr; &sweep;" \ - /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ - /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ "&load; &st; &sopb -R 10 -C 4; " \ - /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ - /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ + /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ "&load"; // Based on ABC's &flow3 -m RTLIL::constpad["abc9.script.flow3"] = "+&scorr; &sweep;" \ - "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ - "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ - "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&if {W} {D}; &save; &st; &syn2; &if {W} {D} {R} -v; &save; &load;"\ + "&st; &if -g -K 6; &dch -f; &if {W} {D} {R} -v; &save; &load;"\ + "&st; &if -g -K 6; &synch2; &if {W} {D} {R} -v; &save; &load;"\ "&mfs"; // As above, but with &mfs calls as in the original &flow3 RTLIL::constpad["abc9.script.flow3mfs"] = "+&scorr; &sweep;" \ - "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ - "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &mfs; &save; &load;"\ - "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &mfs; &save; &load;"\ + "&if {W} {D}; &save; &st; &syn2; &if {W} {D} {R} -v; &save; &load;"\ + "&st; &if -g -K 6; &dch -f; &if {W} {D} {R} -v; &mfs; &save; &load;"\ + "&st; &if -g -K 6; &synch2; &if {W} {D} {R} -v; &mfs; &save; &load;"\ "&mfs"; } void help() override @@ -121,20 +121,11 @@ struct Abc9Pass : public ScriptPass log(" if no -script parameter is given, the following scripts are used:\n"); log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos))); log("\n"); - log(" -fast\n"); - log(" use different default scripts that are slightly faster (at the cost\n"); - log(" of output quality):\n"); - log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos))); - log("\n"); log(" -D \n"); log(" set delay target. the string {D} in the default scripts above is\n"); log(" replaced by this option when used, and an empty string otherwise\n"); log(" (indicating best possible delay).\n"); log("\n"); -// log(" -S \n"); -// log(" maximum number of LUT inputs shared.\n"); -// log(" (replaces {S} in the default scripts above, default: -S 1)\n"); -// log("\n"); log(" -lut \n"); log(" generate netlist using luts of (max) the specified width.\n"); log("\n"); @@ -219,17 +210,14 @@ struct Abc9Pass : public ScriptPass for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if ((arg == "-exe" || arg == "-script" || arg == "-D" || - /*arg == "-S" ||*/ arg == "-lut" || arg == "-luts" || - /*arg == "-box" ||*/ arg == "-W" || arg == "-genlib" || - arg == "-constr" || arg == "-dont_use" || arg == "-liberty") && + arg == "-lut" || arg == "-luts" || arg == "-W") && argidx+1 < args.size()) { if (arg == "-lut" || arg == "-luts") lut_mode = true; exe_cmd << " " << arg << " " << args[++argidx]; continue; } - if (arg == "-fast" || /* arg == "-dff" || */ - /* arg == "-nocleanup" || */ arg == "-showtmp") { + if (arg == "-showtmp") { exe_cmd << " " << arg; continue; } diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index 4449065f8..a32816612 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -24,11 +24,15 @@ #include "kernel/register.h" #include "kernel/log.h" +#include "liberty_cache.h" #ifndef _WIN32 # include # include #endif +#if defined(__wasm) +#include +#endif #ifdef YOSYS_LINK_ABC namespace abc { @@ -165,7 +169,7 @@ struct abc9_output_filter }; void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe_file, - vector lut_costs, bool dff_mode, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, + vector lut_costs, bool dff_mode, std::string delay_target, bool show_tempdir, std::string box_file, std::string lut_file, std::vector liberty_files, std::string wire_delay, std::string tempdir_name, std::string constr_file, std::vector dont_use_cells, std::vector genlib_files) @@ -181,11 +185,19 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe for (std::string dont_use_cell : dont_use_cells) { dont_use_args += stringf("-X \"%s\" ", dont_use_cell); } - bool first_lib = true; - for (std::string liberty_file : liberty_files) { - abc9_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args, first_lib ? "" : "-m", liberty_file); - first_lib = false; + + std::string merged_scl = convert_liberty_files_to_merged_scl(liberty_files, dont_use_args, exe_file); + if (!merged_scl.empty()) { + abc9_script += stringf("read_scl \"%s\" ; ", merged_scl.c_str()); + } else if(!liberty_files.empty()) { + log_warning("ABC: Merged scl conversion failed, using liberty format\n"); + bool first_lib = true; + for (std::string liberty_file : liberty_files) { + abc9_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args, first_lib ? "" : "-m", liberty_file); + first_lib = false; + } } + if (!constr_file.empty()) abc9_script += stringf("read_constr -v \"%s\"; ", constr_file); } else if (!genlib_files.empty()) { @@ -210,26 +222,18 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe } else abc9_script += stringf("source %s", script_file); } else if (!lut_costs.empty() || !lut_file.empty()) { - abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos) - : RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos); + abc9_script += RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos); + } else if (!liberty_files.empty() || !genlib_files.empty()) { + abc9_script += RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos); } else log_abort(); for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos)) abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3); - //for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos)) - // abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3); - for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); - std::string C; - if (design->scratchpad.count("abc9.if.C")) - C = "-C " + design->scratchpad_get_string("abc9.if.C"); - for (size_t pos = abc9_script.find("{C}"); pos != std::string::npos; pos = abc9_script.find("{C}", pos)) - abc9_script = abc9_script.substr(0, pos) + C + abc9_script.substr(pos+3); - std::string R; if (design->scratchpad.count("abc9.if.R")) R = "-R " + design->scratchpad_get_string("abc9.if.R"); @@ -248,7 +252,7 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe } abc9_script += stringf("; &ps -l; &write -n %s/output.aig", tempdir_name); - if (design->scratchpad_get_bool("abc9.verify")) { + if (design->scratchpad_get_bool("abc9.verify", true)) { if (dff_mode) abc9_script += "; &verify -s"; else @@ -295,7 +299,7 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe FILE *old_stdout = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering FILE *old_stderr = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering #if defined(__wasm) -#define fd_renumber(from, to) (void)__wasi_fd_renumber(from, to) +#define fd_renumber(from, to) (void)__wasilibc_fd_renumber(from, to) #else #define fd_renumber(from, to) dup2(from, to) #endif @@ -369,11 +373,6 @@ struct Abc9ExePass : public Pass { log(" if no -script parameter is given, the following scripts are used:\n"); log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos))); log("\n"); - log(" -fast\n"); - log(" use different default scripts that are slightly faster (at the cost\n"); - log(" of output quality):\n"); - log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos))); - log("\n"); log(" -constr \n"); log(" pass this file with timing constraints to ABC.\n"); log(" use with -liberty.\n"); @@ -453,9 +452,9 @@ struct Abc9ExePass : public Pass { std::string exe_file = yosys_abc_executable; std::string script_file, clk_str, box_file, lut_file, constr_file; std::vector liberty_files, genlib_files, dont_use_cells; - std::string delay_target, lutin_shared = "-S 1", wire_delay; + std::string delay_target, wire_delay; std::string tempdir_name; - bool fast_mode = false, dff_mode = false; + bool dff_mode = false; bool show_tempdir = false; vector lut_costs; @@ -472,7 +471,6 @@ struct Abc9ExePass : public Pass { } lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); - fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode); show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); box_file = design->scratchpad_get_string("abc9.box", box_file); @@ -504,20 +502,12 @@ struct Abc9ExePass : public Pass { delay_target = "-D " + args[++argidx]; continue; } - //if (arg == "-S" && argidx+1 < args.size()) { - // lutin_shared = "-S " + args[++argidx]; - // continue; - //} if (arg == "-lut" && argidx+1 < args.size()) { lut_arg = args[++argidx]; continue; } if (arg == "-luts" && argidx+1 < args.size()) { - lut_arg = args[++argidx]; - continue; - } - if (arg == "-fast") { - fast_mode = true; + luts_arg = args[++argidx]; continue; } if (arg == "-dff") { @@ -622,7 +612,7 @@ struct Abc9ExePass : public Pass { log_cmd_error("abc9_exe '-genlib' is incompatible with '-dont_use'.\n"); abc9_module(design, script_file, exe_file, lut_costs, dff_mode, - delay_target, lutin_shared, fast_mode, show_tempdir, + delay_target, show_tempdir, box_file, lut_file, liberty_files, wire_delay, tempdir_name, constr_file, dont_use_cells, genlib_files); } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 8d3869ece..fc27ac58a 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -21,8 +21,9 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/utils.h" -#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" #include "kernel/timinginfo.h" +#include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -96,7 +97,6 @@ void check(RTLIL::Design *design, bool dff_mode) ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_) }; - pool processed; for (auto module : design->selected_modules()) for (auto cell : module->cells()) { auto inst_module = design->module(cell->type); @@ -587,6 +587,7 @@ void break_scc(RTLIL::Module *module) auto id = it->second; auto r = ids_seen.insert(id); cell->attributes.erase(it); + // Cut exactly one representative cell per SCC id. if (!r.second) continue; for (auto &c : cell->connections_) { @@ -710,8 +711,6 @@ void prep_xaiger(RTLIL::Module *module, bool dff) SigMap sigmap(module); - dict> bit_drivers, bit_users; - TopoSort toposort; dict> box_ports; for (auto cell : module->cells()) { @@ -750,39 +749,100 @@ void prep_xaiger(RTLIL::Module *module, bool dff) } } } - else if (!yosys_celltypes.cell_known(cell->type)) - continue; - - // TODO: Speed up toposort -- we care about box ordering only - for (auto conn : cell->connections()) { - if (cell->input(conn.first)) - for (auto bit : sigmap(conn.second)) - bit_users[bit].insert(cell->name); - - if (cell->output(conn.first) && !abc9_flop) - for (auto bit : sigmap(conn.second)) - bit_drivers[bit].insert(cell->name); - } - toposort.node(cell->name); } if (box_ports.empty()) return; - for (auto &it : bit_users) - if (bit_drivers.count(it.first)) - for (auto driver_cell : bit_drivers.at(it.first)) - for (auto user_cell : it.second) - toposort.edge(driver_cell, user_cell); + // Build the same topo graph for the initial pass and the optional retry. + auto build_toposort = [&](TopoSort &toposort) { + dict> bit_drivers, bit_users; - if (ys_debug(1)) - toposort.analyze_loops = true; + for (auto cell : module->cells()) { + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + continue; + if (cell->has_keep_attr()) + continue; - bool no_loops = toposort.sort(); + auto inst_module = design->module(cell->type); + bool abc9_flop = inst_module && inst_module->get_bool_attribute(ID::abc9_flop); + if (abc9_flop && !dff) + continue; + if (!(inst_module && inst_module->get_bool_attribute(ID::abc9_box)) && !yosys_celltypes.cell_known(cell->type)) + continue; + + // TODO: Speed up toposort -- we care about box ordering only + for (auto conn : cell->connections()) { + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell->name); + + if (cell->output(conn.first) && !abc9_flop) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell->name); + } + toposort.node(cell->name); + } + + // Build producer -> consumer edges on sigmapped nets. + for (auto &it : bit_users) + if (bit_drivers.count(it.first)) + for (auto driver_cell : bit_drivers.at(it.first)) + for (auto user_cell : it.second) + toposort.edge(driver_cell, user_cell); + if (ys_debug(1)) + toposort.analyze_loops = true; + return toposort.sort(); + }; + + // Build TopoSort in a container, as we may need to conditionally rebuild it on retry. + std::optional> toposort; + toposort.emplace(); + bool no_loops = build_toposort(toposort.value()); + + // Fallback for residual loops after SCC cutting: insert additional + // breakers on non-box loop cells, then re-run toposort checks. + if (!no_loops) { + SigSpec I, O; + pool broken_cells; + + for (auto &loop : toposort.value().loops) + for (auto cell_name : loop) { + // Loop reports can overlap; cut each cell at most once. + if (!broken_cells.insert(cell_name).second) + continue; + auto cell = module->cell(cell_name); + log_assert(cell); + auto inst_module = design->module(cell->type); + if (inst_module && inst_module->get_bool_attribute(ID::abc9_box)) + continue; + for (auto &c : cell->connections_) { + if (c.second.is_fully_const()) continue; + if (cell->output(c.first)) { + Wire *w = module->addWire(NEW_ID, GetSize(c.second)); + I.append(w); + O.append(c.second); + c.second = w; + } + } + } + + if (!I.empty()) { + auto cell = module->addCell(NEW_ID, ID($__ABC9_SCC_BREAKER)); + log_assert(GetSize(I) == GetSize(O)); + cell->setParam(ID::WIDTH, GetSize(I)); + cell->setPort(ID::I, std::move(I)); + cell->setPort(ID::O, std::move(O)); + + // Rebuild topo ordering after inserting the additional breakers. + toposort.emplace(); + no_loops = build_toposort(toposort.value()); + } + } if (ys_debug(1)) { unsigned i = 0; - for (auto &it : toposort.loops) { + for (auto &it : toposort.value().loops) { log(" loop %d\n", i++); for (auto cell_name : it) { auto cell = module->cell(cell_name); @@ -806,7 +866,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) TimingInfo timing; int port_id = 1, box_count = 0; - for (auto cell_name : toposort.sorted) { + for (auto cell_name : toposort.value().sorted) { RTLIL::Cell *cell = module->cell(cell_name); log_assert(cell); @@ -1559,7 +1619,6 @@ clone_lut: } } - //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); log("ABC RESULTS: input signals: %8d\n", in_wires); log("ABC RESULTS: output signals: %8d\n", out_wires); @@ -1592,7 +1651,7 @@ static void replace_zbufs(Design *design) if (sig[i] == State::Sz) { Wire *w = mod->addWire(NEW_ID); Cell *ud = mod->addCell(NEW_ID, ID($tribuf)); - ud->set_bool_attribute(ID(aiger2_zbuf)); + ud->set_bool_attribute(ID::aiger2_zbuf); ud->setParam(ID::WIDTH, 1); ud->setPort(ID::Y, w); ud->setPort(ID::EN, State::S0); diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 4e279c577..9850ff609 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -18,7 +18,7 @@ */ #include "kernel/register.h" -#include "kernel/rtlil.h" +#include "kernel/yosys_common.h" #include "kernel/utils.h" USING_YOSYS_NAMESPACE @@ -27,7 +27,8 @@ PRIVATE_NAMESPACE_BEGIN std::vector order_modules(Design *design, std::vector modules) { std::set modules_set(modules.begin(), modules.end()); - TopoSort sort; + using Order = IdString::compare_ptr_by_name; + TopoSort sort; for (auto m : modules) { sort.node(m); @@ -49,6 +50,17 @@ struct AbcNewPass : public ScriptPass { experimental(); } + void on_register() override + { + RTLIL::constpad["abc_new.script.speed"] = "+&st; &dch -r;" \ + "&nf; &st; &syn2; &if -g -K 6; &synch2 -r;" \ + "&nf; &st; &syn2; &if -g -K 6; &synch2 -r;" \ + "&nf; &st; &syn2; &if -g -K 6; &synch2 -r;" \ + "&nf; &st; &syn2; &if -g -K 6; &synch2 -r;" \ + "&nf; &st; &syn2; &if -g -K 6; &synch2 -r;" \ + "&nf"; + } + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -109,6 +121,11 @@ struct AbcNewPass : public ScriptPass { } extra_args(args, argidx, d); + // If no script provided, use a default. + if (abc_exe_options.find("-script") == std::string::npos) { + d->scratchpad_set_string("abc9.script", RTLIL::constpad["abc_new.script.speed"]); + } + log_header(d, "Executing ABC_NEW pass.\n"); log_push(); run_script(d, run_from, run_to); diff --git a/passes/techmap/arith_tree.cc b/passes/techmap/arith_tree.cc new file mode 100644 index 000000000..9494fa958 --- /dev/null +++ b/passes/techmap/arith_tree.cc @@ -0,0 +1,426 @@ +/** + * Replaces chains of $add/$sub and $macc cells with carry-save adder trees + * + * Terminology: + * - parent: Cells that consume another cell's output + * - chainable: Adds/subs with no carry-out usage + * - chain: Connected path of chainable cells + */ + +#include "kernel/macc.h" +#include "kernel/sigtools.h" +#include "kernel/wallace_tree.h" +#include "kernel/yosys.h" + +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct Operand { + SigSpec sig; + bool is_signed; + bool negate; +}; + +struct Traversal { + SigMap sigmap; + dict> bit_consumers; + dict fanout; + Traversal(Module *module) : sigmap(module) + { + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_consumers[bit].insert(cell); + + for (auto &pair : bit_consumers) + fanout[pair.first] = pair.second.size(); + + for (auto wire : module->wires()) + if (wire->port_output) + for (auto bit : sigmap(SigSpec(wire))) + fanout[bit]++; + } +}; + +struct Cells { + pool addsub; + pool alu; + pool macc; + + static bool is_addsub(Cell *cell) { return cell->type == ID($add) || cell->type == ID($sub); } + + static bool is_alu(Cell *cell) { return cell->type == ID($alu); } + + static bool is_macc(Cell *cell) { return cell->type == ID($macc) || cell->type == ID($macc_v2); } + + bool empty() { return addsub.empty() && alu.empty() && macc.empty(); } + + Cells(Module *module) + { + for (auto cell : module->cells()) { + if (is_addsub(cell)) + addsub.insert(cell); + else if (is_alu(cell)) + alu.insert(cell); + else if (is_macc(cell)) + macc.insert(cell); + } + } +}; + +struct AluInfo { + Cells &cells; + Traversal &traversal; + bool is_subtract(Cell *cell) + { + SigSpec bi = traversal.sigmap(cell->getPort(ID::BI)); + SigSpec ci = traversal.sigmap(cell->getPort(ID::CI)); + return GetSize(bi) == 1 && bi[0] == State::S1 && GetSize(ci) == 1 && ci[0] == State::S1; + } + + bool is_add(Cell *cell) + { + SigSpec bi = traversal.sigmap(cell->getPort(ID::BI)); + SigSpec ci = traversal.sigmap(cell->getPort(ID::CI)); + return GetSize(bi) == 1 && bi[0] == State::S0 && GetSize(ci) == 1 && ci[0] == State::S0; + } + + bool is_chainable(Cell *cell) + { + if (!(is_add(cell) || is_subtract(cell))) + return false; + + for (auto bit : traversal.sigmap(cell->getPort(ID::X))) + if (traversal.fanout.count(bit) && traversal.fanout[bit] > 0) + return false; + for (auto bit : traversal.sigmap(cell->getPort(ID::CO))) + if (traversal.fanout.count(bit) && traversal.fanout[bit] > 0) + return false; + + return true; + } +}; + +struct Rewriter { + Module *module; + Cells &cells; + Traversal traversal; + AluInfo alu_info; + + Rewriter(Module *module, Cells &cells) : module(module), cells(cells), traversal(module), alu_info{cells, traversal} {} + + Cell *sole_chainable_consumer(SigSpec sig, const pool &candidates) + { + Cell *consumer = nullptr; + for (auto bit : sig) { + if (!traversal.fanout.count(bit) || traversal.fanout[bit] != 1) + return nullptr; + if (!traversal.bit_consumers.count(bit) || traversal.bit_consumers[bit].size() != 1) + return nullptr; + + Cell *c = *traversal.bit_consumers[bit].begin(); + if (!candidates.count(c)) + return nullptr; + + if (consumer == nullptr) + consumer = c; + else if (consumer != c) + return nullptr; + } + return consumer; + } + + dict find_parents(const pool &candidates) + { + dict parent_of; + for (auto cell : candidates) { + Cell *consumer = sole_chainable_consumer(traversal.sigmap(cell->getPort(ID::Y)), candidates); + if (consumer && consumer != cell) + parent_of[cell] = consumer; + } + return parent_of; + } + + std::pair>, pool> invert_parent_map(const dict &parent_of) + { + dict> children_of; + pool has_parent; + for (auto &[child, parent] : parent_of) { + children_of[parent].insert(child); + has_parent.insert(child); + } + return {children_of, has_parent}; + } + + pool collect_chain(Cell *root, const dict> &children_of) + { + pool chain; + std::queue q; + q.push(root); + while (!q.empty()) { + Cell *cur = q.front(); + q.pop(); + if (!chain.insert(cur).second) + continue; + auto it = children_of.find(cur); + if (it != children_of.end()) + for (auto child : it->second) + q.push(child); + } + return chain; + } + + pool internal_bits(const pool &chain) + { + pool bits; + for (auto cell : chain) + for (auto bit : traversal.sigmap(cell->getPort(ID::Y))) + bits.insert(bit); + return bits; + } + + static bool overlaps(SigSpec sig, const pool &bits) + { + for (auto bit : sig) + if (bits.count(bit)) + return true; + return false; + } + + bool feeds_subtracted_port(Cell *child, Cell *parent) + { + bool parent_subtracts; + if (parent->type == ID($sub)) + parent_subtracts = true; + else if (cells.is_alu(parent)) + parent_subtracts = alu_info.is_subtract(parent); + else + return false; + + if (!parent_subtracts) + return false; + + // Check if any bit of child's Y connects to parent's B + SigSpec child_y = traversal.sigmap(child->getPort(ID::Y)); + SigSpec parent_b = traversal.sigmap(parent->getPort(ID::B)); + for (auto bit : child_y) + for (auto pbit : parent_b) + if (bit == pbit) + return true; + return false; + } + + std::vector extract_chain_operands(const pool &chain, Cell *root, const dict &parent_of, int &neg_compensation) + { + pool chain_bits = internal_bits(chain); + + // Propagate negation flags through chain + dict negated; + negated[root] = false; + { + std::queue q; + q.push(root); + while (!q.empty()) { + Cell *cur = q.front(); + q.pop(); + for (auto cell : chain) { + if (!parent_of.count(cell) || parent_of.at(cell) != cur) + continue; + if (negated.count(cell)) + continue; + negated[cell] = negated[cur] ^ feeds_subtracted_port(cell, cur); + q.push(cell); + } + } + } + + // Extract leaf operands + std::vector operands; + neg_compensation = 0; + + for (auto cell : chain) { + bool cell_neg = negated.count(cell) ? negated[cell] : false; + + SigSpec a = traversal.sigmap(cell->getPort(ID::A)); + SigSpec b = traversal.sigmap(cell->getPort(ID::B)); + bool a_signed = cell->getParam(ID::A_SIGNED).as_bool(); + bool b_signed = cell->getParam(ID::B_SIGNED).as_bool(); + bool b_sub = (cell->type == ID($sub)) || (cells.is_alu(cell) && alu_info.is_subtract(cell)); + + // Only add operands not produced by other chain cells + if (!overlaps(a, chain_bits)) { + operands.push_back({a, a_signed, cell_neg}); + if (cell_neg) + neg_compensation++; + } + if (!overlaps(b, chain_bits)) { + bool neg = cell_neg ^ b_sub; + operands.push_back({b, b_signed, neg}); + if (neg) + neg_compensation++; + } + } + return operands; + } + + bool extract_macc_operands(Cell *cell, std::vector &operands, int &neg_compensation) + { + Macc macc(cell); + neg_compensation = 0; + + for (auto &term : macc.terms) { + // Bail on multiplication + if (GetSize(term.in_b) != 0) + return false; + operands.push_back({term.in_a, term.is_signed, term.do_subtract}); + if (term.do_subtract) + neg_compensation++; + } + return true; + } + + SigSpec extend_operand(SigSpec sig, bool is_signed, int width) + { + if (GetSize(sig) < width) { + SigBit pad; + if (is_signed && GetSize(sig) > 0) + pad = sig[GetSize(sig) - 1]; + else + pad = State::S0; + sig.append(SigSpec(pad, width - GetSize(sig))); + } + if (GetSize(sig) > width) + sig = sig.extract(0, width); + return sig; + } + + void replace_with_carry_save_tree(std::vector &operands, SigSpec result_y, int neg_compensation, const char *desc) + { + int width = GetSize(result_y); + std::vector extended; + extended.reserve(operands.size() + 1); + + for (auto &op : operands) { + SigSpec s = extend_operand(op.sig, op.is_signed, width); + if (op.negate) + s = module->Not(NEW_ID, s); + extended.push_back(s); + } + + // Add correction for negated operands (-x = ~x + 1 so 1 per negation) + if (neg_compensation > 0) + extended.push_back(SigSpec(neg_compensation, width)); + + int compressor_count; + auto [a, b] = wallace_reduce_scheduled(module, extended, width, &compressor_count); + log(" %s -> %d $fa + 1 $add (%d operands, module %s)\n", desc, compressor_count, (int)operands.size(), log_id(module)); + + // Emit final add + module->addAdd(NEW_ID, a, b, result_y, false); + } + + void process_chains() + { + pool candidates; + for (auto cell : cells.addsub) + candidates.insert(cell); + for (auto cell : cells.alu) + if (alu_info.is_chainable(cell)) + candidates.insert(cell); + + if (candidates.empty()) + return; + + auto parent_of = find_parents(candidates); + auto [children_of, has_parent] = invert_parent_map(parent_of); + + pool to_remove; + for (auto root : candidates) { + if (has_parent.count(root) || to_remove.count(root)) + continue; // Not a tree root + + pool chain = collect_chain(root, children_of); + if (chain.size() < 2) + continue; + + int neg_compensation; + auto operands = extract_chain_operands(chain, root, parent_of, neg_compensation); + if (operands.size() < 3) + continue; + + for (auto c : chain) + to_remove.insert(c); + + replace_with_carry_save_tree(operands, root->getPort(ID::Y), neg_compensation, "Replaced add/sub chain"); + } + + for (auto cell : to_remove) + module->remove(cell); + } + + void process_maccs() + { + for (auto cell : cells.macc) { + std::vector operands; + int neg_compensation; + if (!extract_macc_operands(cell, operands, neg_compensation)) + continue; + if (operands.size() < 3) + continue; + + replace_with_carry_save_tree(operands, cell->getPort(ID::Y), neg_compensation, "Replaced $macc"); + module->remove(cell); + } + } +}; + +void run(Module *module) +{ + Cells cells(module); + + if (cells.empty()) + return; + + Rewriter rewriter{module, cells}; + rewriter.process_chains(); + rewriter.process_maccs(); +} + +struct ArithTreePass : public Pass { + ArithTreePass() : Pass("arith_tree", "convert add/sub/macc chains to carry-save adder trees") {} + + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" arith_tree [selection]\n"); + log("\n"); + log("This pass replaces chains of $add/$sub cells, $alu cells (with constant\n"); + log("BI/CI), and $macc/$macc_v2 cells (without multiplications) with carry-save\n"); + log("adder trees using $fa cells and a single final $add.\n"); + log("\n"); + log("The tree uses Wallace-tree scheduling: at each level, ready operands are\n"); + log("grouped into triplets and compressed via full adders, giving\n"); + log("O(log_{1.5} N) depth for N input operands.\n"); + log("\n"); + } + + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing ARITH_TREE pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + break; + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + run(module); + } + } +} ArithTreePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/booth.cc b/passes/techmap/booth.cc index 11ff71b29..c0bad784a 100644 --- a/passes/techmap/booth.cc +++ b/passes/techmap/booth.cc @@ -58,6 +58,7 @@ synth -top my_design -booth #include "kernel/sigtools.h" #include "kernel/yosys.h" #include "kernel/macc.h" +#include "kernel/wallace_tree.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -317,36 +318,6 @@ struct BoothPassWorker { } } - SigSig WallaceSum(int width, std::vector summands) - { - for (auto &s : summands) - s.extend_u0(width); - - while (summands.size() > 2) { - std::vector new_summands; - int i; - for (i = 0; i < (int) summands.size() - 2; i += 3) { - SigSpec x = module->addWire(NEW_ID, width); - SigSpec y = module->addWire(NEW_ID, width); - BuildBitwiseFa(module, NEW_ID.str(), summands[i], summands[i + 1], - summands[i + 2], x, y); - new_summands.push_back(y); - new_summands.push_back({x.extract(0, width - 1), State::S0}); - } - - new_summands.insert(new_summands.begin(), summands.begin() + i, summands.end()); - - std::swap(summands, new_summands); - } - - if (!summands.size()) - return SigSig(SigSpec(width, State::S0), SigSpec(width, State::S0)); - else if (summands.size() == 1) - return SigSig(summands[0], SigSpec(width, State::S0)); - else - return SigSig(summands[0], summands[1]); - } - /* Build Multiplier. ------------------------- @@ -415,16 +386,16 @@ struct BoothPassWorker { // Later on yosys will clean up unused constants // DebugDumpAlignPP(aligned_pp); - SigSig wtree_sum = WallaceSum(z_sz, aligned_pp); + auto [wtree_a, wtree_b] = wallace_reduce_scheduled(module, aligned_pp, z_sz); // Debug code: Dump out the csa trees // DumpCSATrees(debug_csa_trees); // Build the CPA to do the final accumulation. - log_assert(wtree_sum.second[0] == State::S0); + log_assert(wtree_b[0] == State::S0); if (mapped_cpa) - BuildCPA(module, wtree_sum.first, {State::S0, wtree_sum.second.extract_end(1)}, Z); + BuildCPA(module, wtree_a, wtree_b, Z); else - module->addAdd(NEW_ID, wtree_sum.first, {wtree_sum.second.extract_end(1), State::S0}, Z); + module->addAdd(NEW_ID, wtree_a, wtree_b, Z); } /* diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index b68e5d93d..650719cd5 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -337,6 +337,8 @@ struct ClockgatePass : public Pass { FfData ff(nullptr, cell); // It would be odd to get constants, but we better handle it if (ff.has_ce) { + if (ff.has_srst && !ff.ce_over_srst) + continue; if (!ff.sig_clk.is_bit() || !ff.sig_ce.is_bit()) continue; if (!ff.sig_clk[0].is_wire() || !ff.sig_ce[0].is_wire()) diff --git a/passes/techmap/constmap.cc b/passes/techmap/constmap.cc index 6d18b8494..1df50e47d 100644 --- a/passes/techmap/constmap.cc +++ b/passes/techmap/constmap.cc @@ -71,6 +71,8 @@ struct ConstmapPass : public Pass { } extra_args(args, argidx, design); + if (celltype.empty()) + log_cmd_error("Missing required option -cell.\n"); if (design->has(celltype)) { Module *existing = design->module(celltype); diff --git a/passes/techmap/dffunmap.cc b/passes/techmap/dffunmap.cc index 020597c4b..e72c250bb 100644 --- a/passes/techmap/dffunmap.cc +++ b/passes/techmap/dffunmap.cc @@ -78,7 +78,6 @@ struct DffunmapPass : public Pass { continue; FfData ff(&initvals, cell); - IdString name = cell->name; if (!ff.has_clk) continue; diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 1984f82f5..46ab7e520 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -40,10 +40,10 @@ int bindec(unsigned char v) r += (~((v & 2) - 1)) & 10; r += (~((v & 4) - 1)) & 100; r += (~((v & 8) - 1)) & 1000; - r += (~((v & 16) - 1)) & 10000; - r += (~((v & 32) - 1)) & 100000; - r += (~((v & 64) - 1)) & 1000000; - r += (~((v & 128) - 1)) & 10000000; + r += (~((v & 16) - 1)) & 10'000; + r += (~((v & 32) - 1)) & 100'000; + r += (~((v & 64) - 1)) & 1'000'000; + r += (~((v & 128) - 1)) & 10'000'000; return r; } diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index f5f225a9b..5b447745a 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -1246,14 +1246,14 @@ struct FlowmapWorker } } log(" Breaking LUT %s to %s LUT %s (potential %d).\n", - log_signal(breaking_lut), lut_nodes[breaking_gate] ? "reuse" : "extract", log_signal(breaking_gate), best_potential); + log_signal(breaking_lut), lut_nodes[breaking_gate] ? "reuse" : "extract", log_signal(breaking_gate), best_potential); if (debug_relax) log(" Removing breaking gate %s from LUT.\n", log_signal(breaking_gate)); lut_gates[breaking_lut].erase(breaking_gate); auto cut_inputs = cut_lut_at_gate(breaking_lut, breaking_gate); - pool gate_inputs = cut_inputs.first, other_inputs = cut_inputs.second; + pool gate_inputs = cut_inputs.first; pool worklist = lut_gates[breaking_lut]; pool elim_gates = gate_inputs; diff --git a/passes/techmap/liberty_cache.h b/passes/techmap/liberty_cache.h new file mode 100644 index 000000000..8ae89947f --- /dev/null +++ b/passes/techmap/liberty_cache.h @@ -0,0 +1,145 @@ +#ifndef LIBERTY_CACHE_H +#define LIBERTY_CACHE_H + +#include "kernel/yosys.h" + +#ifdef YOSYS_LINK_ABC +namespace abc { + int Abc_RealMain(int argc, char *argv[]); +} +#endif + +YOSYS_NAMESPACE_BEGIN + +/* + * convert_liberty_files_to_merged_scl() - Convert multiple Liberty files to a single merged SCL cache file. + * @liberty_files: Vector of liberty file paths to merge + * @dont_use_args: Pre-built ABC -X flags string + * @abc_exe: Path to ABC executable for conversion + * + * Return: Path to merged SCL cache file, or empty string if conversion fails + */ +inline std::string convert_liberty_files_to_merged_scl(const std::vector &liberty_files, const std::string &dont_use_args, const std::string &abc_exe) +{ + if (liberty_files.empty()) + return ""; + + std::string cache_dir = get_base_tmpdir() + "/yosys-liberty-scl-cache"; + + if (!create_directory(cache_dir)) { + log_warning("ABC: cannot create cache directory %s, falling back to liberty format\n", cache_dir.c_str()); + return ""; + } + + // Sort to ensure consistent hash regardless of order + std::vector sorted_files = liberty_files; + std::sort(sorted_files.begin(), sorted_files.end()); + std::string hash_input; + time_t newest_mtime = 0; + + for (const std::string &liberty_file : sorted_files) { + struct stat liberty_stat; + if (stat(liberty_file.c_str(), &liberty_stat) != 0) { + log_error("ABC: cannot stat liberty file: %s\n", liberty_file.c_str()); + return ""; + } + hash_input += liberty_file + "|"; + if (liberty_stat.st_mtime > newest_mtime) + newest_mtime = liberty_stat.st_mtime; + } + + hash_input += dont_use_args; + unsigned int hash = 0; + + for (char c : hash_input) + hash = hash * 31 + c; + + std::string merged_scl = stringf("%s/yosys_merged_%08x.scl", cache_dir.c_str(), hash); + bool need_convert = true; + struct stat scl_stat; + + // Check if merged SCL exists and is newer than all liberty files + if (stat(merged_scl.c_str(), &scl_stat) == 0) { + if (scl_stat.st_mtime >= newest_mtime) { + log("ABC: using cached merged SCL: %s (%zu files)\n", merged_scl.c_str(), liberty_files.size()); + need_convert = false; + } + } + + if (need_convert) { + // read_lib -X cell1 -X cell2 file1 ; read_lib -X cell1 -X cell2 -m file2 ; ... ; write_scl merged.scl + std::string temp_scl = merged_scl + ".tmp"; + +#ifdef YOSYS_LINK_ABC + std::string script_path = stringf("%s/yosys_merged_scl_convert_%08x.script", cache_dir.c_str(), hash); + FILE *f = fopen(script_path.c_str(), "w"); + + if (f == NULL) { + log_warning("ABC: cannot open %s for writing, falling back to liberty format\n", script_path.c_str()); + return ""; + } + + bool first = true; + + for (const std::string &liberty_file : liberty_files) { + fprintf(f, "read_lib %s%s-w \"%s\"\n", dont_use_args.c_str(), first ? "" : "-m ", liberty_file.c_str()); + first = false; + } + + fprintf(f, "write_scl \"%s\"\n", temp_scl.c_str()); + fclose(f); + + char *abc_argv[5]; + abc_argv[0] = strdup(abc_exe.empty() ? "yosys-abc" : abc_exe.c_str()); + abc_argv[1] = strdup("-s"); + abc_argv[2] = strdup("-f"); + abc_argv[3] = strdup(script_path.c_str()); + abc_argv[4] = 0; + int ret = abc::Abc_RealMain(4, abc_argv); + free(abc_argv[0]); + free(abc_argv[1]); + free(abc_argv[2]); + free(abc_argv[3]); + remove(script_path.c_str()); + + if (ret != 0) { + log_warning("ABC: merged SCL conversion failed (ret=%d), falling back to liberty format\n", ret); + remove(temp_scl.c_str()); + return ""; + } +#else + std::string abc_script; + bool first = true; + + for (const std::string &liberty_file : liberty_files) { + abc_script += stringf("read_lib %s%s-w \\\"%s\\\" ; ", dont_use_args.c_str(), first ? "" : "-m ", liberty_file.c_str()); + first = false; + } + + abc_script += stringf("write_scl \\\"%s\\\"", temp_scl.c_str()); + std::string cmd = stringf("\"%s\" -c \"%s\" 2>&1", abc_exe.c_str(), abc_script.c_str()); + std::string abc_output; + int ret = run_command(cmd, [&abc_output](const std::string &line) { abc_output += line + "\n"; }); + + if (ret != 0) { + log_warning("ABC: merged SCL conversion failed, falling back to liberty format\n"); + if (!abc_output.empty()) { + log("ABC: conversion output:\n%s", abc_output.c_str()); + } + remove(temp_scl.c_str()); + return ""; + } +#endif + if (rename(temp_scl.c_str(), merged_scl.c_str()) != 0) { + log_warning("ABC: failed to rename %s to %s, falling back to liberty format\n", temp_scl.c_str(), merged_scl.c_str()); + remove(temp_scl.c_str()); + return ""; + } + } + + return merged_scl; +} + +YOSYS_NAMESPACE_END + +#endif // LIBERTY_CACHE_H \ No newline at end of file diff --git a/passes/techmap/lut2bmux.cc b/passes/techmap/lut2bmux.cc new file mode 100644 index 000000000..42042c942 --- /dev/null +++ b/passes/techmap/lut2bmux.cc @@ -0,0 +1,58 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct Lut2BmuxPass : public Pass { + Lut2BmuxPass() : Pass("lut2bmux", "convert $lut to $bmux") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" lut2bmux [options] [selection]\n"); + log("\n"); + log("This pass converts $lut cells to $bmux cells.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing LUT2BMUX pass (convert $lut to $bmux).\n"); + + size_t argidx = 1; + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + for (auto cell : module->selected_cells()) { + if (cell->type == ID($lut)) { + cell->type = ID($bmux); + cell->setPort(ID::S, cell->getPort(ID::A)); + cell->setPort(ID::A, cell->getParam(ID::LUT)); + cell->unsetParam(ID::LUT); + cell->fixup_parameters(); + log("Converted %s.%s to BMUX cell.\n", log_id(module), log_id(cell)); + } + } + } +} Lut2BmuxPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index ef76e0deb..3d45734ec 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -23,7 +23,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -int lut2mux(Cell *cell) +int lut2mux(Cell *cell, bool word_mode) { SigSpec sig_a = cell->getPort(ID::A); SigSpec sig_y = cell->getPort(ID::Y); @@ -32,7 +32,10 @@ int lut2mux(Cell *cell) if (GetSize(sig_a) == 1) { - cell->module->addMuxGate(NEW_ID, lut.extract(0)[0], lut.extract(1)[0], sig_a, sig_y); + if (!word_mode) + cell->module->addMuxGate(NEW_ID, lut.extract(0)[0], lut.extract(1)[0], sig_a, sig_y); + else + cell->module->addMux(NEW_ID, lut.extract(0)[0], lut.extract(1)[0], sig_a, sig_y); } else { @@ -44,10 +47,13 @@ int lut2mux(Cell *cell) Const lut1 = lut.extract(0, GetSize(lut)/2); Const lut2 = lut.extract(GetSize(lut)/2, GetSize(lut)/2); - count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y1, lut1)); - count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y2, lut2)); + count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y1, lut1), word_mode); + count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y2, lut2), word_mode); - cell->module->addMuxGate(NEW_ID, sig_y1, sig_y2, sig_a_hi, sig_y); + if (!word_mode) + cell->module->addMuxGate(NEW_ID, sig_y1, sig_y2, sig_a_hi, sig_y); + else + cell->module->addMux(NEW_ID, sig_y1, sig_y2, sig_a_hi, sig_y); } cell->module->remove(cell); @@ -55,26 +61,33 @@ int lut2mux(Cell *cell) } struct Lut2muxPass : public Pass { - Lut2muxPass() : Pass("lut2mux", "convert $lut to $_MUX_") { } + Lut2muxPass() : Pass("lut2mux", "convert $lut to $mux/$_MUX_") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" lut2mux [options] [selection]\n"); log("\n"); - log("This pass converts $lut cells to $_MUX_ gates.\n"); + log("This pass converts $lut cells to $mux/$_MUX_ gates.\n"); + log("\n"); + log(" -word\n"); + log(" Convert $lut cells with a single input to word-level $mux gates.\n"); + log(" The default is to convert them to bit-level $_MUX_ gates.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { - log_header(design, "Executing LUT2MUX pass (convert $lut to $_MUX_).\n"); + log_header(design, "Executing LUT2MUX pass (convert $lut to $mux/$_MUX_).\n"); + log("ARGS:"); for (auto &a: args) log(" [%s]", a.c_str()); log("\n"); size_t argidx; + bool word_mode = false; for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-v") { - // continue; - // } + if (args[argidx] == "-word") { + word_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -83,7 +96,7 @@ struct Lut2muxPass : public Pass { for (auto cell : module->selected_cells()) { if (cell->type == ID($lut)) { IdString cell_name = cell->name; - int count = lut2mux(cell); + int count = lut2mux(cell, word_mode); log("Converted %s.%s to %d MUX cells.\n", log_id(module), log_id(cell_name), count); } } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 0c7d1930e..93001df35 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -438,6 +438,48 @@ void simplemap_ff(RTLIL::Module *, RTLIL::Cell *cell) } } +void simplemap_pmux(RTLIL::Module *module, RTLIL::Cell *cell) +{ + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_s = cell->getPort(ID::S); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); + + int width = GetSize(sig_a); + int s_width = GetSize(sig_s); + + // Implement: |S + RTLIL::SigSpec any_s = sig_s; + logic_reduce(module, any_s, cell); + + for (int i = 0; i < width; i++) { + RTLIL::SigSpec b_and_bits; + + // Implement: B_AND_BITS = B_AND_S[WIDTH*j+i] + for (int j = 0; j < s_width; j++) { + RTLIL::Cell *and_gate = module->addCell(NEW_ID, ID($_AND_)); + transfer_src(and_gate, cell); + and_gate->setPort(ID::A, sig_b[j * width + i]); + and_gate->setPort(ID::B, sig_s[j]); + + RTLIL::SigSpec and_y = module->addWire(NEW_ID, 1); + and_gate->setPort(ID::Y, and_y); + b_and_bits.append(and_y); + } + + // Implement: Y_B[i] = |B_AND_BITS + logic_reduce(module, b_and_bits, cell); + + // Implement: Y[i] = |S ? Y_B[i] : A[i] + RTLIL::Cell *mux_gate = module->addCell(NEW_ID, ID($_MUX_)); + transfer_src(mux_gate, cell); + mux_gate->setPort(ID::A, sig_a[i]); + mux_gate->setPort(ID::B, b_and_bits); + mux_gate->setPort(ID::S, any_s); + mux_gate->setPort(ID::Y, sig_y[i]); + } +} + void simplemap_get_mappers(dict &mappers) { mappers[ID($not)] = simplemap_not; @@ -461,6 +503,7 @@ void simplemap_get_mappers(dict mappers[ID($ne)] = simplemap_eqne; mappers[ID($nex)] = simplemap_eqne; mappers[ID($mux)] = simplemap_mux; + mappers[ID($pmux)] = simplemap_pmux; mappers[ID($bwmux)] = simplemap_bwmux; mappers[ID($tribuf)] = simplemap_tribuf; mappers[ID($bmux)] = simplemap_bmux; @@ -515,7 +558,7 @@ struct SimplemapPass : public Pass { log("\n"); log(" $not, $pos, $and, $or, $xor, $xnor\n"); log(" $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool\n"); - log(" $logic_not, $logic_and, $logic_or, $mux, $tribuf\n"); + log(" $logic_not, $logic_and, $logic_or, $mux, $pmux, $tribuf\n"); log(" $sr, $ff, $dff, $dffe, $dffsr, $dffsre, $adff, $adffe, $aldff, $aldffe, $sdff,\n"); log(" $sdffe, $sdffce, $dlatch, $adlatch, $dlatchsr\n"); log("\n"); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index b49a40704..cf7ce56e2 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -333,9 +333,6 @@ struct TechmapWorker RTLIL::Cell *c = module->addCell(c_name, tpl_cell); design->select(module, c); - - if (c->type.begins_with("\\$")) - c->type = c->type.substr(1); if (c->type == ID::_TECHMAP_PLACEHOLDER_ && tpl_cell->has_attribute(ID::techmap_chtype)) { c->type = RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype)); @@ -436,13 +433,9 @@ struct TechmapWorker if (handled_cells.count(cell) > 0) continue; - std::string cell_type = cell->type.str(); - if (in_recursion && cell->type.begins_with("\\$")) - cell_type = cell_type.substr(1); - - if (celltypeMap.count(cell_type) == 0) { - if (assert_mode && cell_type.back() != '_') - log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell_type)); + if (celltypeMap.count(cell->type) == 0) { + if (assert_mode && !cell->type.ends_with("_")) + log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell->type)); continue; } @@ -454,7 +447,7 @@ struct TechmapWorker if (GetSize(sig) == 0) continue; - for (auto &tpl_name : celltypeMap.at(cell_type)) { + for (auto &tpl_name : celltypeMap.at(cell->type)) { RTLIL::Module *tpl = map->module(tpl_name); RTLIL::Wire *port = tpl->wire(conn.first); if (port && port->port_input) @@ -481,12 +474,7 @@ struct TechmapWorker log_assert(cell == module->cell(cell->name)); bool mapped_cell = false; - std::string cell_type = cell->type.str(); - - if (in_recursion && cell->type.begins_with("\\$")) - cell_type = cell_type.substr(1); - - for (auto &tpl_name : celltypeMap.at(cell_type)) + for (auto &tpl_name : celltypeMap.at(cell->type)) { IdString derived_name = tpl_name; RTLIL::Module *tpl = map->module(tpl_name); @@ -508,8 +496,6 @@ struct TechmapWorker if (!extmapper_name.empty()) { - cell->type = cell_type; - if ((extern_mode && !in_recursion) || extmapper_name == "wrap") { std::string m_name = stringf("$extern:%s:%s", extmapper_name, log_id(cell->type)); @@ -935,11 +921,6 @@ struct TechmapWorker RTLIL::Module *m = design->addModule(m_name); tpl->cloneInto(m); - for (auto cell : m->cells()) { - if (cell->type.begins_with("\\$")) - cell->type = cell->type.substr(1); - } - module_queue.insert(m); } @@ -1168,7 +1149,7 @@ struct TechmapPass : public Pass { std::vector map_files; std::vector dont_map; - std::string verilog_frontend = "verilog -nooverwrite -noblackbox"; + std::string verilog_frontend = "verilog -nooverwrite -noblackbox -icells"; int max_iter = -1; size_t argidx; diff --git a/pyosys/generator.py b/pyosys/generator.py index 7d4293abd..f1d429724 100644 --- a/pyosys/generator.py +++ b/pyosys/generator.py @@ -701,6 +701,16 @@ class PyosysWrapperGenerator(object): self.process_class_members(metadata, metadata, cls, basename) + if basename == "Design": + print( + '\t\t\t.def("run_pass", [](Design &s, std::vector cmd) { Pass::call(&s, cmd); })', + file=self.f, + ) + print( + '\t\t\t.def("run_pass", [](Design &s, std::string cmd) { Pass::call(&s, cmd); })', + file=self.f, + ) + if expr := metadata.string_expr: print( f'\t\t.def("__str__", [](const {basename} &s) {{ return {expr}; }})', diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index 1b48f426b..f8993de91 100644 --- a/techlibs/achronix/synth_achronix.cc +++ b/techlibs/achronix/synth_achronix.cc @@ -129,6 +129,7 @@ struct SynthAchronixPass : public ScriptPass { if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); run("tribuf -logic"); run("deminout"); diff --git a/techlibs/analogdevices/Makefile.inc b/techlibs/analogdevices/Makefile.inc new file mode 100644 index 000000000..5c2d6f05d --- /dev/null +++ b/techlibs/analogdevices/Makefile.inc @@ -0,0 +1,21 @@ + +OBJS += techlibs/analogdevices/synth_analogdevices.o + +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/cells_map.v)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/cells_sim.v)) + +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/lutrams.txt)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/lutrams_map.v)) + +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/brams_defs.vh)) + +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/brams.txt)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/brams_map.v)) + +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/arith_map.v)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/ff_map.v)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/lut_map.v)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/mux_map.v)) +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/dsp_map.v)) + +$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/abc9_model.v)) diff --git a/techlibs/analogdevices/abc9_model.v b/techlibs/analogdevices/abc9_model.v new file mode 100644 index 000000000..a5a15026f --- /dev/null +++ b/techlibs/analogdevices/abc9_model.v @@ -0,0 +1,39 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// ============================================================================ + +// Box containing MUXF7.[AB] + MUXF8, +// Necessary to make these an atomic unit so that +// ABC cannot optimise just one of the MUXF7 away +// and expect to save on its delay +(* abc9_box, lib_whitebox *) +module \$__ANALOGDEVICES_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); + assign O = S1 ? (S0 ? I3 : I2) + : (S0 ? I1 : I0); + specify + (I0 => O) = 294; + (I1 => O) = 297; + (I2 => O) = 311; + (I3 => O) = 317; + (S0 => O) = 390; + (S1 => O) = 273; + endspecify +endmodule diff --git a/techlibs/analogdevices/arith_map.v b/techlibs/analogdevices/arith_map.v new file mode 100644 index 000000000..394a5a957 --- /dev/null +++ b/techlibs/analogdevices/arith_map.v @@ -0,0 +1,173 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// ============================================================================ +// LCU + +(* techmap_celltype = "$lcu" *) +module _80_analogdevices_lcu (P, G, CI, CO); + parameter WIDTH = 2; + + (* force_downto *) + input [WIDTH-1:0] P, G; + input CI; + + (* force_downto *) + output [WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = WIDTH <= 2; + + genvar i; + +generate + localparam CARRY4_COUNT = (WIDTH + 3) / 4; + localparam MAX_WIDTH = CARRY4_COUNT * 4; + localparam PAD_WIDTH = MAX_WIDTH - WIDTH; + + (* force_downto *) + wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G}; + (* force_downto *) + wire [MAX_WIDTH-1:0] GG = {{PAD_WIDTH{1'b0}}, G}; + (* force_downto *) + wire [MAX_WIDTH-1:0] C; + assign CO = C; + + generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice + if (i == 0) begin + wire INITCO; + + CRY4INIT init + ( + .CYINIT(CI), + .CO (INITCO) + ); + + CRY4 carry4 + ( + .CYINIT(1'd0), + .CI (INITCO), + .DI (GG[i*4 +: 4]), + .S (S [i*4 +: 4]), + .CO (C [i*4 +: 4]), + ); + end else begin + CRY4 carry4 + ( + .CYINIT(1'd0), + .CI (C [i*4 - 1]), + .DI (GG[i*4 +: 4]), + .S (S [i*4 +: 4]), + .CO (C [i*4 +: 4]), + ); + end + end endgenerate +endgenerate + +endmodule + + +// ============================================================================ +// ALU + +(* techmap_celltype = "$alu" *) +module _80_analogdevices_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + parameter _TECHMAP_CONSTVAL_CI_ = 0; + parameter _TECHMAP_CONSTMSK_CI_ = 0; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; + + (* force_downto *) + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + (* force_downto *) + wire [Y_WIDTH-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + + genvar i; + + localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4; + localparam MAX_WIDTH = CARRY4_COUNT * 4; + localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH; + + (* force_downto *) + wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB}; + (* force_downto *) + wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA}; + + (* force_downto *) + wire [MAX_WIDTH-1:0] O; + (* force_downto *) + wire [MAX_WIDTH-1:0] C; + assign Y = O, CO = C; + + genvar i; + generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice + if (i == 0) begin + wire INITCO; + + CRY4INIT init + ( + .CYINIT(CI), + .CO (INITCO) + ); + + CRY4 carry4 + ( + .CYINIT(1'd0), + .CI (INITCO), + .DI (DI[i*4 +: 4]), + .S (S [i*4 +: 4]), + .O (O [i*4 +: 4]), + .CO (C [i*4 +: 4]) + ); + end else begin + CRY4 carry4 + ( + .CYINIT(1'd0), + .CI (C [i*4 - 1]), + .DI (DI[i*4 +: 4]), + .S (S [i*4 +: 4]), + .O (O [i*4 +: 4]), + .CO (C [i*4 +: 4]) + ); + end + end endgenerate + + assign X = S; +endmodule + diff --git a/techlibs/analogdevices/brams.txt b/techlibs/analogdevices/brams.txt new file mode 100644 index 000000000..10cdadefb --- /dev/null +++ b/techlibs/analogdevices/brams.txt @@ -0,0 +1,285 @@ +ifdef IS_T16FFC { + ram block $__ANALOGDEVICES_BLOCKRAM_FULL_ { + option "ERR" "ECC" { + style "ECC"; + option "SIZE" "2048x32" { + abits 11; + width 32; + byte 32; + option "MODE" "TDP" cost 4502; + option "MODE" "SDP" forbid; + option "MODE" "SP" forbid; + } + option "SIZE" "1024x32" { + abits 10; + width 32; + byte 32; + option "MODE" "TDP" forbid; + option "MODE" "SDP" cost 2402; + option "MODE" "SP" forbid; + } + } + option "ERR" "BP" { + style "BP"; + option "SIZE" "2048x36" { + abits 11; + width 36; + byte 9; + option "MODE" "TDP" cost 4504; + option "MODE" "SDP" forbid; + option "MODE" "SP" forbid; + } + option "SIZE" "1024x36" { + abits 10; + width 36; + byte 9; + option "MODE" "TDP" forbid; + option "MODE" "SDP" cost 2404; + option "MODE" "SP" forbid; + } + } + option "ERR" "FP" { + style "FP"; + option "SIZE" "2048x18" { + abits 11; + width 18; + byte 18; + option "MODE" "TDP" cost 2501; + option "MODE" "SDP" cost 2401; + option "MODE" "SP" forbid; + } + } + option "ERR" "NONE" { + option "SIZE" "8192x05" { + abits 13; + width 5; + byte 1; + option "MODE" "TDP" cost 2505; + option "MODE" "SDP" forbid; + option "MODE" "SP" forbid; + } + option "SIZE" "4096x09" { + abits 12; + width 9; + byte 1; + option "MODE" "TDP" cost 2509; + option "MODE" "SDP" forbid; + option "MODE" "SP" forbid; + } + option "SIZE" "4096x10" { + abits 12; + width 10; + byte 1; + option "MODE" "TDP" forbid; + option "MODE" "SDP" cost 2410; + option "MODE" "SP" forbid; + } + option "SIZE" "2048x20" { + abits 11; + width 20; + byte 1; + option "MODE" "TDP" forbid; + option "MODE" "SDP" forbid; + option "MODE" "SP" cost 2320; + } + option "SIZE" "2048x40" { + abits 11; + width 40; + byte 8; + option "MODE" "TDP" cost 4505; + option "MODE" "SDP" forbid; + option "MODE" "SP" forbid; + } + } + + # supports any initialization value, but need to export memory files + init any; + + option "MODE" "TDP" { + port srsw "A" { + clock anyedge; + clken; + rdwr no_change; + } + port srsw "B" { + clock anyedge; + clken; + rdwr no_change; + } + } + option "MODE" "SDP" { + port sw "A" { + clock anyedge; + clken; + } + port sr "B" { + clock anyedge; + clken; + } + } + option "MODE" "SP" { + port srsw "A" { + clock anyedge; + clken; + rdwr no_change; + } + } + } +} + +ram block $__ANALOGDEVICES_BLOCKRAM_HALF_ { + option "ERR" "ECC" { + style "ECC"; + option "SIZE" "1024x32" { + abits 10; + width 32; + byte 32; + option "MODE" "SDP" cost 2402; + option "MODE" "SP" forbid; + option "MODE" "SP2" forbid; + } + option "SIZE" "512x32" { + abits 9; + width 32; + byte 32; + option "MODE" "SDP" forbid; + option "MODE" "SP" cost 2302; + option "MODE" "SP2" forbid; + } + } + option "ERR" "BP" { + style "BP"; + option "SIZE" "1024x36" { + abits 10; + width 36; + byte 9; + option "MODE" "SDP" cost 2404; + option "MODE" "SP" forbid; + option "MODE" "SP2" forbid; + } + option "SIZE" "512x36" { + abits 9; + width 36; + byte 9; + option "MODE" "SDP" forbid; + option "MODE" "SP" cost 2304; + option "MODE" "SP2" forbid; + } + } + option "ERR" "FP" { + style "FP"; + option "SIZE" "1024x18" { + abits 10; + width 18; + byte 18; + option "MODE" "SDP" forbid; + option "MODE" "SP" forbid; + option "MODE" "SP2" cost 2301; + } + } + option "ERR" "NONE" { + option "SIZE" "4096x05" { + abits 12; + width 5; + byte 1; + option "MODE" "SDP" cost 2405; + option "MODE" "SP" cost 2305; + option "MODE" "SP2" forbid; + } + option "SIZE" "2048x09" { + abits 11; + width 9; + byte 1; + option "MODE" "SDP" cost 2409; + option "MODE" "SP" forbid; + option "MODE" "SP2" cost 2309; + } + option "SIZE" "2048x10" { + abits 11; + width 10; + byte 1; + option "MODE" "SDP" cost 2410; + option "MODE" "SP" forbid; + option "MODE" "SP2" forbid; + } + option "SIZE" "1024x20" { + abits 10; + width 20; + byte 1; + option "MODE" "SDP" forbid; + option "MODE" "SP" cost 2320; + option "MODE" "SP2" forbid; + } + option "SIZE" "1024x40" { + abits 10; + width 40; + byte 8; + option "MODE" "SDP" cost 2405; + option "MODE" "SP" forbid; + option "MODE" "SP2" forbid; + } + } + + option "MODE" "SDP" { + ifdef IS_T16FFC forbid; + port sw "A" { + clock anyedge; + clken; + } + port sr "B" { + clock anyedge; + clken; + } + } + option "MODE" "SP" { + ifdef IS_T16FFC forbid; + port srsw "A" { + clock anyedge; + clken; + rdwr no_change; + } + } + option "MODE" "SP2" { + ifdef IS_T40LP forbid; + port srsw "A" { + clock anyedge; + clken; + rdwr no_change; + } + } +} + +ifdef IS_T40LP { + ram block $__ANALOGDEVICES_BLOCKRAM_QUARTER_ { + option "ERR" "BP" { + style "BP"; + option "SIZE" "512x18" { + abits 9; + width 18; + byte 9; + option "MODE" "SP2" cost 2202; + } + } + option "ERR" "NONE" { + option "SIZE" "2048x05" { + abits 11; + width 5; + byte 1; + option "MODE" "SP2" cost 2205; + } + option "SIZE" "1024x09" { + abits 10; + width 9; + byte 1; + option "MODE" "SP2" cost 2209; + } + } + option "MODE" "SP2" { + port srsw "A" { + clock anyedge; + clken; + rdwr no_change; + } + } + } +} diff --git a/techlibs/analogdevices/brams_defs.vh b/techlibs/analogdevices/brams_defs.vh new file mode 100644 index 000000000..69fe5d716 --- /dev/null +++ b/techlibs/analogdevices/brams_defs.vh @@ -0,0 +1,561 @@ +`define PARAMS_INIT_9 \ + .INIT_00(slice_init('h00)), \ + .INIT_01(slice_init('h01)), \ + .INIT_02(slice_init('h02)), \ + .INIT_03(slice_init('h03)), \ + .INIT_04(slice_init('h04)), \ + .INIT_05(slice_init('h05)), \ + .INIT_06(slice_init('h06)), \ + .INIT_07(slice_init('h07)), \ + .INIT_08(slice_init('h08)), \ + .INIT_09(slice_init('h09)), \ + .INIT_0A(slice_init('h0a)), \ + .INIT_0B(slice_init('h0b)), \ + .INIT_0C(slice_init('h0c)), \ + .INIT_0D(slice_init('h0d)), \ + .INIT_0E(slice_init('h0e)), \ + .INIT_0F(slice_init('h0f)), \ + .INIT_10(slice_init('h10)), \ + .INIT_11(slice_init('h11)), \ + .INIT_12(slice_init('h12)), \ + .INIT_13(slice_init('h13)), \ + .INIT_14(slice_init('h14)), \ + .INIT_15(slice_init('h15)), \ + .INIT_16(slice_init('h16)), \ + .INIT_17(slice_init('h17)), \ + .INIT_18(slice_init('h18)), \ + .INIT_19(slice_init('h19)), \ + .INIT_1A(slice_init('h1a)), \ + .INIT_1B(slice_init('h1b)), \ + .INIT_1C(slice_init('h1c)), \ + .INIT_1D(slice_init('h1d)), \ + .INIT_1E(slice_init('h1e)), \ + .INIT_1F(slice_init('h1f)), + +`define PARAMS_INITP_9 \ + .INITP_00(slice_initp('h00)), \ + .INITP_01(slice_initp('h01)), \ + .INITP_02(slice_initp('h02)), \ + .INITP_03(slice_initp('h03)), + +`define PARAMS_INIT_18 \ + .INIT_00(slice_init('h00)), \ + .INIT_01(slice_init('h01)), \ + .INIT_02(slice_init('h02)), \ + .INIT_03(slice_init('h03)), \ + .INIT_04(slice_init('h04)), \ + .INIT_05(slice_init('h05)), \ + .INIT_06(slice_init('h06)), \ + .INIT_07(slice_init('h07)), \ + .INIT_08(slice_init('h08)), \ + .INIT_09(slice_init('h09)), \ + .INIT_0A(slice_init('h0a)), \ + .INIT_0B(slice_init('h0b)), \ + .INIT_0C(slice_init('h0c)), \ + .INIT_0D(slice_init('h0d)), \ + .INIT_0E(slice_init('h0e)), \ + .INIT_0F(slice_init('h0f)), \ + .INIT_10(slice_init('h10)), \ + .INIT_11(slice_init('h11)), \ + .INIT_12(slice_init('h12)), \ + .INIT_13(slice_init('h13)), \ + .INIT_14(slice_init('h14)), \ + .INIT_15(slice_init('h15)), \ + .INIT_16(slice_init('h16)), \ + .INIT_17(slice_init('h17)), \ + .INIT_18(slice_init('h18)), \ + .INIT_19(slice_init('h19)), \ + .INIT_1A(slice_init('h1a)), \ + .INIT_1B(slice_init('h1b)), \ + .INIT_1C(slice_init('h1c)), \ + .INIT_1D(slice_init('h1d)), \ + .INIT_1E(slice_init('h1e)), \ + .INIT_1F(slice_init('h1f)), \ + .INIT_20(slice_init('h20)), \ + .INIT_21(slice_init('h21)), \ + .INIT_22(slice_init('h22)), \ + .INIT_23(slice_init('h23)), \ + .INIT_24(slice_init('h24)), \ + .INIT_25(slice_init('h25)), \ + .INIT_26(slice_init('h26)), \ + .INIT_27(slice_init('h27)), \ + .INIT_28(slice_init('h28)), \ + .INIT_29(slice_init('h29)), \ + .INIT_2A(slice_init('h2a)), \ + .INIT_2B(slice_init('h2b)), \ + .INIT_2C(slice_init('h2c)), \ + .INIT_2D(slice_init('h2d)), \ + .INIT_2E(slice_init('h2e)), \ + .INIT_2F(slice_init('h2f)), \ + .INIT_30(slice_init('h30)), \ + .INIT_31(slice_init('h31)), \ + .INIT_32(slice_init('h32)), \ + .INIT_33(slice_init('h33)), \ + .INIT_34(slice_init('h34)), \ + .INIT_35(slice_init('h35)), \ + .INIT_36(slice_init('h36)), \ + .INIT_37(slice_init('h37)), \ + .INIT_38(slice_init('h38)), \ + .INIT_39(slice_init('h39)), \ + .INIT_3A(slice_init('h3a)), \ + .INIT_3B(slice_init('h3b)), \ + .INIT_3C(slice_init('h3c)), \ + .INIT_3D(slice_init('h3d)), \ + .INIT_3E(slice_init('h3e)), \ + .INIT_3F(slice_init('h3f)), + +`define PARAMS_INIT_18_U \ + .INIT_00(slice_init('h40)), \ + .INIT_01(slice_init('h41)), \ + .INIT_02(slice_init('h42)), \ + .INIT_03(slice_init('h43)), \ + .INIT_04(slice_init('h44)), \ + .INIT_05(slice_init('h45)), \ + .INIT_06(slice_init('h46)), \ + .INIT_07(slice_init('h47)), \ + .INIT_08(slice_init('h48)), \ + .INIT_09(slice_init('h49)), \ + .INIT_0A(slice_init('h4a)), \ + .INIT_0B(slice_init('h4b)), \ + .INIT_0C(slice_init('h4c)), \ + .INIT_0D(slice_init('h4d)), \ + .INIT_0E(slice_init('h4e)), \ + .INIT_0F(slice_init('h4f)), \ + .INIT_10(slice_init('h50)), \ + .INIT_11(slice_init('h51)), \ + .INIT_12(slice_init('h52)), \ + .INIT_13(slice_init('h53)), \ + .INIT_14(slice_init('h54)), \ + .INIT_15(slice_init('h55)), \ + .INIT_16(slice_init('h56)), \ + .INIT_17(slice_init('h57)), \ + .INIT_18(slice_init('h58)), \ + .INIT_19(slice_init('h59)), \ + .INIT_1A(slice_init('h5a)), \ + .INIT_1B(slice_init('h5b)), \ + .INIT_1C(slice_init('h5c)), \ + .INIT_1D(slice_init('h5d)), \ + .INIT_1E(slice_init('h5e)), \ + .INIT_1F(slice_init('h5f)), \ + .INIT_20(slice_init('h60)), \ + .INIT_21(slice_init('h61)), \ + .INIT_22(slice_init('h62)), \ + .INIT_23(slice_init('h63)), \ + .INIT_24(slice_init('h64)), \ + .INIT_25(slice_init('h65)), \ + .INIT_26(slice_init('h66)), \ + .INIT_27(slice_init('h67)), \ + .INIT_28(slice_init('h68)), \ + .INIT_29(slice_init('h69)), \ + .INIT_2A(slice_init('h6a)), \ + .INIT_2B(slice_init('h6b)), \ + .INIT_2C(slice_init('h6c)), \ + .INIT_2D(slice_init('h6d)), \ + .INIT_2E(slice_init('h6e)), \ + .INIT_2F(slice_init('h6f)), \ + .INIT_30(slice_init('h70)), \ + .INIT_31(slice_init('h71)), \ + .INIT_32(slice_init('h72)), \ + .INIT_33(slice_init('h73)), \ + .INIT_34(slice_init('h74)), \ + .INIT_35(slice_init('h75)), \ + .INIT_36(slice_init('h76)), \ + .INIT_37(slice_init('h77)), \ + .INIT_38(slice_init('h78)), \ + .INIT_39(slice_init('h79)), \ + .INIT_3A(slice_init('h7a)), \ + .INIT_3B(slice_init('h7b)), \ + .INIT_3C(slice_init('h7c)), \ + .INIT_3D(slice_init('h7d)), \ + .INIT_3E(slice_init('h7e)), \ + .INIT_3F(slice_init('h7f)), + +`define PARAMS_INITP_18 \ + .INITP_00(slice_initp('h00)), \ + .INITP_01(slice_initp('h01)), \ + .INITP_02(slice_initp('h02)), \ + .INITP_03(slice_initp('h03)), \ + .INITP_04(slice_initp('h04)), \ + .INITP_05(slice_initp('h05)), \ + .INITP_06(slice_initp('h06)), \ + .INITP_07(slice_initp('h07)), + +`define PARAMS_INIT_36 \ + .INIT_00(slice_init('h00)), \ + .INIT_01(slice_init('h01)), \ + .INIT_02(slice_init('h02)), \ + .INIT_03(slice_init('h03)), \ + .INIT_04(slice_init('h04)), \ + .INIT_05(slice_init('h05)), \ + .INIT_06(slice_init('h06)), \ + .INIT_07(slice_init('h07)), \ + .INIT_08(slice_init('h08)), \ + .INIT_09(slice_init('h09)), \ + .INIT_0A(slice_init('h0a)), \ + .INIT_0B(slice_init('h0b)), \ + .INIT_0C(slice_init('h0c)), \ + .INIT_0D(slice_init('h0d)), \ + .INIT_0E(slice_init('h0e)), \ + .INIT_0F(slice_init('h0f)), \ + .INIT_10(slice_init('h10)), \ + .INIT_11(slice_init('h11)), \ + .INIT_12(slice_init('h12)), \ + .INIT_13(slice_init('h13)), \ + .INIT_14(slice_init('h14)), \ + .INIT_15(slice_init('h15)), \ + .INIT_16(slice_init('h16)), \ + .INIT_17(slice_init('h17)), \ + .INIT_18(slice_init('h18)), \ + .INIT_19(slice_init('h19)), \ + .INIT_1A(slice_init('h1a)), \ + .INIT_1B(slice_init('h1b)), \ + .INIT_1C(slice_init('h1c)), \ + .INIT_1D(slice_init('h1d)), \ + .INIT_1E(slice_init('h1e)), \ + .INIT_1F(slice_init('h1f)), \ + .INIT_20(slice_init('h20)), \ + .INIT_21(slice_init('h21)), \ + .INIT_22(slice_init('h22)), \ + .INIT_23(slice_init('h23)), \ + .INIT_24(slice_init('h24)), \ + .INIT_25(slice_init('h25)), \ + .INIT_26(slice_init('h26)), \ + .INIT_27(slice_init('h27)), \ + .INIT_28(slice_init('h28)), \ + .INIT_29(slice_init('h29)), \ + .INIT_2A(slice_init('h2a)), \ + .INIT_2B(slice_init('h2b)), \ + .INIT_2C(slice_init('h2c)), \ + .INIT_2D(slice_init('h2d)), \ + .INIT_2E(slice_init('h2e)), \ + .INIT_2F(slice_init('h2f)), \ + .INIT_30(slice_init('h30)), \ + .INIT_31(slice_init('h31)), \ + .INIT_32(slice_init('h32)), \ + .INIT_33(slice_init('h33)), \ + .INIT_34(slice_init('h34)), \ + .INIT_35(slice_init('h35)), \ + .INIT_36(slice_init('h36)), \ + .INIT_37(slice_init('h37)), \ + .INIT_38(slice_init('h38)), \ + .INIT_39(slice_init('h39)), \ + .INIT_3A(slice_init('h3a)), \ + .INIT_3B(slice_init('h3b)), \ + .INIT_3C(slice_init('h3c)), \ + .INIT_3D(slice_init('h3d)), \ + .INIT_3E(slice_init('h3e)), \ + .INIT_3F(slice_init('h3f)), \ + .INIT_40(slice_init('h40)), \ + .INIT_41(slice_init('h41)), \ + .INIT_42(slice_init('h42)), \ + .INIT_43(slice_init('h43)), \ + .INIT_44(slice_init('h44)), \ + .INIT_45(slice_init('h45)), \ + .INIT_46(slice_init('h46)), \ + .INIT_47(slice_init('h47)), \ + .INIT_48(slice_init('h48)), \ + .INIT_49(slice_init('h49)), \ + .INIT_4A(slice_init('h4a)), \ + .INIT_4B(slice_init('h4b)), \ + .INIT_4C(slice_init('h4c)), \ + .INIT_4D(slice_init('h4d)), \ + .INIT_4E(slice_init('h4e)), \ + .INIT_4F(slice_init('h4f)), \ + .INIT_50(slice_init('h50)), \ + .INIT_51(slice_init('h51)), \ + .INIT_52(slice_init('h52)), \ + .INIT_53(slice_init('h53)), \ + .INIT_54(slice_init('h54)), \ + .INIT_55(slice_init('h55)), \ + .INIT_56(slice_init('h56)), \ + .INIT_57(slice_init('h57)), \ + .INIT_58(slice_init('h58)), \ + .INIT_59(slice_init('h59)), \ + .INIT_5A(slice_init('h5a)), \ + .INIT_5B(slice_init('h5b)), \ + .INIT_5C(slice_init('h5c)), \ + .INIT_5D(slice_init('h5d)), \ + .INIT_5E(slice_init('h5e)), \ + .INIT_5F(slice_init('h5f)), \ + .INIT_60(slice_init('h60)), \ + .INIT_61(slice_init('h61)), \ + .INIT_62(slice_init('h62)), \ + .INIT_63(slice_init('h63)), \ + .INIT_64(slice_init('h64)), \ + .INIT_65(slice_init('h65)), \ + .INIT_66(slice_init('h66)), \ + .INIT_67(slice_init('h67)), \ + .INIT_68(slice_init('h68)), \ + .INIT_69(slice_init('h69)), \ + .INIT_6A(slice_init('h6a)), \ + .INIT_6B(slice_init('h6b)), \ + .INIT_6C(slice_init('h6c)), \ + .INIT_6D(slice_init('h6d)), \ + .INIT_6E(slice_init('h6e)), \ + .INIT_6F(slice_init('h6f)), \ + .INIT_70(slice_init('h70)), \ + .INIT_71(slice_init('h71)), \ + .INIT_72(slice_init('h72)), \ + .INIT_73(slice_init('h73)), \ + .INIT_74(slice_init('h74)), \ + .INIT_75(slice_init('h75)), \ + .INIT_76(slice_init('h76)), \ + .INIT_77(slice_init('h77)), \ + .INIT_78(slice_init('h78)), \ + .INIT_79(slice_init('h79)), \ + .INIT_7A(slice_init('h7a)), \ + .INIT_7B(slice_init('h7b)), \ + .INIT_7C(slice_init('h7c)), \ + .INIT_7D(slice_init('h7d)), \ + .INIT_7E(slice_init('h7e)), \ + .INIT_7F(slice_init('h7f)), + +`define PARAMS_INIT_36_U \ + .INIT_00(slice_init('h80)), \ + .INIT_01(slice_init('h81)), \ + .INIT_02(slice_init('h82)), \ + .INIT_03(slice_init('h83)), \ + .INIT_04(slice_init('h84)), \ + .INIT_05(slice_init('h85)), \ + .INIT_06(slice_init('h86)), \ + .INIT_07(slice_init('h87)), \ + .INIT_08(slice_init('h88)), \ + .INIT_09(slice_init('h89)), \ + .INIT_0A(slice_init('h8a)), \ + .INIT_0B(slice_init('h8b)), \ + .INIT_0C(slice_init('h8c)), \ + .INIT_0D(slice_init('h8d)), \ + .INIT_0E(slice_init('h8e)), \ + .INIT_0F(slice_init('h8f)), \ + .INIT_10(slice_init('h90)), \ + .INIT_11(slice_init('h91)), \ + .INIT_12(slice_init('h92)), \ + .INIT_13(slice_init('h93)), \ + .INIT_14(slice_init('h94)), \ + .INIT_15(slice_init('h95)), \ + .INIT_16(slice_init('h96)), \ + .INIT_17(slice_init('h97)), \ + .INIT_18(slice_init('h98)), \ + .INIT_19(slice_init('h99)), \ + .INIT_1A(slice_init('h9a)), \ + .INIT_1B(slice_init('h9b)), \ + .INIT_1C(slice_init('h9c)), \ + .INIT_1D(slice_init('h9d)), \ + .INIT_1E(slice_init('h9e)), \ + .INIT_1F(slice_init('h9f)), \ + .INIT_20(slice_init('ha0)), \ + .INIT_21(slice_init('ha1)), \ + .INIT_22(slice_init('ha2)), \ + .INIT_23(slice_init('ha3)), \ + .INIT_24(slice_init('ha4)), \ + .INIT_25(slice_init('ha5)), \ + .INIT_26(slice_init('ha6)), \ + .INIT_27(slice_init('ha7)), \ + .INIT_28(slice_init('ha8)), \ + .INIT_29(slice_init('ha9)), \ + .INIT_2A(slice_init('haa)), \ + .INIT_2B(slice_init('hab)), \ + .INIT_2C(slice_init('hac)), \ + .INIT_2D(slice_init('had)), \ + .INIT_2E(slice_init('hae)), \ + .INIT_2F(slice_init('haf)), \ + .INIT_30(slice_init('hb0)), \ + .INIT_31(slice_init('hb1)), \ + .INIT_32(slice_init('hb2)), \ + .INIT_33(slice_init('hb3)), \ + .INIT_34(slice_init('hb4)), \ + .INIT_35(slice_init('hb5)), \ + .INIT_36(slice_init('hb6)), \ + .INIT_37(slice_init('hb7)), \ + .INIT_38(slice_init('hb8)), \ + .INIT_39(slice_init('hb9)), \ + .INIT_3A(slice_init('hba)), \ + .INIT_3B(slice_init('hbb)), \ + .INIT_3C(slice_init('hbc)), \ + .INIT_3D(slice_init('hbd)), \ + .INIT_3E(slice_init('hbe)), \ + .INIT_3F(slice_init('hbf)), \ + .INIT_40(slice_init('hc0)), \ + .INIT_41(slice_init('hc1)), \ + .INIT_42(slice_init('hc2)), \ + .INIT_43(slice_init('hc3)), \ + .INIT_44(slice_init('hc4)), \ + .INIT_45(slice_init('hc5)), \ + .INIT_46(slice_init('hc6)), \ + .INIT_47(slice_init('hc7)), \ + .INIT_48(slice_init('hc8)), \ + .INIT_49(slice_init('hc9)), \ + .INIT_4A(slice_init('hca)), \ + .INIT_4B(slice_init('hcb)), \ + .INIT_4C(slice_init('hcc)), \ + .INIT_4D(slice_init('hcd)), \ + .INIT_4E(slice_init('hce)), \ + .INIT_4F(slice_init('hcf)), \ + .INIT_50(slice_init('hd0)), \ + .INIT_51(slice_init('hd1)), \ + .INIT_52(slice_init('hd2)), \ + .INIT_53(slice_init('hd3)), \ + .INIT_54(slice_init('hd4)), \ + .INIT_55(slice_init('hd5)), \ + .INIT_56(slice_init('hd6)), \ + .INIT_57(slice_init('hd7)), \ + .INIT_58(slice_init('hd8)), \ + .INIT_59(slice_init('hd9)), \ + .INIT_5A(slice_init('hda)), \ + .INIT_5B(slice_init('hdb)), \ + .INIT_5C(slice_init('hdc)), \ + .INIT_5D(slice_init('hdd)), \ + .INIT_5E(slice_init('hde)), \ + .INIT_5F(slice_init('hdf)), \ + .INIT_60(slice_init('he0)), \ + .INIT_61(slice_init('he1)), \ + .INIT_62(slice_init('he2)), \ + .INIT_63(slice_init('he3)), \ + .INIT_64(slice_init('he4)), \ + .INIT_65(slice_init('he5)), \ + .INIT_66(slice_init('he6)), \ + .INIT_67(slice_init('he7)), \ + .INIT_68(slice_init('he8)), \ + .INIT_69(slice_init('he9)), \ + .INIT_6A(slice_init('hea)), \ + .INIT_6B(slice_init('heb)), \ + .INIT_6C(slice_init('hec)), \ + .INIT_6D(slice_init('hed)), \ + .INIT_6E(slice_init('hee)), \ + .INIT_6F(slice_init('hef)), \ + .INIT_70(slice_init('hf0)), \ + .INIT_71(slice_init('hf1)), \ + .INIT_72(slice_init('hf2)), \ + .INIT_73(slice_init('hf3)), \ + .INIT_74(slice_init('hf4)), \ + .INIT_75(slice_init('hf5)), \ + .INIT_76(slice_init('hf6)), \ + .INIT_77(slice_init('hf7)), \ + .INIT_78(slice_init('hf8)), \ + .INIT_79(slice_init('hf9)), \ + .INIT_7A(slice_init('hfa)), \ + .INIT_7B(slice_init('hfb)), \ + .INIT_7C(slice_init('hfc)), \ + .INIT_7D(slice_init('hfd)), \ + .INIT_7E(slice_init('hfe)), \ + .INIT_7F(slice_init('hff)), + +`define PARAMS_INITP_36 \ + .INITP_00(slice_initp('h00)), \ + .INITP_01(slice_initp('h01)), \ + .INITP_02(slice_initp('h02)), \ + .INITP_03(slice_initp('h03)), \ + .INITP_04(slice_initp('h04)), \ + .INITP_05(slice_initp('h05)), \ + .INITP_06(slice_initp('h06)), \ + .INITP_07(slice_initp('h07)), \ + .INITP_08(slice_initp('h08)), \ + .INITP_09(slice_initp('h09)), \ + .INITP_0A(slice_initp('h0a)), \ + .INITP_0B(slice_initp('h0b)), \ + .INITP_0C(slice_initp('h0c)), \ + .INITP_0D(slice_initp('h0d)), \ + .INITP_0E(slice_initp('h0e)), \ + .INITP_0F(slice_initp('h0f)), + +`define MAKE_DO(do, dop, rdata) \ + wire [63:0] do; \ + wire [7:0] dop; \ + assign rdata = { \ + dop[7], \ + do[63:56], \ + dop[6], \ + do[55:48], \ + dop[5], \ + do[47:40], \ + dop[4], \ + do[39:32], \ + dop[3], \ + do[31:24], \ + dop[2], \ + do[23:16], \ + dop[1], \ + do[15:8], \ + dop[0], \ + do[7:0] \ + }; + +`define MAKE_DI(di, dip, wdata) \ + wire [63:0] di; \ + wire [7:0] dip; \ + assign { \ + dip[7], \ + di[63:56], \ + dip[6], \ + di[55:48], \ + dip[5], \ + di[47:40], \ + dip[4], \ + di[39:32], \ + dip[3], \ + di[31:24], \ + dip[2], \ + di[23:16], \ + dip[1], \ + di[15:8], \ + dip[0], \ + di[7:0] \ + } = wdata; + +function [71:0] ival; + input integer width; + input [71:0] val; + if (width == 72) + ival = { + val[71], + val[62], + val[53], + val[44], + val[35], + val[26], + val[17], + val[8], + val[70:63], + val[61:54], + val[52:45], + val[43:36], + val[34:27], + val[25:18], + val[16:9], + val[7:0] + }; + else if (width == 36) + ival = { + val[35], + val[26], + val[17], + val[8], + val[34:27], + val[25:18], + val[16:9], + val[7:0] + }; + else if (width == 18) + ival = { + val[17], + val[8], + val[16:9], + val[7:0] + }; + else + ival = val; +endfunction + +function [255:0] slice_init; + input integer idx; + integer i; + for (i = 0; i < 32; i = i + 1) + slice_init[i*8+:8] = INIT[(idx * 32 + i)*9+:8]; +endfunction + +function [255:0] slice_initp; + input integer idx; + integer i; + for (i = 0; i < 256; i = i + 1) + slice_initp[i] = INIT[(idx * 256 + i)*9+8]; +endfunction diff --git a/techlibs/analogdevices/brams_map.v b/techlibs/analogdevices/brams_map.v new file mode 100644 index 000000000..f1acaaf78 --- /dev/null +++ b/techlibs/analogdevices/brams_map.v @@ -0,0 +1,238 @@ +module $__ANALOGDEVICES_BLOCKRAM_FULL_ (...); + // libmap params + parameter INIT = 0; + parameter OPTION_MODE = "NONE"; + parameter OPTION_SIZE = "NONE"; + parameter OPTION_ERR = "NONE"; + parameter PORT_A_WR_EN_WIDTH = 1; + parameter PORT_A_CLK_POL = 1; + parameter PORT_B_WR_EN_WIDTH = PORT_A_WR_EN_WIDTH; + parameter PORT_B_CLK_POL = 1; + + // needs -force-params + parameter WIDTH = 40; + parameter ABITS = 13; + + // non libmap params +`ifdef IS_T40LP + localparam NODE = "T40LP_Gen2.4"; +`endif +`ifdef IS_T16FFC + localparam NODE = "T16FFC_Gen2.4"; +`endif + // localparam BRAM_MODE = "SDP_2048x36_BP"; + localparam BRAM_MODE = (OPTION_ERR!="NONE") ? {OPTION_MODE, "_", OPTION_SIZE, "_", OPTION_ERR} : + {OPTION_MODE, "_", OPTION_SIZE}; + localparam PBITS = (OPTION_ERR=="BP") ? PORT_A_WR_EN_WIDTH : 1; + + // libmap ports + input PORT_A_CLK; + input PORT_A_CLK_EN; + input [ABITS-1:0] PORT_A_ADDR; + input [WIDTH-1:0] PORT_A_WR_DATA; + output [WIDTH-1:0] PORT_A_RD_DATA; + input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; + + input PORT_B_CLK; + input PORT_B_CLK_EN; + input [ABITS-1:0] PORT_B_ADDR; + input [WIDTH-1:0] PORT_B_WR_DATA; + output [WIDTH-1:0] PORT_B_RD_DATA; + input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; + +`ifdef IS_T40LP + RBRAM +`endif +`ifdef IS_T16FFC + RBRAM2 +`endif + #( + .TARGET_NODE(NODE), + .BRAM_MODE(BRAM_MODE), + .QA_REG((OPTION_ERR=="ECC") ? 1 : 0), + .QB_REG((OPTION_ERR=="ECC") ? 1 : 0), + .CLKA_INV(!PORT_A_CLK_POL), + .CLKB_INV(!PORT_B_CLK_POL), + .DATA_WIDTH(WIDTH), + .ADDR_WIDTH(ABITS), + .WE_WIDTH(PORT_A_WR_EN_WIDTH), + .PERR_WIDTH(PBITS), + ) + _TECHMAP_REPLACE_ + ( + .QA(PORT_A_RD_DATA), + .DA(PORT_A_WR_DATA), + .CEA(PORT_A_CLK_EN), + .WEA(PORT_A_WR_EN), + .AA(PORT_A_ADDR), + .CLKA(PORT_A_CLK), + .QB(PORT_B_RD_DATA), + .DB(PORT_B_WR_DATA), + .CEB(PORT_B_CLK_EN), + .WEB(PORT_B_WR_EN), + .AB(PORT_B_ADDR), + .CLKB(PORT_B_CLK), + ); + + // check config + generate + if (PORT_A_WR_EN_WIDTH == PORT_B_WR_EN_WIDTH) + case (BRAM_MODE) + `ifdef IS_T40LP + "SDP_1024x18_FP", + "SDP_1024x16_BP", + "SDP_2048x09", + "SDP_4096x05", + "SDP_1024x32_ECC", + "SDP_1024x40", + "SDP_1024x36_BP", + "SDP_512x32_ECC", + "SDP_512x36_BP", + "SDP_2048x10", + "SP_512x32_ECC", + "SP_512x36_BP", + "SP_1024x20", + "SP2_512x18_BP", + "SP2_1024x09", + "SP2_2048x05": wire _TECHMAP_FAIL_ = 0; + `endif + `ifdef IS_T16FFC + "TDP_2048x18_FP", + "TDP_2048x16_BP", + "TDP_4096x09", + "TDP_8192x05", + "TDP_2048x32_ECC", + "TDP_2048x40", + "TDP_2048x36_BP", + "SDP_2048x18_FP", + "SDP_2048x16_BP", + // The following are rejected in eXpreso + // "SDP_4096x09", + // "SDP_8192x05", + // "SDP_2048x32_ECC", + // "SDP_2048x40", + // "SDP_2048x36_BP", + "SDP_1024x32_ECC", + "SDP_1024x36_BP", + "SDP_4096x10", + "SP_1024x32_ECC", + "SP_1024x36_BP", + "SP_2048x20", + "SP2_1024x18_BP", + "SP2_2048x09", + "SP2_4096x05": wire _TECHMAP_FAIL_ = 0; + `endif + default: wire _TECHMAP_FAIL_ = 1; + endcase + else + wire _TECHMAP_FAIL_ = 1; + endgenerate + +endmodule + +module $__ANALOGDEVICES_BLOCKRAM_HALF_ (...); + // libmap params + parameter INIT = 0; + parameter OPTION_MODE = "NONE"; + parameter OPTION_SIZE = "NONE"; + parameter OPTION_ERR = "NONE"; + parameter PORT_A_WR_EN_WIDTH = 1; + parameter PORT_A_CLK_POL = 1; + parameter PORT_B_WR_EN_WIDTH = PORT_A_WR_EN_WIDTH; + parameter PORT_B_CLK_POL = 1; + + // needs -force-params + parameter WIDTH = 40; + parameter ABITS = 13; + + // libmap ports + input PORT_A_CLK; + input PORT_A_CLK_EN; + input [ABITS-1:0] PORT_A_ADDR; + input [WIDTH-1:0] PORT_A_WR_DATA; + output [WIDTH-1:0] PORT_A_RD_DATA; + input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; + + input PORT_B_CLK; + input PORT_B_CLK_EN; + input [ABITS-1:0] PORT_B_ADDR; + input [WIDTH-1:0] PORT_B_WR_DATA; + output [WIDTH-1:0] PORT_B_RD_DATA; + input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN; + + $__ANALOGDEVICES_BLOCKRAM_FULL_ + # ( + .INIT(INIT), + .OPTION_MODE(OPTION_MODE), + .OPTION_SIZE(OPTION_SIZE), + .OPTION_ERR(OPTION_ERR), + .PORT_A_WR_EN_WIDTH(PORT_A_WR_EN_WIDTH), + .PORT_A_CLK_POL(PORT_A_CLK_POL), + .PORT_B_WR_EN_WIDTH(PORT_B_WR_EN_WIDTH), + .PORT_B_CLK_POL(PORT_B_CLK_POL), + .WIDTH(WIDTH), + .ABITS(ABITS) + ) + _TECHMAP_REPLACE_ + ( + .PORT_A_CLK(PORT_A_CLK), + .PORT_A_CLK_EN(PORT_A_CLK_EN), + .PORT_A_ADDR(PORT_A_ADDR), + .PORT_A_WR_DATA(PORT_A_WR_DATA), + .PORT_A_RD_DATA(PORT_A_RD_DATA), + .PORT_A_WR_EN(PORT_A_WR_EN), + .PORT_B_CLK(PORT_B_CLK), + .PORT_B_CLK_EN(PORT_B_CLK_EN), + .PORT_B_ADDR(PORT_B_ADDR), + .PORT_B_WR_DATA(PORT_B_WR_DATA), + .PORT_B_RD_DATA(PORT_B_RD_DATA), + .PORT_B_WR_EN(PORT_B_WR_EN) + ); +endmodule + +module $__ANALOGDEVICES_BLOCKRAM_QUARTER_ (...); + // libmap params + parameter INIT = 0; + parameter OPTION_MODE = "NONE"; + parameter OPTION_SIZE = "NONE"; + parameter OPTION_ERR = "NONE"; + parameter PORT_A_WR_EN_WIDTH = 1; + parameter PORT_A_CLK_POL = 1; + parameter PORT_B_WR_EN_WIDTH = PORT_A_WR_EN_WIDTH; + parameter PORT_B_CLK_POL = 1; + + // needs -force-params + parameter WIDTH = 40; + parameter ABITS = 13; + + // libmap ports + input PORT_A_CLK; + input PORT_A_CLK_EN; + input [ABITS-1:0] PORT_A_ADDR; + input [WIDTH-1:0] PORT_A_WR_DATA; + output [WIDTH-1:0] PORT_A_RD_DATA; + input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN; + + $__ANALOGDEVICES_BLOCKRAM_FULL_ + # ( + .INIT(INIT), + .OPTION_MODE(OPTION_MODE), + .OPTION_SIZE(OPTION_SIZE), + .OPTION_ERR(OPTION_ERR), + .PORT_A_WR_EN_WIDTH(PORT_A_WR_EN_WIDTH), + .PORT_A_CLK_POL(PORT_A_CLK_POL), + .PORT_B_WR_EN_WIDTH(PORT_B_WR_EN_WIDTH), + .PORT_B_CLK_POL(PORT_B_CLK_POL), + .WIDTH(WIDTH), + .ABITS(ABITS) + ) + _TECHMAP_REPLACE_ + ( + .PORT_A_CLK(PORT_A_CLK), + .PORT_A_CLK_EN(PORT_A_CLK_EN), + .PORT_A_ADDR(PORT_A_ADDR), + .PORT_A_WR_DATA(PORT_A_WR_DATA), + .PORT_A_RD_DATA(PORT_A_RD_DATA), + .PORT_A_WR_EN(PORT_A_WR_EN), + ); +endmodule diff --git a/techlibs/analogdevices/cells_map.v b/techlibs/analogdevices/cells_map.v new file mode 100644 index 000000000..b8d362e4f --- /dev/null +++ b/techlibs/analogdevices/cells_map.v @@ -0,0 +1,364 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +module \$__SHREG_ (input C, input D, input E, output Q); + parameter DEPTH = 0; + parameter [DEPTH-1:0] INIT = 0; + parameter CLKPOL = 1; + parameter ENPOL = 2; + + \$__XILINX_SHREG_ #(.DEPTH(DEPTH), .INIT(INIT), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(DEPTH-1), .E(E), .Q(Q)); +endmodule + +module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, output SO); + parameter DEPTH = 0; + parameter [DEPTH-1:0] INIT = 0; + parameter CLKPOL = 1; + parameter ENPOL = 2; + + // shregmap's INIT parameter shifts out LSB first; + // however Analog Devices expects MSB first + function [DEPTH-1:0] brev; + input [DEPTH-1:0] din; + integer i; + begin + for (i = 0; i < DEPTH; i=i+1) + brev[i] = din[DEPTH-1-i]; + end + endfunction + localparam [DEPTH-1:0] INIT_R = brev(INIT); + + parameter _TECHMAP_CONSTMSK_L_ = 0; + + wire CE; + generate + if (ENPOL == 0) + assign CE = ~E; + else if (ENPOL == 1) + assign CE = E; + else + assign CE = 1'b1; + if (DEPTH == 1) begin + if (CLKPOL) + FFRE #(.INIT(INIT_R)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(CE), .R(1'b0)); + else + FFRE_N #(.INIT(INIT_R)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(CE), .R(1'b0)); + end else + if (DEPTH <= 16) begin + SRL16E #(.INIT(INIT_R), .IS_CLK_INVERTED(~CLKPOL[0])) _TECHMAP_REPLACE_ (.A0(L[0]), .A1(L[1]), .A2(L[2]), .A3(L[3]), .CE(CE), .CLK(C), .D(D), .Q(Q)); + end else + if (DEPTH > 17 && DEPTH <= 32) begin + SRLC32E #(.INIT(INIT_R), .IS_CLK_INVERTED(~CLKPOL[0])) _TECHMAP_REPLACE_ (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(Q)); + end else + if (DEPTH > 33 && DEPTH <= 64) begin + wire T0, T1, T2; + SRLC32E #(.INIT(INIT_R[32-1:0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(T0), .Q31(T1)); + \$__XILINX_SHREG_ #(.DEPTH(DEPTH-32), .INIT(INIT[DEPTH-32-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_1 (.C(C), .D(T1), .L(L), .E(E), .Q(T2)); + if (&_TECHMAP_CONSTMSK_L_) + assign Q = T2; + else + LUTMUX7 fpga_mux_0 (.O(Q), .I0(T0), .I1(T2), .S(L[5])); + end else + if (DEPTH > 65 && DEPTH <= 96) begin + wire T0, T1, T2, T3, T4, T5, T6; + SRLC32E #(.INIT(INIT_R[32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1)); + SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); + \$__XILINX_SHREG_ #(.DEPTH(DEPTH-64), .INIT(INIT[DEPTH-64-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_2 (.C(C), .D(T3), .L(L[4:0]), .E(E), .Q(T4)); + if (&_TECHMAP_CONSTMSK_L_) + assign Q = T4; + else + \$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(1'bx), .S0(L[5]), .S1(L[6]), .O(Q)); + end else + if (DEPTH > 97 && DEPTH < 128) begin + wire T0, T1, T2, T3, T4, T5, T6, T7, T8; + SRLC32E #(.INIT(INIT_R[32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1)); + SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); + SRLC32E #(.INIT(INIT_R[96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5)); + \$__XILINX_SHREG_ #(.DEPTH(DEPTH-96), .INIT(INIT[DEPTH-96-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_3 (.C(C), .D(T5), .L(L[4:0]), .E(E), .Q(T6)); + if (&_TECHMAP_CONSTMSK_L_) + assign Q = T6; + else + \$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(T6), .S0(L[5]), .S1(L[6]), .O(Q)); + end + else if (DEPTH == 128) begin + wire T0, T1, T2, T3, T4, T5, T6; + SRLC32E #(.INIT(INIT_R[ 32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1)); + SRLC32E #(.INIT(INIT_R[ 64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3)); + SRLC32E #(.INIT(INIT_R[ 96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5)); + SRLC32E #(.INIT(INIT_R[128-1:96]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_3 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T5), .Q(T6), .Q31(SO)); + if (&_TECHMAP_CONSTMSK_L_) + assign Q = T6; + else + \$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(T6), .S0(L[5]), .S1(L[6]), .O(Q)); + end + // For fixed length, if just 1 over a convenient value, decompose + else if (DEPTH <= 129 && &_TECHMAP_CONSTMSK_L_) begin + wire T; + \$__XILINX_SHREG_ #(.DEPTH(DEPTH-1), .INIT(INIT[DEPTH-1:1]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(D), .L({32{1'b1}}), .E(E), .Q(T)); + \$__XILINX_SHREG_ #(.DEPTH(1), .INIT(INIT[0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(T), .L(L), .E(E), .Q(Q)); + end + // For variable length, if just 1 over a convenient value, then bump up one more + else if (DEPTH < 129 && ~&_TECHMAP_CONSTMSK_L_) + \$__XILINX_SHREG_ #(.DEPTH(DEPTH+1), .INIT({INIT,1'b0}), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(L), .E(E), .Q(Q)); + else begin + localparam depth0 = 128; + localparam num_srl128 = DEPTH / depth0; + localparam depthN = DEPTH % depth0; + wire [num_srl128 + (depthN > 0 ? 1 : 0) - 1:0] T; + wire [num_srl128 + (depthN > 0 ? 1 : 0) :0] S; + assign S[0] = D; + genvar i; + for (i = 0; i < num_srl128; i++) + \$__XILINX_SHREG_ #(.DEPTH(depth0), .INIT(INIT[DEPTH-1-i*depth0-:depth0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(S[i]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[i]), .SO(S[i+1])); + + if (depthN > 0) + \$__XILINX_SHREG_ #(.DEPTH(depthN), .INIT(INIT[depthN-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(S[num_srl128]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[num_srl128])); + + if (&_TECHMAP_CONSTMSK_L_) + assign Q = T[num_srl128 + (depthN > 0 ? 1 : 0) - 1]; + else + assign Q = T[L[DEPTH-1:$clog2(depth0)]]; + end + endgenerate +endmodule + +`ifdef MIN_MUX_INPUTS +module \$__ANALOGDEVICES_SHIFTX (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + parameter [A_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0; + parameter [A_WIDTH-1:0] _TECHMAP_CONSTVAL_A_ = 0; + parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0; + parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0; + + function integer A_WIDTH_trimmed; + input integer start; + begin + A_WIDTH_trimmed = start; + while (A_WIDTH_trimmed > 0 && _TECHMAP_CONSTMSK_A_[A_WIDTH_trimmed-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH_trimmed-1] === 1'bx) + A_WIDTH_trimmed = A_WIDTH_trimmed - 1; + end + endfunction + + generate + genvar i, j; + // Bit-blast + if (Y_WIDTH > 1) begin + for (i = 0; i < Y_WIDTH; i++) + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH-Y_WIDTH+1), .B_WIDTH(B_WIDTH), .Y_WIDTH(1'd1)) bitblast (.A(A[A_WIDTH-Y_WIDTH+i:i]), .B(B), .Y(Y[i])); + end + // If the LSB of B is constant zero (and Y_WIDTH is 1) then + // we can optimise by removing every other entry from A + // and popping the constant zero from B + else if (_TECHMAP_CONSTMSK_B_[0] && !_TECHMAP_CONSTVAL_B_[0]) begin + wire [(A_WIDTH+1)/2-1:0] A_i; + for (i = 0; i < (A_WIDTH+1)/2; i++) + assign A_i[i] = A[i*2]; + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH((A_WIDTH+1'd1)/2'd2), .B_WIDTH(B_WIDTH-1'd1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_i), .B(B[B_WIDTH-1:1]), .Y(Y)); + end + // Trim off any leading 1'bx -es in A + else if (_TECHMAP_CONSTMSK_A_[A_WIDTH-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH-1] === 1'bx) begin + localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1); + if (A_WIDTH_new == 0) + assign Y = 1'bx; + else + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH_new), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A[A_WIDTH_new-1:0]), .B(B), .Y(Y)); + end + else if (A_WIDTH < `MIN_MUX_INPUTS) begin + wire _TECHMAP_FAIL_ = 1; + end + else if (A_WIDTH == 2) begin + LUTMUX7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y)); + end + else if (A_WIDTH <= 4) begin + wire [4-1:0] Ax; + if (A_WIDTH == 4) + assign Ax = A; + else + // Rather than extend with 1'bx which gets flattened to 1'b0 + // causing the "don't care" status to get lost, extend with + // the same driver of F7B.I0 so that we can optimise F7B away + // later + assign Ax = {A[1], A}; + \$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y)); + end + // Note that the following decompositions are 'backwards' in that + // the LSBs are placed on the hard resources, and the soft resources + // are used for MSBs. + // This has the effect of more effectively utilising the hard mux; + // take for example a 5:1 multiplexer, currently this would map as: + // + // A[0] \___ __ A[0] \__ __ + // A[4] / \| \ whereas the more A[1] / \| \ + // A[1] _____| | obvious mapping A[2] \___| | + // A[2] _____| |-- of MSBs to hard A[3] / | |__ + // A[3]______| | resources would A[4] ____| | + // |__/ lead to: 1'bx ____| | + // || |__/ + // || || + // B[1:0] B[1:2] + // + // Expectation would be that the 'forward' mapping (right) is more + // area efficient (consider a 9:1 multiplexer using 2x4:1 multiplexers + // on its I0 and I1 inputs, and A[8] and 1'bx on its I2 and I3 inputs) + // but that the 'backwards' mapping (left) is more delay efficient + // since smaller LUTs are faster than wider ones. + else if (A_WIDTH <= 8) begin + wire [8-1:0] Ax = {{{8-A_WIDTH}{1'bx}}, A}; + wire T0 = B[2] ? Ax[4] : Ax[0]; + wire T1 = B[2] ? Ax[5] : Ax[1]; + wire T2 = B[2] ? Ax[6] : Ax[2]; + wire T3 = B[2] ? Ax[7] : Ax[3]; + \$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y)); + end + else if (A_WIDTH <= 16) begin + wire [16-1:0] Ax = {{{16-A_WIDTH}{1'bx}}, A}; + wire T0 = B[2] ? B[3] ? Ax[12] : Ax[4] + : B[3] ? Ax[ 8] : Ax[0]; + wire T1 = B[2] ? B[3] ? Ax[13] : Ax[5] + : B[3] ? Ax[ 9] : Ax[1]; + wire T2 = B[2] ? B[3] ? Ax[14] : Ax[6] + : B[3] ? Ax[10] : Ax[2]; + wire T3 = B[2] ? B[3] ? Ax[15] : Ax[7] + : B[3] ? Ax[11] : Ax[3]; + \$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y)); + end + else begin + localparam num_mux16 = (A_WIDTH+15) / 16; + localparam clog2_num_mux16 = $clog2(num_mux16); + wire [num_mux16-1:0] T; + wire [num_mux16*16-1:0] Ax = {{(num_mux16*16-A_WIDTH){1'bx}}, A}; + for (i = 0; i < num_mux16; i++) + \$__ANALOGDEVICES_SHIFTX #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(16), + .B_WIDTH(4), + .Y_WIDTH(Y_WIDTH) + ) fpga_mux ( + .A(Ax[i*16+:16]), + .B(B[3:0]), + .Y(T[i]) + ); + \$__ANALOGDEVICES_SHIFTX #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(num_mux16), + .B_WIDTH(clog2_num_mux16), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(T), + .B(B[B_WIDTH-1-:clog2_num_mux16]), + .Y(Y)); + end + endgenerate +endmodule + +(* techmap_celltype = "$__ANALOGDEVICES_SHIFTX" *) +module _90__ANALOGDEVICES_SHIFTX (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + \$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y)); +endmodule + +module \$_MUX_ (A, B, S, Y); + input A, B, S; + output Y; + generate + if (`MIN_MUX_INPUTS == 2) + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(2), .B_WIDTH(1), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({B,A}), .B(S), .Y(Y)); + else + wire _TECHMAP_FAIL_ = 1; + endgenerate +endmodule + +module \$_MUX4_ (A, B, C, D, S, T, Y); + input A, B, C, D, S, T; + output Y; + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({D,C,B,A}), .B({T,S}), .Y(Y)); +endmodule + +module \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y); + input A, B, C, D, E, F, G, H, S, T, U; + output Y; + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(3), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({H,G,F,E,D,C,B,A}), .B({U,T,S}), .Y(Y)); +endmodule + +module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y); + input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V; + output Y; + \$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(16), .B_WIDTH(4), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A}), .B({V,U,T,S}), .Y(Y)); +endmodule +`endif + +module \$__ANALOGDEVICES_LUTMUX78 (O, I0, I1, I2, I3, S0, S1); + output O; + input I0, I1, I2, I3, S0, S1; + wire T0, T1; + parameter _TECHMAP_BITS_CONNMAP_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I0_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I1_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I2_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I3_ = 0; + parameter _TECHMAP_CONSTMSK_S0_ = 0; + parameter _TECHMAP_CONSTVAL_S0_ = 0; + parameter _TECHMAP_CONSTMSK_S1_ = 0; + parameter _TECHMAP_CONSTVAL_S1_ = 0; + if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1) + assign T0 = I1; + else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_) + assign T0 = I0; + else + LUTMUX7 mux7a (.I0(I0), .I1(I1), .S(S0), .O(T0)); + if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1) + assign T1 = I3; + else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_) + assign T1 = I2; + else + LUTMUX7 mux7b (.I0(I2), .I1(I3), .S(S0), .O(T1)); + if (_TECHMAP_CONSTMSK_S1_ && _TECHMAP_CONSTVAL_S1_ === 1'b1) + assign O = T1; + else if (_TECHMAP_CONSTMSK_S1_ || (_TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_ && _TECHMAP_CONNMAP_I1_ === _TECHMAP_CONNMAP_I2_ && _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_)) + assign O = T0; + else + LUTMUX8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); +endmodule diff --git a/techlibs/analogdevices/cells_sim.v b/techlibs/analogdevices/cells_sim.v new file mode 100644 index 000000000..2bf958d8f --- /dev/null +++ b/techlibs/analogdevices/cells_sim.v @@ -0,0 +1,1216 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +module VDD(output P); + assign P = 1; +endmodule + +module GND(output G); + assign G = 0; +endmodule + +module INBUF( + output O, + (* iopad_external_pin *) + input I); + parameter CCIO_EN = "TRUE"; + parameter CAPACITANCE = "DONT_CARE"; + parameter IBUF_DELAY_VALUE = "0"; + parameter IBUF_LOW_PWR = "TRUE"; + parameter IFD_DELAY_VALUE = "AUTO"; + parameter IOSTANDARD = "DEFAULT"; + assign O = I; +`ifdef IS_T16FFC + specify + (I => O) = 42; + endspecify +`endif +`ifdef IS_T40LP + specify + (I => O) = 187; + endspecify +`endif +endmodule + +module OUTBUF( + (* iopad_external_pin *) + output O, + input I); + parameter CAPACITANCE = "DONT_CARE"; + parameter IOSTANDARD = "DEFAULT"; + parameter DRIVE = 12; + parameter SLEW = "SLOW"; + assign O = I; +`ifdef IS_T16FFC + specify + (I => O) = 42; + endspecify +`endif +`ifdef IS_T40LP + specify + (I => O) = 187; + endspecify +`endif +endmodule + +(* abc9_lut=1 *) +module LUT1(output O, input I0); + parameter [1:0] INIT = 0; + assign O = I0 ? INIT[1] : INIT[0]; +`ifdef IS_T16FFC + specify + (I0 => O) = 42; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 187; + endspecify +`endif +endmodule + +(* abc9_lut=2 *) +module LUT2(output O, input I0, I1); + parameter [3:0] INIT = 0; + wire [ 1: 0] s1 = I1 ? INIT[ 3: 2] : INIT[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +`ifdef IS_T16FFC + specify + (I0 => O) = 42; + (I1 => O) = 39; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 187; + (I1 => O) = 176; + endspecify +`endif +endmodule + +(* abc9_lut=3 *) +module LUT3(output O, input I0, I1, I2); + parameter [7:0] INIT = 0; + wire [ 3: 0] s2 = I2 ? INIT[ 7: 4] : INIT[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +`ifdef IS_T16FFC + specify + (I0 => O) = 54; + (I1 => O) = 51; + (I2 => O) = 48; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 249; + (I1 => O) = 238; + (I2 => O) = 227; + endspecify +`endif +endmodule + +(* abc9_lut=4 *) +module LUT4(output O, input I0, I1, I2, I3); + parameter [15:0] INIT = 0; + wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +`ifdef IS_T16FFC + specify + (I0 => O) = 96; + (I1 => O) = 87; + (I2 => O) = 79; + (I3 => O) = 71; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 192; + (I1 => O) = 181; + (I2 => O) = 170; + (I3 => O) = 160; + endspecify +`endif +endmodule + +(* abc9_lut=5 *) +module LUT5(output O, input I0, I1, I2, I3, I4); + parameter [31:0] INIT = 0; + wire [15: 0] s4 = I4 ? INIT[31:16] : INIT[15: 0]; + wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +`ifdef IS_T16FFC + specify + (I0 => O) = 99; + (I1 => O) = 90; + (I2 => O) = 82; + (I3 => O) = 74; + (I4 => O) = 66; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 204; + (I1 => O) = 195; + (I2 => O) = 186; + (I3 => O) = 178; + (I4 => O) = 169; + endspecify +`endif +endmodule + +(* abc9_lut=6 *) +module LUT6(output O, input I0, I1, I2, I3, I4, I5); + parameter [63:0] INIT = 0; + wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0]; + wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0]; + wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +`ifdef IS_T16FFC + specify + (I0 => O) = 42; + (I1 => O) = 39; + (I2 => O) = 36; + (I3 => O) = 33; + (I4 => O) = 30; + (I5 => O) = 28; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 185; + (I1 => O) = 176; + (I2 => O) = 165; + (I3 => O) = 155; + (I4 => O) = 144; + (I5 => O) = 134; + endspecify +`endif +endmodule + +module LUT6_D(output O6, output O5, input I0, I1, I2, I3, I4, I5); + parameter [63:0] INIT = 0; + wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0]; + wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0]; + wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O6 = I0 ? s1[1] : s1[0]; + + wire [15: 0] s5_4 = I4 ? INIT[31:16] : INIT[15: 0]; + wire [ 7: 0] s5_3 = I3 ? s5_4[15: 8] : s5_4[ 7: 0]; + wire [ 3: 0] s5_2 = I2 ? s5_3[ 7: 4] : s5_3[ 3: 0]; + wire [ 1: 0] s5_1 = I1 ? s5_2[ 3: 2] : s5_2[ 1: 0]; + assign O5 = I0 ? s5_1[1] : s5_1[0]; +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// cost of 3-input LUTs and is not intended to be instantiated +(* abc9_lut=12 *) +module \$__ABC9_LUT7 (output O, input I0, I1, I2, I3, I4, I5, I6); +`ifndef __ICARUS__ +`ifdef IS_T16FFC + specify + (I0 => O) = 42 + 111 /* LUTMUX7.I1 */; + (I1 => O) = 39 + 111 /* LUTMUX7.I1 */; + (I2 => O) = 36 + 111 /* LUTMUX7.I1 */; + (I3 => O) = 33 + 111 /* LUTMUX7.I1 */; + (I4 => O) = 30 + 111 /* LUTMUX7.I1 */; + (I5 => O) = 28 + 111 /* LUTMUX7.I1 */; + (I6 => O) = 0 + 57 /* LUTMUX7.S */; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 185 + 210 /* LUTMUX7.I0 */; + (I1 => O) = 176 + 210 /* LUTMUX7.I0 */; + (I2 => O) = 165 + 210 /* LUTMUX7.I0 */; + (I3 => O) = 155 + 210 /* LUTMUX7.I0 */; + (I4 => O) = 144 + 210 /* LUTMUX7.I0 */; + (I5 => O) = 134 + 210 /* LUTMUX7.I0 */; + (I6 => O) = 0 + 188 /* LUTMUX7.S */; + endspecify +`endif +`endif +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// cost of 3-input LUTs and is not intended to be instantiated +(* abc9_lut=24 *) +module \$__ABC9_LUT8 (output O, input I0, I1, I2, I3, I4, I5, I6, I7); +`ifndef __ICARUS__ +`ifdef IS_T16FFC + specify + (I0 => O) = 42 + 111 /* LUTMUX7.I1 */ + 59 /* LUTMUX8.I0 */; + (I1 => O) = 39 + 111 /* LUTMUX7.I1 */ + 59 /* LUTMUX8.I0 */; + (I2 => O) = 36 + 111 /* LUTMUX7.I1 */ + 59 /* LUTMUX8.I0 */; + (I3 => O) = 33 + 111 /* LUTMUX7.I1 */ + 59 /* LUTMUX8.I0 */; + (I4 => O) = 30 + 111 /* LUTMUX7.I1 */ + 59 /* LUTMUX8.I0 */; + (I5 => O) = 28 + 111 /* LUTMUX7.I1 */ + 59 /* LUTMUX8.I0 */; + (I6 => O) = 0 + 57 /* LUTMUX7.S */ + 59 /* LUTMUX8.I0 */; + (I7 => O) = 0 + 0 + 60 /* LUTMUX8.S */; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 185 + 210 /* LUTMUX7.I0 */ + 155 /* LUTMUX8.I0 */; + (I1 => O) = 176 + 210 /* LUTMUX7.I0 */ + 155 /* LUTMUX8.I0 */; + (I2 => O) = 165 + 210 /* LUTMUX7.I0 */ + 155 /* LUTMUX8.I0 */; + (I3 => O) = 155 + 210 /* LUTMUX7.I0 */ + 155 /* LUTMUX8.I0 */; + (I4 => O) = 144 + 210 /* LUTMUX7.I0 */ + 155 /* LUTMUX8.I0 */; + (I5 => O) = 134 + 210 /* LUTMUX7.I0 */ + 155 /* LUTMUX8.I0 */; + (I6 => O) = 0 + 188 /* LUTMUX7.S */ + 155 /* LUTMUX8.I0 */; + (I7 => O) = 0 + 0 + 193 /* LUTMUX8.S */; + endspecify +`endif +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module LUTMUX7(output O, input I0, I1, S); + assign O = S ? I1 : I0; +`ifdef IS_T16FFC + specify + (I0 => O) = 95; + (I1 => O) = 111; + (S => O) = 57; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 210; + (I1 => O) = 182; + (S => O) = 188; + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module LUTMUX8(output O, input I0, I1, S); + assign O = S ? I1 : I0; +`ifdef IS_T16FFC + specify + (I0 => O) = 59; + (I1 => O) = 59; + (S => O) = 60; + endspecify +`endif +`ifdef IS_T40LP + specify + (I0 => O) = 155; + (I1 => O) = 147; + (S => O) = 193; + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module CRY4( + (* abc9_carry *) + output [3:0] CO, + output [3:0] O, + (* abc9_carry *) + input CI, + input CYINIT, + input [3:0] DI, S +); + assign O = S ^ {CO[2:0], CI | CYINIT}; + assign CO[0] = S[0] ? CI | CYINIT : DI[0]; + assign CO[1] = S[1] ? CO[0] : DI[1]; + assign CO[2] = S[2] ? CO[1] : DI[2]; + assign CO[3] = S[3] ? CO[2] : DI[3]; +`ifdef IS_T16FFC + specify + (CI => CO[0]) = 69; + (DI[0] => CO[0]) = 74; + (S[0] => CO[0]) = 76; + + (CI => CO[1]) = 76; + (DI[0] => CO[1]) = 109; + (DI[1] => CO[1]) = 69; + (S[0] => CO[1]) = 99; + (S[1] => CO[1]) = 59; + + (CI => CO[2]) = 144; + (DI[0] => CO[2]) = 155; + (DI[1] => CO[2]) = 126; + (DI[2] => CO[2]) = 63; + (S[0] => CO[2]) = 168; + (S[1] => CO[2]) = 117; + (S[2] => CO[2]) = 50; + + (CI => CO[3]) = 20; + (DI[0] => CO[3]) = 167; + (DI[1] => CO[3]) = 181; + (DI[2] => CO[3]) = 173; + (DI[3] => CO[3]) = 77; + (S[0] => CO[3]) = 185; + (S[1] => CO[3]) = 182; + (S[2] => CO[3]) = 159; + (S[3] => CO[3]) = 179; + + (CI => O[0]) = 50; + (S[0] => O[0]) = 82; + + (CI => O[1]) = 61; + (DI[0] => O[1]) = 117; + (S[0] => O[1]) = 132; + (S[1] => O[1]) = 49; + + (CI => O[2]) = 148; + (DI[0] => O[2]) = 196; + (DI[1] => O[2]) = 130; + (S[0] => O[2]) = 218; + (S[1] => O[2]) = 145; + (S[2] => O[2]) = 65; + + (CI => O[3]) = 132; + (DI[0] => O[3]) = 208; + (DI[1] => O[3]) = 148; + (DI[2] => O[3]) = 110; + (S[0] => O[3]) = 204; + (S[1] => O[3]) = 160; + (S[2] => O[3]) = 97; + (S[3] => O[3]) = 39; + endspecify +`endif +`ifdef IS_T40LP + specify + (CI => CO[0]) = 132; + (DI[0] => CO[0]) = 245; + (S[0] => CO[0]) = 218; + + (CI => CO[1]) = 183; + (DI[0] => CO[1]) = 261; + (DI[1] => CO[1]) = 325; + (S[0] => CO[1]) = 270; + (S[1] => CO[1]) = 199; + + (CI => CO[2]) = 218; + (DI[0] => CO[2]) = 284; + (DI[1] => CO[2]) = 345; + (DI[2] => CO[2]) = 242; + (S[0] => CO[2]) = 334; + (S[1] => CO[2]) = 271; + (S[2] => CO[2]) = 228; + + (CI => CO[3]) = 258; + (DI[0] => CO[3]) = 334; + (DI[1] => CO[3]) = 395; + (DI[2] => CO[3]) = 342; + (DI[3] => CO[3]) = 205; + (S[0] => CO[3]) = 382; + (S[1] => CO[3]) = 321; + (S[2] => CO[3]) = 324; + (S[3] => CO[3]) = 252; + + (CI => O[0]) = 123; + (S[0] => O[0]) = 150; + + (CI => O[1]) = 265; + (DI[0] => O[1]) = 331; + (S[0] => O[1]) = 292; + (S[1] => O[1]) = 151; + + (CI => O[2]) = 288; + (DI[0] => O[2]) = 371; + (DI[1] => O[2]) = 407; + (S[0] => O[2]) = 391; + (S[1] => O[2]) = 314; + (S[2] => O[2]) = 144; + + (CI => O[3]) = 313; + (DI[0] => O[3]) = 388; + (DI[1] => O[3]) = 432; + (DI[2] => O[3]) = 335; + (S[0] => O[3]) = 418; + (S[1] => O[3]) = 357; + (S[2] => O[3]) = 331; + (S[3] => O[3]) = 145; + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module CRY4INIT( + (* abc9_carry *) + output CO, + (* abc9_carry *) + input CYINIT +); + assign CO = CYINIT; +`ifdef IS_T16FFC + specify + (CYINIT => CO) = 77; + endspecify +`endif +`ifdef IS_T40LP + specify + (CYINIT => CO) = 205; + endspecify +`endif +endmodule + +// Flip-flops. + +(* abc9_flop, lib_whitebox *) +module FFRE ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input D, + input R +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @(posedge C) if (R) Q <= 1'b0; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D , posedge C, 65); + $setup(CE, posedge C, 63); + $setup(R , posedge C, 63); + if (R) (posedge C => (Q : 1'b0)) = 291; + if (!R && CE) (posedge C => (Q : D)) = 291; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D , posedge C, 144); + $setup(CE, posedge C, 412); + $setup(R , posedge C, 667); + if (R) (posedge C => (Q : 1'b0)) = 712; + if (!R && CE) (posedge C => (Q : D)) = 712; + endspecify +`endif +endmodule + +(* abc9_flop, lib_whitebox *) +module FFRE_N ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input D, + input R +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D , negedge C, 65); + $setup(CE, negedge C, 63); + $setup(R , negedge C, 63); + if (R) (negedge C => (Q : 1'b0)) = 291; + if (!R && CE) (negedge C => (Q : D)) = 291; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D , negedge C, 144); + $setup(CE, negedge C, 412); + $setup(R , negedge C, 667); + if (R) (negedge C => (Q : 1'b0)) = 712; + if (!R && CE) (negedge C => (Q : D)) = 712; + endspecify +`endif +endmodule + +(* abc9_flop, lib_whitebox *) +module FFSE ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input D, + input S +); + parameter [0:0] INIT = 1'b1; + initial Q = INIT; + always @(posedge C) if (S) Q <= 1'b1; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D , posedge C, 65); + $setup(CE, posedge C, 63); + $setup(S , posedge C, 63); + if (S) (posedge C => (Q : 1'b1)) = 265; + if (!S && CE) (posedge C => (Q : D)) = 265; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D , posedge C, 144); + $setup(CE, posedge C, 412); + $setup(S , posedge C, 689); + if (S) (posedge C => (Q : 1'b1)) = 693; + if (!S && CE) (posedge C => (Q : D)) = 693; + endspecify +`endif +endmodule + +(* abc9_flop, lib_whitebox *) +module FFSE_N ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input D, + input S +); + parameter [0:0] INIT = 1'b1; + initial Q = INIT; + always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D , negedge C, 65); + $setup(CE, negedge C, 63); + $setup(S , negedge C, 63); + if (S) (negedge C => (Q : 1'b1)) = 265; + if (!S && CE) (negedge C => (Q : D)) = 265; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D , negedge C, 144); + $setup(CE, negedge C, 412); + $setup(S , negedge C, 689); + if (S) (negedge C => (Q : 1'b1)) = 693; + if (!S && CE) (negedge C => (Q : D)) = 693; + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module FFCE ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input CLR, + input D +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D , posedge C, 65); + $setup(CE, posedge C, 64); + $setup(CLR, posedge C, 64); + if (!CLR && CE) (posedge C => (Q : D)) = 192; +`ifdef YOSYS + if (CLR) (CLR => Q) = 192; +`endif + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D , posedge C, 140); + $setup(CE, posedge C, 412); + $setup(CLR, posedge C, 6); + if (!CLR && CE) (posedge C => (Q : D)) = 55; +`ifdef YOSYS + if (CLR) (CLR => Q) = 55; +`endif + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module FFCE_N ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input CLR, + input D +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D, negedge C, 65); + $setup(CE, negedge C, 64); + $setup(CLR, negedge C, 64); + if (!CLR && CE) (negedge C => (Q : D)) = 192; +`ifdef YOSYS + if (CLR) (CLR => Q) = 192; +`endif + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D, negedge C, 140); + $setup(CE, negedge C, 412); + $setup(CLR, negedge C, 6); + if (!CLR && CE) (negedge C => (Q : D)) = 55; +`ifdef YOSYS + if (CLR) (CLR => Q) = 55; +`endif + endspecify +`endif +endmodule + +module FFPE ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input PRE, + input D +); + parameter [0:0] INIT = 1'b1; + initial Q = INIT; + always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D, posedge C, 65); + $setup(CE, posedge C, 65); + $setup(PRE, posedge C, 65); + if (!PRE && CE) (posedge C => (Q : D)) = 191; +`ifdef YOSYS + if (PRE) (PRE => Q) = 191; +`endif + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D, posedge C, 140); + $setup(CE, posedge C, 412); + $setup(PRE, posedge C, 6); + if (!PRE && CE) (posedge C => (Q : D)) = 55; +`ifdef YOSYS + if (PRE) (PRE => Q) = 55; +`endif + endspecify +`endif +endmodule + +module FFPE_N ( + output reg Q, + (* clkbuf_sink *) + input C, + input CE, + input PRE, + input D +); + parameter [0:0] INIT = 1'b1; + initial Q = INIT; + always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; +`ifdef IS_T16FFC + specify + $setup(D, negedge C, 64); + $setup(CE, negedge C, 64); + $setup(PRE, negedge C, 64); + if (!PRE && CE) (negedge C => (Q : D)) = 291; +`ifdef YOSYS + if (PRE) (PRE => Q) = 333; +`endif + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(D, negedge C, 89); + $setup(CE, negedge C, 89); + $setup(PRE, negedge C, 89); + if (!PRE && CE) (negedge C => (Q : D)) = 712; +`ifdef YOSYS + if (PRE) (PRE => Q) = 57; +`endif + endspecify +`endif +endmodule + +// LUTRAM. + +// Single port. + +(* abc9_box, lib_whitebox *) +module RAMS32X1 ( + output O, + input A0, A1, A2, A3, A4, + input D, + (* clkbuf_sink *) + input WCLK, + input WE +); + parameter [31:0] INIT = 32'h00000000; + wire [4:0] a = {A4, A3, A2, A1, A0}; + reg [31:0] mem = INIT; + assign O = mem[a]; + always @(posedge WCLK) if (WE) mem[a] <= D; +`ifdef IS_T16FFC + specify + $setup(A0, posedge WCLK, 62); + $setup(A1, posedge WCLK, 62); + $setup(A2, posedge WCLK, 62); + $setup(A3, posedge WCLK, 62); + $setup(A4, posedge WCLK, 62); + $setup(D, posedge WCLK, 62); + $setup(WE, posedge WCLK, 62); + (A0 => O) = 100; + (A1 => O) = 91; + (A2 => O) = 83; + (A3 => O) = 75; + (A4 => O) = 67; + (posedge WCLK => (O : D)) = 807; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(A0, posedge WCLK, 198); + $setup(A1, posedge WCLK, 198); + $setup(A2, posedge WCLK, 198); + $setup(A3, posedge WCLK, 198); + $setup(A4, posedge WCLK, 198); + $setup(D, posedge WCLK, 198); + $setup(WE, posedge WCLK, 198); + (A0 => O) = 211; + (A1 => O) = 202; + (A2 => O) = 193; + (A3 => O) = 185; + (A4 => O) = 176; + (posedge WCLK => (O : D)) = 1586; + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module RAMS64X1 ( + output O, + input A0, A1, A2, A3, A4, A5, + input D, + (* clkbuf_sink *) + input WCLK, + input WE +); + parameter [63:0] INIT = 64'h0000000000000000; + wire [5:0] a = {A5, A4, A3, A2, A1, A0}; + reg [63:0] mem = INIT; + assign O = mem[a]; + always @(posedge WCLK) if (WE) mem[a] <= D; +`ifdef IS_T16FFC + specify + $setup(A0, posedge WCLK, 65); + $setup(A1, posedge WCLK, 65); + $setup(A2, posedge WCLK, 65); + $setup(A3, posedge WCLK, 65); + $setup(A4, posedge WCLK, 65); + $setup(A5, posedge WCLK, 65); + $setup(D, posedge WCLK, 65); + $setup(WE, posedge WCLK, 65); + (A0 => O) = 184; + (A1 => O) = 175; + (A2 => O) = 167; + (A3 => O) = 159; + (A4 => O) = 151; + (A5 => O) = 61; + (posedge WCLK => (O : D)) = 747; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(A0, posedge WCLK, 224); + $setup(A1, posedge WCLK, 224); + $setup(A2, posedge WCLK, 224); + $setup(A3, posedge WCLK, 224); + $setup(A4, posedge WCLK, 224); + $setup(A5, posedge WCLK, 224); + $setup(D, posedge WCLK, 224); + $setup(WE, posedge WCLK, 224); + (A0 => O) = 509; + (A1 => O) = 500; + (A2 => O) = 491; + (A3 => O) = 483; + (A4 => O) = 474; + (A5 => O) = 187; + (posedge WCLK => (O : D)) = 1730; + endspecify +`endif +endmodule + +// Dual port. + +(* abc9_box, lib_whitebox *) +module RAMD32X1 ( + output DPO, SPO, + input D, + (* clkbuf_sink *) + input WCLK, + input WE, + input A0, A1, A2, A3, A4, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 +); + parameter INIT = 32'h0; + wire [4:0] a = {A4, A3, A2, A1, A0}; + wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}; + reg [31:0] mem = INIT; + assign SPO = mem[a]; + assign DPO = mem[dpra]; + always @(posedge WCLK) if (WE) mem[a] <= D; +`ifdef IS_T16FFC + specify + $setup(A0, posedge WCLK, 62); + $setup(A1, posedge WCLK, 62); + $setup(A2, posedge WCLK, 62); + $setup(A3, posedge WCLK, 62); + $setup(A4, posedge WCLK, 62); + $setup(D, posedge WCLK, 62); + $setup(WE, posedge WCLK, 62); + (A0 => SPO) = 100; + (A1 => SPO) = 91; + (A2 => SPO) = 83; + (A3 => SPO) = 75; + (A4 => SPO) = 67; + (DPRA0 => DPO) = 101; + (DPRA1 => DPO) = 92; + (DPRA2 => DPO) = 84; + (DPRA3 => DPO) = 76; + (DPRA4 => DPO) = 68; + (posedge WCLK => (SPO : D)) = 807; + (posedge WCLK => (DPO : D)) = 807; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(A0, posedge WCLK, 198); + $setup(A1, posedge WCLK, 198); + $setup(A2, posedge WCLK, 198); + $setup(A3, posedge WCLK, 198); + $setup(A4, posedge WCLK, 198); + $setup(D, posedge WCLK, 198); + $setup(WE, posedge WCLK, 198); + (A0 => SPO) = 211; + (A1 => SPO) = 202; + (A2 => SPO) = 193; + (A3 => SPO) = 185; + (A4 => SPO) = 176; + (DPRA0 => DPO) = 185; + (DPRA1 => DPO) = 176; + (DPRA2 => DPO) = 167; + (DPRA3 => DPO) = 159; + (DPRA4 => DPO) = 150; + (posedge WCLK => (SPO : D)) = 1586; + (posedge WCLK => (DPO : D)) = 1586; + endspecify +`endif +endmodule + +(* abc9_box, lib_whitebox *) +module RAMD64X1 ( + output DPO, SPO, + input D, + (* clkbuf_sink *) + input WCLK, + input WE, + input A0, A1, A2, A3, A4, A5, + input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 +); + parameter INIT = 64'h0; + wire [5:0] a = {A5, A4, A3, A2, A1, A0}; + wire [5:0] dpra = {DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}; + reg [63:0] mem = INIT; + assign SPO = mem[a]; + assign DPO = mem[dpra]; + always @(posedge WCLK) if (WE) mem[a] <= D; +`ifdef IS_T16FFC + specify + $setup(A0, posedge WCLK, 65); + $setup(A1, posedge WCLK, 65); + $setup(A2, posedge WCLK, 65); + $setup(A3, posedge WCLK, 65); + $setup(A4, posedge WCLK, 65); + $setup(A5, posedge WCLK, 65); + $setup(D, posedge WCLK, 65); + $setup(WE, posedge WCLK, 65); + (A0 => SPO) = 184; + (A1 => SPO) = 175; + (A2 => SPO) = 167; + (A3 => SPO) = 159; + (A4 => SPO) = 151; + (A5 => SPO) = 61; + (DPRA0 => DPO) = 164; + (DPRA1 => DPO) = 155; + (DPRA2 => DPO) = 147; + (DPRA3 => DPO) = 139; + (DPRA4 => DPO) = 131; + (DPRA5 => DPO) = 64; + (posedge WCLK => (SPO : D)) = 761; + (posedge WCLK => (DPO : D)) = 733; + endspecify +`endif +`ifdef IS_T40LP + specify + $setup(A0, posedge WCLK, 224); + $setup(A1, posedge WCLK, 224); + $setup(A2, posedge WCLK, 224); + $setup(A3, posedge WCLK, 224); + $setup(A4, posedge WCLK, 224); + $setup(A5, posedge WCLK, 224); + $setup(D, posedge WCLK, 224); + $setup(WE, posedge WCLK, 224); + (A0 => SPO) = 509; + (A1 => SPO) = 500; + (A2 => SPO) = 491; + (A3 => SPO) = 483; + (A4 => SPO) = 474; + (A5 => SPO) = 187; + (DPRA0 => DPO) = 531; + (DPRA1 => DPO) = 522; + (DPRA2 => DPO) = 513; + (DPRA3 => DPO) = 505; + (DPRA4 => DPO) = 496; + (DPRA5 => DPO) = 199; + (posedge WCLK => (SPO : D)) = 1798; + (posedge WCLK => (DPO : D)) = 1807; + endspecify +`endif +endmodule + +// Shift registers. + +(* abc9_box, lib_whitebox *) +module SRG16E ( + output Q, + input A0, A1, A2, A3, CE, + (* clkbuf_sink *) + input CLK, + input D +); + parameter [15:0] INIT = 16'h0000; + + reg [15:0] r = INIT; + assign Q = r[{A3,A2,A1,A0}]; + always @(posedge CLK) if (CE) r <= { r[14:0], D }; + specify + $setup(D , posedge CLK, 173); + if (CE) (posedge CLK => (Q : D)) = 1472; + if (CE) (posedge CLK => (Q : 1'bx)) = 1472; + (A0 => Q) = 631; + (A1 => Q) = 472; + (A2 => Q) = 407; + (A3 => Q) = 238; + endspecify +endmodule + +// DSP + +(* abc9_box *) +module RBBDSP ( + output [21:0] AO_LOC, + output [21:0] BO_LOC, + output CE_O, + output [1:0] CO_LOC, + output [47:0] DO_LOC, + output [1:0] OPCODE_O, + output [47:0] P, + output [47:0] PO_LOC, + output RST_O, + + input [1:0] CI_LOC, + input [1:0] OPCODE, + input [1:0] OPCODE_I, + input [21:0] A, + input [21:0] AI_LOC, + input [21:0] B, + input [21:0] BI_LOC, + input [47:0] D, + input [47:0] DI_LOC, + input [47:0] PI_LOC, + input CE, + input CE_I, + (* clkbuf_sink *) + input CLK, + input CHIP_RST, + input RST_I, + input RST +); + +parameter AI_SEL_IN = 1'b0; +parameter [1:0] BC_CI = 2'b00; +parameter BI_SEL = 1'b0; +parameter BI_SEL_IN = 1'b0; +parameter CE_A = 1'b0; +parameter CE_ADD = 1'b0; +parameter CE_B = 1'b0; +parameter CE_C = 1'b0; +parameter CE_CRY = 1'b0; +parameter [1:0] CE_D = 2'b0; +parameter CE_M = 1'b0; +parameter CE_OPCODE = 1'b0; +parameter CE_PADD = 1'b0; +parameter CE_RST = 1'b1; +parameter CE_SEL = 1'b0; +parameter CE_SFT = 1'b0; +parameter [3:0] CI_SEL = 4'b0011; +parameter DI_SEL = 1'b0; +parameter DI_SEL_IN = 1'b0; +parameter OPCODE_SEL = 1'b0; +parameter [9:0] OP_ADD = 10'b0; +parameter OP_CPLX = 1'b0; +parameter [1:0] OP_MULT = 2'b11; +parameter [9:0] OP_PADD = 10'b0; +parameter [5:0] OP_SFT = 6'b0; +parameter [3:0] OP_X = 4'b1010; +parameter [3:0] OP_Y = 4'b0101; +parameter [3:0] OP_Z = 4'b0000; +parameter PO_LOC_SEL = 1'b1; +parameter PO_NWK_SEL = 1'b1; +parameter REG_A = 1'b0; +parameter REG_ADD = 1'b0; +parameter REG_B = 1'b0; +parameter REG_C = 1'b0; +parameter REG_CRY = 1'b0; +parameter [1:0] REG_D = 2'b0; +parameter REG_M = 1'b0; +parameter REG_OPCODE = 1'b0; +parameter REG_PADD = 1'b0; +parameter REG_SFT = 1'b0; +parameter RST_SEL = 1'b0; +parameter FF_SYNC_RST = 1'b0; + +specify + if (!REG_A) (A *> P) = 1000; + if (!REG_B) (B *> P) = 1000; + if (!REG_D) (D *> P) = 1000; +endspecify + +// Much of this functionality is TODO. + +assign P = $signed(A) * $signed(B); + +endmodule + +// Block RAM + +module RBRAM #( + parameter TARGET_NODE = "T40LP_Gen2.4", + parameter BRAM_MODE = "SDP_1024x40", + parameter QA_REG = 0, + parameter QB_REG = 0, + parameter CLKA_INV = 0, + parameter CLKB_INV = 0, + parameter DATA_WIDTH = 40, + parameter ADDR_WIDTH = 12, + parameter WE_WIDTH = 20, + parameter PERR_WIDTH = 4 +) ( + output [DATA_WIDTH-1:0] QA, + input [DATA_WIDTH-1:0] DA, + input CEA, + input [WE_WIDTH-1:0] WEA, + input [ADDR_WIDTH-1:0] AA, + (* clkbuf_sink *) + (* invertible_pin = "CLKA_INV" *) + input CLKA, + output [DATA_WIDTH-1:0] QB, + input [DATA_WIDTH-1:0] DB, + input CEB, + input [WE_WIDTH-1:0] WEB, + input [ADDR_WIDTH-1:0] AB, + (* clkbuf_sink *) + (* invertible_pin = "CLKB_INV" *) + input CLKB, + output reg [PERR_WIDTH-1:0] PERRA, + output reg [PERR_WIDTH-1:0] PERRB, + output SBEA, + output SBEB, + output MBEA, + output MBEB, + input SLP, + input PD +); + +// Timings simplified for now +specify + $setup(DA, posedge CLKA, 715); + $setup(CEA, posedge CLKA, 414); + $setup(AA, posedge CLKA, 624); + + $setup(DB, posedge CLKB, 744); + $setup(CEB, posedge CLKB, 350); + $setup(AB, posedge CLKB, 643); + + (posedge CLKA => (QA : DA)) = 2380; + (posedge CLKB => (QB : DB)) = 2289; +endspecify + +endmodule + +module RBRAM2 #( + parameter TARGET_NODE = "T16FFC_Gen2.4", + parameter BRAM_MODE = "SDP_2048x40", + parameter QA_REG = 0, + parameter QB_REG = 0, + parameter CLKA_INV = 0, + parameter CLKB_INV = 0, + parameter DATA_WIDTH = 40, + parameter ADDR_WIDTH = 13, + parameter WE_WIDTH = 20, + parameter PERR_WIDTH = 4 +) ( + output [DATA_WIDTH-1:0] QA, + input [DATA_WIDTH-1:0] DA, + input CEA, + input [WE_WIDTH-1:0] WEA, + input [ADDR_WIDTH-1:0] AA, + (* clkbuf_sink *) + (* invertible_pin = "CLKA_INV" *) + input CLKA, + output [DATA_WIDTH-1:0] QB, + input [DATA_WIDTH-1:0] DB, + input CEB, + input [WE_WIDTH-1:0] WEB, + input [ADDR_WIDTH-1:0] AB, + (* clkbuf_sink *) + (* invertible_pin = "CLKB_INV" *) + input CLKB, + output reg [PERR_WIDTH-1:0] PERRA, + output reg [PERR_WIDTH-1:0] PERRB, + output SBEA, + output SBEB, + output MBEA, + output MBEB, + input SLP, + input PD +); + +// Timings simplified for now +specify + $setup(DA, posedge CLKA, 2440); + $setup(CEA, posedge CLKA, 1668); + $setup(AA, posedge CLKA, 2289); + + $setup(DB, posedge CLKB, 2420); + $setup(CEB, posedge CLKB, 1805); + $setup(AB, posedge CLKB, 2170); + + (posedge CLKA => (QA : DA)) = 2227; + (posedge CLKB => (QB : DB)) = 2189; +endspecify + +endmodule diff --git a/techlibs/analogdevices/dsp_map.v b/techlibs/analogdevices/dsp_map.v new file mode 100644 index 000000000..6f4b0822b --- /dev/null +++ b/techlibs/analogdevices/dsp_map.v @@ -0,0 +1,60 @@ +module \$__MUL22X22 (input [21:0] A, input [21:0] B, output [43:0] Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 0; + parameter B_WIDTH = 0; + parameter Y_WIDTH = 0; + + wire [47:0] P_48; + RBBDSP #( + // Disable all registers + .AI_SEL_IN(1'b0), + .BC_CI(2'b00), + .BI_SEL(1'b0), + .BI_SEL_IN(1'b0), + .CE_A(1'b0), + .CE_ADD(1'b0), + .CE_B(1'b0), + .CE_C(1'b0), + .CE_CRY(1'b0), + .CE_D(2'b0), + .CE_M(1'b0), + .CE_OPCODE(1'b0), + .CE_PADD(1'b0), + .CE_RST(1'b1), + .CE_SEL(1'b0), + .CE_SFT(1'b0), + .CI_SEL(4'd3), + .DI_SEL(1'b0), + .DI_SEL_IN(1'b0), + .OPCODE_SEL(1'b0), + .OP_ADD(10'b0), + .OP_CPLX(1'b0), + .OP_MULT(2'b11), + .OP_PADD(10'b0000000000), + .OP_SFT(6'b000000), + .OP_X(4'b1010), + .OP_Y(4'b0101), + .OP_Z(4'b0000), + .PO_LOC_SEL(1'b1), + .PO_NWK_SEL(1'b1), + .REG_A(1'b0), + .REG_ADD(1'b0), + .REG_B(1'b0), + .REG_C(1'b0), + .REG_CRY(1'b0), + .REG_D(2'b0), + .REG_M(1'b0), + .REG_OPCODE(1'b0), + .REG_PADD(1'b0), + .REG_SFT(1'b0), + .RST_SEL(1'b0), + .FF_SYNC_RST(1'b0), + ) _TECHMAP_REPLACE_ ( + .P(P_48), + .A(A), + .B(B), + .D(48'b0) + ); + assign Y = P_48; +endmodule diff --git a/techlibs/analogdevices/ff_map.v b/techlibs/analogdevices/ff_map.v new file mode 100644 index 000000000..0be742b49 --- /dev/null +++ b/techlibs/analogdevices/ff_map.v @@ -0,0 +1,63 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +`ifndef _NO_FFS + +// Async reset, enable. + +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); + FFCE_N #(.INIT(1'b0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); + FFCE #(.INIT(1'b0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); + FFPE_N #(.INIT(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); + FFPE #(.INIT(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Sync reset, enable. + +module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); + FFRE_N #(.INIT(1'b0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); + FFRE #(.INIT(1'b0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); + FFSE_N #(.INIT(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); + FFSE #(.INIT(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +`endif + diff --git a/techlibs/analogdevices/lut_map.v b/techlibs/analogdevices/lut_map.v new file mode 100644 index 000000000..832b5cbfb --- /dev/null +++ b/techlibs/analogdevices/lut_map.v @@ -0,0 +1,79 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// ============================================================================ +// LUT mapping + +`ifndef _NO_LUTS + +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + (* force_downto *) + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0])); + end else + if (WIDTH == 2) begin + LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1])); + end else + if (WIDTH == 3) begin + LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2])); + end else + if (WIDTH == 4) begin + LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3])); + end else + if (WIDTH == 5) begin + LUT5 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4])); + end else + if (WIDTH == 6) begin + LUT6 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); + end else + if (WIDTH == 7) begin + wire f0, f1; + \$lut #(.LUT(LUT[ 63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0)); + \$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1)); + LUTMUX7 mux7(.I0(f0), .I1(f1), .S(A[6]), .O(Y)); + end else + if (WIDTH == 8) begin + wire f0, f1; + \$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0)); + \$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1)); + LUTMUX8 mux8 (.I0(f0), .I1(f1), .S(A[7]), .O(Y)); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule + +`endif + diff --git a/techlibs/analogdevices/lutrams.txt b/techlibs/analogdevices/lutrams.txt new file mode 100644 index 000000000..c391cdb43 --- /dev/null +++ b/techlibs/analogdevices/lutrams.txt @@ -0,0 +1,20 @@ +ram distributed $__ANALOGDEVICES_LUTRAM_ { + option "SIZE" 32 abits 5; + option "SIZE" 64 abits 6; + width 1; + init no_undef; + prune_rom; + port arsw "RW" { + clock posedge; + } + option "MODE" "SP" { + option "SIZE" 32 cost 2; + option "SIZE" 64 cost 2; + } + option "MODE" "DP" { + option "SIZE" 32 cost 4; + option "SIZE" 64 cost 8; + port ar "R" { + } + } +} diff --git a/techlibs/analogdevices/lutrams_map.v b/techlibs/analogdevices/lutrams_map.v new file mode 100644 index 000000000..18fa93516 --- /dev/null +++ b/techlibs/analogdevices/lutrams_map.v @@ -0,0 +1,139 @@ +module $__ANALOGDEVICES_LUTRAM_ (...); + +parameter INIT = 0; +parameter OPTION_SIZE = 32; +parameter OPTION_MODE = "SP"; +parameter ABITS = 5; +parameter WIDTH = 1; + +output PORT_RW_RD_DATA; +input PORT_RW_WR_DATA; +input [ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +output PORT_R_RD_DATA; +input [ABITS-1:0] PORT_R_ADDR; + +generate + if (OPTION_MODE=="SP") + case(OPTION_SIZE) + 32: + RAMS32X1 + #( + .INIT(INIT) + ) + _TECHMAP_REPLACE_ + ( + .O(PORT_RW_RD_DATA), + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .D(PORT_RW_WR_DATA), + .WCLK(PORT_RW_CLK), + .WE(PORT_RW_WR_EN) + ); + 64: + RAMS64X1 + #( + .INIT(INIT) + ) + _TECHMAP_REPLACE_ + ( + .O(PORT_RW_RD_DATA), + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .D(PORT_RW_WR_DATA), + .WCLK(PORT_RW_CLK), + .WE(PORT_RW_WR_EN) + ); + default: + $error("invalid SIZE/MODE combination"); + endcase + else if (OPTION_MODE=="DP") + case (OPTION_SIZE) + 32: + RAMD32X1 + #( + .INIT(INIT) + ) + _TECHMAP_REPLACE_ + ( + .DPO(PORT_R_RD_DATA), + .SPO(PORT_RW_RD_DATA), + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .D(PORT_RW_WR_DATA), + .DPRA0(PORT_R_ADDR[0]), + .DPRA1(PORT_R_ADDR[1]), + .DPRA2(PORT_R_ADDR[2]), + .DPRA3(PORT_R_ADDR[3]), + .DPRA4(PORT_R_ADDR[4]), + .WCLK(PORT_RW_CLK), + .WE(PORT_RW_WR_EN) + ); + 64: + RAMD64X1 + #( + .INIT(INIT) + ) + _TECHMAP_REPLACE_ + ( + .DPO(PORT_R_RD_DATA), + .SPO(PORT_RW_RD_DATA), + .A0(PORT_RW_ADDR[0]), + .A1(PORT_RW_ADDR[1]), + .A2(PORT_RW_ADDR[2]), + .A3(PORT_RW_ADDR[3]), + .A4(PORT_RW_ADDR[4]), + .A5(PORT_RW_ADDR[5]), + .D(PORT_RW_WR_DATA), + .DPRA0(PORT_R_ADDR[0]), + .DPRA1(PORT_R_ADDR[1]), + .DPRA2(PORT_R_ADDR[2]), + .DPRA3(PORT_R_ADDR[3]), + .DPRA4(PORT_R_ADDR[4]), + .DPRA5(PORT_R_ADDR[5]), + .WCLK(PORT_RW_CLK), + .WE(PORT_RW_WR_EN) + ); + default: + $error("invalid SIZE/MODE combination"); + endcase + else + wire _TECHMAP_FAIL_ = 1; +endgenerate + +endmodule + + +module $__ANALOGDEVICES_LUTRAM_DP_ (...); + +parameter INIT = 0; +parameter OPTION_SIZE = 32; +parameter ABITS = 5; +parameter WIDTH = 1; + +output PORT_RW_RD_DATA; +input PORT_RW_WR_DATA; +input [ABITS-1:0] PORT_RW_ADDR; +input PORT_RW_WR_EN; +input PORT_RW_CLK; + +output PORT_R_RD_DATA; +input [ABITS-1:0] PORT_R_ADDR; + +generate + +endgenerate + +endmodule diff --git a/techlibs/analogdevices/mux_map.v b/techlibs/analogdevices/mux_map.v new file mode 100644 index 000000000..7fa45cb54 --- /dev/null +++ b/techlibs/analogdevices/mux_map.v @@ -0,0 +1,74 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// The purpose of these mapping rules is to allow preserve all (sufficiently +// wide) $shiftx cells during 'techmap' so that they can be mapped to hard +// resources, rather than being bit-blasted to gates during 'techmap' +// execution + +module \$shiftx (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0; + parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0; + + generate + if (B_SIGNED) begin + if (_TECHMAP_CONSTMSK_B_[B_WIDTH-1] && (_TECHMAP_CONSTVAL_B_[B_WIDTH-1] == 1'b0 || _TECHMAP_CONSTVAL_B_[B_WIDTH-1] === 1'bx)) + // Optimisation to remove B_SIGNED if sign bit of B is constant-0 + \$shiftx #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(0), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH-1'd1), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B[B_WIDTH-2:0]), .Y(Y) + ); + else + wire _TECHMAP_FAIL_ = 1; + end + else begin + if (((A_WIDTH + Y_WIDTH - 1) / Y_WIDTH) < `MIN_MUX_INPUTS) + wire _TECHMAP_FAIL_ = 1; + else + \$__ANALOGDEVICES_SHIFTX #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), .Y(Y) + ); + end + endgenerate +endmodule diff --git a/techlibs/analogdevices/retarget_map.v b/techlibs/analogdevices/retarget_map.v new file mode 100644 index 000000000..a9712219f --- /dev/null +++ b/techlibs/analogdevices/retarget_map.v @@ -0,0 +1,49 @@ +module FF (input C, D, output Q); +parameter INIT = 1'b0; +if (INIT === 1'b1) begin +FFPE _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(1'b0), .CE(1'b1), .Q(Q)); +end else begin +FFCE _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(1'b0), .CE(1'b1), .Q(Q)); +end +endmodule + +module FF_N (input C, D, output Q); +parameter INIT = 1'b0; +if (INIT === 1'b1) begin +FFPE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(1'b0), .CE(1'b1), .Q(Q)); +end else begin +FFCE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(1'b0), .CE(1'b1), .Q(Q)); +end +endmodule + +module FFC (input C, D, CLR, output Q); +FFCE _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(CLR), .CE(1'b1), .Q(Q)); +endmodule + +module FFC_N (input C, D, CLR, output Q); +FFCE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(CLR), .CE(1'b1), .Q(Q)); +endmodule + +module FFP (input C, D, PRE, output Q); +FFPE _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(PRE), .CE(1'b1), .Q(Q)); +endmodule + +module FFP_N (input C, D, CLR, output Q); +FFPE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(PRE), .CE(1'b1), .Q(Q)); +endmodule + +module FFR (input C, D, R, output Q); +FFRE _TECHMAP_REPLACE_ (.C(C), .D(D), .R(R), .CE(1'b1), .Q(Q)); +endmodule + +module FFR_N (input C, D, R, output Q); +FFRE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .R(R), .CE(1'b1), .Q(Q)); +endmodule + +module FFS (input C, D, S, output Q); +FFSE _TECHMAP_REPLACE_ (.C(C), .D(D), .S(S), .CE(1'b1), .Q(Q)); +endmodule + +module FFS_N (input C, D, S, output Q); +FFSE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .S(S), .CE(1'b1), .Q(Q)); +endmodule diff --git a/techlibs/analogdevices/synth_analogdevices.cc b/techlibs/analogdevices/synth_analogdevices.cc new file mode 100644 index 000000000..aa27c78b6 --- /dev/null +++ b/techlibs/analogdevices/synth_analogdevices.cc @@ -0,0 +1,520 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * (C) 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthAnalogDevicesPass : public ScriptPass +{ + SynthAnalogDevicesPass() : ScriptPass("synth_analogdevices", "synthesis for Analog Devices FPGAs") { } + + void on_register() override + { + RTLIL::constpad["synth_analogdevices.abc9.W"] = "300"; // Number with which ABC will map a 6-input gate + // to one LUT6 (instead of a LUT5 + LUT2) + } + + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_analogdevices [options]\n"); + log("\n"); + log("This command runs synthesis for Analog Devices FPGAs. This command does not operate on\n"); + log("partly selected designs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -tech \n"); + log(" run synthesis for the specified ADI technology process\n"); + log(" currently only affects the type of BRAM used.\n"); + log(" supported values:\n"); + log(" - t40lp (RBRAM)\n"); + log(" - t16ffc (RBRAM2, default)\n"); + log("\n"); + log(" -edif \n"); + log(" write the design to the specified edif file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -nobram\n"); + log(" do not use block RAM cells in output netlist\n"); + log("\n"); + log(" -nolutram\n"); + log(" do not use distributed RAM cells in output netlist\n"); + log("\n"); + log(" -nosrl\n"); + log(" do not use distributed SRL cells in output netlist\n"); + log("\n"); + log(" -nocarry\n"); + log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n"); + log("\n"); + log(" -nowidelut\n"); + log(" do not use MUXF[7-8] resources to implement LUTs larger than native for\n"); + log(" the target\n"); + log("\n"); + log(" -nodsp\n"); + log(" do not use DSP48*s to implement multipliers and associated logic\n"); + log("\n"); + log(" -noiopad\n"); + log(" disable I/O buffer insertion (useful for hierarchical or \n"); + log(" out-of-context flows)\n"); + log("\n"); + log(" -noclkbuf\n"); + log(" disable automatic clock buffer insertion\n"); + log("\n"); + log(" -widemux \n"); + log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at\n"); + log(" or above this number of inputs (minimum value 2, recommended value >= 5)\n"); + log(" default: 0 (no inference)\n"); + log("\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -dff\n"); + log(" run 'abc'/'abc9' with -dff option\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with '-D 1' option to enable flip-flop retiming.\n"); + log(" implies -dff.\n"); + log("\n"); + log(" -noabc9\n"); + log(" disable use of new ABC9 flow\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + std::string top_opt, edif_file, json_file, tech, tech_param; + bool flatten, retime, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp; + bool abc9, dff; + bool flatten_before_abc; + int widemux; + int widelut_size; + + void clear_flags() override + { + top_opt = "-auto-top"; + edif_file.clear(); + tech = "t16ffc"; + tech_param = " -D IS_T16FFC"; + flatten = true; + retime = false; + noiopad = false; + noclkbuf = false; + nocarry = false; + nobram = false; + nolutram = false; + nosrl = false; + nocarry = false; + nowidelut = false; + nodsp = false; + abc9 = true; + dff = false; + flatten_before_abc = false; + widemux = 0; + } + + void execute(std::vector args, RTLIL::Design *design) override + { + std::string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-tech" && argidx+1 < args.size()) { + tech = args[++argidx]; + if (tech == "t16ffc") + tech_param = " -D IS_T16FFC"; + else if (tech == "t40lp") + tech_param = " -D IS_T40LP"; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-flatten_before_abc") { + flatten_before_abc = true; + continue; + } + if (args[argidx] == "-retime") { + dff = true; + retime = true; + continue; + } + if (args[argidx] == "-nocarry") { + nocarry = true; + continue; + } + if (args[argidx] == "-nowidelut") { + nowidelut = true; + continue; + } + if (args[argidx] == "-iopad") { + continue; + } + if (args[argidx] == "-noiopad") { + noiopad = true; + continue; + } + if (args[argidx] == "-noclkbuf") { + noclkbuf = true; + continue; + } + if (args[argidx] == "-nocarry") { + nocarry = true; + continue; + } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } + if (args[argidx] == "-nolutram") { + nolutram = true; + continue; + } + if (args[argidx] == "-nosrl") { + nosrl = true; + continue; + } + if (args[argidx] == "-widemux" && argidx+1 < args.size()) { + widemux = atoi(args[++argidx].c_str()); + continue; + } + if (args[argidx] == "-noabc9") { + abc9 = false; + continue; + } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } + if (args[argidx] == "-dff") { + dff = true; + continue; + } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_file = args[++argidx]; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (!(tech == "t16ffc" || tech == "t40lp")) + log_cmd_error("Invalid ADI -tech setting: '%s'.\n", tech); + + if (widemux != 0 && widemux < 2) + log_cmd_error("-widemux value must be 0 or >= 2.\n"); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + if (abc9 && retime) + log_cmd_error("-retime option not currently compatible with -abc9!\n"); + + log_header(design, "Executing SYNTH_ANALOGDEVICES pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() override + { + if (check_label("begin")) { + run(stringf("read_verilog -lib -specify %s +/analogdevices/cells_sim.v", tech_param)); + run(stringf("hierarchy -check %s", top_opt.c_str())); + } + + if (check_label("prepare")) { + run("proc"); + if (flatten || help_mode) { + run("check"); + run("flatten", "(with '-flatten')"); + } + if (active_design) + active_design->scratchpad_unset("tribuf.added_something"); + run("tribuf -logic"); + if (noiopad && active_design && active_design->scratchpad_get_bool("tribuf.added_something")) + log_error("Tristate buffers are unsupported without the '-iopad' option.\n"); + run("deminout"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + if (help_mode) + run("wreduce [-keepdc]", "(option for '-widemux')"); + else + run("wreduce" + std::string(widemux > 0 ? " -keepdc" : "")); + run("peepopt"); + run("opt_clean"); + + if (widemux > 0 || help_mode) + run("muxpack", " ('-widemux' only)"); + + // xilinx_srl looks for $shiftx cells for identifying variable-length + // shift registers, so attempt to convert $pmux-es to this + // Also: wide multiplexer inference benefits from this too + if (!(nosrl && widemux == 0) || help_mode) { + run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')"); + run("clean", " (skip if '-nosrl' and '-widemux=0')"); + } + } + + if (check_label("map_dsp", "(skip if '-nodsp')")) { + if (!nodsp || help_mode) { + run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first + // NB: Analog Devices multipliers are signed only + if (help_mode) + run("techmap -map +/mul2dsp.v -map +/analogdevices/{family}_dsp_map.v {options}"); + run("techmap -map +/mul2dsp.v -map +/analogdevices/dsp_map.v -D DSP_A_MAXWIDTH=22 -D DSP_B_MAXWIDTH=22 " + "-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally + // limited to 18x18 in order to take + // advantage of the (PCOUT << 17) -> PCIN + // dedicated cascade chain capability + "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers + "-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller + "-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL22X22"); + + run("select a:mul2dsp"); + run("setattr -unset mul2dsp"); + run("opt_expr -fine"); + run("wreduce"); + run("select -clear"); + if (help_mode) + run("xilinx_dsp -family "); + else + run("xilinx_dsp -family xc7"); + run("chtype -set $mul t:$__soft_mul"); + } + } + + if (check_label("coarse")) { + run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=6"); + run("alumacc"); + run("share"); + run("opt"); + run("memory -nomap"); + run("opt_clean"); + } + + if (check_label("map_memory")) { + std::string params = ""; + std::string lutrams_map = "+/analogdevices/lutrams_map.v"; + std::string brams_map = "+/analogdevices/brams_map.v"; + if (help_mode) { + params = " [...]"; + } else { + params += " -logic-cost-rom 0.015625"; + params += " -force-params"; + params += " -lib +/analogdevices/lutrams.txt"; + params += " -lib +/analogdevices/brams.txt"; + params += tech_param; + brams_map += tech_param; + if (nolutram) + params += " -no-auto-distributed"; + if (nobram) + params += " -no-auto-block"; + } + run("memory_libmap" + params); + run("techmap -map " + lutrams_map); + run("techmap -map " + brams_map); + } + + if (check_label("map_ffram")) { + if (widemux > 0) { + run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover + // performs less efficiently + } else { + run("opt -fast -full"); + } + run("memory_map"); + } + + if (check_label("fine")) { + if (help_mode) { + run("simplemap t:$mux", "('-widemux' only)"); + run("muxcover ", "('-widemux' only)"); + } else if (widemux > 0) { + run("simplemap t:$mux"); + constexpr int cost_mux2 = 100; + std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); + switch (widemux) { + case 2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break; + case 3: + case 4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break; + case 5: + case 6: + case 7: + case 8: muxcover_args += stringf(" -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + default: muxcover_args += stringf(" -mux16=%d", cost_mux2*(widemux-1)-1); break; + } + run("muxcover " + muxcover_args); + } + run("opt -full"); + + if (!nosrl || help_mode) + run("xilinx_srl -variable -minlen 3", "(skip if '-nosrl')"); + + std::string techmap_args = " -map +/techmap.v -D LUT_SIZE=6"; + if (help_mode) + techmap_args += " [-map +/analogdevices/mux_map.v]"; + else if (widemux > 0) + techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/analogdevices/mux_map.v", widemux); + if (!nocarry) { + techmap_args += " -map +/analogdevices/arith_map.v"; + } + run("techmap " + techmap_args); + run("opt -fast"); + } + + if (check_label("map_cells")) { + // Needs to be done before logic optimization, so that inverters (inserted + // here because of negative-polarity output enable) are handled. + if (help_mode || !noiopad) + run("iopadmap -bits -outpad OUTBUF I:O -inpad INBUF O:I A:top", "(skip if '-noiopad')"); + std::string techmap_args = "-map +/techmap.v -map +/analogdevices/cells_map.v"; + if (widemux > 0) + techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); + run("techmap " + techmap_args); + run("clean"); + } + + if (check_label("map_ffs")) { + run("dfflegalize -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r"); + if (abc9 || help_mode) { + if (dff || help_mode) + run("zinit -all w:* t:$_SDFFE_*", "('-dff' only)"); + run("techmap -map +/analogdevices/ff_map.v", "('-abc9' only)"); + } + } + + if (check_label("map_luts")) { + run("opt_expr -mux_undef -noclkinv"); + if (flatten_before_abc) { + run("check"); + run("flatten"); + } + if (help_mode) + run("abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1]", "(option for '-nowidelut', '-dff', '-retime')"); + else if (abc9) { + run("read_verilog -icells -lib -specify +/analogdevices/abc9_model.v"); + std::string abc9_opts; + std::string k = "synth_analogdevices.abc9.W"; + if (active_design && active_design->scratchpad.count(k)) + abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); + else { + abc9_opts += stringf(" -W %s", RTLIL::constpad.at("synth_analogdevices.abc9.W").c_str()); + } + if (nowidelut) + abc9_opts += stringf(" -maxlut 6"); + if (dff) + abc9_opts += " -dff"; + run("abc9" + abc9_opts); + } + else { + std::string abc_opts; + if (nowidelut) + abc_opts += " -luts 2:2,3,6:5"; + else + abc_opts += " -luts 2:2,3,6:5,10,20"; + if (dff) + abc_opts += " -dff"; + if (retime) + abc_opts += " -D 1"; + run("abc -dress" + abc_opts); + } + run("clean"); + + if (help_mode || !abc9) + run("techmap -map +/analogdevices/ff_map.v", "(only if not '-abc9')"); + // This shregmap call infers fixed length shift registers after abc + // has performed any necessary retiming + if (!nosrl || help_mode) + run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')"); + std::string techmap_args = "-map +/analogdevices/lut_map.v -map +/analogdevices/cells_map.v"; + techmap_args += " -D LUT_WIDTH=6"; + run("techmap " + techmap_args); + run("xilinx_dffopt"); + run("opt_lut_ins -tech analogdevices"); + } + + if (check_label("finalize")) { + run("clean"); + } + + if (check_label("check")) { + run("hierarchy -check"); + run("stat -tech analogdevices"); + run("check -noinit"); + run("blackbox =A:whitebox"); + } + + if (check_label("edif")) { + if (!edif_file.empty() || help_mode) { + run("delete t:$assert t:$scopeinfo"); + run(stringf("write_edif %s", edif_file.c_str())); + } + } + } +} SynthAnalogDevicesPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index a03374fb0..5c7c0b532 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -156,6 +156,7 @@ struct SynthAnlogicPass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); run("tribuf -logic"); run("deminout"); diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc index a98619abd..6798f2a5d 100644 --- a/techlibs/common/prep.cc +++ b/techlibs/common/prep.cc @@ -211,6 +211,7 @@ struct PrepPass : public ScriptPass run("memory_collect"); } run(nokeepdc ? "opt -noff -fast" : "opt -noff -keepdc -fast"); + run("sort"); } if (check_label("check")) diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 1a113447e..3c38ca8b9 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -1613,6 +1613,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 0 0 - | x //- - - 0 - | 0 //- - 0 - - | 1 //- \ - - d | d @@ -1641,6 +1642,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 0 1 - | x //- - - 1 - | 0 //- - 0 - - | 1 //- \ - - d | d @@ -1669,6 +1671,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 1 0 - | x //- - - 0 - | 0 //- - 1 - - | 1 //- \ - - d | d @@ -1697,6 +1700,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 1 1 - | x //- - - 1 - | 0 //- - 1 - - | 1 //- \ - - d | d @@ -1725,6 +1729,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 0 0 - | x //- - - 0 - | 0 //- - 0 - - | 1 //- / - - d | d @@ -1753,6 +1758,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 0 1 - | x //- - - 1 - | 0 //- - 0 - - | 1 //- / - - d | d @@ -1781,6 +1787,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 1 0 - | x //- - - 0 - | 0 //- - 1 - - | 1 //- / - - d | d @@ -1809,6 +1816,7 @@ endmodule //- //- Truth table: C S R D | Q //- ---------+--- +//- - 1 1 - | x //- - - 1 - | 0 //- - 1 - - | 1 //- / - - d | d @@ -1837,6 +1845,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 0 - - | x //- - - 0 - - | 0 //- - 0 - - - | 1 //- \ - - 0 d | d @@ -1865,6 +1874,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 0 - - | x //- - - 0 - - | 0 //- - 0 - - - | 1 //- \ - - 1 d | d @@ -1893,6 +1903,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 1 - - | x //- - - 1 - - | 0 //- - 0 - - - | 1 //- \ - - 0 d | d @@ -1921,6 +1932,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 1 - - | x //- - - 1 - - | 0 //- - 0 - - - | 1 //- \ - - 1 d | d @@ -1949,6 +1961,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 0 - - | x //- - - 0 - - | 0 //- - 1 - - - | 1 //- \ - - 0 d | d @@ -1977,6 +1990,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 0 - - | x //- - - 0 - - | 0 //- - 1 - - - | 1 //- \ - - 1 d | d @@ -2005,6 +2019,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 1 - - | x //- - - 1 - - | 0 //- - 1 - - - | 1 //- \ - - 0 d | d @@ -2033,6 +2048,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 1 - - | x //- - - 1 - - | 0 //- - 1 - - - | 1 //- \ - - 1 d | d @@ -2061,6 +2077,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 0 - - | x //- - - 0 - - | 0 //- - 0 - - - | 1 //- / - - 0 d | d @@ -2089,6 +2106,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 0 - - | x //- - - 0 - - | 0 //- - 0 - - - | 1 //- / - - 1 d | d @@ -2117,6 +2135,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 1 - - | x //- - - 1 - - | 0 //- - 0 - - - | 1 //- / - - 0 d | d @@ -2145,6 +2164,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 0 1 - - | x //- - - 1 - - | 0 //- - 0 - - - | 1 //- / - - 1 d | d @@ -2173,6 +2193,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 0 - - | x //- - - 0 - - | 0 //- - 1 - - - | 1 //- / - - 0 d | d @@ -2201,6 +2222,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 0 - - | x //- - - 0 - - | 0 //- - 1 - - - | 1 //- / - - 1 d | d @@ -2229,6 +2251,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 1 - - | x //- - - 1 - - | 0 //- - 1 - - - | 1 //- / - - 0 d | d @@ -2257,6 +2280,7 @@ endmodule //- //- Truth table: C S R E D | Q //- -----------+--- +//- - 1 1 - - | x //- - - 1 - - | 0 //- - 1 - - - | 1 //- / - - 1 d | d diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index e0fb9fbfa..3f34bfd22 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1976,7 +1976,7 @@ endmodule // -------------------------------------------------------- //* group spec -module \$specrule (EN_SRC, EN_DST, SRC, DST); +module \$specrule (SRC_EN, DST_EN, SRC, DST); parameter TYPE = ""; parameter T_LIMIT = 0; @@ -1991,7 +1991,7 @@ parameter SRC_POL = 0; parameter DST_PEN = 0; parameter DST_POL = 0; -input EN_SRC, EN_DST; +input SRC_EN, DST_EN; input [SRC_WIDTH-1:0] SRC; input [DST_WIDTH-1:0] DST; diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 0dbb7cbec..00d884107 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -67,6 +67,10 @@ struct SynthPass : public ScriptPass { log(" -booth\n"); log(" run the booth pass to map $mul to Booth encoded multipliers\n"); log("\n"); + log(" -arith_tree\n"); + log(" run the arith_tree pass to convert $add/$sub chains and $macc cells to\n"); + log(" carry-save adder trees.\n"); + log("\n"); log(" -noalumacc\n"); log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n"); log(" their direct form ($add, $sub, etc.).\n"); @@ -108,7 +112,7 @@ struct SynthPass : public ScriptPass { } string top_module, fsm_opts, memory_opts, abc; - bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth, hieropt, relative_share; + bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth, arith_tree, hieropt, relative_share; int lut; std::vector techmap_maps; @@ -127,6 +131,7 @@ struct SynthPass : public ScriptPass { noshare = false; flowmap = false; booth = false; + arith_tree = false; hieropt = false; relative_share = false; abc = "abc"; @@ -187,7 +192,10 @@ struct SynthPass : public ScriptPass { booth = true; continue; } - + if (args[argidx] == "-arith_tree") { + arith_tree = true; + continue; + } if (args[argidx] == "-nordff") { memory_opts += " -nordff"; continue; @@ -269,8 +277,10 @@ struct SynthPass : public ScriptPass { if (check_label("coarse")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten", " (if -flatten)"); + } run("opt_expr"); run("opt_clean"); run("check"); @@ -289,6 +299,8 @@ struct SynthPass : public ScriptPass { run("booth", " (if -booth)"); if (!noalumacc) run("alumacc", " (unless -noalumacc)"); + if (arith_tree || help_mode) + run("arith_tree", " (if -arith_tree)"); if (!noshare) run("share", " (unless -noshare)"); run("opt" + hieropt_flag); @@ -301,7 +313,7 @@ struct SynthPass : public ScriptPass { run("memory_map"); run("opt -full"); if (help_mode) { - run(techmap_cmd, " (unless -extra-map)"); + run(techmap_cmd, " (unless -extra-map)"); run(techmap_cmd + " -map +/techmap.v -map ", " (if -extra-map)"); } else { std::string techmap_opts; @@ -326,13 +338,13 @@ struct SynthPass : public ScriptPass { if ((!noabc && !flowmap) || help_mode) { #ifdef YOSYS_ENABLE_ABC if (help_mode) { - run(abc + " -fast", " (unless -noabc, unless -lut)"); - run(abc + " -fast -lut k", "(unless -noabc, if -lut)"); + run(abc, " (unless -noabc, unless -lut)"); + run(abc + " -lut k", "(unless -noabc, if -lut)"); } else { if (lut) - run(stringf("%s -fast -lut %d", abc, lut)); + run(stringf("%s -lut %d", abc, lut)); else - run(abc + " -fast"); + run(abc); } run("opt -fast", " (unless -noabc)"); #endif diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index c3364e628..8061b2e81 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -59,7 +59,7 @@ module _90_simplemap_compare_ops; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$buf $pos $slice $concat $mux $tribuf $bmux $bwmux $bweqx" *) +(* techmap_celltype = "$buf $pos $slice $concat $mux $pmux $tribuf $bmux $bwmux $bweqx" *) module _90_simplemap_various; endmodule @@ -563,48 +563,6 @@ module _90_pow (A, B, Y); wire _TECHMAP_FAIL_ = 1; endmodule - -// -------------------------------------------------------- -// Parallel Multiplexers -// -------------------------------------------------------- - -(* techmap_celltype = "$pmux" *) -module _90_pmux (A, B, S, Y); - parameter WIDTH = 1; - parameter S_WIDTH = 1; - - (* force_downto *) - input [WIDTH-1:0] A; - (* force_downto *) - input [WIDTH*S_WIDTH-1:0] B; - (* force_downto *) - input [S_WIDTH-1:0] S; - (* force_downto *) - output [WIDTH-1:0] Y; - - (* force_downto *) - wire [WIDTH-1:0] Y_B; - - genvar i, j; - generate - (* force_downto *) - wire [WIDTH*S_WIDTH-1:0] B_AND_S; - for (i = 0; i < S_WIDTH; i = i + 1) begin:B_AND - assign B_AND_S[WIDTH*(i+1)-1:WIDTH*i] = B[WIDTH*(i+1)-1:WIDTH*i] & {WIDTH{S[i]}}; - end:B_AND - for (i = 0; i < WIDTH; i = i + 1) begin:B_OR - (* force_downto *) - wire [S_WIDTH-1:0] B_AND_BITS; - for (j = 0; j < S_WIDTH; j = j + 1) begin:B_AND_BITS_COLLECT - assign B_AND_BITS[j] = B_AND_S[WIDTH*j+i]; - end:B_AND_BITS_COLLECT - assign Y_B[i] = |B_AND_BITS; - end:B_OR - endgenerate - - assign Y = |S ? Y_B : A; -endmodule - // -------------------------------------------------------- // Demultiplexers // -------------------------------------------------------- diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc index 7ee1393be..1b30f51bc 100644 --- a/techlibs/coolrunner2/synth_coolrunner2.cc +++ b/techlibs/coolrunner2/synth_coolrunner2.cc @@ -132,6 +132,7 @@ struct SynthCoolrunner2Pass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); run("tribuf -logic"); } diff --git a/techlibs/easic/synth_easic.cc b/techlibs/easic/synth_easic.cc index 6c5df7beb..aea517cc5 100644 --- a/techlibs/easic/synth_easic.cc +++ b/techlibs/easic/synth_easic.cc @@ -142,6 +142,7 @@ struct SynthEasicPass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); } diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index ef245e755..14457c64b 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -148,6 +148,7 @@ struct SynthEfinixPass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); run("tribuf -logic"); run("deminout"); diff --git a/techlibs/fabulous/prims.v b/techlibs/fabulous/prims.v index 21dc5223d..0dab9b8fd 100644 --- a/techlibs/fabulous/prims.v +++ b/techlibs/fabulous/prims.v @@ -149,6 +149,30 @@ module OutPass4_frame_config (input CLK, I0, I1, I2, I3); endmodule +(* blackbox, keep *) +module InPass4_frame_config_mux #( + parameter [3:0] O_reg = 0 +) ( + input CLK, + output O0, + output O1, + output O2, + output O3 +); +endmodule + +(* blackbox, keep *) +module OutPass4_frame_config_mux #( + parameter [3:0] I_reg = 0 +) ( + input I0, + input I1, + input I2, + input I3, + input CLK +); +endmodule + (* keep *) module IO_1_bidirectional_frame_config_pass (input CLK, T, I, output Q, O, (* iopad_external_pin *) inout PAD); assign PAD = T ? 1'bz : I; diff --git a/techlibs/fabulous/synth_fabulous.cc b/techlibs/fabulous/synth_fabulous.cc index f74dc8e26..0074a52af 100644 --- a/techlibs/fabulous/synth_fabulous.cc +++ b/techlibs/fabulous/synth_fabulous.cc @@ -286,6 +286,7 @@ struct SynthPass : public ScriptPass if (check_label("flatten", "(unless -noflatten)")) { if (flatten) { + run("check"); run("flatten"); run("tribuf -logic"); run("deminout"); diff --git a/techlibs/fix_mod.py b/techlibs/fix_mod.py new file mode 100644 index 000000000..d6406108d --- /dev/null +++ b/techlibs/fix_mod.py @@ -0,0 +1,47 @@ +import sys +import subprocess +import re +import os + +def main(): + script = sys.argv.pop(0) + try: + verilog, yosys = sys.argv + except ValueError: + print(f"Expected to be called as 'python3 {script} '.") + exit(1) + + proc = subprocess.run([yosys, '-p', f'read_verilog -lib {verilog}; write_verilog -blackboxes -'], stdout=subprocess.PIPE) + modules = {} + in_mod = False + mod = "" + decl = "" + for line in proc.stdout.decode('utf-8').splitlines(keepends=True): + m = re.match(r'(module (\S+)\(.+)', line, re.S) + if m: + decl, mod = m.groups() + in_mod = True + elif in_mod: + decl += line + + if in_mod and decl.rstrip()[-1] == ';': + in_mod = False + modules[mod] = decl + + src = f'{verilog}.tmp' + os.rename(verilog, src) + dest = verilog + + with open(dest, 'w') as f_out: + with open(src, 'r') as f_in: + for line in f_in: + m = re.match(r'module (\S+) \(\.\.\.\)', line) + if m: + line = modules[m.group(1)] + print(line, end='', file=f_out) + + if src.endswith('.tmp'): + os.remove(src) + +if __name__ == "__main__": + main() diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc index 7726e7a15..f7cdcbd12 100644 --- a/techlibs/gatemate/synth_gatemate.cc +++ b/techlibs/gatemate/synth_gatemate.cc @@ -69,7 +69,8 @@ struct SynthGateMatePass : public ScriptPass log(" do not use CC_MX{8,4} multiplexer cells in output netlist.\n"); log("\n"); log(" -luttree\n"); - log(" use new LUT tree mapping approach (EXPERIMENTAL).\n"); + log(" use LUT tree mapping for output to nextpnr. Do not use this if targeting\n"); + log(" legacy p_r.\n"); log("\n"); log(" -dff\n"); log(" run 'abc' with -dff option\n"); @@ -77,6 +78,9 @@ struct SynthGateMatePass : public ScriptPass log(" -retime\n"); log(" run 'abc' with '-dff -D 1' options\n"); log("\n"); + log(" -abc_new\n"); + log(" use 'abc_new' instead of 'abc' for mapping. (EXPERIMENTAL)\n"); + log("\n"); log(" -noiopad\n"); log(" disable I/O buffer insertion (useful for hierarchical or \n"); log(" out-of-context flows).\n"); @@ -90,7 +94,7 @@ struct SynthGateMatePass : public ScriptPass } string top_opt, vlog_file, json_file; - bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, luttree, dff, retime, noiopad, noclkbuf; + bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, luttree, dff, retime, noiopad, noclkbuf, abc_new; void clear_flags() override { @@ -108,6 +112,7 @@ struct SynthGateMatePass : public ScriptPass retime = false; noiopad = false; noclkbuf = false; + abc_new = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -182,6 +187,10 @@ struct SynthGateMatePass : public ScriptPass noclkbuf = true; continue; } + if (args[argidx] == "-abc_new") { + abc_new = true; + continue; + } break; } extra_args(args, argidx, design); @@ -210,6 +219,7 @@ struct SynthGateMatePass : public ScriptPass { run("proc"); if (!noflatten) { + run("check"); run("flatten"); } run("tribuf -logic"); @@ -312,7 +322,11 @@ struct SynthGateMatePass : public ScriptPass if (dff) { abc_args += " -dff"; } - run("abc " + abc_args, "(with -luttree)"); + if (abc_new) { + run("abc_new " + abc_args, "(with -luttree and -abc_new)"); + } else { + run("abc " + abc_args, "(with -luttree, without -abc_new)"); + } run("techmap -map +/gatemate/lut_tree_map.v", "(with -luttree)"); run("gatemate_foldinv", "(with -luttree)"); run("techmap -map +/gatemate/inv_map.v", "(with -luttree)"); diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc index df1b79317..be9adb857 100644 --- a/techlibs/gowin/Makefile.inc +++ b/techlibs/gowin/Makefile.inc @@ -3,6 +3,7 @@ OBJS += techlibs/gowin/synth_gowin.o $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_sim.v)) +$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_latch.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw1n.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw2a.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw5a.v)) @@ -12,3 +13,4 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map_gw5a.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt)) +$(eval $(call add_share_file,share/gowin,techlibs/gowin/dsp_map.v)) diff --git a/techlibs/gowin/brams.txt b/techlibs/gowin/brams.txt index ee76dd73a..1507d2781 100644 --- a/techlibs/gowin/brams.txt +++ b/techlibs/gowin/brams.txt @@ -2,6 +2,7 @@ ram block $__GOWIN_SP_ { abits 14; widths 1 2 4 9 18 36 per_port; cost 128; + byte 9; init no_undef; port srsw "A" { clock posedge; @@ -24,6 +25,7 @@ ram block $__GOWIN_SP_ { rdwr old; } } + wrbe_separate; } } @@ -31,6 +33,7 @@ ram block $__GOWIN_DP_ { abits 14; widths 1 2 4 9 18 per_port; cost 128; + byte 9; init no_undef; port srsw "A" "B" { clock posedge; @@ -48,11 +51,7 @@ ram block $__GOWIN_DP_ { portoption "WRITE_MODE" 1 { rdwr new; } - ifndef gw5a { - portoption "WRITE_MODE" 2 { - rdwr old; - } - } + wrbe_separate; } } @@ -60,6 +59,7 @@ ram block $__GOWIN_SDP_ { abits 14; widths 1 2 4 9 18 36 per_port; cost 128; + byte 9; init no_undef; port sr "R" { clock posedge; @@ -75,5 +75,6 @@ ram block $__GOWIN_SDP_ { port sw "W" { clock posedge; clken; + wrbe_separate; } } diff --git a/techlibs/gowin/brams_map.v b/techlibs/gowin/brams_map.v index 8e6cc6140..6187eadac 100644 --- a/techlibs/gowin/brams_map.v +++ b/techlibs/gowin/brams_map.v @@ -14,7 +14,7 @@ `define x8_width(width) (width / 9 * 8 + width % 9) `define x8_rd_data(data) {1'bx, data[31:24], 1'bx, data[23:16], 1'bx, data[15:8], 1'bx, data[7:0]} `define x8_wr_data(data) {data[34:27], data[25:18], data[16:9], data[7:0]} -`define addrbe_always(width, addr) (width < 18 ? addr : width == 18 ? {addr[13:4], 4'b0011} : {addr[13:5], 5'b01111}) +`define addrbe(width, addr, w_be) (width < 18 ? addr : width == 18 ? {addr[13:4], 2'b00, w_be[1:0]} : {addr[13:5], 1'b0, w_be[3:0]}) `define INIT(func) \ @@ -90,6 +90,7 @@ parameter OPTION_RESET_MODE = "SYNC"; parameter PORT_A_WIDTH = 36; parameter PORT_A_OPTION_WRITE_MODE = 0; +parameter PORT_A_WR_BE_WIDTH = 4; input PORT_A_CLK; input PORT_A_CLK_EN; @@ -97,13 +98,14 @@ input PORT_A_WR_EN; input PORT_A_RD_SRST; input PORT_A_RD_ARST; input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; `DEF_FUNCS wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; -wire [13:0] AD = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR); +wire [13:0] AD = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE); generate @@ -173,9 +175,11 @@ parameter OPTION_RESET_MODE = "SYNC"; parameter PORT_A_WIDTH = 18; parameter PORT_A_OPTION_WRITE_MODE = 0; +parameter PORT_A_WR_BE_WIDTH = 4; parameter PORT_B_WIDTH = 18; parameter PORT_B_OPTION_WRITE_MODE = 0; +parameter PORT_B_WR_BE_WIDTH = 4; input PORT_A_CLK; input PORT_A_CLK_EN; @@ -183,6 +187,7 @@ input PORT_A_WR_EN; input PORT_A_RD_SRST; input PORT_A_RD_ARST; input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; @@ -192,6 +197,7 @@ input PORT_B_WR_EN; input PORT_B_RD_SRST; input PORT_B_RD_ARST; input [13:0] PORT_B_ADDR; +input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE; input [PORT_A_WIDTH-1:0] PORT_B_WR_DATA; output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA; @@ -199,8 +205,8 @@ output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA; wire RSTA = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; wire RSTB = OPTION_RESET_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST; -wire [13:0] ADA = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR); -wire [13:0] ADB = `addrbe_always(PORT_B_WIDTH, PORT_B_ADDR); +wire [13:0] ADA = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE); +wire [13:0] ADB = `addrbe(PORT_B_WIDTH, PORT_B_ADDR, PORT_B_WR_BE); generate @@ -306,6 +312,7 @@ parameter OPTION_RESET_MODE = "SYNC"; parameter PORT_R_WIDTH = 18; parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_BE_WIDTH = 4; input PORT_R_CLK; input PORT_R_CLK_EN; @@ -318,12 +325,13 @@ input PORT_W_CLK; input PORT_W_CLK_EN; input PORT_W_WR_EN; input [13:0] PORT_W_ADDR; +input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE; input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; `DEF_FUNCS wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST; -wire [13:0] ADW = `addrbe_always(PORT_W_WIDTH, PORT_W_ADDR); +wire [13:0] ADW = `addrbe(PORT_W_WIDTH, PORT_W_ADDR, PORT_W_WR_BE); wire WRE = PORT_W_CLK_EN & PORT_W_WR_EN; generate diff --git a/techlibs/gowin/brams_map_gw5a.v b/techlibs/gowin/brams_map_gw5a.v index 246146ee5..8bc77bf4f 100644 --- a/techlibs/gowin/brams_map_gw5a.v +++ b/techlibs/gowin/brams_map_gw5a.v @@ -14,7 +14,7 @@ `define x8_width(width) (width / 9 * 8 + width % 9) `define x8_rd_data(data) {1'bx, data[31:24], 1'bx, data[23:16], 1'bx, data[15:8], 1'bx, data[7:0]} `define x8_wr_data(data) {data[34:27], data[25:18], data[16:9], data[7:0]} -`define addrbe_always(width, addr) (width < 18 ? addr : width == 18 ? {addr[13:4], 4'b0011} : {addr[13:5], 5'b01111}) +`define addrbe(width, addr, w_be) (width < 18 ? addr : width == 18 ? {addr[13:4], 2'b00, w_be[1:0]} : {addr[13:5], 1'b0, w_be[3:0]}) `define INIT(func) \ @@ -90,6 +90,7 @@ parameter OPTION_RESET_MODE = "SYNC"; parameter PORT_A_WIDTH = 36; parameter PORT_A_OPTION_WRITE_MODE = 0; +parameter PORT_A_WR_BE_WIDTH = 4; input PORT_A_CLK; input PORT_A_CLK_EN; @@ -97,13 +98,14 @@ input PORT_A_WR_EN; input PORT_A_RD_SRST; input PORT_A_RD_ARST; input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; `DEF_FUNCS wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; -wire [13:0] AD = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR); +wire [13:0] AD = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE); generate @@ -173,9 +175,11 @@ parameter OPTION_RESET_MODE = "SYNC"; parameter PORT_A_WIDTH = 18; parameter PORT_A_OPTION_WRITE_MODE = 0; +parameter PORT_A_WR_BE_WIDTH = 4; parameter PORT_B_WIDTH = 18; parameter PORT_B_OPTION_WRITE_MODE = 0; +parameter PORT_B_WR_BE_WIDTH = 4; input PORT_A_CLK; input PORT_A_CLK_EN; @@ -183,6 +187,7 @@ input PORT_A_WR_EN; input PORT_A_RD_SRST; input PORT_A_RD_ARST; input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; @@ -192,6 +197,7 @@ input PORT_B_WR_EN; input PORT_B_RD_SRST; input PORT_B_RD_ARST; input [13:0] PORT_B_ADDR; +input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE; input [PORT_A_WIDTH-1:0] PORT_B_WR_DATA; output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA; @@ -199,8 +205,8 @@ output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA; wire RSTA = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; wire RSTB = OPTION_RESET_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST; -wire [13:0] ADA = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR); -wire [13:0] ADB = `addrbe_always(PORT_B_WIDTH, PORT_B_ADDR); +wire [13:0] ADA = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE); +wire [13:0] ADB = `addrbe(PORT_B_WIDTH, PORT_B_ADDR, PORT_B_WR_BE); generate @@ -306,6 +312,7 @@ parameter OPTION_RESET_MODE = "SYNC"; parameter PORT_R_WIDTH = 18; parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_BE_WIDTH = 4; input PORT_R_CLK; input PORT_R_CLK_EN; @@ -318,12 +325,13 @@ input PORT_W_CLK; input PORT_W_CLK_EN; input PORT_W_WR_EN; input [13:0] PORT_W_ADDR; +input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE; input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; `DEF_FUNCS wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST; -wire [13:0] ADW = `addrbe_always(PORT_W_WIDTH, PORT_W_ADDR); +wire [13:0] ADW = `addrbe(PORT_W_WIDTH, PORT_W_ADDR, PORT_W_WR_BE); wire WRE = PORT_W_CLK_EN & PORT_W_WR_EN; generate diff --git a/techlibs/gowin/cells_latch.v b/techlibs/gowin/cells_latch.v new file mode 100644 index 000000000..b3d6c29f9 --- /dev/null +++ b/techlibs/gowin/cells_latch.v @@ -0,0 +1,37 @@ +`default_nettype none + +// DL D Latch with Positive Gate +module \$_DLATCH_P_ (input E, D, output Q); + DL _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(E)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// DLN D Latch with Negative Gate +module \$_DLATCH_N_ (input E, D, output Q); + DLN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(E)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// DLC D Latch with Positive Gate and Asynchronous Clear +module \$_DLATCH_PP0_ (input E, R, D, output Q); + DLC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(E), .CLEAR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// DLNC D Latch with Negative Gate and Asynchronous Clear +module \$_DLATCH_NP0_ (input E, R, D, output Q); + DLNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(E), .CLEAR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// DLP D Latch with Positive Gate and Asynchronous Preset +module \$_DLATCH_PP1_ (input E, R, D, output Q); + DLP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(E), .PRESET(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// DLNP D Latch with Negative Gate and Asynchronous Preset +module \$_DLATCH_NP1_ (input E, R, D, output Q); + DLNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(E), .PRESET(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 5e6083426..8d4303800 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -540,6 +540,101 @@ module DFFNCE (output reg Q, input D, CLK, CE, CLEAR); end endmodule // DFFNCE (negative clock edge; asynchronous clear; clock enable) +// Latch sim cells +// Gate signal uses CLK port name to match the physical DFF BEL pin + +module DL (output reg Q, input D, CLK); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (CLK) Q <= D; +endmodule + +module DLN (output reg Q, input D, CLK); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (!CLK) Q <= D; +endmodule + +module DLE (output reg Q, input D, CLK, CE); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (CLK && CE) Q <= D; +endmodule + +module DLNE (output reg Q, input D, CLK, CE); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (!CLK && CE) Q <= D; +endmodule + +module DLC (output reg Q, input D, CLK, CLEAR); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (CLEAR) Q <= 1'b0; + else if (CLK) Q <= D; +endmodule + +module DLCE (output reg Q, input D, CLK, CE, CLEAR); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (CLEAR) Q <= 1'b0; + else if (CLK && CE) Q <= D; +endmodule + +module DLNC (output reg Q, input D, CLK, CLEAR); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (CLEAR) Q <= 1'b0; + else if (!CLK) Q <= D; +endmodule + +module DLNCE (output reg Q, input D, CLK, CE, CLEAR); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (CLEAR) Q <= 1'b0; + else if (!CLK && CE) Q <= D; +endmodule + +module DLP (output reg Q, input D, CLK, PRESET); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (PRESET) Q <= 1'b1; + else if (CLK) Q <= D; +endmodule + +module DLPE (output reg Q, input D, CLK, CE, PRESET); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (PRESET) Q <= 1'b1; + else if (CLK && CE) Q <= D; +endmodule + +module DLNP (output reg Q, input D, CLK, PRESET); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (PRESET) Q <= 1'b1; + else if (!CLK) Q <= D; +endmodule + +module DLNPE (output reg Q, input D, CLK, CE, PRESET); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + always @* + if (PRESET) Q <= 1'b1; + else if (!CLK && CE) Q <= D; +endmodule + // TODO add more DFF sim cells module VCC(output V); diff --git a/techlibs/gowin/cells_xtra_gw1n.v b/techlibs/gowin/cells_xtra_gw1n.v index 436fda0fa..0ab375ec8 100644 --- a/techlibs/gowin/cells_xtra_gw1n.v +++ b/techlibs/gowin/cells_xtra_gw1n.v @@ -1,41 +1,41 @@ // Created by cells_xtra.py -module LUT5 (...); +module LUT5(I0, I1, I2, I3, I4, F); parameter INIT = 32'h00000000; input I0, I1, I2, I3, I4; output F; endmodule -module LUT6 (...); +module LUT6(I0, I1, I2, I3, I4, I5, F); parameter INIT = 64'h0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5; output F; endmodule -module LUT7 (...); +module LUT7(I0, I1, I2, I3, I4, I5, I6, F); parameter INIT = 128'h0000_0000_0000_0000_0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5, I6; output F; endmodule -module LUT8 (...); +module LUT8(I0, I1, I2, I3, I4, I5, I6, I7, F); parameter INIT = 256'h0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5, I6, I7; output F; endmodule -module INV (...); +module INV(I, O); input I; output O; endmodule -module IODELAY (...); +module IODELAY(DI, SDTAP, SETN, VALUE, DF, DO); parameter C_STATIC_DLY = 0; input DI; input SDTAP; @@ -46,7 +46,7 @@ output DO; endmodule -module IEM (...); +module IEM(D, CLK, RESET, MCLK, LAG, LEAD); parameter WINSIZE = "SMALL"; parameter GSREN = "false"; parameter LSREN = "true"; @@ -55,14 +55,14 @@ output LAG, LEAD; endmodule -module ROM16 (...); +module ROM16(AD, DO); parameter INIT_0 = 16'h0000; input [3:0] AD; output DO; endmodule -module ROM (...); +module ROM(CLK, CE, OCE, RESET, WRE, AD, BLKSEL, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; parameter BLK_SEL = 3'b000; @@ -141,7 +141,7 @@ output [31:0] DO; endmodule -module ROMX9 (...); +module ROMX9(CLK, CE, OCE, RESET, WRE, AD, BLKSEL, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 36; parameter BLK_SEL = 3'b000; @@ -220,7 +220,7 @@ output [35:0] DO; endmodule -module pROM (...); +module pROM(CLK, CE, OCE, RESET, AD, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; parameter RESET_MODE = "SYNC"; @@ -296,7 +296,7 @@ output [31:0] DO; endmodule -module pROMX9 (...); +module pROMX9(CLK, CE, OCE, RESET, AD, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 36; parameter RESET_MODE = "SYNC"; @@ -372,7 +372,7 @@ output [35:0] DO; endmodule -module SDPB (...); +module SDPB(CLKA, CEA, CLKB, CEB, OCE, RESETA, RESETB, ADA, ADB, DI, BLKSELA, BLKSELB, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 32; parameter BIT_WIDTH_1 = 32; @@ -453,7 +453,7 @@ output [31:0] DO; endmodule -module SDPX9B (...); +module SDPX9B(CLKA, CEA, CLKB, CEB, OCE, RESETA, RESETB, ADA, ADB, BLKSELA, BLKSELB, DI, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 36; parameter BIT_WIDTH_1 = 36; @@ -534,7 +534,7 @@ output [35:0] DO; endmodule -module DPB (...); +module DPB(CLKA, CEA, CLKB, CEB, OCEA, OCEB, RESETA, RESETB, WREA, WREB, ADA, ADB, BLKSELA, BLKSELB, DIA, DIB, DOA, DOB); parameter READ_MODE0 = 1'b0; parameter READ_MODE1 = 1'b0; parameter WRITE_MODE0 = 2'b00; @@ -619,7 +619,7 @@ output [15:0] DOA, DOB; endmodule -module DPX9B (...); +module DPX9B(CLKA, CEA, CLKB, CEB, OCEA, OCEB, RESETA, RESETB, WREA, WREB, ADA, ADB, DIA, DIB, BLKSELA, BLKSELB, DOA, DOB); parameter READ_MODE0 = 1'b0; parameter READ_MODE1 = 1'b0; parameter WRITE_MODE0 = 2'b00; @@ -704,7 +704,7 @@ output [17:0] DOA, DOB; endmodule -module PADD18 (...); +module PADD18(A, B, ASEL, CE, CLK, RESET, SI, SBI, SO, SBO, DOUT); input [17:0] A; input [17:0] B; input ASEL; @@ -720,7 +720,7 @@ parameter BSEL_MODE = 1'b1; parameter SOREG = 1'b0; endmodule -module PADD9 (...); +module PADD9(A, B, ASEL, CE, CLK, RESET, SI, SBI, SO, SBO, DOUT); input [8:0] A; input [8:0] B; input ASEL; @@ -736,7 +736,7 @@ parameter BSEL_MODE = 1'b1; parameter SOREG = 1'b0; endmodule -module MULT9X9 (...); +module MULT9X9(A, SIA, B, SIB, ASIGN, BSIGN, ASEL, BSEL, CE, CLK, RESET, DOUT, SOA, SOB); input [8:0] A,SIA; input [8:0] B,SIB; input ASIGN,BSIGN; @@ -756,7 +756,7 @@ parameter SOA_REG = 1'b0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULT18X18 (...); +module MULT18X18(A, SIA, B, SIB, ASIGN, BSIGN, ASEL, BSEL, CE, CLK, RESET, DOUT, SOA, SOB); input [17:0] A,SIA; input [17:0] B,SIB; input ASIGN,BSIGN; @@ -776,7 +776,7 @@ parameter SOA_REG = 1'b0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULT36X36 (...); +module MULT36X36(A, B, ASIGN, BSIGN, CE, CLK, RESET, DOUT); input [35:0] A; input [35:0] B; input ASIGN,BSIGN; @@ -794,7 +794,7 @@ parameter BSIGN_REG = 1'b0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULTALU36X18 (...); +module MULTALU36X18(A, B, C, ASIGN, BSIGN, ACCLOAD, CE, CLK, RESET, CASI, DOUT, CASO); input [17:0] A; input [35:0] B; input [53:0] C; @@ -819,7 +819,7 @@ parameter MULTALU36X18_MODE = 0; parameter C_ADD_SUB = 1'b0; endmodule -module MULTADDALU18X18 (...); +module MULTADDALU18X18(A0, B0, A1, B1, C, SIA, SIB, ASIGN, BSIGN, ASEL, BSEL, CASI, CE, CLK, RESET, ACCLOAD, DOUT, CASO, SOA, SOB); input [17:0] A0; input [17:0] B0; input [17:0] A1; @@ -857,7 +857,7 @@ parameter MULTADDALU18X18_MODE = 0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULTALU18X18 (...); +module MULTALU18X18(A, B, CLK, CE, RESET, ASIGN, BSIGN, ACCLOAD, DSIGN, C, D, CASI, DOUT, CASO); input [17:0] A, B; input CLK,CE,RESET; input ASIGN, BSIGN; @@ -883,7 +883,7 @@ parameter C_ADD_SUB = 1'b0; parameter MULTALU18X18_MODE = 0; endmodule -module ALU54D (...); +module ALU54D(A, B, ASIGN, BSIGN, ACCLOAD, CASI, CLK, CE, RESET, DOUT, CASO); input [53:0] A, B; input ASIGN,BSIGN; input ACCLOAD; @@ -903,19 +903,19 @@ parameter ALUD_MODE = 0; parameter ALU_RESET_MODE = "SYNC"; endmodule -module BUFG (...); +module BUFG(O, I); output O; input I; endmodule -module BUFS (...); +module BUFS(O, I); output O; input I; endmodule -module PLL (...); +module PLL(CLKIN, CLKFB, RESET, RESET_P, RESET_I, RESET_S, FBDSEL, IDSEL, ODSEL, PSDA, FDLY, DUTYDA, CLKOUT, LOCK, CLKOUTP, CLKOUTD, CLKOUTD3); input CLKIN; input CLKFB; input RESET; @@ -956,39 +956,39 @@ parameter CLKOUTD3_SRC = "CLKOUT"; parameter DEVICE = "GW1N-4"; endmodule -module TLVDS_IBUF (...); +module TLVDS_IBUF(O, I, IB); output O; input I, IB; endmodule -module TLVDS_TBUF (...); +module TLVDS_TBUF(O, OB, I, OEN); output O, OB; input I, OEN; endmodule -module TLVDS_IOBUF (...); +module TLVDS_IOBUF(O, IO, IOB, I, OEN); output O; inout IO, IOB; input I, OEN; endmodule -module ELVDS_IBUF (...); +module ELVDS_IBUF(O, I, IB); output O; input I, IB; endmodule -module ELVDS_TBUF (...); +module ELVDS_TBUF(O, OB, I, OEN); output O, OB; input I, OEN; endmodule -module ELVDS_IOBUF (...); +module ELVDS_IOBUF(O, IO, IOB, I, OEN); output O; inout IO, IOB; input I, OEN; endmodule -module MIPI_IBUF (...); +module MIPI_IBUF(OH, OL, OB, IO, IOB, I, IB, OEN, OENB, HSREN); output OH, OL, OB; inout IO, IOB; input I, IB; @@ -996,40 +996,40 @@ input OEN, OENB; input HSREN; endmodule -module MIPI_IBUF_HS (...); +module MIPI_IBUF_HS(OH, I, IB); output OH; input I, IB; endmodule -module MIPI_IBUF_LP (...); +module MIPI_IBUF_LP(OL, OB, I, IB); output OL; output OB; input I; input IB; endmodule -module MIPI_OBUF (...); +module MIPI_OBUF(O, OB, I, IB, MODESEL); output O, OB; input I, IB, MODESEL; endmodule -module MIPI_OBUF_A (...); +module MIPI_OBUF_A(O, OB, I, IB, IL, MODESEL); output O, OB; input I, IB, IL, MODESEL; endmodule -module ELVDS_IBUF_MIPI (...); +module ELVDS_IBUF_MIPI(OH, OL, I, IB); output OH, OL; input I, IB; endmodule -module I3C_IOBUF (...); +module I3C_IOBUF(O, IO, I, MODESEL); output O; inout IO; input I, MODESEL; endmodule -module CLKDIV (...); +module CLKDIV(HCLKIN, RESETN, CALIB, CLKOUT); input HCLKIN; input RESETN; input CALIB; @@ -1038,12 +1038,12 @@ parameter DIV_MODE = "2"; parameter GSREN = "false"; endmodule -module DHCEN (...); +module DHCEN(CLKIN, CE, CLKOUT); input CLKIN,CE; output CLKOUT; endmodule -module DLLDLY (...); +module DLLDLY(CLKIN, DLLSTEP, DIR, LOADN, MOVE, CLKOUT, FLAG); input CLKIN; input [7:0] DLLSTEP; input DIR,LOADN,MOVE; @@ -1054,7 +1054,7 @@ parameter DLY_SIGN = 1'b0; parameter DLY_ADJ = 0; endmodule -module FLASH96K (...); +module FLASH96K(RA, CA, PA, MODE, SEQ, ACLK, PW, RESET, PE, OE, RMODE, WMODE, RBYTESEL, WBYTESEL, DIN, DOUT); input [5:0] RA,CA,PA; input [3:0] MODE; input [1:0] SEQ; @@ -1065,7 +1065,7 @@ input [31:0] DIN; output [31:0] DOUT; endmodule -module FLASH256K (...); +module FLASH256K(XADR, YADR, XE, YE, SE, ERASE, PROG, NVSTR, DIN, DOUT); input[6:0]XADR; input[5:0]YADR; input XE,YE,SE; @@ -1087,7 +1087,7 @@ parameter IDLE = 4'd0, RD_S2 = 4'd12; endmodule -module FLASH608K (...); +module FLASH608K(XADR, YADR, XE, YE, SE, ERASE, PROG, NVSTR, DIN, DOUT); input[8:0]XADR; input[5:0]YADR; input XE,YE,SE; @@ -1109,31 +1109,31 @@ parameter IDLE = 4'd0, RD_S2 = 4'd12; endmodule -module DCS (...); +module DCS(CLK0, CLK1, CLK2, CLK3, SELFORCE, CLKSEL, CLKOUT); input CLK0, CLK1, CLK2, CLK3, SELFORCE; input [3:0] CLKSEL; output CLKOUT; parameter DCS_MODE = "RISING"; endmodule -module DQCE (...); +module DQCE(CLKIN, CE, CLKOUT); input CLKIN; input CE; output CLKOUT; endmodule -module CLKDIV2 (...); +module CLKDIV2(HCLKIN, RESETN, CLKOUT); parameter GSREN = "false"; input HCLKIN, RESETN; output CLKOUT; endmodule -module DHCENC (...); +module DHCENC(CLKIN, CE, CLKOUT, CLKOUTN); input CLKIN, CE; output CLKOUT, CLKOUTN; endmodule -module FLASH64K (...); +module FLASH64K(XADR, YADR, XE, YE, SE, ERASE, PROG, NVSTR, SLEEP, DIN, DOUT); input[4:0]XADR; input[5:0]YADR; input XE,YE,SE; @@ -1156,7 +1156,7 @@ parameter IDLE = 4'd0, RD_S2 = 4'd12; endmodule -module FLASH64KZ (...); +module FLASH64KZ(XADR, YADR, XE, YE, SE, ERASE, PROG, NVSTR, DIN, DOUT); input[4:0]XADR; input[5:0]YADR; input XE,YE,SE; diff --git a/techlibs/gowin/cells_xtra_gw2a.v b/techlibs/gowin/cells_xtra_gw2a.v index 4df48ab64..643723db6 100644 --- a/techlibs/gowin/cells_xtra_gw2a.v +++ b/techlibs/gowin/cells_xtra_gw2a.v @@ -1,41 +1,41 @@ // Created by cells_xtra.py -module LUT5 (...); +module LUT5(I0, I1, I2, I3, I4, F); parameter INIT = 32'h00000000; input I0, I1, I2, I3, I4; output F; endmodule -module LUT6 (...); +module LUT6(I0, I1, I2, I3, I4, I5, F); parameter INIT = 64'h0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5; output F; endmodule -module LUT7 (...); +module LUT7(I0, I1, I2, I3, I4, I5, I6, F); parameter INIT = 128'h0000_0000_0000_0000_0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5, I6; output F; endmodule -module LUT8 (...); +module LUT8(I0, I1, I2, I3, I4, I5, I6, I7, F); parameter INIT = 256'h0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5, I6, I7; output F; endmodule -module INV (...); +module INV(I, O); input I; output O; endmodule -module IDDR_MEM (...); +module IDDR_MEM(D, ICLK, PCLK, WADDR, RADDR, RESET, Q0, Q1); parameter GSREN = "false"; parameter LSREN = "true"; input D, ICLK, PCLK; @@ -46,7 +46,7 @@ output Q0,Q1; endmodule -module ODDR_MEM (...); +module ODDR_MEM(D0, D1, TX, PCLK, TCLK, RESET, Q0, Q1); parameter GSREN = "false"; parameter LSREN = "true"; parameter TCLK_SOURCE = "DQSW"; @@ -57,7 +57,7 @@ output Q0, Q1; endmodule -module IDES4_MEM (...); +module IDES4_MEM(D, ICLK, FCLK, PCLK, WADDR, RADDR, RESET, CALIB, Q0, Q1, Q2, Q3); parameter GSREN = "false"; parameter LSREN = "true"; input D, ICLK, FCLK, PCLK; @@ -68,7 +68,7 @@ output Q0,Q1,Q2,Q3; endmodule -module IDES8_MEM (...); +module IDES8_MEM(D, ICLK, FCLK, PCLK, WADDR, RADDR, RESET, CALIB, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7); parameter GSREN = "false"; parameter LSREN = "true"; input D, ICLK, FCLK, PCLK; @@ -79,7 +79,7 @@ output Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7; endmodule -module OSER4_MEM (...); +module OSER4_MEM(D0, D1, D2, D3, TX0, TX1, PCLK, FCLK, TCLK, RESET, Q0, Q1); parameter GSREN = "false"; parameter LSREN = "true"; parameter HWL = "false"; @@ -92,7 +92,7 @@ output Q0, Q1; endmodule -module OSER8_MEM (...); +module OSER8_MEM(D0, D1, D2, D3, D4, D5, D6, D7, TX0, TX1, TX2, TX3, PCLK, FCLK, TCLK, RESET, Q0, Q1); parameter GSREN = "false"; parameter LSREN = "true"; parameter HWL = "false"; @@ -105,7 +105,7 @@ output Q0, Q1; endmodule -module IODELAY (...); +module IODELAY(DI, SDTAP, SETN, VALUE, DF, DO); parameter C_STATIC_DLY = 0; input DI; input SDTAP; @@ -116,7 +116,7 @@ output DO; endmodule -module IEM (...); +module IEM(D, CLK, RESET, MCLK, LAG, LEAD); parameter WINSIZE = "SMALL"; parameter GSREN = "false"; parameter LSREN = "true"; @@ -125,14 +125,14 @@ output LAG, LEAD; endmodule -module ROM16 (...); +module ROM16(AD, DO); parameter INIT_0 = 16'h0000; input [3:0] AD; output DO; endmodule -module ROM (...); +module ROM(CLK, CE, OCE, RESET, WRE, AD, BLKSEL, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; parameter BLK_SEL = 3'b000; @@ -211,7 +211,7 @@ output [31:0] DO; endmodule -module ROMX9 (...); +module ROMX9(CLK, CE, OCE, RESET, WRE, AD, BLKSEL, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 36; parameter BLK_SEL = 3'b000; @@ -290,7 +290,7 @@ output [35:0] DO; endmodule -module pROM (...); +module pROM(CLK, CE, OCE, RESET, AD, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; parameter RESET_MODE = "SYNC"; @@ -366,7 +366,7 @@ output [31:0] DO; endmodule -module pROMX9 (...); +module pROMX9(CLK, CE, OCE, RESET, AD, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 36; parameter RESET_MODE = "SYNC"; @@ -442,7 +442,7 @@ output [35:0] DO; endmodule -module SDPB (...); +module SDPB(CLKA, CEA, CLKB, CEB, OCE, RESETA, RESETB, ADA, ADB, DI, BLKSELA, BLKSELB, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 32; parameter BIT_WIDTH_1 = 32; @@ -523,7 +523,7 @@ output [31:0] DO; endmodule -module SDPX9B (...); +module SDPX9B(CLKA, CEA, CLKB, CEB, OCE, RESETA, RESETB, ADA, ADB, BLKSELA, BLKSELB, DI, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 36; parameter BIT_WIDTH_1 = 36; @@ -604,7 +604,7 @@ output [35:0] DO; endmodule -module DPB (...); +module DPB(CLKA, CEA, CLKB, CEB, OCEA, OCEB, RESETA, RESETB, WREA, WREB, ADA, ADB, BLKSELA, BLKSELB, DIA, DIB, DOA, DOB); parameter READ_MODE0 = 1'b0; parameter READ_MODE1 = 1'b0; parameter WRITE_MODE0 = 2'b00; @@ -689,7 +689,7 @@ output [15:0] DOA, DOB; endmodule -module DPX9B (...); +module DPX9B(CLKA, CEA, CLKB, CEB, OCEA, OCEB, RESETA, RESETB, WREA, WREB, ADA, ADB, DIA, DIB, BLKSELA, BLKSELB, DOA, DOB); parameter READ_MODE0 = 1'b0; parameter READ_MODE1 = 1'b0; parameter WRITE_MODE0 = 2'b00; @@ -774,7 +774,7 @@ output [17:0] DOA, DOB; endmodule -module PADD18 (...); +module PADD18(A, B, ASEL, CE, CLK, RESET, SI, SBI, SO, SBO, DOUT); input [17:0] A; input [17:0] B; input ASEL; @@ -790,7 +790,7 @@ parameter BSEL_MODE = 1'b1; parameter SOREG = 1'b0; endmodule -module PADD9 (...); +module PADD9(A, B, ASEL, CE, CLK, RESET, SI, SBI, SO, SBO, DOUT); input [8:0] A; input [8:0] B; input ASEL; @@ -806,7 +806,7 @@ parameter BSEL_MODE = 1'b1; parameter SOREG = 1'b0; endmodule -module MULT9X9 (...); +module MULT9X9(A, SIA, B, SIB, ASIGN, BSIGN, ASEL, BSEL, CE, CLK, RESET, DOUT, SOA, SOB); input [8:0] A,SIA; input [8:0] B,SIB; input ASIGN,BSIGN; @@ -826,7 +826,7 @@ parameter SOA_REG = 1'b0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULT18X18 (...); +module MULT18X18(A, SIA, B, SIB, ASIGN, BSIGN, ASEL, BSEL, CE, CLK, RESET, DOUT, SOA, SOB); input [17:0] A,SIA; input [17:0] B,SIB; input ASIGN,BSIGN; @@ -846,7 +846,7 @@ parameter SOA_REG = 1'b0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULT36X36 (...); +module MULT36X36(A, B, ASIGN, BSIGN, CE, CLK, RESET, DOUT); input [35:0] A; input [35:0] B; input ASIGN,BSIGN; @@ -864,7 +864,7 @@ parameter BSIGN_REG = 1'b0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULTALU36X18 (...); +module MULTALU36X18(A, B, C, ASIGN, BSIGN, ACCLOAD, CE, CLK, RESET, CASI, DOUT, CASO); input [17:0] A; input [35:0] B; input [53:0] C; @@ -889,7 +889,7 @@ parameter MULTALU36X18_MODE = 0; parameter C_ADD_SUB = 1'b0; endmodule -module MULTADDALU18X18 (...); +module MULTADDALU18X18(A0, B0, A1, B1, C, SIA, SIB, ASIGN, BSIGN, ASEL, BSEL, CASI, CE, CLK, RESET, ACCLOAD, DOUT, CASO, SOA, SOB); input [17:0] A0; input [17:0] B0; input [17:0] A1; @@ -927,7 +927,7 @@ parameter MULTADDALU18X18_MODE = 0; parameter MULT_RESET_MODE = "SYNC"; endmodule -module MULTALU18X18 (...); +module MULTALU18X18(A, B, CLK, CE, RESET, ASIGN, BSIGN, ACCLOAD, DSIGN, C, D, CASI, DOUT, CASO); input [17:0] A, B; input CLK,CE,RESET; input ASIGN, BSIGN; @@ -953,7 +953,7 @@ parameter C_ADD_SUB = 1'b0; parameter MULTALU18X18_MODE = 0; endmodule -module ALU54D (...); +module ALU54D(A, B, ASIGN, BSIGN, ACCLOAD, CASI, CLK, CE, RESET, DOUT, CASO); input [53:0] A, B; input ASIGN,BSIGN; input ACCLOAD; @@ -973,19 +973,19 @@ parameter ALUD_MODE = 0; parameter ALU_RESET_MODE = "SYNC"; endmodule -module BUFG (...); +module BUFG(O, I); output O; input I; endmodule -module BUFS (...); +module BUFS(O, I); output O; input I; endmodule -module PLL (...); +module PLL(CLKIN, CLKFB, RESET, RESET_P, RESET_I, RESET_S, FBDSEL, IDSEL, ODSEL, PSDA, FDLY, DUTYDA, CLKOUT, LOCK, CLKOUTP, CLKOUTD, CLKOUTD3); input CLKIN; input CLKFB; input RESET; @@ -1026,39 +1026,39 @@ parameter CLKOUTD3_SRC = "CLKOUT"; parameter DEVICE = "GW2A-18"; endmodule -module TLVDS_IBUF (...); +module TLVDS_IBUF(O, I, IB); output O; input I, IB; endmodule -module TLVDS_TBUF (...); +module TLVDS_TBUF(O, OB, I, OEN); output O, OB; input I, OEN; endmodule -module TLVDS_IOBUF (...); +module TLVDS_IOBUF(O, IO, IOB, I, OEN); output O; inout IO, IOB; input I, OEN; endmodule -module ELVDS_IBUF (...); +module ELVDS_IBUF(O, I, IB); output O; input I, IB; endmodule -module ELVDS_TBUF (...); +module ELVDS_TBUF(O, OB, I, OEN); output O, OB; input I, OEN; endmodule -module ELVDS_IOBUF (...); +module ELVDS_IOBUF(O, IO, IOB, I, OEN); output O; inout IO, IOB; input I, OEN; endmodule -module CLKDIV (...); +module CLKDIV(HCLKIN, RESETN, CALIB, CLKOUT); input HCLKIN; input RESETN; input CALIB; @@ -1067,12 +1067,13 @@ parameter DIV_MODE = "2"; parameter GSREN = "false"; endmodule -module DHCEN (...); +module DHCEN(CLKIN, CE, CLKOUT); input CLKIN,CE; output CLKOUT; endmodule -module DQS (...); +module DQS(DQSIN, PCLK, FCLK, RESET, READ, RCLKSEL, DLLSTEP, WSTEP, RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, HOLD, DQSR90, DQSW0, DQSW270, RPOINT, WPOINT, RVALID +, RBURST, RFLAG, WFLAG); input DQSIN,PCLK,FCLK,RESET; input [3:0] READ; input [2:0] RCLKSEL; @@ -1089,7 +1090,7 @@ output RVALID,RBURST, RFLAG, WFLAG; parameter GSREN = "false"; endmodule -module DLLDLY (...); +module DLLDLY(CLKIN, DLLSTEP, DIR, LOADN, MOVE, CLKOUT, FLAG); input CLKIN; input [7:0] DLLSTEP; input DIR,LOADN,MOVE; @@ -1100,67 +1101,67 @@ parameter DLY_SIGN = 1'b0; parameter DLY_ADJ = 0; endmodule -module DCS (...); +module DCS(CLK0, CLK1, CLK2, CLK3, SELFORCE, CLKSEL, CLKOUT); input CLK0, CLK1, CLK2, CLK3, SELFORCE; input [3:0] CLKSEL; output CLKOUT; parameter DCS_MODE = "RISING"; endmodule -module DQCE (...); +module DQCE(CLKIN, CE, CLKOUT); input CLKIN; input CE; output CLKOUT; endmodule -module CLKDIV2 (...); +module CLKDIV2(HCLKIN, RESETN, CLKOUT); parameter GSREN = "false"; input HCLKIN, RESETN; output CLKOUT; endmodule -module IBUF_R (...); +module IBUF_R(I, RTEN, O); input I; input RTEN; output O; endmodule -module IOBUF_R (...); +module IOBUF_R(I, OEN, RTEN, O, IO); input I,OEN; input RTEN; output O; inout IO; endmodule -module ELVDS_IBUF_R (...); +module ELVDS_IBUF_R(O, I, IB, RTEN); output O; input I, IB; input RTEN; endmodule -module ELVDS_IOBUF_R (...); +module ELVDS_IOBUF_R(O, IO, IOB, I, OEN, RTEN); output O; inout IO, IOB; input I, OEN; input RTEN; endmodule -module OTP (...); +module OTP(CSB, SCLK, DOUT); input CSB, SCLK; output DOUT; endmodule -module SAMB (...); +module SAMB(SPIAD, LOADN_SPIAD); input [23:0] SPIAD; input LOADN_SPIAD; endmodule -module ELVDS_IBUF_MIPI (...); +module ELVDS_IBUF_MIPI(OH, OL, I, IB); output OH, OL; input I, IB; endmodule -module MIPI_IBUF (...); +module MIPI_IBUF(OH, OL, OB, IO, IOB, I, IB, OEN, OENB, HSREN); output OH, OL, OB; inout IO, IOB; input I, IB; @@ -1168,7 +1169,7 @@ input OEN, OENB; input HSREN; endmodule -module I3C_IOBUF (...); +module I3C_IOBUF(O, IO, I, MODESEL); output O; inout IO; input I, MODESEL; diff --git a/techlibs/gowin/cells_xtra_gw5a.v b/techlibs/gowin/cells_xtra_gw5a.v index b2dc06236..dd6a540b3 100644 --- a/techlibs/gowin/cells_xtra_gw5a.v +++ b/techlibs/gowin/cells_xtra_gw5a.v @@ -1,75 +1,75 @@ // Created by cells_xtra.py -module LUT5 (...); +module LUT5(I0, I1, I2, I3, I4, F); parameter INIT = 32'h00000000; input I0, I1, I2, I3, I4; output F; endmodule -module LUT6 (...); +module LUT6(I0, I1, I2, I3, I4, I5, F); parameter INIT = 64'h0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5; output F; endmodule -module LUT7 (...); +module LUT7(I0, I1, I2, I3, I4, I5, I6, F); parameter INIT = 128'h0000_0000_0000_0000_0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5, I6; output F; endmodule -module LUT8 (...); +module LUT8(I0, I1, I2, I3, I4, I5, I6, I7, F); parameter INIT = 256'h0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000; input I0, I1, I2, I3, I4, I5, I6, I7; output F; endmodule -module ROM16 (...); +module ROM16(AD, DO); parameter INIT_0 = 16'h0000; input [3:0] AD; output DO; endmodule -module INV (...); +module INV(I, O); input I; output O; endmodule -module TLVDS_IBUF (...); +module TLVDS_IBUF(O, I, IB); output O; input I, IB; endmodule -module TLVDS_TBUF (...); +module TLVDS_TBUF(O, OB, I, OEN); output O, OB; input I, OEN; endmodule -module TLVDS_IOBUF (...); +module TLVDS_IOBUF(O, IO, IOB, I, OEN); output O; inout IO, IOB; input I, OEN; endmodule -module ELVDS_TBUF (...); +module ELVDS_TBUF(O, OB, I, OEN); output O, OB; input I, OEN; endmodule -module ELVDS_IOBUF (...); +module ELVDS_IOBUF(O, IO, IOB, I, OEN); output O; inout IO, IOB; input I, OEN; endmodule -module MIPI_IBUF (...); +module MIPI_IBUF(OH, OL, OB, IO, IOB, I, IB, OEN, OENB, HSEN, HSREN); output OH, OL, OB; inout IO, IOB; input I, IB; @@ -77,32 +77,33 @@ input OEN, OENB; input HSEN, HSREN; endmodule -module MIPI_OBUF_A (...); +module MIPI_OBUF_A(O, OB, I, IB, IL, MODESEL, IO, IOB, OEN, OENB); output O, OB; input I, IB, IL, MODESEL; inout IO, IOB; input OEN, OENB; endmodule -module ELVDS_IOBUF_R (...); +module ELVDS_IOBUF_R(O, IO, IOB, I, OEN, RTEN); output O; inout IO, IOB; input I, OEN; input RTEN; endmodule -module I3C_IOBUF (...); +module I3C_IOBUF(O, IO, I, MODESEL); output O; inout IO; input I, MODESEL; endmodule -module TLVDS_IBUF_ADC (...); +module TLVDS_IBUF_ADC(I, IB, ADCEN); input I, IB; input ADCEN; endmodule -module MIPI_CPHY_IBUF (...); +module MIPI_CPHY_IBUF(OH0, OL0, OB0, OH1, OL1, OB1, OH2, OL2, OB2, IO0, IOB0, IO1, IOB1, IO2, IOB2, I0, IB0, I1, IB1, I2, IB2 +, OEN, OENB, HSEN); output OH0, OL0, OB0, OH1, OL1, OB1, OH2, OL2, OB2; inout IO0, IOB0, IO1, IOB1, IO2, IOB2; input I0, IB0, I1, IB1, I2, IB2; @@ -110,14 +111,15 @@ input OEN, OENB; input HSEN; endmodule -module MIPI_CPHY_OBUF (...); +module MIPI_CPHY_OBUF(O0, OB0, O1, OB1, O2, OB2, I0, IB0, IL0, I1, IB1, IL1, I2, IB2, IL2, IO0, IOB0, IO1, IOB1, IO2, IOB2 +, OEN, OENB, MODESEL, VCOME); output O0, OB0, O1, OB1, O2, OB2; input I0, IB0, IL0, I1, IB1, IL1, I2, IB2, IL2; inout IO0, IOB0, IO1, IOB1, IO2, IOB2; input OEN, OENB, MODESEL, VCOME; endmodule -module SDPB (...); +module SDPB(CLKA, CEA, CLKB, CEB, OCE, RESET, ADA, ADB, DI, BLKSELA, BLKSELB, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 32; parameter BIT_WIDTH_1 = 32; @@ -198,7 +200,7 @@ output [31:0] DO; endmodule -module SDPX9B (...); +module SDPX9B(CLKA, CEA, CLKB, CEB, OCE, RESET, ADA, ADB, BLKSELA, BLKSELB, DI, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH_0 = 36; parameter BIT_WIDTH_1 = 36; @@ -279,7 +281,7 @@ output [35:0] DO; endmodule -module DPB (...); +module DPB(CLKA, CEA, CLKB, CEB, OCEA, OCEB, RESETA, RESETB, WREA, WREB, ADA, ADB, BLKSELA, BLKSELB, DIA, DIB, DOA, DOB); parameter READ_MODE0 = 1'b0; parameter READ_MODE1 = 1'b0; parameter WRITE_MODE0 = 2'b00; @@ -364,7 +366,7 @@ output [15:0] DOA, DOB; endmodule -module DPX9B (...); +module DPX9B(CLKA, CEA, CLKB, CEB, OCEA, OCEB, RESETA, RESETB, WREA, WREB, ADA, ADB, DIA, DIB, BLKSELA, BLKSELB, DOA, DOB); parameter READ_MODE0 = 1'b0; parameter READ_MODE1 = 1'b0; parameter WRITE_MODE0 = 2'b00; @@ -449,7 +451,7 @@ output [17:0] DOA, DOB; endmodule -module pROM (...); +module pROM(CLK, CE, OCE, RESET, AD, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 32; parameter RESET_MODE = "SYNC"; @@ -525,7 +527,7 @@ output [31:0] DO; endmodule -module pROMX9 (...); +module pROMX9(CLK, CE, OCE, RESET, AD, DO); parameter READ_MODE = 1'b0; parameter BIT_WIDTH = 36; parameter RESET_MODE = "SYNC"; @@ -601,7 +603,7 @@ output [35:0] DO; endmodule -module SDP36KE (...); +module SDP36KE(CLKA, CEA, CLKB, CEB, OCE, RESET, ADA, ADB, DI, DIP, BLKSELA, BLKSELB, DECCI, SECCI, DO, DOP, DECCO, SECCO, ECCP); parameter ECC_WRITE_EN="TRUE"; parameter ECC_READ_EN="TRUE"; parameter READ_MODE = 1'b0; @@ -768,7 +770,7 @@ output [7:0] ECCP; endmodule -module SDP136K (...); +module SDP136K(CLKA, CLKB, WE, RE, ADA, ADB, DI, DO); input CLKA, CLKB; input WE, RE; input [10:0] ADA, ADB; @@ -776,7 +778,7 @@ input [67:0] DI; output [67:0] DO; endmodule -module MULTADDALU12X12 (...); +module MULTADDALU12X12(DOUT, CASO, A0, B0, A1, B1, CASI, ACCSEL, CASISEL, ADDSUB, CLK, CE, RESET); parameter A0REG_CLK = "BYPASS"; parameter A0REG_CE = "CE0"; parameter A0REG_RESET = "RESET0"; @@ -842,7 +844,7 @@ input [1:0] ADDSUB; input [1:0] CLK, CE, RESET; endmodule -module MULTALU27X18 (...); +module MULTALU27X18(DOUT, CASO, SOA, A, SIA, B, C, D, CASI, ACCSEL, PSEL, ASEL, PADDSUB, CSEL, CASISEL, ADDSUB, CLK, CE, RESET); parameter AREG_CLK = "BYPASS"; parameter AREG_CE = "CE0"; parameter AREG_RESET = "RESET0"; @@ -937,7 +939,7 @@ input [1:0] ADDSUB; input [1:0] CLK, CE, RESET; endmodule -module MULT12X12 (...); +module MULT12X12(DOUT, A, B, CLK, CE, RESET); parameter AREG_CLK = "BYPASS"; parameter AREG_CE = "CE0"; parameter AREG_RESET = "RESET0"; @@ -956,7 +958,7 @@ input [11:0] A, B; input [1:0] CLK, CE, RESET; endmodule -module MULT27X36 (...); +module MULT27X36(DOUT, A, B, D, CLK, CE, RESET, PSEL, PADDSUB); parameter AREG_CLK = "BYPASS"; parameter AREG_CE = "CE0"; parameter AREG_RESET = "RESET0"; @@ -992,7 +994,7 @@ input PSEL; input PADDSUB; endmodule -module MULTACC (...); +module MULTACC(DATAO, CASO, CE, CLK, COFFIN0, COFFIN1, COFFIN2, DATAIN0, DATAIN1, DATAIN2, RSTN, CASI); output [23:0] DATAO, CASO; input CE, CLK; input [5:0] COFFIN0, COFFIN1, COFFIN2; @@ -1010,7 +1012,7 @@ parameter CASI_EN = "FALSE"; parameter CASO_EN = "FALSE"; endmodule -module IDDR_MEM (...); +module IDDR_MEM(D, ICLK, PCLK, WADDR, RADDR, RESET, Q0, Q1); input D, ICLK, PCLK; input [2:0] WADDR; input [2:0] RADDR; @@ -1019,7 +1021,7 @@ output Q0,Q1; endmodule -module ODDR_MEM (...); +module ODDR_MEM(D0, D1, TX, PCLK, TCLK, RESET, Q0, Q1); parameter TCLK_SOURCE = "DQSW"; parameter TXCLK_POL = 1'b0; input D0, D1; @@ -1028,7 +1030,7 @@ output Q0, Q1; endmodule -module IDES4_MEM (...); +module IDES4_MEM(PCLK, D, ICLK, FCLK, RESET, CALIB, WADDR, RADDR, Q0, Q1, Q2, Q3); input PCLK, D, ICLK, FCLK, RESET, CALIB; input [2:0] WADDR; input [2:0] RADDR; @@ -1036,7 +1038,7 @@ output Q0,Q1,Q2,Q3; endmodule -module IDES8_MEM (...); +module IDES8_MEM(PCLK, D, ICLK, FCLK, RESET, CALIB, WADDR, RADDR, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7); input PCLK, D, ICLK, FCLK, RESET, CALIB; input [2:0] WADDR; input [2:0] RADDR; @@ -1044,19 +1046,20 @@ output Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7; endmodule -module IDES14 (...); +module IDES14(D, FCLK, PCLK, CALIB, RESET, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13); input D, FCLK, PCLK, CALIB,RESET; output Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13; endmodule -module IDES32 (...); +module IDES32(D, FCLK, PCLK, CALIB, RESET, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 +, Q16, Q17, Q18, Q19, Q20, Q21, Q22, Q23, Q24, Q25, Q26, Q27, Q28, Q29, Q30, Q31); input D, FCLK, PCLK, CALIB,RESET; output Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, Q16, Q17, Q18, Q19, Q20, Q21, Q22, Q23, Q24, Q25, Q26, Q27, Q28, Q29, Q30, Q31; endmodule -module OSER4_MEM (...); +module OSER4_MEM(D0, D1, D2, D3, TX0, TX1, PCLK, FCLK, TCLK, RESET, Q0, Q1); parameter HWL = "false"; parameter TCLK_SOURCE = "DQSW"; parameter TXCLK_POL = 1'b0; @@ -1067,7 +1070,7 @@ output Q0, Q1; endmodule -module OSER8_MEM (...); +module OSER8_MEM(D0, D1, D2, D3, D4, D5, D6, D7, TX0, TX1, TX2, TX3, PCLK, FCLK, TCLK, RESET, Q0, Q1); parameter HWL = "false"; parameter TCLK_SOURCE = "DQSW"; parameter TXCLK_POL = 1'b0; @@ -1078,13 +1081,13 @@ output Q0, Q1; endmodule -module OSER14 (...); +module OSER14(D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, PCLK, FCLK, RESET, Q); input D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13; input PCLK, FCLK, RESET; output Q; endmodule -module IODELAY (...); +module IODELAY(DI, SDTAP, VALUE, DLYSTEP, DF, DO); parameter C_STATIC_DLY = 0; parameter DYN_DLY_EN = "FALSE"; parameter ADAPT_EN = "FALSE"; @@ -1097,7 +1100,7 @@ output DO; endmodule -module OSIDES32 (...); +module OSIDES32(Q, D, PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN, RESET, DF0, DF1, SDTAP0, SDTAP1, VALUE0, VALUE1, DLYSTEP0, DLYSTEP1); output [31:0] Q; input D; input PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN; @@ -1114,7 +1117,8 @@ parameter DYN_DLY_EN_1 = "FALSE"; parameter ADAPT_EN_1 = "FALSE"; endmodule -module OSIDES64 (...); +module OSIDES64(Q, D, PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN, RESET, DF0, DF1, DF2, DF3, SDTAP0, SDTAP1, SDTAP2, SDTAP3, VALUE0, VALUE1, VALUE2, VALUE3, DLYSTEP0 +, DLYSTEP1, DLYSTEP2, DLYSTEP3); output [63:0] Q; input D; input PCLK, FCLKP, FCLKN, FCLKQP, FCLKQN; @@ -1137,20 +1141,20 @@ parameter DYN_DLY_EN_3 = "FALSE"; parameter ADAPT_EN_3 = "FALSE"; endmodule -module DCE (...); +module DCE(CLKIN, CE, CLKOUT); input CLKIN; input CE; output CLKOUT; endmodule -module DCS (...); +module DCS(CLKIN0, CLKIN1, CLKIN2, CLKIN3, SELFORCE, CLKSEL, CLKOUT); input CLKIN0, CLKIN1, CLKIN2, CLKIN3, SELFORCE; input [3:0] CLKSEL; output CLKOUT; parameter DCS_MODE = "RISING"; endmodule -module DDRDLL (...); +module DDRDLL(CLKIN, STOP, UPDNCNTL, RESET, STEP, LOCK); input CLKIN; input STOP; input UPDNCNTL; @@ -1163,7 +1167,7 @@ parameter SCAL_EN = "TRUE"; parameter DIV_SEL = 1'b0; endmodule -module DLLDLY (...); +module DLLDLY(CLKIN, DLLSTEP, CSTEP, LOADN, MOVE, CLKOUT, FLAG); input CLKIN; input [7:0] DLLSTEP, CSTEP; input LOADN,MOVE; @@ -1176,7 +1180,7 @@ parameter ADAPT_EN = "FALSE"; parameter STEP_SEL = 1'b0; endmodule -module CLKDIV (...); +module CLKDIV(HCLKIN, RESETN, CALIB, CLKOUT); input HCLKIN; input RESETN; input CALIB; @@ -1184,24 +1188,24 @@ output CLKOUT; parameter DIV_MODE = "2"; endmodule -module CLKDIV2 (...); +module CLKDIV2(HCLKIN, RESETN, CLKOUT); input HCLKIN, RESETN; output CLKOUT; endmodule -module DHCE (...); +module DHCE(CLKIN, CEN, CLKOUT); input CLKIN; input CEN; output CLKOUT; endmodule -module OSCA (...); +module OSCA(OSCOUT, OSCEN); parameter FREQ_DIV = 100; output OSCOUT; input OSCEN; endmodule -module OSCB (...); +module OSCB(OSCOUT, OSCREF, OSCEN, FMODE, RTRIM, RTCTRIM); parameter FREQ_MODE = "25"; parameter FREQ_DIV = 10; parameter DYN_TRIM_EN = "FALSE"; @@ -1212,7 +1216,9 @@ input [7:0] RTRIM; input [5:0] RTCTRIM; endmodule -module PLL (...); +module PLL(CLKIN, CLKFB, RESET, PLLPWD, RESET_I, RESET_O, FBDSEL, IDSEL, MDSEL, MDSEL_FRAC, ODSEL0, ODSEL0_FRAC, ODSEL1, ODSEL2, ODSEL3, ODSEL4, ODSEL5, ODSEL6, DT0, DT1, DT2 +, DT3, ICPSEL, LPFRES, LPFCAP, PSSEL, PSDIR, PSPULSE, ENCLK0, ENCLK1, ENCLK2, ENCLK3, ENCLK4, ENCLK5, ENCLK6, SSCPOL, SSCON, SSCMDSEL, SSCMDSEL_FRAC, LOCK, CLKOUT0, CLKOUT1 +, CLKOUT2, CLKOUT3, CLKOUT4, CLKOUT5, CLKOUT6, CLKFBOUT); input CLKIN; input CLKFB; input RESET; @@ -1354,7 +1360,8 @@ parameter LPF_CAP = 2'b00; parameter SSC_EN = "FALSE"; endmodule -module PLLA (...); +module PLLA(CLKIN, CLKFB, RESET, PLLPWD, RESET_I, RESET_O, PSSEL, PSDIR, PSPULSE, SSCPOL, SSCON, SSCMDSEL, SSCMDSEL_FRAC, MDCLK, MDOPC, MDAINC, MDWDI, MDRDO, LOCK, CLKOUT0, CLKOUT1 +, CLKOUT2, CLKOUT3, CLKOUT4, CLKOUT5, CLKOUT6, CLKFBOUT); input CLKIN; input CLKFB; input RESET; @@ -1462,7 +1469,14 @@ parameter LPF_CAP = 2'b00; parameter SSC_EN = "FALSE"; endmodule -module AE350_SOC (...); +module AE350_SOC(POR_N, HW_RSTN, CORE_CLK, DDR_CLK, AHB_CLK, APB_CLK, DBG_TCK, RTC_CLK, CORE_CE, AXI_CE, DDR_CE, AHB_CE, APB_CE, APB2AHB_CE, SCAN_TEST, SCAN_EN, PRESETN, HRESETN, DDR_RSTN, GP_INT, DMA_REQ +, DMA_ACK, CORE0_WFI_MODE, WAKEUP_IN, RTC_WAKEUP, TEST_CLK, TEST_MODE, TEST_RSTN, ROM_HADDR, ROM_HRDATA, ROM_HREADY, ROM_HRESP, ROM_HTRANS, ROM_HWRITE, APB_PADDR, APB_PENABLE, APB_PRDATA, APB_PREADY, APB_PSEL, APB_PWDATA, APB_PWRITE, APB_PSLVERR +, APB_PPROT, APB_PSTRB, EXTS_HRDATA, EXTS_HREADYIN, EXTS_HRESP, EXTS_HADDR, EXTS_HBURST, EXTS_HPROT, EXTS_HSEL, EXTS_HSIZE, EXTS_HTRANS, EXTS_HWDATA, EXTS_HWRITE, EXTM_HADDR, EXTM_HBURST, EXTM_HPROT, EXTM_HRDATA, EXTM_HREADY, EXTM_HREADYOUT, EXTM_HRESP, EXTM_HSEL +, EXTM_HSIZE, EXTM_HTRANS, EXTM_HWDATA, EXTM_HWRITE, DDR_HADDR, DDR_HBURST, DDR_HPROT, DDR_HRDATA, DDR_HREADY, DDR_HRESP, DDR_HSIZE, DDR_HTRANS, DDR_HWDATA, DDR_HWRITE, TMS_IN, TRST_IN, TDI_IN, TDO_OUT, TDO_OE, SPI2_HOLDN_IN, SPI2_WPN_IN +, SPI2_CLK_IN, SPI2_CSN_IN, SPI2_MISO_IN, SPI2_MOSI_IN, SPI2_HOLDN_OUT, SPI2_HOLDN_OE, SPI2_WPN_OUT, SPI2_WPN_OE, SPI2_CLK_OUT, SPI2_CLK_OE, SPI2_CSN_OUT, SPI2_CSN_OE, SPI2_MISO_OUT, SPI2_MISO_OE, SPI2_MOSI_OUT, SPI2_MOSI_OE, I2C_SCL_IN, I2C_SDA_IN, I2C_SCL, I2C_SDA, UART1_TXD +, UART1_RTSN, UART1_RXD, UART1_CTSN, UART1_DSRN, UART1_DCDN, UART1_RIN, UART1_DTRN, UART1_OUT1N, UART1_OUT2N, UART2_TXD, UART2_RTSN, UART2_RXD, UART2_CTSN, UART2_DCDN, UART2_DSRN, UART2_RIN, UART2_DTRN, UART2_OUT1N, UART2_OUT2N, CH0_PWM, CH0_PWMOE +, CH1_PWM, CH1_PWMOE, CH2_PWM, CH2_PWMOE, CH3_PWM, CH3_PWMOE, GPIO_IN, GPIO_OE, GPIO_OUT, SCAN_IN, INTEG_TCK, INTEG_TDI, INTEG_TMS, INTEG_TRST, INTEG_TDO, SCAN_OUT, PGEN_CHAIN_I, PRDYN_CHAIN_O, EMA, EMAW, EMAS +, RET1N, RET2N); input POR_N; input HW_RSTN; input CORE_CLK; @@ -1614,7 +1628,8 @@ input RET1N; input RET2N; endmodule -module AE350_RAM (...); +module AE350_RAM(POR_N, HW_RSTN, CORE_CLK, AHB_CLK, APB_CLK, RTC_CLK, CORE_CE, AXI_CE, AHB_CE, EXTM_HADDR, EXTM_HBURST, EXTM_HPROT, EXTM_HRDATA, EXTM_HREADY, EXTM_HREADYOUT, EXTM_HRESP, EXTM_HSEL, EXTM_HSIZE, EXTM_HTRANS, EXTM_HWDATA, EXTM_HWRITE +, EMA, EMAW, EMAS, RET1N, RET2N); input POR_N; input HW_RSTN; input CORE_CLK; @@ -1643,20 +1658,20 @@ input RET1N; input RET2N; endmodule -module SAMB (...); +module SAMB(SPIAD, LOAD, ADWSEL); parameter MODE = 2'b00; input [23:0] SPIAD; input LOAD; input ADWSEL; endmodule -module OTP (...); +module OTP(CLK, READ, SHIFT, DOUT); parameter MODE = 2'b01; input CLK, READ, SHIFT; output DOUT; endmodule -module CMSER (...); +module CMSER(RUNNING, CRCERR, CRCDONE, ECCCORR, ECCUNCORR, ERRLOC, ECCDEC, DSRRD, DSRWR, ASRRESET, ASRINC, REFCLK, CLK, SEREN, ERRINJECT, ERRINJLOC); output RUNNING; output CRCERR; output CRCDONE; @@ -1675,7 +1690,7 @@ input ERRINJECT; input [6:0] ERRINJLOC; endmodule -module CMSERA (...); +module CMSERA(RUNNING, CRCERR, CRCDONE, ECCCORR, ECCUNCORR, ERR0LOC, ERR1LOC, ECCDEC, DSRRD, DSRWR, ASRRESET, ASRINC, REFCLK, CLK, SEREN, ERR0INJECT, ERR1INJECT, ERRINJ0LOC, ERRINJ1LOC); output RUNNING; output CRCERR; output CRCDONE; @@ -1695,7 +1710,7 @@ input ERR0INJECT,ERR1INJECT; input [6:0] ERRINJ0LOC,ERRINJ1LOC; endmodule -module CMSERB (...); +module CMSERB(RUNNING, CRCERR, CRCDONE, ECCCORR, ECCUNCORR, ERRLOC, ECCDEC, DSRRD, DSRWR, ASRRESET, ASRINC, REFCLK, CLK, SEREN, ERR0INJECT, ERR1INJECT, ERRINJ0LOC, ERRINJ1LOC); output RUNNING; output CRCERR; output CRCDONE; @@ -1714,13 +1729,13 @@ input ERR0INJECT,ERR1INJECT; input [6:0] ERRINJ0LOC,ERRINJ1LOC; endmodule -module SAMBA (...); +module SAMBA(SPIAD, LOAD); parameter MODE = 2'b00; input SPIAD; input LOAD; endmodule -module LICD (...); +module LICD(); parameter STAGE_NUM = 2'b00; parameter ENCDEC_NUM = 2'b00; parameter CODE_WIDTH = 2'b00; @@ -1728,7 +1743,13 @@ module LICD (...); parameter INTERLEAVE_MODE = 3'b000; endmodule -module MIPI_DPHY (...); +module MIPI_DPHY(RX_CLK_O, TX_CLK_O, D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD, D0LN_HSRXD_VLD, D1LN_HSRXD_VLD, D2LN_HSRXD_VLD, D3LN_HSRXD_VLD, D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN, DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N +, DI_LPRX3_P, DI_LPRXCK_N, DI_LPRXCK_P, CK_N, CK_P, D0_N, D0_P, D1_N, D1_P, D2_N, D2_P, D3_N, D3_P, HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK, LPTXEN_LN0, LPTXEN_LN1 +, LPTXEN_LN2, LPTXEN_LN3, LPTXEN_LNCK, PWRON_RX, PWRON_TX, RESET, RX_CLK_1X, TX_CLK_1X, TXDPEN_LN0, TXDPEN_LN1, TXDPEN_LN2, TXDPEN_LN3, TXDPEN_LNCK, TXHCLK_EN, CKLN_HSTXD, D0LN_HSTXD, D1LN_HSTXD, D2LN_HSTXD, D3LN_HSTXD, HSTXD_VLD, CK0 +, CK90, CK180, CK270, DO_LPTX0_N, DO_LPTX1_N, DO_LPTX2_N, DO_LPTX3_N, DO_LPTXCK_N, DO_LPTX0_P, DO_LPTX1_P, DO_LPTX2_P, DO_LPTX3_P, DO_LPTXCK_P, HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK, HSRX_ODTEN_D0, HSRX_ODTEN_D1 +, HSRX_ODTEN_D2, HSRX_ODTEN_D3, LPRX_EN_CK, LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3, RX_DRST_N, TX_DRST_N, WALIGN_DVLD, MRDATA, MA_INC, MCLK, MOPCODE, MWDATA, ALPEDO_LANE0, ALPEDO_LANE1, ALPEDO_LANE2, ALPEDO_LANE3, ALPEDO_LANECK, D1LN_DESKEW_DONE +, D2LN_DESKEW_DONE, D3LN_DESKEW_DONE, D0LN_DESKEW_DONE, D1LN_DESKEW_ERROR, D2LN_DESKEW_ERROR, D3LN_DESKEW_ERROR, D0LN_DESKEW_ERROR, D0LN_DESKEW_REQ, D1LN_DESKEW_REQ, D2LN_DESKEW_REQ, D3LN_DESKEW_REQ, HSRX_DLYDIR_LANE0, HSRX_DLYDIR_LANE1, HSRX_DLYDIR_LANE2, HSRX_DLYDIR_LANE3, HSRX_DLYDIR_LANECK, HSRX_DLYLDN_LANE0, HSRX_DLYLDN_LANE1, HSRX_DLYLDN_LANE2, HSRX_DLYLDN_LANE3, HSRX_DLYLDN_LANECK +, HSRX_DLYMV_LANE0, HSRX_DLYMV_LANE1, HSRX_DLYMV_LANE2, HSRX_DLYMV_LANE3, HSRX_DLYMV_LANECK, ALP_EDEN_LANE0, ALP_EDEN_LANE1, ALP_EDEN_LANE2, ALP_EDEN_LANE3, ALP_EDEN_LANECK, ALPEN_LN0, ALPEN_LN1, ALPEN_LN2, ALPEN_LN3, ALPEN_LNCK); output RX_CLK_O, TX_CLK_O; output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; @@ -2024,7 +2045,13 @@ parameter TEST_P_IMP_LN3 = 1'b0 ; parameter TEST_P_IMP_LNCK = 1'b0 ; endmodule -module MIPI_DPHYA (...); +module MIPI_DPHYA(RX_CLK_O, TX_CLK_O, D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD, D0LN_HSRXD_VLD, D1LN_HSRXD_VLD, D2LN_HSRXD_VLD, D3LN_HSRXD_VLD, D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN, DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N +, DI_LPRX3_P, DI_LPRXCK_N, DI_LPRXCK_P, CK_N, CK_P, D0_N, D0_P, D1_N, D1_P, D2_N, D2_P, D3_N, D3_P, HSRX_STOP, HSTXEN_LN0, HSTXEN_LN1, HSTXEN_LN2, HSTXEN_LN3, HSTXEN_LNCK, LPTXEN_LN0, LPTXEN_LN1 +, LPTXEN_LN2, LPTXEN_LN3, LPTXEN_LNCK, PWRON_RX, PWRON_TX, RESET, RX_CLK_1X, TX_CLK_1X, TXDPEN_LN0, TXDPEN_LN1, TXDPEN_LN2, TXDPEN_LN3, TXDPEN_LNCK, TXHCLK_EN, CKLN_HSTXD, D0LN_HSTXD, D1LN_HSTXD, D2LN_HSTXD, D3LN_HSTXD, HSTXD_VLD, CK0 +, CK90, CK180, CK270, DO_LPTX0_N, DO_LPTX1_N, DO_LPTX2_N, DO_LPTX3_N, DO_LPTXCK_N, DO_LPTX0_P, DO_LPTX1_P, DO_LPTX2_P, DO_LPTX3_P, DO_LPTXCK_P, HSRX_EN_CK, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_EN_D3, HSRX_ODTEN_CK, HSRX_ODTEN_D0, HSRX_ODTEN_D1 +, HSRX_ODTEN_D2, HSRX_ODTEN_D3, LPRX_EN_CK, LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3, RX_DRST_N, TX_DRST_N, WALIGN_DVLD, MRDATA, MA_INC, MCLK, MOPCODE, MWDATA, SPLL_CKN, SPLL_CKP, ALPEDO_LANE0, ALPEDO_LANE1, ALPEDO_LANE2, ALPEDO_LANE3 +, ALPEDO_LANECK, D1LN_DESKEW_DONE, D2LN_DESKEW_DONE, D3LN_DESKEW_DONE, D0LN_DESKEW_DONE, D1LN_DESKEW_ERROR, D2LN_DESKEW_ERROR, D3LN_DESKEW_ERROR, D0LN_DESKEW_ERROR, D0LN_DESKEW_REQ, D1LN_DESKEW_REQ, D2LN_DESKEW_REQ, D3LN_DESKEW_REQ, HSRX_DLYDIR_LANE0, HSRX_DLYDIR_LANE1, HSRX_DLYDIR_LANE2, HSRX_DLYDIR_LANE3, HSRX_DLYDIR_LANECK, HSRX_DLYLDN_LANE0, HSRX_DLYLDN_LANE1, HSRX_DLYLDN_LANE2 +, HSRX_DLYLDN_LANE3, HSRX_DLYLDN_LANECK, HSRX_DLYMV_LANE0, HSRX_DLYMV_LANE1, HSRX_DLYMV_LANE2, HSRX_DLYMV_LANE3, HSRX_DLYMV_LANECK, ALP_EDEN_LANE0, ALP_EDEN_LANE1, ALP_EDEN_LANE2, ALP_EDEN_LANE3, ALP_EDEN_LANECK, ALPEN_LN0, ALPEN_LN1, ALPEN_LN2, ALPEN_LN3, ALPEN_LNCK); output RX_CLK_O, TX_CLK_O; output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; @@ -2323,7 +2350,12 @@ parameter TEST_P_IMP_LN3 = 1'b0 ; parameter TEST_P_IMP_LNCK = 1'b0 ; endmodule -module MIPI_CPHY (...); +module MIPI_CPHY(D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D0LN_HSRXD_VLD, D1LN_HSRXD_VLD, D2LN_HSRXD_VLD, D0LN_HSRX_DEMAP_INVLD, D1LN_HSRX_DEMAP_INVLD, D2LN_HSRX_DEMAP_INVLD, D0LN_HSRX_FIFO_RDE_ERR, D0LN_HSRX_FIFO_WRF_ERR, D1LN_HSRX_FIFO_RDE_ERR, D1LN_HSRX_FIFO_WRF_ERR, D2LN_HSRX_FIFO_RDE_ERR, D2LN_HSRX_FIFO_WRF_ERR, D0LN_HSRX_WA, D1LN_HSRX_WA, D2LN_HSRX_WA, D0LN_RX_CLK_1X_O, D1LN_RX_CLK_1X_O, D2LN_RX_CLK_1X_O +, HSTX_FIFO_AE, HSTX_FIFO_AF, HSTX_FIFO_RDE_ERR, HSTX_FIFO_WRF_ERR, RX_CLK_MUXED, TX_CLK_1X_O, DI_LPRX0_A, DI_LPRX0_B, DI_LPRX0_C, DI_LPRX1_A, DI_LPRX1_B, DI_LPRX1_C, DI_LPRX2_A, DI_LPRX2_B, DI_LPRX2_C, MDRP_RDATA, D0A, D0B, D0C, D1A, D1B +, D1C, D2A, D2B, D2C, D0LN_HSRX_EN, D0LN_HSTX_EN, D1LN_HSRX_EN, D1LN_HSTX_EN, D2LN_HSRX_EN, D2LN_HSTX_EN, D0LN_HSTX_DATA, D1LN_HSTX_DATA, D2LN_HSTX_DATA, D0LN_HSTX_DATA_VLD, D1LN_HSTX_DATA_VLD, D2LN_HSTX_DATA_VLD, D0LN_HSTX_MAP_DIS, D1LN_HSTX_MAP_DIS, D2LN_HSTX_MAP_DIS, D0LN_RX_CLK_1X_I, D1LN_RX_CLK_1X_I +, D2LN_RX_CLK_1X_I, D0LN_RX_DRST_N, D0LN_TX_DRST_N, D1LN_RX_DRST_N, D1LN_TX_DRST_N, D2LN_RX_DRST_N, D2LN_TX_DRST_N, HSTX_ENLN0, HSTX_ENLN1, HSTX_ENLN2, LPTX_ENLN0, LPTX_ENLN1, LPTX_ENLN2, MDRP_A_D_I, MDRP_A_INC_I, MDRP_CLK_I, MDRP_OPCODE_I, PWRON_RX_LN0, PWRON_RX_LN1, PWRON_RX_LN2, PWRON_TX +, ARST_RXLN0, ARST_RXLN1, ARST_RXLN2, ARSTN_TX, RX_CLK_EN_LN0, RX_CLK_EN_LN1, RX_CLK_EN_LN2, TX_CLK_1X_I, TXDP_ENLN0, TXDP_ENLN1, TXDP_ENLN2, TXHCLK_EN, DO_LPTX_A_LN0, DO_LPTX_A_LN1, DO_LPTX_A_LN2, DO_LPTX_B_LN0, DO_LPTX_B_LN1, DO_LPTX_B_LN2, DO_LPTX_C_LN0, DO_LPTX_C_LN1, DO_LPTX_C_LN2 +, GPLL_CK0, GPLL_CK90, GPLL_CK180, GPLL_CK270, HSRX_EN_D0, HSRX_EN_D1, HSRX_EN_D2, HSRX_ODT_EN_D0, HSRX_ODT_EN_D1, HSRX_ODT_EN_D2, LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, SPLL0_CKN, SPLL0_CKP, SPLL1_CKN, SPLL1_CKP); output [41:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD; output D0LN_HSRXD_VLD, D1LN_HSRXD_VLD, D2LN_HSRXD_VLD; output [1:0] D0LN_HSRX_DEMAP_INVLD, D1LN_HSRX_DEMAP_INVLD, D2LN_HSRX_DEMAP_INVLD; @@ -2455,29 +2487,30 @@ parameter EQ_PBIAS_LN2 = 4'b0100; parameter EQ_ZLD_LN2 = 4'b1000; endmodule -module GTR12_QUAD (...); +module GTR12_QUAD(); parameter POSITION = "Q0"; endmodule -module GTR12_UPAR (...); +module GTR12_UPAR(); endmodule -module GTR12_PMAC (...); +module GTR12_PMAC(); endmodule -module GTR12_QUADA (...); +module GTR12_QUADA(); endmodule -module GTR12_UPARA (...); +module GTR12_UPARA(); endmodule -module GTR12_PMACA (...); +module GTR12_PMACA(); endmodule -module GTR12_QUADB (...); +module GTR12_QUADB(); endmodule -module DQS (...); +module DQS(DQSIN, PCLK, FCLK, RESET, READ, RCLKSEL, DLLSTEP, WSTEP, RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, HOLD, DQSR90, DQSW0, DQSW270, RPOINT, WPOINT, RVALID +, RBURST, RFLAG, WFLAG); input DQSIN,PCLK,FCLK,RESET; input [3:0] READ; input [2:0] RCLKSEL; diff --git a/techlibs/gowin/dsp_map.v b/techlibs/gowin/dsp_map.v new file mode 100644 index 000000000..f03bcdff0 --- /dev/null +++ b/techlibs/gowin/dsp_map.v @@ -0,0 +1,70 @@ +module \$__MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y); + + parameter A_WIDTH = 9; + parameter B_WIDTH = 9; + parameter Y_WIDTH = 18; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT9X9 __TECHMAP_REPLACE__ ( + .CLK(1'b0), + .CE(1'b0), + .RESET(1'b0), + .A(A), + .SIA({A_WIDTH{1'b0}}), + .ASEL(1'b0), + .ASIGN(A_SIGNED ? 1'b1 : 1'b0), + .B(B), + .SIB({B_WIDTH{1'b0}}), + .BSEL(1'b0), + .BSIGN(B_SIGNED ? 1'b1 : 1'b0), + .DOUT(Y) + ); + +endmodule + +module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); + + parameter A_WIDTH = 18; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 36; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X18 __TECHMAP_REPLACE__ ( + .CLK(1'b0), + .CE(1'b0), + .RESET(1'b0), + .A(A), + .SIA({A_WIDTH{1'b0}}), + .ASEL(1'b0), + .ASIGN(A_SIGNED ? 1'b1 : 1'b0), + .B(B), + .SIB({B_WIDTH{1'b0}}), + .BSEL(1'b0), + .BSIGN(B_SIGNED ? 1'b1 : 1'b0), + .DOUT(Y) + ); + +endmodule + +module \$__MUL36X36 (input [35:0] A, input [35:0] B, output [71:0] Y); + + parameter A_WIDTH = 36; + parameter B_WIDTH = 36; + parameter Y_WIDTH = 72; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT36X36 __TECHMAP_REPLACE__ ( + .CLK(1'b0), + .RESET(1'b0), + .CE(1'b0), + .A(A), + .ASIGN(A_SIGNED ? 1'b1 : 1'b0), + .B(B), + .BSIGN(B_SIGNED ? 1'b1 : 1'b0), + .DOUT(Y) + ); + +endmodule diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index b9902659c..d5ebdafea 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -29,6 +29,21 @@ struct SynthGowinPass : public ScriptPass { SynthGowinPass() : ScriptPass("synth_gowin", "synthesis for Gowin FPGAs") { } + struct DSPRule { + int a_maxwidth; + int b_maxwidth; + int a_minwidth; + int b_minwidth; + std::string prim; + }; + + const std::vector dsp_rules = { + {36, 36, 22, 22, "$__MUL36X36"}, + {18, 18, 10, 4, "$__MUL18X18"}, + {18, 18, 4, 10, "$__MUL18X18"}, + {9, 9, 4, 4, "$__MUL9X9"}, + }; + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -97,13 +112,16 @@ struct SynthGowinPass : public ScriptPass log(" -setundef\n"); log(" set undriven wires and parameters to zero\n"); log("\n"); + log(" -nodsp\n"); + log(" do not infer DSP multipliers\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, vout_file, json_file, family; - bool retime, nobram, nolutram, flatten, nodffe, strict_gw5a_dffs, nowidelut, abc9, noiopads, noalu, no_rw_check, setundef; + bool retime, nobram, nolutram, flatten, nodffe, strict_gw5a_dffs, nowidelut, abc9, noiopads, noalu, no_rw_check, setundef, nodsp; void clear_flags() override { @@ -123,6 +141,7 @@ struct SynthGowinPass : public ScriptPass noalu = false; no_rw_check = false; setundef = false; + nodsp = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -209,6 +228,10 @@ struct SynthGowinPass : public ScriptPass setundef = true; continue; } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } break; } extra_args(args, argidx, design); @@ -239,17 +262,42 @@ struct SynthGowinPass : public ScriptPass run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt)); } - if (flatten && check_label("flatten", "(unless -noflatten)")) - { - run("proc"); - run("flatten"); - run("tribuf -logic"); - run("deminout"); - } - if (check_label("coarse")) { - run("synth -run coarse" + no_rw_check_opt); + run("proc"); + if (flatten || help_mode) { + run("check"); + run("flatten", "(unless -noflatten)"); + } + run("tribuf -logic"); + run("deminout"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + run("wreduce"); + run("peepopt"); + run("opt_clean"); + run("share"); + + if (help_mode) { + run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp and if -family gw1n or gw2a)"); + run("techmap -map +/gowin/dsp_map.v", "(unless -nodsp and if -family gw1n or gw2a)"); + } else if (!nodsp && (family == "gw1n" || family == "gw2a")) { + for (const auto &rule : dsp_rules) { + run(stringf("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d -D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_NAME=%s", + rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.prim)); + run("chtype -set $mul t:$__soft_mul"); + } + run("techmap -map +/gowin/dsp_map.v"); + } + + run("alumacc"); + run("opt"); + run("memory -nomap" + no_rw_check_opt); + run("opt_clean"); } if (check_label("map_ram")) @@ -263,7 +311,7 @@ struct SynthGowinPass : public ScriptPass if (nolutram) args += " -no-auto-distributed"; } - run(stringf("memory_libmap -lib +/gowin/lutrams.txt -lib +/gowin/brams.txt -D %s", family) + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run(stringf("memory_libmap -lib +/gowin/lutrams.txt -lib +/gowin/brams.txt%s", family == "gw5a" ? " -D gw5a" : "") + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); run(stringf("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map%s.v", family == "gw5a" ? "_gw5a" : "")); } @@ -294,23 +342,25 @@ struct SynthGowinPass : public ScriptPass run("opt_clean"); if (family == "gw5a") { if (strict_gw5a_dffs) { - run("dfflegalize -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r"); + run("dfflegalize -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r -cell $_DLATCH_?_ x -cell $_DLATCH_?P?_ x"); } else { - run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r"); + run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r -cell $_DLATCH_?_ x -cell $_DLATCH_?P?_ x"); } } else { if (nodffe) - run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r"); + run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r -cell $_DLATCH_?_ x -cell $_DLATCH_?P?_ x"); else - run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r"); + run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r -cell $_DLATCH_?_ x -cell $_DLATCH_?P?_ x"); } run("techmap -map +/gowin/cells_map.v"); + run("techmap -map +/gowin/cells_latch.v"); run("opt_expr -mux_undef"); run("simplemap"); } if (check_label("map_luts")) { + run("sort"); if (nowidelut && abc9) { run("read_verilog -icells -lib -specify +/abc9_model.v"); run("abc9 -maxlut 4 -W 500"); diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index fa52ecfc6..7f91d6332 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -144,6 +144,7 @@ struct SynthGreenPAK4Pass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); run("tribuf -logic"); } diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 0a4144451..86189c848 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -309,6 +309,7 @@ struct SynthIce40Pass : public ScriptPass if (check_label("flatten", "(unless -noflatten)")) { if (flatten) { + run("check"); run("flatten"); run("tribuf -logic"); run("deminout"); diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index e02885cd0..0b0eb6ae9 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -198,9 +198,11 @@ struct SynthIntelPass : public ScriptPass { if (check_label("coarse")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten", "(skip if -noflatten)"); - run("tribuf -logic"); + } + run("tribuf -logic"); run("deminout"); run("opt_expr"); run("opt_clean"); diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 28852d7df..95dbb6e35 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -184,8 +184,10 @@ struct SynthIntelALMPass : public ScriptPass { if (check_label("coarse")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten", "(skip if -noflatten)"); + } run("tribuf -logic"); run("deminout"); run("opt_expr"); diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v index 1b1b9a1f4..61f3da502 100644 --- a/techlibs/lattice/cells_bb_ecp5.v +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -1,24 +1,29 @@ // Created by cells_xtra.py from Lattice models (* blackbox *) (* keep *) -module GSR (...); +module GSR(GSR); input GSR; endmodule (* blackbox *) -module PUR (...); +module PUR(PUR); parameter RST_PULSE = 1; input PUR; endmodule (* blackbox *) (* keep *) -module SGSR (...); +module SGSR(GSR, CLK); input GSR; input CLK; endmodule (* blackbox *) -module PDPW16KD (...); +module PDPW16KD(DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18, DI17, DI16, DI15 +, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, ADW8, ADW7, ADW6, ADW5, ADW4, ADW3 +, ADW2, ADW1, ADW0, BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5 +, ADR4, ADR3, ADR2, ADR1, ADR0, CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27 +, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18, DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6 +, DO5, DO4, DO3, DO2, DO1, DO0); parameter CLKRMUX = "CLKR"; parameter CLKWMUX = "CLKW"; parameter DATA_WIDTH_W = 36; @@ -208,7 +213,18 @@ module PDPW16KD (...); endmodule (* blackbox *) -module MULT18X18D (...); +module MULT18X18D(A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, A3, A2, A1, A0, B17, B16, B15 +, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0, C17, C16, C15, C14, C13, C12 +, C11, C10, C9, C8, C7, C6, C5, C4, C3, C2, C1, C0, SIGNEDA, SIGNEDB, SOURCEA, SOURCEB, CLK3, CLK2, CLK1, CLK0, CE3 +, CE2, CE1, CE0, RST3, RST2, RST1, RST0, SRIA17, SRIA16, SRIA15, SRIA14, SRIA13, SRIA12, SRIA11, SRIA10, SRIA9, SRIA8, SRIA7, SRIA6, SRIA5, SRIA4 +, SRIA3, SRIA2, SRIA1, SRIA0, SRIB17, SRIB16, SRIB15, SRIB14, SRIB13, SRIB12, SRIB11, SRIB10, SRIB9, SRIB8, SRIB7, SRIB6, SRIB5, SRIB4, SRIB3, SRIB2, SRIB1 +, SRIB0, SROA17, SROA16, SROA15, SROA14, SROA13, SROA12, SROA11, SROA10, SROA9, SROA8, SROA7, SROA6, SROA5, SROA4, SROA3, SROA2, SROA1, SROA0, SROB17, SROB16 +, SROB15, SROB14, SROB13, SROB12, SROB11, SROB10, SROB9, SROB8, SROB7, SROB6, SROB5, SROB4, SROB3, SROB2, SROB1, SROB0, ROA17, ROA16, ROA15, ROA14, ROA13 +, ROA12, ROA11, ROA10, ROA9, ROA8, ROA7, ROA6, ROA5, ROA4, ROA3, ROA2, ROA1, ROA0, ROB17, ROB16, ROB15, ROB14, ROB13, ROB12, ROB11, ROB10 +, ROB9, ROB8, ROB7, ROB6, ROB5, ROB4, ROB3, ROB2, ROB1, ROB0, ROC17, ROC16, ROC15, ROC14, ROC13, ROC12, ROC11, ROC10, ROC9, ROC8, ROC7 +, ROC6, ROC5, ROC4, ROC3, ROC2, ROC1, ROC0, P35, P34, P33, P32, P31, P30, P29, P28, P27, P26, P25, P24, P23, P22 +, P21, P20, P19, P18, P17, P16, P15, P14, P13, P12, P11, P10, P9, P8, P7, P6, P5, P4, P3, P2, P1 +, P0, SIGNEDP); parameter REG_INPUTA_CLK = "NONE"; parameter REG_INPUTA_CE = "CE0"; parameter REG_INPUTA_RST = "RST0"; @@ -470,7 +486,28 @@ module MULT18X18D (...); endmodule (* blackbox *) -module ALU54B (...); +module ALU54B(CE3, CE2, CE1, CE0, CLK3, CLK2, CLK1, CLK0, RST3, RST2, RST1, RST0, SIGNEDIA, SIGNEDIB, SIGNEDCIN, A35, A34, A33, A32, A31, A30 +, A29, A28, A27, A26, A25, A24, A23, A22, A21, A20, A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9 +, A8, A7, A6, A5, A4, A3, A2, A1, A0, B35, B34, B33, B32, B31, B30, B29, B28, B27, B26, B25, B24 +, B23, B22, B21, B20, B19, B18, B17, B16, B15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3 +, B2, B1, B0, C53, C52, C51, C50, C49, C48, C47, C46, C45, C44, C43, C42, C41, C40, C39, C38, C37, C36 +, C35, C34, C33, C32, C31, C30, C29, C28, C27, C26, C25, C24, C23, C22, C21, C20, C19, C18, C17, C16, C15 +, C14, C13, C12, C11, C10, C9, C8, C7, C6, C5, C4, C3, C2, C1, C0, CFB53, CFB52, CFB51, CFB50, CFB49, CFB48 +, CFB47, CFB46, CFB45, CFB44, CFB43, CFB42, CFB41, CFB40, CFB39, CFB38, CFB37, CFB36, CFB35, CFB34, CFB33, CFB32, CFB31, CFB30, CFB29, CFB28, CFB27 +, CFB26, CFB25, CFB24, CFB23, CFB22, CFB21, CFB20, CFB19, CFB18, CFB17, CFB16, CFB15, CFB14, CFB13, CFB12, CFB11, CFB10, CFB9, CFB8, CFB7, CFB6 +, CFB5, CFB4, CFB3, CFB2, CFB1, CFB0, MA35, MA34, MA33, MA32, MA31, MA30, MA29, MA28, MA27, MA26, MA25, MA24, MA23, MA22, MA21 +, MA20, MA19, MA18, MA17, MA16, MA15, MA14, MA13, MA12, MA11, MA10, MA9, MA8, MA7, MA6, MA5, MA4, MA3, MA2, MA1, MA0 +, MB35, MB34, MB33, MB32, MB31, MB30, MB29, MB28, MB27, MB26, MB25, MB24, MB23, MB22, MB21, MB20, MB19, MB18, MB17, MB16, MB15 +, MB14, MB13, MB12, MB11, MB10, MB9, MB8, MB7, MB6, MB5, MB4, MB3, MB2, MB1, MB0, CIN53, CIN52, CIN51, CIN50, CIN49, CIN48 +, CIN47, CIN46, CIN45, CIN44, CIN43, CIN42, CIN41, CIN40, CIN39, CIN38, CIN37, CIN36, CIN35, CIN34, CIN33, CIN32, CIN31, CIN30, CIN29, CIN28, CIN27 +, CIN26, CIN25, CIN24, CIN23, CIN22, CIN21, CIN20, CIN19, CIN18, CIN17, CIN16, CIN15, CIN14, CIN13, CIN12, CIN11, CIN10, CIN9, CIN8, CIN7, CIN6 +, CIN5, CIN4, CIN3, CIN2, CIN1, CIN0, OP10, OP9, OP8, OP7, OP6, OP5, OP4, OP3, OP2, OP1, OP0, R53, R52, R51, R50 +, R49, R48, R47, R46, R45, R44, R43, R42, R41, R40, R39, R38, R37, R36, R35, R34, R33, R32, R31, R30, R29 +, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8 +, R7, R6, R5, R4, R3, R2, R1, R0, CO53, CO52, CO51, CO50, CO49, CO48, CO47, CO46, CO45, CO44, CO43, CO42, CO41 +, CO40, CO39, CO38, CO37, CO36, CO35, CO34, CO33, CO32, CO31, CO30, CO29, CO28, CO27, CO26, CO25, CO24, CO23, CO22, CO21, CO20 +, CO19, CO18, CO17, CO16, CO15, CO14, CO13, CO12, CO11, CO10, CO9, CO8, CO7, CO6, CO5, CO4, CO3, CO2, CO1, CO0, EQZ +, EQZM, EQOM, EQPAT, EQPATB, OVER, UNDER, OVERUNDER, SIGNEDR); parameter REG_INPUTC0_CLK = "NONE"; parameter REG_INPUTC0_CE = "CE0"; parameter REG_INPUTC0_RST = "RST0"; @@ -970,7 +1007,7 @@ module ALU54B (...); endmodule (* blackbox *) -module CLKDIVF (...); +module CLKDIVF(CLKI, RST, ALIGNWD, CDIVX); parameter GSR = "DISABLED"; parameter DIV = "2.0"; input CLKI; @@ -980,7 +1017,7 @@ module CLKDIVF (...); endmodule (* blackbox *) -module PCSCLKDIV (...); +module PCSCLKDIV(CLKI, RST, SEL2, SEL1, SEL0, CDIV1, CDIVX); parameter GSR = "DISABLED"; input CLKI; input RST; @@ -992,7 +1029,7 @@ module PCSCLKDIV (...); endmodule (* blackbox *) -module DCSC (...); +module DCSC(CLK1, CLK0, SEL1, SEL0, MODESEL, DCSOUT); parameter DCSMODE = "POS"; input CLK1; input CLK0; @@ -1003,21 +1040,21 @@ module DCSC (...); endmodule (* blackbox *) -module DCCA (...); +module DCCA(CLKI, CE, CLKO); input CLKI; input CE; output CLKO; endmodule (* blackbox *) -module ECLKSYNCB (...); +module ECLKSYNCB(ECLKI, STOP, ECLKO); input ECLKI; input STOP; output ECLKO; endmodule (* blackbox *) -module ECLKBRIDGECS (...); +module ECLKBRIDGECS(CLK0, CLK1, SEL, ECSOUT); input CLK0; input CLK1; input SEL; @@ -1025,7 +1062,7 @@ module ECLKBRIDGECS (...); endmodule (* blackbox *) -module DELAYF (...); +module DELAYF(A, LOADN, MOVE, DIRECTION, Z, CFLAG); parameter DEL_MODE = "USER_DEFINED"; parameter DEL_VALUE = 0; input A; @@ -1037,7 +1074,7 @@ module DELAYF (...); endmodule (* blackbox *) -module DELAYG (...); +module DELAYG(A, Z); parameter DEL_MODE = "USER_DEFINED"; parameter DEL_VALUE = 0; input A; @@ -1045,13 +1082,14 @@ module DELAYG (...); endmodule (* blackbox *) (* keep *) -module USRMCLK (...); +module USRMCLK(USRMCLKI, USRMCLKTS); input USRMCLKI; input USRMCLKTS; endmodule (* blackbox *) -module DQSBUFM (...); +module DQSBUFM(DQSI, READ1, READ0, READCLKSEL2, READCLKSEL1, READCLKSEL0, DDRDEL, ECLK, SCLK, RST, DYNDELAY7, DYNDELAY6, DYNDELAY5, DYNDELAY4, DYNDELAY3, DYNDELAY2, DYNDELAY1, DYNDELAY0, PAUSE, RDLOADN, RDMOVE +, RDDIRECTION, WRLOADN, WRMOVE, WRDIRECTION, DQSR90, DQSW, DQSW270, RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, DATAVALID, BURSTDET, RDCFLAG, WRCFLAG); parameter DQS_LI_DEL_VAL = 4; parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; parameter DQS_LO_DEL_VAL = 0; @@ -1098,7 +1136,7 @@ module DQSBUFM (...); endmodule (* blackbox *) -module DDRDLLA (...); +module DDRDLLA(CLK, RST, UDDCNTLN, FREEZE, DDRDEL, LOCK, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0); parameter FORCE_MAX_DELAY = "NO"; parameter GSR = "ENABLED"; input CLK; @@ -1118,7 +1156,7 @@ module DDRDLLA (...); endmodule (* blackbox *) -module DLLDELD (...); +module DLLDELD(A, DDRDEL, LOADN, MOVE, DIRECTION, Z, CFLAG); input A; input DDRDEL; input LOADN; @@ -1129,7 +1167,7 @@ module DLLDELD (...); endmodule (* blackbox *) -module IDDRX1F (...); +module IDDRX1F(D, SCLK, RST, Q0, Q1); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1139,7 +1177,7 @@ module IDDRX1F (...); endmodule (* blackbox *) -module IDDRX2F (...); +module IDDRX2F(D, SCLK, ECLK, RST, ALIGNWD, Q3, Q2, Q1, Q0); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1153,7 +1191,7 @@ module IDDRX2F (...); endmodule (* blackbox *) -module IDDR71B (...); +module IDDR71B(D, SCLK, ECLK, RST, ALIGNWD, Q6, Q5, Q4, Q3, Q2, Q1, Q0); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1170,7 +1208,7 @@ module IDDR71B (...); endmodule (* blackbox *) -module IDDRX2DQA (...); +module IDDRX2DQA(SCLK, ECLK, DQSR90, D, RST, RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, Q3, Q2, Q1, Q0, QWL); parameter GSR = "ENABLED"; input SCLK; input ECLK; @@ -1191,7 +1229,7 @@ module IDDRX2DQA (...); endmodule (* blackbox *) -module ODDRX1F (...); +module ODDRX1F(SCLK, RST, D0, D1, Q); parameter GSR = "ENABLED"; input SCLK; input RST; @@ -1201,7 +1239,7 @@ module ODDRX1F (...); endmodule (* blackbox *) -module ODDRX2F (...); +module ODDRX2F(SCLK, ECLK, RST, D3, D2, D1, D0, Q); parameter GSR = "ENABLED"; input SCLK; input ECLK; @@ -1214,7 +1252,7 @@ module ODDRX2F (...); endmodule (* blackbox *) -module ODDR71B (...); +module ODDR71B(SCLK, ECLK, RST, D6, D5, D4, D3, D2, D1, D0, Q); parameter GSR = "ENABLED"; input SCLK; input ECLK; @@ -1230,7 +1268,7 @@ module ODDR71B (...); endmodule (* blackbox *) -module OSHX2A (...); +module OSHX2A(D1, D0, SCLK, ECLK, RST, Q); parameter GSR = "ENABLED"; input D1; input D0; @@ -1241,7 +1279,7 @@ module OSHX2A (...); endmodule (* blackbox *) -module TSHX2DQA (...); +module TSHX2DQA(T1, T0, SCLK, ECLK, DQSW270, RST, Q); parameter GSR = "ENABLED"; parameter REGSET = "SET"; input T1; @@ -1254,7 +1292,7 @@ module TSHX2DQA (...); endmodule (* blackbox *) -module TSHX2DQSA (...); +module TSHX2DQSA(T1, T0, SCLK, ECLK, DQSW, RST, Q); parameter GSR = "ENABLED"; parameter REGSET = "SET"; input T1; @@ -1267,7 +1305,7 @@ module TSHX2DQSA (...); endmodule (* blackbox *) -module ODDRX2DQA (...); +module ODDRX2DQA(D3, D2, D1, D0, DQSW270, SCLK, ECLK, RST, Q); parameter GSR = "ENABLED"; input D3; input D2; @@ -1281,7 +1319,7 @@ module ODDRX2DQA (...); endmodule (* blackbox *) -module ODDRX2DQSB (...); +module ODDRX2DQSB(D3, D2, D1, D0, SCLK, ECLK, DQSW, RST, Q); parameter GSR = "ENABLED"; input D3; input D2; @@ -1295,7 +1333,8 @@ module ODDRX2DQSB (...); endmodule (* blackbox *) -module EHXPLLL (...); +module EHXPLLL(CLKI, CLKFB, PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, PHASELOADREG, STDBY, PLLWAKESYNC, RST, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK +, CLKINTFB); parameter CLKI_DIV = 1; parameter CLKFB_DIV = 1; parameter CLKOP_DIV = 8; @@ -1357,7 +1396,7 @@ module EHXPLLL (...); endmodule (* blackbox *) -module DTR (...); +module DTR(STARTPULSE, DTROUT7, DTROUT6, DTROUT5, DTROUT4, DTROUT3, DTROUT2, DTROUT1, DTROUT0); parameter DTR_TEMP = 25; input STARTPULSE; output DTROUT7; @@ -1371,13 +1410,13 @@ module DTR (...); endmodule (* blackbox *) -module OSCG (...); +module OSCG(OSC); parameter DIV = 128; output OSC; endmodule (* blackbox *) -module EXTREFB (...); +module EXTREFB(REFCLKP, REFCLKN, REFCLKO); parameter REFCK_PWDNB = "DONTCARE"; parameter REFCK_RTERM = "DONTCARE"; parameter REFCK_DCBIAS_EN = "DONTCARE"; @@ -1389,7 +1428,7 @@ module EXTREFB (...); endmodule (* blackbox *) (* keep *) -module JTAGG (...); +module JTAGG(TCK, TMS, TDI, JTDO2, JTDO1, TDO, JTDI, JTCK, JRTI2, JRTI1, JSHIFT, JUPDATE, JRSTN, JCE2, JCE1); parameter ER1 = "ENABLED"; parameter ER2 = "ENABLED"; (* iopad_external_pin *) @@ -1414,7 +1453,20 @@ module JTAGG (...); endmodule (* blackbox *) (* keep *) -module DCUA (...); +module DCUA(CH0_HDINP, CH1_HDINP, CH0_HDINN, CH1_HDINN, D_TXBIT_CLKP_FROM_ND, D_TXBIT_CLKN_FROM_ND, D_SYNC_ND, D_TXPLL_LOL_FROM_ND, CH0_RX_REFCLK, CH1_RX_REFCLK, CH0_FF_RXI_CLK, CH1_FF_RXI_CLK, CH0_FF_TXI_CLK, CH1_FF_TXI_CLK, CH0_FF_EBRD_CLK, CH1_FF_EBRD_CLK, CH0_FF_TX_D_0, CH1_FF_TX_D_0, CH0_FF_TX_D_1, CH1_FF_TX_D_1, CH0_FF_TX_D_2 +, CH1_FF_TX_D_2, CH0_FF_TX_D_3, CH1_FF_TX_D_3, CH0_FF_TX_D_4, CH1_FF_TX_D_4, CH0_FF_TX_D_5, CH1_FF_TX_D_5, CH0_FF_TX_D_6, CH1_FF_TX_D_6, CH0_FF_TX_D_7, CH1_FF_TX_D_7, CH0_FF_TX_D_8, CH1_FF_TX_D_8, CH0_FF_TX_D_9, CH1_FF_TX_D_9, CH0_FF_TX_D_10, CH1_FF_TX_D_10, CH0_FF_TX_D_11, CH1_FF_TX_D_11, CH0_FF_TX_D_12, CH1_FF_TX_D_12 +, CH0_FF_TX_D_13, CH1_FF_TX_D_13, CH0_FF_TX_D_14, CH1_FF_TX_D_14, CH0_FF_TX_D_15, CH1_FF_TX_D_15, CH0_FF_TX_D_16, CH1_FF_TX_D_16, CH0_FF_TX_D_17, CH1_FF_TX_D_17, CH0_FF_TX_D_18, CH1_FF_TX_D_18, CH0_FF_TX_D_19, CH1_FF_TX_D_19, CH0_FF_TX_D_20, CH1_FF_TX_D_20, CH0_FF_TX_D_21, CH1_FF_TX_D_21, CH0_FF_TX_D_22, CH1_FF_TX_D_22, CH0_FF_TX_D_23 +, CH1_FF_TX_D_23, CH0_FFC_EI_EN, CH1_FFC_EI_EN, CH0_FFC_PCIE_DET_EN, CH1_FFC_PCIE_DET_EN, CH0_FFC_PCIE_CT, CH1_FFC_PCIE_CT, CH0_FFC_SB_INV_RX, CH1_FFC_SB_INV_RX, CH0_FFC_ENABLE_CGALIGN, CH1_FFC_ENABLE_CGALIGN, CH0_FFC_SIGNAL_DETECT, CH1_FFC_SIGNAL_DETECT, CH0_FFC_FB_LOOPBACK, CH1_FFC_FB_LOOPBACK, CH0_FFC_SB_PFIFO_LP, CH1_FFC_SB_PFIFO_LP, CH0_FFC_PFIFO_CLR, CH1_FFC_PFIFO_CLR, CH0_FFC_RATE_MODE_RX, CH1_FFC_RATE_MODE_RX +, CH0_FFC_RATE_MODE_TX, CH1_FFC_RATE_MODE_TX, CH0_FFC_DIV11_MODE_RX, CH1_FFC_DIV11_MODE_RX, CH0_FFC_RX_GEAR_MODE, CH1_FFC_RX_GEAR_MODE, CH0_FFC_TX_GEAR_MODE, CH1_FFC_TX_GEAR_MODE, CH0_FFC_DIV11_MODE_TX, CH1_FFC_DIV11_MODE_TX, CH0_FFC_LDR_CORE2TX_EN, CH1_FFC_LDR_CORE2TX_EN, CH0_FFC_LANE_TX_RST, CH1_FFC_LANE_TX_RST, CH0_FFC_LANE_RX_RST, CH1_FFC_LANE_RX_RST, CH0_FFC_RRST, CH1_FFC_RRST, CH0_FFC_TXPWDNB, CH1_FFC_TXPWDNB, CH0_FFC_RXPWDNB +, CH1_FFC_RXPWDNB, CH0_LDR_CORE2TX, CH1_LDR_CORE2TX, D_SCIWDATA0, D_SCIWDATA1, D_SCIWDATA2, D_SCIWDATA3, D_SCIWDATA4, D_SCIWDATA5, D_SCIWDATA6, D_SCIWDATA7, D_SCIADDR0, D_SCIADDR1, D_SCIADDR2, D_SCIADDR3, D_SCIADDR4, D_SCIADDR5, D_SCIENAUX, D_SCISELAUX, CH0_SCIEN, CH1_SCIEN +, CH0_SCISEL, CH1_SCISEL, D_SCIRD, D_SCIWSTN, D_CYAWSTN, D_FFC_SYNC_TOGGLE, D_FFC_DUAL_RST, D_FFC_MACRO_RST, D_FFC_MACROPDB, D_FFC_TRST, CH0_FFC_CDR_EN_BITSLIP, CH1_FFC_CDR_EN_BITSLIP, D_SCAN_ENABLE, D_SCAN_IN_0, D_SCAN_IN_1, D_SCAN_IN_2, D_SCAN_IN_3, D_SCAN_IN_4, D_SCAN_IN_5, D_SCAN_IN_6, D_SCAN_IN_7 +, D_SCAN_MODE, D_SCAN_RESET, D_CIN0, D_CIN1, D_CIN2, D_CIN3, D_CIN4, D_CIN5, D_CIN6, D_CIN7, D_CIN8, D_CIN9, D_CIN10, D_CIN11, CH0_HDOUTP, CH1_HDOUTP, CH0_HDOUTN, CH1_HDOUTN, D_TXBIT_CLKP_TO_ND, D_TXBIT_CLKN_TO_ND, D_SYNC_PULSE2ND +, D_TXPLL_LOL_TO_ND, CH0_FF_RX_F_CLK, CH1_FF_RX_F_CLK, CH0_FF_RX_H_CLK, CH1_FF_RX_H_CLK, CH0_FF_TX_F_CLK, CH1_FF_TX_F_CLK, CH0_FF_TX_H_CLK, CH1_FF_TX_H_CLK, CH0_FF_RX_PCLK, CH1_FF_RX_PCLK, CH0_FF_TX_PCLK, CH1_FF_TX_PCLK, CH0_FF_RX_D_0, CH1_FF_RX_D_0, CH0_FF_RX_D_1, CH1_FF_RX_D_1, CH0_FF_RX_D_2, CH1_FF_RX_D_2, CH0_FF_RX_D_3, CH1_FF_RX_D_3 +, CH0_FF_RX_D_4, CH1_FF_RX_D_4, CH0_FF_RX_D_5, CH1_FF_RX_D_5, CH0_FF_RX_D_6, CH1_FF_RX_D_6, CH0_FF_RX_D_7, CH1_FF_RX_D_7, CH0_FF_RX_D_8, CH1_FF_RX_D_8, CH0_FF_RX_D_9, CH1_FF_RX_D_9, CH0_FF_RX_D_10, CH1_FF_RX_D_10, CH0_FF_RX_D_11, CH1_FF_RX_D_11, CH0_FF_RX_D_12, CH1_FF_RX_D_12, CH0_FF_RX_D_13, CH1_FF_RX_D_13, CH0_FF_RX_D_14 +, CH1_FF_RX_D_14, CH0_FF_RX_D_15, CH1_FF_RX_D_15, CH0_FF_RX_D_16, CH1_FF_RX_D_16, CH0_FF_RX_D_17, CH1_FF_RX_D_17, CH0_FF_RX_D_18, CH1_FF_RX_D_18, CH0_FF_RX_D_19, CH1_FF_RX_D_19, CH0_FF_RX_D_20, CH1_FF_RX_D_20, CH0_FF_RX_D_21, CH1_FF_RX_D_21, CH0_FF_RX_D_22, CH1_FF_RX_D_22, CH0_FF_RX_D_23, CH1_FF_RX_D_23, CH0_FFS_PCIE_DONE, CH1_FFS_PCIE_DONE +, CH0_FFS_PCIE_CON, CH1_FFS_PCIE_CON, CH0_FFS_RLOS, CH1_FFS_RLOS, CH0_FFS_LS_SYNC_STATUS, CH1_FFS_LS_SYNC_STATUS, CH0_FFS_CC_UNDERRUN, CH1_FFS_CC_UNDERRUN, CH0_FFS_CC_OVERRUN, CH1_FFS_CC_OVERRUN, CH0_FFS_RXFBFIFO_ERROR, CH1_FFS_RXFBFIFO_ERROR, CH0_FFS_TXFBFIFO_ERROR, CH1_FFS_TXFBFIFO_ERROR, CH0_FFS_RLOL, CH1_FFS_RLOL, CH0_FFS_SKP_ADDED, CH1_FFS_SKP_ADDED, CH0_FFS_SKP_DELETED, CH1_FFS_SKP_DELETED, CH0_LDR_RX2CORE +, CH1_LDR_RX2CORE, D_SCIRDATA0, D_SCIRDATA1, D_SCIRDATA2, D_SCIRDATA3, D_SCIRDATA4, D_SCIRDATA5, D_SCIRDATA6, D_SCIRDATA7, D_SCIINT, D_SCAN_OUT_0, D_SCAN_OUT_1, D_SCAN_OUT_2, D_SCAN_OUT_3, D_SCAN_OUT_4, D_SCAN_OUT_5, D_SCAN_OUT_6, D_SCAN_OUT_7, D_COUT0, D_COUT1, D_COUT2 +, D_COUT3, D_COUT4, D_COUT5, D_COUT6, D_COUT7, D_COUT8, D_COUT9, D_COUT10, D_COUT11, D_COUT12, D_COUT13, D_COUT14, D_COUT15, D_COUT16, D_COUT17, D_COUT18, D_COUT19, D_REFCLKI, D_FFS_PLOL); parameter D_MACROPDB = "DONTCARE"; parameter D_IB_PWDNB = "DONTCARE"; parameter D_XGE_MODE = "DONTCARE"; diff --git a/techlibs/lattice/cells_bb_nexus.v b/techlibs/lattice/cells_bb_nexus.v index 6cf3a645d..42da827d6 100644 --- a/techlibs/lattice/cells_bb_nexus.v +++ b/techlibs/lattice/cells_bb_nexus.v @@ -1,6 +1,7 @@ // Created by cells_xtra.py from Lattice models -module ACC54 (...); +module ACC54(SFTCTRL, DSPIN, PP, CINPUT, LOAD, M9ADDSUB, ADDSUB, CIN, CASIN, CEO, RSTO, CEC, RSTC, CLK, SIGNEDI, SUM1, SUM0, DSPOUT, CASCOUT, ROUNDEN, CECIN +, CECTRL, RSTCIN, RSTCTRL); parameter SIGN = "DISABLED"; parameter M9ADDSUB_CTRL = "ADDITION"; parameter ADDSUB_CTRL = "ADD_ADD_CTRL_54_BIT_ADDER"; @@ -60,7 +61,8 @@ module ACC54 (...); input RSTCTRL; endmodule -module ADC (...); +module ADC(DN0, DN1, DP0, DP1, ADCEN, CAL, CALRDY, CHAEN, CHASEL, CHBEN, CHBSEL, CLKDCLK, CLKFAB, COG, COMP1IN, COMP1IP, COMP1OL, COMP2IN, COMP2IP, COMP2OL, COMP3IN +, COMP3IP, COMP3OL, CONVSTOP, DA, DB, EOC, GPION, GPIOP, RESETN, RSTN, SOC, COMP1O, COMP2O, COMP3O); parameter ADC_ENP = "ENABLED"; parameter CLK_DIV = "2"; parameter CTLCOMPSW1 = "DISABLED"; @@ -120,7 +122,8 @@ module ADC (...); output COMP3O; endmodule -module ALUREG (...); +module ALUREG(ALUCLK, ALUFLAGC, ALUFLAGV, ALUFLAGZ, ALUFORWARDA, ALUFORWARDB, ALUIREGEN, ALUOREGEN, ALURST, DATAA, DATAB, DATAC, OPC, OPCCUSTOM, RADDRA, RADDRB, RDATAA, RDATAB, REGCLK, REGCLKEN, REGRST +, RESULT, WADDR, WDROTATE, WDSIGNEXT, WDSIZE, WDATA, WREN); parameter ALURST_ACTIVELOW = "DISABLE"; parameter GSR = "ENABLED"; parameter INREG = "DISABLE"; @@ -163,21 +166,21 @@ module ALUREG (...); endmodule (* keep *) -module BB_ADC (...); +module BB_ADC(IOPAD, INADC); (* iopad_external_pin *) inout IOPAD; output INADC; endmodule (* keep *) -module BB_CDR (...); +module BB_CDR(IOPAD, INADC); (* iopad_external_pin *) inout IOPAD; output INADC; endmodule (* keep *) -module BB_I3C_A (...); +module BB_I3C_A(IOPAD, PADDI, PADDO, PADDT, I3CRESEN, I3CWKPU); (* iopad_external_pin *) inout IOPAD; output PADDI; @@ -187,7 +190,7 @@ module BB_I3C_A (...); input I3CWKPU; endmodule -module BFD1P3KX (...); +module BFD1P3KX(DOUT, DIN, DT, CEOUT, CLKOUT, SROUT, CEIN, CLKIN, SRIN, QOUT, QIN, QT); parameter GSR = "ENABLED"; parameter OUTSET = "RESET"; parameter INSET = "RESET"; @@ -206,7 +209,7 @@ module BFD1P3KX (...); output QT; endmodule -module BFD1P3LX (...); +module BFD1P3LX(DOUT, DIN, DT, CEOUT, CLKOUT, SROUT, CEIN, CLKIN, SRIN, QOUT, QIN, QT); parameter GSR = "ENABLED"; parameter OUTSET = "RESET"; parameter INSET = "RESET"; @@ -226,7 +229,7 @@ module BFD1P3LX (...); endmodule (* keep *) -module BNKREF18 (...); +module BNKREF18(STDBYINR, STDBYDIF, PVTCODE); parameter BANK = "0b0000"; parameter STANDBY_DIFFIO = "DISABLED"; parameter STANDBY_INR = "DISABLED"; @@ -236,7 +239,7 @@ module BNKREF18 (...); endmodule (* keep *) -module CONFIG_LMMI (...); +module CONFIG_LMMI(LMMICLK, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIREADY, LMMIRDATAVALID, LMMIRESETN, RSTSMCLK, SMCLK); parameter LMMI_EN = "DIS"; input LMMICLK; input LMMIREQUEST; @@ -251,7 +254,7 @@ module CONFIG_LMMI (...); input SMCLK; endmodule -module DDRDLL (...); +module DDRDLL(CODE, FREEZE, LOCK, CLKIN, RST, DCNTL, UDDCNTL_N); parameter GSR = "ENABLED"; parameter ENA_ROUNDOFF = "ENABLED"; parameter FORCE_MAX_DELAY = "CODE_OR_LOCK_FROM_DLL_LOOP"; @@ -264,7 +267,7 @@ module DDRDLL (...); input UDDCNTL_N; endmodule -module DELAYA (...); +module DELAYA(A, LOAD_N, MOVE, DIRECTION, COARSE0, COARSE1, RANKSELECT, RANKENABLE, RANK0UPDATE, RANK1UPDATE, Z, EDETERR, CFLAG); parameter DEL_MODE = "USER_DEFINED"; parameter DEL_VALUE = "0"; parameter COARSE_DELAY_MODE = "STATIC"; @@ -286,7 +289,7 @@ module DELAYA (...); output CFLAG; endmodule -module DELAYB (...); +module DELAYB(A, Z); parameter DEL_VALUE = "0"; parameter COARSE_DELAY = "0NS"; parameter DEL_MODE = "USER_DEFINED"; @@ -295,7 +298,7 @@ module DELAYB (...); endmodule (* keep *) -module DIFFIO18 (...); +module DIFFIO18(PADDO, DOLP, IOPAD, PADDI, INLP, PADDT, INADC, HSRXEN, HSTXEN); parameter PULLMODE = "DOWN"; parameter ENADC_IN = "DISABLED"; parameter MIPI = "DISABLED"; @@ -311,7 +314,7 @@ module DIFFIO18 (...); input HSTXEN; endmodule -module DLLDEL (...); +module DLLDEL(CLKIN, CLKOUT, CODE, COUT, DIR, LOAD_N, MOVE); parameter ADJUST = "0"; parameter DEL_ADJUST = "PLUS"; parameter ENABLE = "ENABLED"; @@ -324,7 +327,12 @@ module DLLDEL (...); input MOVE; endmodule -module DP16K_MODE (...); +module DP16K_MODE(DIA0, DIA1, DIA2, DIA3, DIA4, DIA5, DIA6, DIA7, DIA8, DIA9, DIA10, DIA11, DIA12, DIA13, DIA14, DIA15, DIA16, DIA17, DIB0, DIB1, DIB2 +, DIB3, DIB4, DIB5, DIB6, DIB7, DIB8, DIB9, DIB10, DIB11, DIB12, DIB13, DIB14, DIB15, DIB16, DIB17, ADA0, ADA1, ADA2, ADA3, ADA4, ADA5 +, ADA6, ADA7, ADA8, ADA9, ADA10, ADA11, ADA12, ADA13, ADB0, ADB1, ADB2, ADB3, ADB4, ADB5, ADB6, ADB7, ADB8, ADB9, ADB10, ADB11, ADB12 +, ADB13, CLKA, CLKB, CEA, CEB, WEA, WEB, CSA0, CSA1, CSA2, CSB0, CSB1, CSB2, RSTA, RSTB, DOA0, DOA1, DOA2, DOA3, DOA4, DOA5 +, DOA6, DOA7, DOA8, DOA9, DOA10, DOA11, DOA12, DOA13, DOA14, DOA15, DOA16, DOA17, DOB0, DOB1, DOB2, DOB3, DOB4, DOB5, DOB6, DOB7, DOB8 +, DOB9, DOB10, DOB11, DOB12, DOB13, DOB14, DOB15, DOB16, DOB17); parameter DATA_WIDTH_A = "X18"; parameter DATA_WIDTH_B = "X18"; parameter OUTREG_A = "BYPASSED"; @@ -517,7 +525,7 @@ module DP16K_MODE (...); output DOB17; endmodule -module DP16K (...); +module DP16K(DIA, DIB, ADA, ADB, CLKA, CLKB, CEA, CEB, WEA, WEB, CSA, CSB, RSTA, RSTB, DOA, DOB); parameter DATA_WIDTH_A = "X18"; parameter DATA_WIDTH_B = "X18"; parameter OUTREG_A = "BYPASSED"; @@ -613,7 +621,20 @@ module DP16K (...); endmodule (* keep *) -module DPHY (...); +module DPHY(LMMICLK, LMMIRESET_N, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIRDATAVALID, LMMIREADY, BITCKEXT, CKN, CKP, CLKREF, D0ACTIVE, D0BYTCNT, D0ERRCNT, D0PASS, D0VALID, D1ACTIVE, D1BYTCNT, D1ERRCNT +, D1PASS, D1VALID, D2ACTIVE, D2BYTCNT, D2ERRCNT, D2PASS, D2VALID, D3ACTIVE, D3BYTCNT, D3ERRCNT, D3PASS, D3VALID, DCTSTOUT, DN0, DN1, DN2, DN3, DP0, DP1, DP2, DP3 +, LOCK, PDDPHY, PDPLL, SCCLKIN, UDIR, UED0THEN, UERCLP0, UERCLP1, UERCTRL, UERE, UERSTHS, UERSSHS, UERSE, UFRXMODE, UTXMDTX, URXACTHS, URXCKE, URXCKINE, URXDE, URXDHS, URXLPDTE +, URXSKCHS, URXDRX, URXSHS, URE0D3DP, URE1D3DN, URE2CKDP, URE3CKDN, URXULPSE, URXVDE, URXVDHS, USSTT, UTDIS, UTXCKE, UDE0D0TN, UDE1D1TN, UDE2D2TN, UDE3D3TN, UDE4CKTN, UDE5D0RN, UDE6D1RN, UDE7D2RN +, UTXDHS, UTXENER, UTXRRS, UTXRYP, UTXRYSK, UTXRD0EN, UTRD0SEN, UTXSKD0N, UTXTGE0, UTXTGE1, UTXTGE2, UTXTGE3, UTXULPSE, UTXUPSEX, UTXVDE, UTXWVDHS, UUSAN, U1DIR, U1ENTHEN, U1ERCLP0, U1ERCLP1 +, U1ERCTRL, U1ERE, U1ERSTHS, U1ERSSHS, U1ERSE, U1FRXMD, U1FTXST, U1RXATHS, U1RXCKE, U1RXDE, U1RXDHS, U1RXDTE, U1RXSKS, U1RXSK, U1RXSHS, U1RE0D, U1RE1CN, U1RE2D, U1RE3N, U1RXUPSE, U1RXVDE +, U1RXVDHS, U1SSTT, U1TDIS, U1TREQ, U1TDE0D3, U1TDE1CK, U1TDE2D0, U1TDE3D1, U1TDE4D2, U1TDE5D3, U1TDE6, U1TDE7, U1TXDHS, U1TXLPD, U1TXRYE, U1TXRY, U1TXRYSK, U1TXREQ, U1TXREQH, U1TXSK, U1TXTGE0 +, U1TXTGE1, U1TXTGE2, U1TXTGE3, U1TXUPSE, U1TXUPSX, U1TXVDE, U1TXWVHS, U1USAN, U2DIR, U2END2, U2ERCLP0, U2ERCLP1, U2ERCTRL, U2ERE, U2ERSTHS, U2ERSSHS, U2ERSE, U2FRXMD, U2FTXST, U2RXACHS, U2RXCKE +, U2RXDE, U2RXDHS, U2RPDTE, U2RXSK, U2RXSKC, U2RXSHS, U2RE0D2, U2RE1D2, U2RE2D3, U2RE3D3, U2RXUPSE, U2RXVDE, U2RXVDHS, U2SSTT, U2TDIS, U2TREQ, U2TDE0D0, U2TDE1D1, U2TDE2D2, U2TDE3D3, U2TDE4CK +, U2TDE5D0, U2TDE6D1, U2TDE7D2, U2TXDHS, U2TPDTE, U2TXRYE, U2TXRYH, U2TXRYSK, U2TXREQ, U2TXREQH, U2TXSKC, U2TXTGE0, U2TXTGE1, U2TXTGE2, U2TXTGE3, U2TXUPSE, U2TXUPSX, U2TXVDE, U2TXWVHS, U2USAN, U3DIR +, U3END3, U3ERCLP0, U3ERCLP1, U3ERCTRL, U3ERE, U3ERSTHS, U3ERSSHS, U3ERSE, U3FRXMD, U3FTXST, U3RXATHS, U3RXCKE, U3RXDE, U3RXDHS, U3RPDTE, U3RXSK, U3RXSKC, U3RXSHS, U3RE0CK, U3RE1CK, U3RE2 +, U3RE3, U3RXUPSE, U3RXVDE, U3RXVDHS, U3SSTT, U3TDISD2, U3TREQD2, U3TDE0D3, U3TDE1D0, U3TDE2D1, U3TDE3D2, U3TDE4D3, U3TDE5CK, U3TDE6, U3TDE7, U3TXDHS, U3TXLPDT, U3TXRY, U3TXRYHS, U3TXRYSK, U3TXREQ +, U3TXREQH, U3TXSKC, U3TXTGE0, U3TXTGE1, U3TXTGE2, U3TXTGE3, U3TXULPS, U3TXUPSX, U3TXVD3, U3TXWVHS, U3USAN, UCENCK, UCRXCKAT, UCRXUCKN, UCSSTT, UCTXREQH, UCTXUPSC, UCTXUPSX, UCUSAN, LTSTEN, LTSTLANE +, URWDCKHS, UTRNREQ, UTWDCKHS, UCRXWCHS, CLKLBACT); parameter GSR = "ENABLED"; parameter AUTO_PD_EN = "POWERED_UP"; parameter CFG_NUM_LANES = "ONE_LANE"; @@ -935,7 +956,8 @@ module DPHY (...); output CLKLBACT; endmodule -module DPSC512K (...); +module DPSC512K(DIA, DIB, ADA, ADB, CLK, CEA, CEB, WEA, WEB, CSA, CSB, RSTA, RSTB, BENA_N, BENB_N, CEOUTA, CEOUTB, DOA, DOB, ERRDECA, ERRDECB +); parameter OUTREG_A = "NO_REG"; parameter OUTREG_B = "NO_REG"; parameter GSR = "ENABLED"; @@ -1093,7 +1115,8 @@ module DPSC512K (...); output [1:0] ERRDECB; endmodule -module DQSBUF (...); +module DQSBUF(BTDETECT, BURSTDETECT, DATAVALID, DQSI, DQSW, DQSWRD, PAUSE, RDCLKSEL, RDDIR, RDLOADN, RDPNTR, READ, READCOUT, READMOVE, RST, SCLK, SELCLK, DQSR90, DQSW270, WRCOUT, WRDIR +, WRLOAD_N, WRLVCOUT, WRLVDIR, WRLVLOAD_N, WRLVMOVE, WRMOVE, WRPNTR, ECLKIN, RSTSMCNT, DLLCODE); parameter GSR = "ENABLED"; parameter ENABLE_FIFO = "DISABLED"; parameter FORCE_READ = "DISABLED"; @@ -1148,7 +1171,12 @@ module DQSBUF (...); input [8:0] DLLCODE; endmodule -module EBR_CORE (...); +module EBR_CORE(DIA0, DIA1, DIA2, DIA3, DIA4, DIA5, DIA6, DIA7, DIA8, DIA9, DIA10, DIA11, DIA12, DIA13, DIA14, DIA15, DIA16, DIA17, DIB0, DIB1, DIB2 +, DIB3, DIB4, DIB5, DIB6, DIB7, DIB8, DIB9, DIB10, DIB11, DIB12, DIB13, DIB14, DIB15, DIB16, DIB17, ADA0, ADA1, ADA2, ADA3, ADA4, ADA5 +, ADA6, ADA7, ADA8, ADA9, ADA10, ADA11, ADA12, ADA13, ADB0, ADB1, ADB2, ADB3, ADB4, ADB5, ADB6, ADB7, ADB8, ADB9, ADB10, ADB11, ADB12 +, ADB13, CLKA, CLKB, WEA, WEB, CEA, CEB, RSTA, RSTB, CSA0, CSA1, CSA2, CSB0, CSB1, CSB2, FULLF, AFULL, EMPTYF, AEMPTY, DOA0, DOA1 +, DOA2, DOA3, DOA4, DOA5, DOA6, DOA7, DOA8, DOA9, DOA10, DOA11, DOA12, DOA13, DOA14, DOA15, DOA16, DOA17, DOB0, DOB1, DOB2, DOB3, DOB4 +, DOB5, DOB6, DOB7, DOB8, DOB9, DOB10, DOB11, DOB12, DOB13, DOB14, DOB15, DOB16, DOB17, ONEERR, TWOERR); parameter INIT_DATA = "STATIC"; parameter DATA_WIDTH_A = "X36"; parameter DATA_WIDTH_B = "X36"; @@ -1354,7 +1382,8 @@ module EBR_CORE (...); output TWOERR; endmodule -module EBR (...); +module EBR(DIA, DIB, ADA, ADB, CLKA, CLKB, WEA, WEB, CEA, CEB, RSTA, RSTB, CSA, CSB, FULLF, AFULL, EMPTYF, AEMPTY, DOA, DOB, ONEERR +, TWOERR); parameter INIT_DATA = "STATIC"; parameter DATA_WIDTH_A = "X36"; parameter DATA_WIDTH_B = "X36"; @@ -1461,7 +1490,7 @@ module EBR (...); output TWOERR; endmodule -module ECLKDIV (...); +module ECLKDIV(DIVOUT, DIVRST, ECLKIN, SLIP); parameter ECLK_DIV = "DISABLE"; parameter GSR = "ENABLED"; output DIVOUT; @@ -1470,14 +1499,14 @@ module ECLKDIV (...); input SLIP; endmodule -module ECLKSYNC (...); +module ECLKSYNC(ECLKIN, ECLKOUT, STOP); parameter STOP_EN = "DISABLE"; input ECLKIN; output ECLKOUT; input STOP; endmodule -module FBMUX (...); +module FBMUX(ENEXT, FBKCK, LGYRDYN, INTLOCK, WKUPSYNC, FBKCLK); parameter INTFB = "IGNORED"; parameter SEL_FBK = "DIVA"; parameter CLKMUX_FB = "CMUX_CLKOP"; @@ -1490,7 +1519,11 @@ module FBMUX (...); input [15:0] FBKCLK; endmodule -module FIFO16K_MODE (...); +module FIFO16K_MODE(DIA0, DIA1, DIA2, DIA3, DIA4, DIA5, DIA6, DIA7, DIA8, DIA9, DIA10, DIA11, DIA12, DIA13, DIA14, DIA15, DIA16, DIA17, DIB0, DIB1, DIB2 +, DIB3, DIB4, DIB5, DIB6, DIB7, DIB8, DIB9, DIB10, DIB11, DIB12, DIB13, DIB14, DIB15, DIB16, DIB17, CKA, CKB, CEA, CEB, CSA0, CSA1 +, CSA2, CSB0, CSB1, CSB2, RSTA, RSTB, DOA0, DOA1, DOA2, DOA3, DOA4, DOA5, DOA6, DOA7, DOA8, DOA9, DOA10, DOA11, DOA12, DOA13, DOA14 +, DOA15, DOA16, DOA17, DOB0, DOB1, DOB2, DOB3, DOB4, DOB5, DOB6, DOB7, DOB8, DOB9, DOB10, DOB11, DOB12, DOB13, DOB14, DOB15, DOB16, DOB17 +, ALMOSTFULL, FULL, ALMOSTEMPTY, EMPTY, ONEBITERR, TWOBITERR); parameter DATA_WIDTH_A = "X18"; parameter DATA_WIDTH_B = "X18"; parameter OUTREG_A = "BYPASSED"; @@ -1596,7 +1629,7 @@ module FIFO16K_MODE (...); output TWOBITERR; endmodule -module FIFO16K (...); +module FIFO16K(DIA, DIB, CKA, CKB, CEA, CEB, CSA, CSB, RSTA, RSTB, DOA, DOB, ALMOSTFULL, FULL, ALMOSTEMPTY, EMPTY, ONEBITERR, TWOBITERR); parameter DATA_WIDTH_A = "X18"; parameter DATA_WIDTH_B = "X18"; parameter OUTREG_A = "BYPASSED"; @@ -1630,7 +1663,7 @@ module FIFO16K (...); output TWOBITERR; endmodule -module HSE (...); +module HSE(LMMICLK, LMMIRESET_N, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIRDATAVALID, LMMIREADY, ASFCLKI, ASFEMPTYO, ASFFULLO, ASFRDI, ASFRESETI, ASFWRI, CFG_CLK, HSE_CLK, HSELRSTN); parameter MCGLBGSRNDIS = "EN"; parameter MCHSEDISABLE = "EN"; parameter MCHSEOTPEN = "DIS"; @@ -1654,7 +1687,8 @@ module HSE (...); input HSELRSTN; endmodule -module I2CFIFO (...); +module I2CFIFO(LMMICLK, LMMIRESET_N, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIRDATAVALID, LMMIREADY, ALTSCLIN, ALTSCLOEN, ALTSCLOUT, ALTSDAIN, ALTSDAOEN, ALTSDAOUT, BUSBUSY, FIFORESET, I2CLSRRSTN, INSLEEP, IRQ, MRDCMPL +, RXFIFOAF, RXFIFOE, RXFIFOF, SCLIN, SCLOE, SCLOEN, SCLOUT, SDAIN, SDAOE, SDAOEN, SDAOUT, SLVADDRMATCH, SLVADDRMATCHSCL, SRDWR, TXFIFOAE, TXFIFOE, TXFIFOF); parameter BRNBASEDELAY = "0b0000"; parameter CR1CKDIS = "EN"; parameter CR1FIFOMODE = "REG"; @@ -1733,7 +1767,7 @@ module I2CFIFO (...); output TXFIFOF; endmodule -module IDDR71 (...); +module IDDR71(D, SCLK, RST, ECLK, ALIGNWD, Q0, Q1, Q2, Q3, Q4, Q5, Q6); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1749,7 +1783,7 @@ module IDDR71 (...); output Q6; endmodule -module IDDRX1 (...); +module IDDRX1(D, SCLK, RST, Q0, Q1); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1758,7 +1792,7 @@ module IDDRX1 (...); output Q1; endmodule -module IDDRX2DQ (...); +module IDDRX2DQ(D, DQSR90, ECLK, SCLK, RST, RDPNTR0, RDPNTR1, RDPNTR2, WRPNTR0, WRPNTR1, WRPNTR2, Q0, Q1, Q2, Q3); parameter GSR = "ENABLED"; input D; input DQSR90; @@ -1777,7 +1811,7 @@ module IDDRX2DQ (...); output Q3; endmodule -module IDDRX2 (...); +module IDDRX2(D, SCLK, RST, ECLK, ALIGNWD, Q0, Q1, Q2, Q3); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1790,7 +1824,7 @@ module IDDRX2 (...); output Q3; endmodule -module IDDRX4DQ (...); +module IDDRX4DQ(D, DQSR90, ECLK, SCLK, RST, RDPNTR0, RDPNTR1, RDPNTR2, WRPNTR0, WRPNTR1, WRPNTR2, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7); parameter GSR = "ENABLED"; input D; input DQSR90; @@ -1813,7 +1847,7 @@ module IDDRX4DQ (...); output Q7; endmodule -module IDDRX4 (...); +module IDDRX4(D, SCLK, RST, ECLK, ALIGNWD, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1830,7 +1864,7 @@ module IDDRX4 (...); output Q7; endmodule -module IDDRX5 (...); +module IDDRX5(D, SCLK, RST, ECLK, ALIGNWD, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9); parameter GSR = "ENABLED"; input D; input SCLK; @@ -1849,7 +1883,7 @@ module IDDRX5 (...); output Q9; endmodule -module IFD1P3BX (...); +module IFD1P3BX(D, SP, CK, PD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -1858,7 +1892,7 @@ module IFD1P3BX (...); output Q; endmodule -module IFD1P3DX (...); +module IFD1P3DX(D, SP, CK, CD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -1867,7 +1901,7 @@ module IFD1P3DX (...); output Q; endmodule -module IFD1P3IX (...); +module IFD1P3IX(D, SP, CK, CD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -1876,7 +1910,7 @@ module IFD1P3IX (...); output Q; endmodule -module IFD1P3JX (...); +module IFD1P3JX(D, SP, CK, PD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -1886,7 +1920,7 @@ module IFD1P3JX (...); endmodule (* keep *) -module JTAG (...); +module JTAG(JCE1, JCE2, JRSTN, JRTI1, JRTI2, JSHIFT, JTDI, JUPDATE, JTDO1, JTDO2, SMCLK, TCK, JTCK, TDI, TDO_OEN, TDO, TMS); parameter MCER1EXIST = "NEXIST"; parameter MCER2EXIST = "NEXIST"; output JCE1; @@ -1908,7 +1942,8 @@ module JTAG (...); input TMS; endmodule -module LRAM (...); +module LRAM(ADA, ADB, BENA_N, BENB_N, CEA, CEB, CLK, CSA, CSB, DIA, DIB, DOA, DOB, DPS, ERRDECA, ERRDECB, OCEA, OCEB, OEA, OEB, RSTA +, RSTB, WEA, WEB, ERRDET, LRAMREADY); parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; @@ -2077,7 +2112,7 @@ module LRAM (...); output LRAMREADY; endmodule -module M18X36 (...); +module M18X36(SFTCTRL, PH36, PL36, SGNED18H, SGNED18L, P72, ROUNDEN); parameter SFTEN = "DISABLED"; parameter MULT18X36 = "ENABLED"; parameter MULT36 = "DISABLED"; @@ -2094,7 +2129,7 @@ module M18X36 (...); input ROUNDEN; endmodule -module MULT18 (...); +module MULT18(SFTCTRL, ARHSIGN, BRHSIGN, ARH, BRH, ARL, BRL, PL18, PH18, SIGNED18, P36, ROUNDEN); parameter SFTEN = "DISABLED"; parameter MULT18X18 = "ENABLED"; parameter ROUNDHALFUP = "DISABLED"; @@ -2114,7 +2149,7 @@ module MULT18 (...); input ROUNDEN; endmodule -module MULT36 (...); +module MULT36(PH72, PL72, PML72, PMH72); parameter MULT36X36 = "ENABLED"; input [72:0] PH72; input [72:0] PL72; @@ -2122,7 +2157,7 @@ module MULT36 (...); output [71:0] PMH72; endmodule -module MULT9 (...); +module MULT9(A, ASIGNED, BR, AS1, AS2, ASSIGNED1, ASSIGNED2, BRSIGNED, CLK, CEA, RSTA, AO, BO, AOSIGNED, BOSIGNED, AR, ARSIGNED, P18, CEP, RSTP); parameter SIGNEDSTATIC_EN = "DISABLED"; parameter ASIGNED_OPERAND_EN = "DISABLED"; parameter BYPASS_MULT9 = "USED"; @@ -2155,7 +2190,8 @@ module MULT9 (...); input RSTP; endmodule -module MULTADDSUB18X18WIDE (...); +module MULTADDSUB18X18WIDE(A0, B0, A1, B1, C, CLK, CEA0, CEA1, RSTA0, RSTA1, CEB0, CEB1, RSTB0, RSTB1, CEC, RSTC, RSTCTRL, CECTRL, SIGNED, RSTPIPE, CEPIPE +, Z, RSTOUT, CEOUT, LOADC, ADDSUB); parameter REGINPUTAB0 = "REGISTER"; parameter REGINPUTAB1 = "REGISTER"; parameter REGINPUTC = "REGISTER"; @@ -2194,7 +2230,8 @@ module MULTADDSUB18X18WIDE (...); input [1:0] ADDSUB; endmodule -module MULTADDSUB9X9WIDE (...); +module MULTADDSUB9X9WIDE(A0, B0, A1, B1, A2, B2, A3, B3, C, CLK, CEA0A1, CEA2A3, RSTA0A1, RSTA2A3, CEB0B1, CEB2B3, RSTB0B1, RSTB2B3, CEC, RSTC, RSTCTRL +, CECTRL, SIGNED, RSTPIPE, CEPIPE, RSTOUT, CEOUT, LOADC, ADDSUB, Z); parameter REGINPUTAB0 = "REGISTER"; parameter REGINPUTAB1 = "REGISTER"; parameter REGINPUTAB2 = "REGISTER"; @@ -2240,14 +2277,14 @@ module MULTADDSUB9X9WIDE (...); endmodule (* keep *) -module MULTIBOOT (...); +module MULTIBOOT(AUTOREBOOT, MSPIMADDR); parameter MSPIADDR = "0b00000000000000000000000000000000"; parameter SOURCESEL = "DIS"; input AUTOREBOOT; input [31:0] MSPIMADDR; endmodule -module ODDR71 (...); +module ODDR71(D0, D1, D2, D3, D4, D5, D6, SCLK, RST, ECLK, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2262,7 +2299,7 @@ module ODDR71 (...); output Q; endmodule -module ODDRX1 (...); +module ODDRX1(D0, D1, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2271,7 +2308,7 @@ module ODDRX1 (...); output Q; endmodule -module ODDRX2DQS (...); +module ODDRX2DQS(D0, D1, D2, D3, DQSW, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2284,7 +2321,7 @@ module ODDRX2DQS (...); output Q; endmodule -module ODDRX2DQ (...); +module ODDRX2DQ(D0, D1, D2, D3, DQSW270, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2297,7 +2334,7 @@ module ODDRX2DQ (...); output Q; endmodule -module ODDRX2 (...); +module ODDRX2(D0, D1, D2, D3, SCLK, RST, ECLK, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2309,7 +2346,7 @@ module ODDRX2 (...); output Q; endmodule -module ODDRX4DQS (...); +module ODDRX4DQS(D0, D1, D2, D3, D4, D5, D6, D7, DQSW, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2326,7 +2363,7 @@ module ODDRX4DQS (...); output Q; endmodule -module ODDRX4DQ (...); +module ODDRX4DQ(D0, D1, D2, D3, D4, D5, D6, D7, DQSW270, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2343,7 +2380,7 @@ module ODDRX4DQ (...); output Q; endmodule -module ODDRX4 (...); +module ODDRX4(D0, D1, D2, D3, D4, D5, D6, D7, SCLK, RST, ECLK, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2359,7 +2396,7 @@ module ODDRX4 (...); output Q; endmodule -module ODDRX5 (...); +module ODDRX5(D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, SCLK, RST, ECLK, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2377,7 +2414,7 @@ module ODDRX5 (...); output Q; endmodule -module OFD1P3BX (...); +module OFD1P3BX(D, SP, CK, PD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -2386,7 +2423,7 @@ module OFD1P3BX (...); output Q; endmodule -module OFD1P3DX (...); +module OFD1P3DX(D, SP, CK, CD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -2395,7 +2432,7 @@ module OFD1P3DX (...); output Q; endmodule -module OFD1P3IX (...); +module OFD1P3IX(D, SP, CK, CD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -2404,7 +2441,7 @@ module OFD1P3IX (...); output Q; endmodule -module OFD1P3JX (...); +module OFD1P3JX(D, SP, CK, PD, Q); parameter GSR = "ENABLED"; input D; input SP; @@ -2413,7 +2450,7 @@ module OFD1P3JX (...); output Q; endmodule -module OSHX2 (...); +module OSHX2(D0, D1, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2423,7 +2460,7 @@ module OSHX2 (...); output Q; endmodule -module OSHX4 (...); +module OSHX4(D0, D1, D2, D3, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input D0; input D1; @@ -2435,7 +2472,11 @@ module OSHX4 (...); output Q; endmodule -module PCIE (...); +module PCIE(LMMICLK, LMMIRESET_N, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIRDATAVALID, LMMIREADY, ACJNOUT, ACJPOUT, AUXCK, CKUSRI, CKUSRO, ECKIN, ECKIND2, ECKINDO, ERSTN, ERSTND2, ERXCKD2, ERXCKDO +, ERXRSND2, ETXCKD2, ETXCKDO, ETXRSND2, FLR, FLRACK, MINTLEG, MINTO, PERSTN, PMCTRL, PMCTRLEN, PMDPAST, PRMSGSD, PRNOSNP, PRNSNPRE, PRSNOOP, PRSNPRE, PPBDREG, PPBDSEL, REXTCK, REXTRST +, RSTUSRN, UDLLKUP, ULTSDIS, UPLLKUP, UTLLKUP, UCFGADDR, UCFGF, UCFGRDD, UCFGRDE, UCFGRDY, UCFGSERD, UCFGVD, UCFGWRBE, UCFGWRD, UCFGWRDN, USERAUPD, USERTRS, VRXCMDD, VRXCINIT, VRXCNH, VRXCNINF +, VRXCRRE, VRXD, VRXDP, VRXEOP, VRXERR, VRXF, VRXRDY, VRXSEL, VRXSOP, VRXVD, VXCDINIT, VXCDNH, VTXCRRE, VXD, VXDP, VXEOP, VXEOPN, VXRDY, VXSOP, VXVD, TESTOUT +, S0REFCKN, S0REFCKP, S0REFRET, S0REXT, S0RXN, S0RXP, S0TXN, S0TXP, CLKREQI, CLKREQO, CLKREQOE); parameter ENABLE_USER_CFG = "DISABLED"; parameter PWDN_N = "DISABLED"; parameter GSR = "ENABLED"; @@ -3595,7 +3636,12 @@ module PCIE (...); output CLKREQOE; endmodule -module PDP16K_MODE (...); +module PDP16K_MODE(DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, DI18, DI19, DI20 +, DI21, DI22, DI23, DI24, DI25, DI26, DI27, DI28, DI29, DI30, DI31, DI32, DI33, DI34, DI35, ADW0, ADW1, ADW2, ADW3, ADW4, ADW5 +, ADW6, ADW7, ADW8, ADW9, ADW10, ADW11, ADW12, ADW13, ADR0, ADR1, ADR2, ADR3, ADR4, ADR5, ADR6, ADR7, ADR8, ADR9, ADR10, ADR11, ADR12 +, ADR13, CLKW, CLKR, CEW, CER, CSW0, CSW1, CSW2, CSR0, CSR1, CSR2, RST, DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8 +, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, DO18, DO19, DO20, DO21, DO22, DO23, DO24, DO25, DO26, DO27, DO28, DO29 +, DO30, DO31, DO32, DO33, DO34, DO35, ONEBITERR, TWOBITERR); parameter DATA_WIDTH_W = "X36"; parameter DATA_WIDTH_R = "X36"; parameter OUTREG = "BYPASSED"; @@ -3785,7 +3831,7 @@ module PDP16K_MODE (...); output TWOBITERR; endmodule -module PDP16K (...); +module PDP16K(DI, ADW, ADR, CLKW, CLKR, CEW, CER, CSW, CSR, RST, DO, ONEBITERR, TWOBITERR); parameter DATA_WIDTH_W = "X36"; parameter DATA_WIDTH_R = "X36"; parameter OUTREG = "BYPASSED"; @@ -3875,7 +3921,12 @@ module PDP16K (...); output TWOBITERR; endmodule -module PDPSC16K_MODE (...); +module PDPSC16K_MODE(DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, DI18, DI19, DI20 +, DI21, DI22, DI23, DI24, DI25, DI26, DI27, DI28, DI29, DI30, DI31, DI32, DI33, DI34, DI35, ADW0, ADW1, ADW2, ADW3, ADW4, ADW5 +, ADW6, ADW7, ADW8, ADW9, ADW10, ADW11, ADW12, ADW13, ADR0, ADR1, ADR2, ADR3, ADR4, ADR5, ADR6, ADR7, ADR8, ADR9, ADR10, ADR11, ADR12 +, ADR13, CLK, CER, CEW, CSW0, CSW1, CSW2, CSR0, CSR1, CSR2, RST, DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9 +, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, DO18, DO19, DO20, DO21, DO22, DO23, DO24, DO25, DO26, DO27, DO28, DO29, DO30 +, DO31, DO32, DO33, DO34, DO35, ONEBITERR, TWOBITERR); parameter DATA_WIDTH_W = "X36"; parameter DATA_WIDTH_R = "X36"; parameter OUTREG = "BYPASSED"; @@ -4064,7 +4115,7 @@ module PDPSC16K_MODE (...); output TWOBITERR; endmodule -module PDPSC16K (...); +module PDPSC16K(DI, ADW, ADR, CLK, CER, CEW, CSW, CSR, RST, DO, ONEBITERR, TWOBITERR); parameter DATA_WIDTH_W = "X36"; parameter DATA_WIDTH_R = "X36"; parameter OUTREG = "BYPASSED"; @@ -4153,7 +4204,7 @@ module PDPSC16K (...); output TWOBITERR; endmodule -module PDPSC512K (...); +module PDPSC512K(DI, ADW, ADR, CLK, CEW, CER, WE, CSW, CSR, RSTR, BYTEEN_N, DO, ERRDECA, ERRDECB); parameter OUTREG = "NO_REG"; parameter GSR = "ENABLED"; parameter RESETMODE = "SYNC"; @@ -4303,7 +4354,9 @@ module PDPSC512K (...); output [1:0] ERRDECB; endmodule -module PLL (...); +module PLL(INTFBKOP, INTFBKOS, INTFBKOS2, INTFBKOS3, INTFBKOS4, INTFBKOS5, DIR, DIRSEL, LOADREG, DYNROTATE, LMMICLK, LMMIRESET_N, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIRDATAVALID, LMMIREADY, PLLPOWERDOWN_N, REFCK +, CLKOP, CLKOS, CLKOS2, CLKOS3, CLKOS4, CLKOS5, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, ENCLKOS4, ENCLKOS5, FBKCK, INTLOCK, LEGACY, LEGRDYN, LOCK, PFDDN, PFDUP, PLLRESET, STDBY +, REFMUXCK, REGQA, REGQB, REGQB1, CLKOUTDL, ROTDEL, DIRDEL, ROTDELP1, GRAYTEST, BINTEST, DIRDELP1, GRAYACT, BINACT); parameter BW_CTL_BIAS = "0b0101"; parameter CLKOP_TRIM = "0b0000"; parameter CLKOS_TRIM = "0b0000"; @@ -4478,7 +4531,8 @@ module PLL (...); input [1:0] BINACT; endmodule -module PREADD9 (...); +module PREADD9(B, BSIGNED, C, BRS1, BRS2, BLS1, BLS2, BRSS1, BRSS2, BLSS1, BLSS2, PRCASIN, CLK, RSTB, CEB, RSTCL, CECL, BRSO, BLSO, BRSOSGND, BLSOSGND +, PRCASOUT, BR, BRSIGNED); parameter SIGNEDSTATIC_EN = "DISABLED"; parameter SUBSTRACT_EN = "SUBTRACTION"; parameter CSIGNED = "DISABLED"; @@ -4520,7 +4574,7 @@ module PREADD9 (...); output BRSIGNED; endmodule -module REFMUX (...); +module REFMUX(REFCK, ZRSEL3, REFSEL, REFCLK1, REFCLK2); parameter REFSEL_ATT = "MC1"; parameter SEL1 = "SELECT_REFCLK1"; parameter SEL_REF2 = "REFCLK2_0"; @@ -4532,7 +4586,7 @@ module REFMUX (...); input [7:0] REFCLK2; endmodule -module REG18 (...); +module REG18(PM, PP, CEP, RSTP, CLK); parameter REGBYPS = "REGISTER"; parameter GSR = "ENABLED"; parameter RESET = "SYNC"; @@ -4544,7 +4598,7 @@ module REG18 (...); endmodule (* keep *) -module SEDC (...); +module SEDC(SEDENABLE, SEDCCOF, SEDCENABLE, SEDCMODE, SEDCSTART, SEDCBUSY, SEDCERR, SEDCERRC, SEDCERRCRC, SEDCERRM, SEDCFRMERRLOC, OSCCLKSEDC, RSTSEDC, SEDCDSRERRLOCCIB); parameter SEDCEN = "DIS"; input SEDENABLE; input SEDCCOF; @@ -4562,7 +4616,7 @@ module SEDC (...); output [12:0] SEDCDSRERRLOCCIB; endmodule -module SEIO18 (...); +module SEIO18(PADDO, DOLP, IOPAD, PADDI, INLP, PADDT, INADC); parameter PULLMODE = "DOWN"; parameter MIPI = "DISABLED"; parameter ENADC_IN = "DISABLED"; @@ -4576,7 +4630,7 @@ module SEIO18 (...); output INADC; endmodule -module SEIO33 (...); +module SEIO33(IOPAD, PADDI, PADDO, PADDT, I3CRESEN, I3CWKPU); parameter PULLMODE = "DOWN"; (* iopad_external_pin *) inout IOPAD; @@ -4587,7 +4641,7 @@ module SEIO33 (...); input I3CWKPU; endmodule -module SGMIICDR (...); +module SGMIICDR(LMMICLK, LMMIRESET_N, LMMIREQUEST, LMMIWRRD_N, LMMIOFFSET, LMMIWDATA, LMMIRDATA, LMMIRDATAVALID, LMMIREADY, DCALIRST, DFACQRST, RRST, SPCLK, SRCLK, SRXD, RSTBFBW, RSTBRXF, SGMIIIN, SREFCLK, CDRLOL); parameter GSR = "ENABLED"; parameter DCOITUNE4LSB = "0_PERCENT"; parameter DCOCTLGI = "0_PERCENT"; @@ -4644,7 +4698,9 @@ module SGMIICDR (...); output CDRLOL; endmodule -module SP16K_MODE (...); +module SP16K_MODE(DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, AD0, AD1, AD2 +, AD3, AD4, AD5, AD6, AD7, AD8, AD9, AD10, AD11, AD12, AD13, CLK, CE, WE, CS0, CS1, CS2, RST, DO0, DO1, DO2 +, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17); parameter DATA_WIDTH = "X18"; parameter OUTREG = "BYPASSED"; parameter RESETMODE = "SYNC"; @@ -4775,7 +4831,7 @@ module SP16K_MODE (...); output DO17; endmodule -module SP16K (...); +module SP16K(DI, AD, CLK, CE, WE, CS, RST, DO); parameter DATA_WIDTH = "X18"; parameter OUTREG = "BYPASSED"; parameter RESETMODE = "SYNC"; @@ -4857,7 +4913,7 @@ module SP16K (...); output [17:0] DO; endmodule -module SP512K (...); +module SP512K(DI, AD, CLK, CE, WE, CS, RSTOUT, CEOUT, BYTEEN_N, DO, ERRDECA, ERRDECB); parameter OUTREG = "NO_REG"; parameter GSR = "ENABLED"; parameter RESETMODE = "SYNC"; @@ -5005,7 +5061,7 @@ module SP512K (...); output [1:0] ERRDECB; endmodule -module TSHX2DQS (...); +module TSHX2DQS(T0, T1, DQSW, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input T0; input T1; @@ -5016,7 +5072,7 @@ module TSHX2DQS (...); output Q; endmodule -module TSHX2DQ (...); +module TSHX2DQ(T0, T1, DQSW270, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input T0; input T1; @@ -5027,7 +5083,7 @@ module TSHX2DQ (...); output Q; endmodule -module TSHX4DQS (...); +module TSHX4DQS(T0, T1, T2, T3, DQSW, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input T0; input T1; @@ -5040,7 +5096,7 @@ module TSHX4DQS (...); output Q; endmodule -module TSHX4DQ (...); +module TSHX4DQ(T0, T1, T2, T3, DQSW270, ECLK, SCLK, RST, Q); parameter GSR = "ENABLED"; input T0; input T1; @@ -5054,7 +5110,7 @@ module TSHX4DQ (...); endmodule (* keep *) -module WDT (...); +module WDT(WDTRELOAD, WDT_CLK, WDT_RST); parameter WDTEN = "DIS"; parameter WDTMODE = "SINGLE"; parameter WDTVALUE = "0b000000000000000000"; @@ -5063,7 +5119,7 @@ module WDT (...); input WDT_RST; endmodule -module MIPI (...); +module MIPI(BP, BN, AP, AN, TP, TN, IHS, HSRXEN, HSTXEN, OHS, OLSP, OLSN); parameter MIPI_ID = "0"; (* iopad_external_pin *) inout BP; @@ -5082,7 +5138,8 @@ module MIPI (...); endmodule (* keep *) -module CONFIG_IP_CORE (...); +module CONFIG_IP_CORE(CFGDONECIB, CIBTSALL, FREEZEIOCIB, LASTADDRCIB15, LASTADDRCIB14, LASTADDRCIB13, LASTADDRCIB12, LASTADDRCIB11, LASTADDRCIB10, LASTADDRCIB9, LASTADDRCIB8, LASTADDRCIB7, LASTADDRCIB6, LASTADDRCIB5, LASTADDRCIB4, LASTADDRCIB3, LASTADDRCIB2, LASTADDRCIB1, LASTADDRCIB0, MBISTENABLEN, MBISTRRMATCH +, MBISTTRRAEN); parameter DONEPHASE = "DIS"; parameter DSRFCTRL = "0b00"; parameter ENTSALL = "DIS"; @@ -5135,11 +5192,11 @@ module CONFIG_IP_CORE (...); input MBISTTRRAEN; endmodule -module TSALLA (...); +module TSALLA(TSALL); input TSALL; endmodule -module OSCA (...); +module OSCA(HFOUTEN, HFSDSCEN, HFCLKOUT, LFCLKOUT, HFCLKCFG, HFSDCOUT); parameter HF_CLK_DIV = "1"; parameter HF_SED_SEC_DIV = "1"; parameter HF_OSC_EN = "ENABLED"; @@ -5152,7 +5209,7 @@ module OSCA (...); output HFSDCOUT; endmodule -module OSC (...); +module OSC(HFCLKOUT, HFSDSCEN, LFCLKOUT, HFSDCOUT, HSE_CLK, JTAG_LRST_N, LMMI_CLK, LMMI_CLK_O, LMMI_LRST_N, LMMI_RST, SEDC_CLK, SEDC_LRST_N, SEDC_RST, CFG_CLK, SMCLK_RST, WDT_CLK, WDT_LRST_N, WDT_RST); parameter DTR_EN = "ENABLED"; parameter HF_CLK_DIV = "1"; parameter HF_SED_SEC_DIV = "1"; @@ -5187,7 +5244,22 @@ module OSC (...); output WDT_RST; endmodule -module ACC54_CORE (...); +module ACC54_CORE(SFTCTRL3, SFTCTRL2, SFTCTRL1, SFTCTRL0, DSPIN53, DSPIN52, DSPIN51, DSPIN50, DSPIN49, DSPIN48, DSPIN47, DSPIN46, DSPIN45, DSPIN44, DSPIN43, DSPIN42, DSPIN41, DSPIN40, DSPIN39, DSPIN38, DSPIN37 +, DSPIN36, DSPIN35, DSPIN34, DSPIN33, DSPIN32, DSPIN31, DSPIN30, DSPIN29, DSPIN28, DSPIN27, DSPIN26, DSPIN25, DSPIN24, DSPIN23, DSPIN22, DSPIN21, DSPIN20, DSPIN19, DSPIN18, DSPIN17, DSPIN16 +, DSPIN15, DSPIN14, DSPIN13, DSPIN12, DSPIN11, DSPIN10, DSPIN9, DSPIN8, DSPIN7, DSPIN6, DSPIN5, DSPIN4, DSPIN3, DSPIN2, DSPIN1, DSPIN0, PP71, PP70, PP69, PP68, PP67 +, PP66, PP65, PP64, PP63, PP62, PP61, PP60, PP59, PP58, PP57, PP56, PP55, PP54, PP53, PP52, PP51, PP50, PP49, PP48, PP47, PP46 +, PP45, PP44, PP43, PP42, PP41, PP40, PP39, PP38, PP37, PP36, PP35, PP34, PP33, PP32, PP31, PP30, PP29, PP28, PP27, PP26, PP25 +, PP24, PP23, PP22, PP21, PP20, PP19, PP18, PP17, PP16, PP15, PP14, PP13, PP12, PP11, PP10, PP9, PP8, PP7, PP6, PP5, PP4 +, PP3, PP2, PP1, PP0, CINPUT53, CINPUT52, CINPUT51, CINPUT50, CINPUT49, CINPUT48, CINPUT47, CINPUT46, CINPUT45, CINPUT44, CINPUT43, CINPUT42, CINPUT41, CINPUT40, CINPUT39, CINPUT38, CINPUT37 +, CINPUT36, CINPUT35, CINPUT34, CINPUT33, CINPUT32, CINPUT31, CINPUT30, CINPUT29, CINPUT28, CINPUT27, CINPUT26, CINPUT25, CINPUT24, CINPUT23, CINPUT22, CINPUT21, CINPUT20, CINPUT19, CINPUT18, CINPUT17, CINPUT16 +, CINPUT15, CINPUT14, CINPUT13, CINPUT12, CINPUT11, CINPUT10, CINPUT9, CINPUT8, CINPUT7, CINPUT6, CINPUT5, CINPUT4, CINPUT3, CINPUT2, CINPUT1, CINPUT0, LOAD, M9ADDSUB1, M9ADDSUB0, ADDSUB1, ADDSUB0 +, CIN, CASIN1, CASIN0, CEO, RSTO, CEC, RSTC, CLK, SIGNEDI, SUM135, SUM134, SUM133, SUM132, SUM131, SUM130, SUM129, SUM128, SUM127, SUM126, SUM125, SUM124 +, SUM123, SUM122, SUM121, SUM120, SUM119, SUM118, SUM117, SUM116, SUM115, SUM114, SUM113, SUM112, SUM111, SUM110, SUM19, SUM18, SUM17, SUM16, SUM15, SUM14, SUM13 +, SUM12, SUM11, SUM10, SUM035, SUM034, SUM033, SUM032, SUM031, SUM030, SUM029, SUM028, SUM027, SUM026, SUM025, SUM024, SUM023, SUM022, SUM021, SUM020, SUM019, SUM018 +, SUM017, SUM016, SUM015, SUM014, SUM013, SUM012, SUM011, SUM010, SUM09, SUM08, SUM07, SUM06, SUM05, SUM04, SUM03, SUM02, SUM01, SUM00, DSPOUT53, DSPOUT52, DSPOUT51 +, DSPOUT50, DSPOUT49, DSPOUT48, DSPOUT47, DSPOUT46, DSPOUT45, DSPOUT44, DSPOUT43, DSPOUT42, DSPOUT41, DSPOUT40, DSPOUT39, DSPOUT38, DSPOUT37, DSPOUT36, DSPOUT35, DSPOUT34, DSPOUT33, DSPOUT32, DSPOUT31, DSPOUT30 +, DSPOUT29, DSPOUT28, DSPOUT27, DSPOUT26, DSPOUT25, DSPOUT24, DSPOUT23, DSPOUT22, DSPOUT21, DSPOUT20, DSPOUT19, DSPOUT18, DSPOUT17, DSPOUT16, DSPOUT15, DSPOUT14, DSPOUT13, DSPOUT12, DSPOUT11, DSPOUT10, DSPOUT9 +, DSPOUT8, DSPOUT7, DSPOUT6, DSPOUT5, DSPOUT4, DSPOUT3, DSPOUT2, DSPOUT1, DSPOUT0, CASCOUT1, CASCOUT0, ROUNDEN, CECIN, CECTRL, RSTCIN, RSTCTRL); parameter SIGN = "DISABLED"; parameter M9ADDSUB_CTRL = "ADDITION"; parameter ADDSUB_CTRL = "ADD_ADD_CTRL_54_BIT_ADDER"; @@ -5554,7 +5626,11 @@ module ACC54_CORE (...); input RSTCTRL; endmodule -module ADC_CORE (...); +module ADC_CORE(ADCEN, CAL, CALRDY, CHAEN, CHASEL3, CHASEL2, CHASEL1, CHASEL0, CHBEN, CHBSEL3, CHBSEL2, CHBSEL1, CHBSEL0, CLKDCLK, CLKFAB, COG, COMP1IN, COMP1IP, COMP1OL, COMP2IN, COMP2IP +, COMP2OL, COMP3IN, COMP3IP, COMP3OL, CONVSTOP, DA11, DA10, DA9, DA8, DA7, DA6, DA5, DA4, DA3, DA2, DA1, DA0, DB11, DB10, DB9, DB8 +, DB7, DB6, DB5, DB4, DB3, DB2, DB1, DB0, DN1, DN0, DP1, DP0, EOC, GPION15, GPION14, GPION13, GPION12, GPION11, GPION10, GPION9, GPION8 +, GPION7, GPION6, GPION5, GPION4, GPION3, GPION2, GPION1, GPION0, GPIOP15, GPIOP14, GPIOP13, GPIOP12, GPIOP11, GPIOP10, GPIOP9, GPIOP8, GPIOP7, GPIOP6, GPIOP5, GPIOP4, GPIOP3 +, GPIOP2, GPIOP1, GPIOP0, RESETN, RSTN, RSVDH, RSVDL, SOC, COMP1O, COMP2O, COMP3O); parameter ADC_ENP = "ENABLED"; parameter CLK_DIV = "2"; parameter CTLCOMPSW1 = "DISABLED"; @@ -5674,7 +5750,18 @@ module ADC_CORE (...); output COMP3O; endmodule -module ALUREG_CORE (...); +module ALUREG_CORE(OPCGLOADCLK, ALUCLK, ALUFLAGC, ALUFLAGV, ALUFLAGZ, ALUFORWARDA, ALUFORWARDB, ALUIREGEN, ALUOREGEN, ALURST, DATAA31, DATAA30, DATAA29, DATAA28, DATAA27, DATAA26, DATAA25, DATAA24, DATAA23, DATAA22, DATAA21 +, DATAA20, DATAA19, DATAA18, DATAA17, DATAA16, DATAA15, DATAA14, DATAA13, DATAA12, DATAA11, DATAA10, DATAA9, DATAA8, DATAA7, DATAA6, DATAA5, DATAA4, DATAA3, DATAA2, DATAA1, DATAA0 +, DATAB31, DATAB30, DATAB29, DATAB28, DATAB27, DATAB26, DATAB25, DATAB24, DATAB23, DATAB22, DATAB21, DATAB20, DATAB19, DATAB18, DATAB17, DATAB16, DATAB15, DATAB14, DATAB13, DATAB12, DATAB11 +, DATAB10, DATAB9, DATAB8, DATAB7, DATAB6, DATAB5, DATAB4, DATAB3, DATAB2, DATAB1, DATAB0, DATAC4, DATAC3, DATAC2, DATAC1, DATAC0, OPC6, OPC5, OPC4, OPC3, OPC2 +, OPC1, OPC0, OPCCUSTOM, RADDRA4, RADDRA3, RADDRA2, RADDRA1, RADDRA0, RADDRB4, RADDRB3, RADDRB2, RADDRB1, RADDRB0, RDATAA31, RDATAA30, RDATAA29, RDATAA28, RDATAA27, RDATAA26, RDATAA25, RDATAA24 +, RDATAA23, RDATAA22, RDATAA21, RDATAA20, RDATAA19, RDATAA18, RDATAA17, RDATAA16, RDATAA15, RDATAA14, RDATAA13, RDATAA12, RDATAA11, RDATAA10, RDATAA9, RDATAA8, RDATAA7, RDATAA6, RDATAA5, RDATAA4, RDATAA3 +, RDATAA2, RDATAA1, RDATAA0, RDATAB31, RDATAB30, RDATAB29, RDATAB28, RDATAB27, RDATAB26, RDATAB25, RDATAB24, RDATAB23, RDATAB22, RDATAB21, RDATAB20, RDATAB19, RDATAB18, RDATAB17, RDATAB16, RDATAB15, RDATAB14 +, RDATAB13, RDATAB12, RDATAB11, RDATAB10, RDATAB9, RDATAB8, RDATAB7, RDATAB6, RDATAB5, RDATAB4, RDATAB3, RDATAB2, RDATAB1, RDATAB0, REGCLK, REGCLKEN, REGRST, RESULT31, RESULT30, RESULT29, RESULT28 +, RESULT27, RESULT26, RESULT25, RESULT24, RESULT23, RESULT22, RESULT21, RESULT20, RESULT19, RESULT18, RESULT17, RESULT16, RESULT15, RESULT14, RESULT13, RESULT12, RESULT11, RESULT10, RESULT9, RESULT8, RESULT7 +, RESULT6, RESULT5, RESULT4, RESULT3, RESULT2, RESULT1, RESULT0, SCANCLK, SCANRST, WADDR4, WADDR3, WADDR2, WADDR1, WADDR0, WDROTATE1, WDROTATE0, WDSIGNEXT, WDSIZE1, WDSIZE0, WDATA31, WDATA30 +, WDATA29, WDATA28, WDATA27, WDATA26, WDATA25, WDATA24, WDATA23, WDATA22, WDATA21, WDATA20, WDATA19, WDATA18, WDATA17, WDATA16, WDATA15, WDATA14, WDATA13, WDATA12, WDATA11, WDATA10, WDATA9 +, WDATA8, WDATA7, WDATA6, WDATA5, WDATA4, WDATA3, WDATA2, WDATA1, WDATA0, WREN); parameter ALURST_ACTIVELOW = "DISABLE"; parameter GSR = "ENABLED"; parameter INREG = "DISABLE"; @@ -5929,7 +6016,8 @@ module ALUREG_CORE (...); input WREN; endmodule -module BNKREF18_CORE (...); +module BNKREF18_CORE(STDBYINR, STDBYDIF, PVTSNKI6, PVTSNKI5, PVTSNKI4, PVTSNKI3, PVTSNKI2, PVTSNKI1, PVTSNKI0, PVTSRCI6, PVTSRCI5, PVTSRCI4, PVTSRCI3, PVTSRCI2, PVTSRCI1, PVTSRCI0, PVTCODE6, PVTCODE5, PVTCODE4, PVTCODE3, PVTCODE2 +, PVTCODE1, PVTCODE0, PVTSEL); parameter BANK = "0b0000"; parameter STANDBY_DIFFIO = "DISABLED"; parameter STANDBY_INR = "DISABLED"; @@ -5959,7 +6047,8 @@ module BNKREF18_CORE (...); input PVTSEL; endmodule -module BNKREF33_CORE (...); +module BNKREF33_CORE(PVTSEL, PVTSNKI6, PVTSNKI5, PVTSNKI4, PVTSNKI3, PVTSNKI2, PVTSNKI1, PVTSNKI0, PVTSRCI6, PVTSRCI5, PVTSRCI4, PVTSRCI3, PVTSRCI2, PVTSRCI1, PVTSRCI0, PVTCODE6, PVTCODE5, PVTCODE4, PVTCODE3, PVTCODE2, PVTCODE1 +, PVTCODE0); parameter BANK = "0b0000"; input PVTSEL; input PVTSNKI6; @@ -5985,7 +6074,7 @@ module BNKREF33_CORE (...); output PVTCODE0; endmodule -module DIFFIO18_CORE (...); +module DIFFIO18_CORE(I, DOLP, B, O, INLP, T, INADC, HSRXEN, HSTXEN); parameter MIPI_ID = "0"; parameter PULLMODE = "DOWN"; parameter ENADC_IN = "DISABLED"; @@ -6003,7 +6092,7 @@ module DIFFIO18_CORE (...); endmodule (* keep *) -module CONFIG_CLKRST_CORE (...); +module CONFIG_CLKRST_CORE(HSE_CLK, JTAG_LRST_N, LMMI_CLK, LMMI_CLK_O, LMMI_LRST_N, LMMI_RST, OSCCLK, SEDC_CLK, SEDC_LRST_N, SEDC_RST, CFG_CLK, SMCLK_RST, WDT_CLK, WDT_LRST_N, WDT_RST); parameter MCJTAGGSRNDIS = "EN"; parameter MCLMMIGSRNDIS = "EN"; parameter MCSEDCGSRNDIS = "EN"; @@ -6027,7 +6116,11 @@ module CONFIG_CLKRST_CORE (...); endmodule (* keep *) -module CONFIG_HSE_CORE (...); +module CONFIG_HSE_CORE(ASFCLKI, ASFEMPTYO, ASFFULLO, ASFRDI, ASFRESETI, ASFWRI, CFG_CLK, HSE_CLK, HSELRSTN, LMMICLK, LMMIOFFSET17, LMMIOFFSET16, LMMIOFFSET15, LMMIOFFSET14, LMMIOFFSET13, LMMIOFFSET12, LMMIOFFSET11, LMMIOFFSET10, LMMIOFFSET9, LMMIOFFSET8, LMMIOFFSET7 +, LMMIOFFSET6, LMMIOFFSET5, LMMIOFFSET4, LMMIOFFSET3, LMMIOFFSET2, LMMIOFFSET1, LMMIOFFSET0, LMMIRDATA31, LMMIRDATA30, LMMIRDATA29, LMMIRDATA28, LMMIRDATA27, LMMIRDATA26, LMMIRDATA25, LMMIRDATA24, LMMIRDATA23, LMMIRDATA22, LMMIRDATA21, LMMIRDATA20, LMMIRDATA19, LMMIRDATA18 +, LMMIRDATA17, LMMIRDATA16, LMMIRDATA15, LMMIRDATA14, LMMIRDATA13, LMMIRDATA12, LMMIRDATA11, LMMIRDATA10, LMMIRDATA9, LMMIRDATA8, LMMIRDATA7, LMMIRDATA6, LMMIRDATA5, LMMIRDATA4, LMMIRDATA3, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIREQUEST +, LMMIRESETN, LMMIWDATA31, LMMIWDATA30, LMMIWDATA29, LMMIWDATA28, LMMIWDATA27, LMMIWDATA26, LMMIWDATA25, LMMIWDATA24, LMMIWDATA23, LMMIWDATA22, LMMIWDATA21, LMMIWDATA20, LMMIWDATA19, LMMIWDATA18, LMMIWDATA17, LMMIWDATA16, LMMIWDATA15, LMMIWDATA14, LMMIWDATA13, LMMIWDATA12 +, LMMIWDATA11, LMMIWDATA10, LMMIWDATA9, LMMIWDATA8, LMMIWDATA7, LMMIWDATA6, LMMIWDATA5, LMMIWDATA4, LMMIWDATA3, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIWRRDN, OTM); parameter MCGLBGSRNDIS = "EN"; parameter MCHSEDISABLE = "EN"; parameter MCHSEOTPEN = "DIS"; @@ -6132,7 +6225,7 @@ module CONFIG_HSE_CORE (...); endmodule (* keep *) -module CONFIG_JTAG_CORE (...); +module CONFIG_JTAG_CORE(JCE1, JCE2, JRSTN, JRTI1, JRTI2, JSHIFT, JTDI, JUPDATE, JTDO1, JTDO2, SMCLK, TCK, JTCK, TDI, TDO_OEN, TDO, TMS); parameter MCER1EXIST = "NEXIST"; parameter MCER2EXIST = "NEXIST"; output JCE1; @@ -6155,7 +6248,8 @@ module CONFIG_JTAG_CORE (...); endmodule (* keep *) -module CONFIG_LMMI_CORE (...); +module CONFIG_LMMI_CORE(LMMIOFFSET7, LMMIOFFSET6, LMMIOFFSET5, LMMIOFFSET4, LMMIOFFSET3, LMMIOFFSET2, LMMIOFFSET1, LMMIOFFSET0, LMMICLK, LMMIRDATA7, LMMIRDATA6, LMMIRDATA5, LMMIRDATA4, LMMIRDATA3, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIRESETN, LMMIREQUEST +, LMMIWDATA7, LMMIWDATA6, LMMIWDATA5, LMMIWDATA4, LMMIWDATA3, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIWRRDN, RSTSMCLK, SMCLK); parameter LMMI_EN = "DIS"; input LMMIOFFSET7; input LMMIOFFSET6; @@ -6192,7 +6286,8 @@ module CONFIG_LMMI_CORE (...); endmodule (* keep *) -module CONFIG_MULTIBOOT_CORE (...); +module CONFIG_MULTIBOOT_CORE(CIBAUTOREBOOT, CIBMSPIMADDR31, CIBMSPIMADDR30, CIBMSPIMADDR29, CIBMSPIMADDR28, CIBMSPIMADDR27, CIBMSPIMADDR26, CIBMSPIMADDR25, CIBMSPIMADDR24, CIBMSPIMADDR23, CIBMSPIMADDR22, CIBMSPIMADDR21, CIBMSPIMADDR20, CIBMSPIMADDR19, CIBMSPIMADDR18, CIBMSPIMADDR17, CIBMSPIMADDR16, CIBMSPIMADDR15, CIBMSPIMADDR14, CIBMSPIMADDR13, CIBMSPIMADDR12 +, CIBMSPIMADDR11, CIBMSPIMADDR10, CIBMSPIMADDR9, CIBMSPIMADDR8, CIBMSPIMADDR7, CIBMSPIMADDR6, CIBMSPIMADDR5, CIBMSPIMADDR4, CIBMSPIMADDR3, CIBMSPIMADDR2, CIBMSPIMADDR1, CIBMSPIMADDR0); parameter MSPIADDR = "0b00000000000000000000000000000000"; parameter SOURCESEL = "DIS"; input CIBAUTOREBOOT; @@ -6231,7 +6326,8 @@ module CONFIG_MULTIBOOT_CORE (...); endmodule (* keep *) -module CONFIG_SEDC_CORE (...); +module CONFIG_SEDC_CORE(CIBSED1ENABLE, CIBSEDCCOF, CIBSEDCENABLE, CIBSEDCMODE, CIBSEDCSTART, OSCCLKSEDC, RSTSEDC, SEDCBUSYCIB, SEDCDSRERRLOCCIB12, SEDCDSRERRLOCCIB11, SEDCDSRERRLOCCIB10, SEDCDSRERRLOCCIB9, SEDCDSRERRLOCCIB8, SEDCDSRERRLOCCIB7, SEDCDSRERRLOCCIB6, SEDCDSRERRLOCCIB5, SEDCDSRERRLOCCIB4, SEDCDSRERRLOCCIB3, SEDCDSRERRLOCCIB2, SEDCDSRERRLOCCIB1, SEDCDSRERRLOCCIB0 +, SEDCERR1CIB, SEDCERRCCIB, SEDCERRCRCCIB, SEDCERRMCIB, SEDCFRMERRLOCCIB15, SEDCFRMERRLOCCIB14, SEDCFRMERRLOCCIB13, SEDCFRMERRLOCCIB12, SEDCFRMERRLOCCIB11, SEDCFRMERRLOCCIB10, SEDCFRMERRLOCCIB9, SEDCFRMERRLOCCIB8, SEDCFRMERRLOCCIB7, SEDCFRMERRLOCCIB6, SEDCFRMERRLOCCIB5, SEDCFRMERRLOCCIB4, SEDCFRMERRLOCCIB3, SEDCFRMERRLOCCIB2, SEDCFRMERRLOCCIB1, SEDCFRMERRLOCCIB0); parameter SEDCEN = "DIS"; input CIBSED1ENABLE; input CIBSEDCCOF; @@ -6277,7 +6373,7 @@ module CONFIG_SEDC_CORE (...); endmodule (* keep *) -module CONFIG_WDT_CORE (...); +module CONFIG_WDT_CORE(CIBWDTRELOAD, WDT_CLK, WDT_RST); parameter WDTEN = "DIS"; parameter WDTMODE = "SINGLE"; parameter WDTVALUE = "0b000000000000000000"; @@ -6286,7 +6382,8 @@ module CONFIG_WDT_CORE (...); input WDT_RST; endmodule -module DDRDLL_CORE (...); +module DDRDLL_CORE(CODE8, CODE7, CODE6, CODE5, CODE4, CODE3, CODE2, CODE1, CODE0, FREEZE, LOCK, CLKIN, RST, DCNTL8, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1 +, DCNTL0, UDDCNTL_N); parameter GSR = "ENABLED"; parameter ENA_ROUNDOFF = "ENABLED"; parameter FORCE_MAX_DELAY = "CODE_OR_LOCK_FROM_DLL_LOOP"; @@ -6315,7 +6412,7 @@ module DDRDLL_CORE (...); input UDDCNTL_N; endmodule -module DLLDEL_CORE (...); +module DLLDEL_CORE(CLKIN, CLKOUT, CODE8, CODE7, CODE6, CODE5, CODE4, CODE3, CODE2, CODE1, CODE0, COUT, DIR, LOAD_N, MOVE); parameter ADJUST = "0"; parameter DEL_ADJUST = "PLUS"; parameter ENABLE = "DISABLED"; @@ -6336,7 +6433,37 @@ module DLLDEL_CORE (...); input MOVE; endmodule -module DPHY_CORE (...); +module DPHY_CORE(BITCKEXT, CKN, CKP, CLKREF, D0ACTIVE1, D0ACTIVE0, D0BYTCNT9, D0BYTCNT8, D0BYTCNT7, D0BYTCNT6, D0BYTCNT5, D0BYTCNT4, D0BYTCNT3, D0BYTCNT2, D0BYTCNT1, D0BYTCNT0, D0ERRCNT9, D0ERRCNT8, D0ERRCNT7, D0ERRCNT6, D0ERRCNT5 +, D0ERRCNT4, D0ERRCNT3, D0ERRCNT2, D0ERRCNT1, D0ERRCNT0, D0PASS1, D0PASS0, D0VALID1, D0VALID0, D1ACTIVE1, D1ACTIVE0, D1BYTCNT9, D1BYTCNT8, D1BYTCNT7, D1BYTCNT6, D1BYTCNT5, D1BYTCNT4, D1BYTCNT3, D1BYTCNT2, D1BYTCNT1, D1BYTCNT0 +, D1ERRCNT9, D1ERRCNT8, D1ERRCNT7, D1ERRCNT6, D1ERRCNT5, D1ERRCNT4, D1ERRCNT3, D1ERRCNT2, D1ERRCNT1, D1ERRCNT0, D1PASS1, D1PASS0, D1VALID1, D1VALID0, D2ACTIVE1, D2ACTIVE0, D2BYTCNT9, D2BYTCNT8, D2BYTCNT7, D2BYTCNT6, D2BYTCNT5 +, D2BYTCNT4, D2BYTCNT3, D2BYTCNT2, D2BYTCNT1, D2BYTCNT0, D2ERRCNT9, D2ERRCNT8, D2ERRCNT7, D2ERRCNT6, D2ERRCNT5, D2ERRCNT4, D2ERRCNT3, D2ERRCNT2, D2ERRCNT1, D2ERRCNT0, D2PASS1, D2PASS0, D2VALID1, D2VALID0, D3ACTIVE1, D3ACTIVE0 +, D3BYTCNT9, D3BYTCNT8, D3BYTCNT7, D3BYTCNT6, D3BYTCNT5, D3BYTCNT4, D3BYTCNT3, D3BYTCNT2, D3BYTCNT1, D3BYTCNT0, D3ERRCNT9, D3ERRCNT8, D3ERRCNT7, D3ERRCNT6, D3ERRCNT5, D3ERRCNT4, D3ERRCNT3, D3ERRCNT2, D3ERRCNT1, D3ERRCNT0, D3PASS1 +, D3PASS0, D3VALID1, D3VALID0, DCTSTOUT9, DCTSTOUT8, DCTSTOUT7, DCTSTOUT6, DCTSTOUT5, DCTSTOUT4, DCTSTOUT3, DCTSTOUT2, DCTSTOUT1, DCTSTOUT0, DN0, DN1, DN2, DN3, DP0, DP1, DP2, DP3 +, LOCK, PDDPHY, PDPLL, SCCLKIN, SCRSTNIN, UDIR, UED0THEN, UERCLP0, UERCLP1, UERCTRL, UERE, UERSTHS, UERSSHS, UERSE, UFRXMODE, UTXMDTX, URXACTHS, URXCKE, URXCKINE, URXDE7, URXDE6 +, URXDE5, URXDE4, URXDE3, URXDE2, URXDE1, URXDE0, URXDHS15, URXDHS14, URXDHS13, URXDHS12, URXDHS11, URXDHS10, URXDHS9, URXDHS8, URXDHS7, URXDHS6, URXDHS5, URXDHS4, URXDHS3, URXDHS2, URXDHS1 +, URXDHS0, URXLPDTE, URXSKCHS, URXDRX, URXSHS3, URXSHS2, URXSHS1, URXSHS0, URE0D3DP, URE1D3DN, URE2CKDP, URE3CKDN, URXULPSE, URXVDE, URXVDHS3, URXVDHS2, URXVDHS1, URXVDHS0, USSTT, UTDIS, UTXCKE +, UDE0D0TN, UDE1D1TN, UDE2D2TN, UDE3D3TN, UDE4CKTN, UDE5D0RN, UDE6D1RN, UDE7D2RN, UTXDHS31, UTXDHS30, UTXDHS29, UTXDHS28, UTXDHS27, UTXDHS26, UTXDHS25, UTXDHS24, UTXDHS23, UTXDHS22, UTXDHS21, UTXDHS20, UTXDHS19 +, UTXDHS18, UTXDHS17, UTXDHS16, UTXDHS15, UTXDHS14, UTXDHS13, UTXDHS12, UTXDHS11, UTXDHS10, UTXDHS9, UTXDHS8, UTXDHS7, UTXDHS6, UTXDHS5, UTXDHS4, UTXDHS3, UTXDHS2, UTXDHS1, UTXDHS0, UTXENER, UTXRRS +, UTXRYP, UTXRYSK, UTXRD0EN, UTRD0SEN, UTXSKD0N, UTXTGE0, UTXTGE1, UTXTGE2, UTXTGE3, UTXULPSE, UTXUPSEX, UTXVDE, UTXWVDHS3, UTXWVDHS2, UTXWVDHS1, UTXWVDHS0, UUSAN, U1DIR, U1ENTHEN, U1ERCLP0, U1ERCLP1 +, U1ERCTRL, U1ERE, U1ERSTHS, U1ERSSHS, U1ERSE, U1FRXMD, U1FTXST, U1RXATHS, U1RXCKE, U1RXDE7, U1RXDE6, U1RXDE5, U1RXDE4, U1RXDE3, U1RXDE2, U1RXDE1, U1RXDE0, U1RXDHS15, U1RXDHS14, U1RXDHS13, U1RXDHS12 +, U1RXDHS11, U1RXDHS10, U1RXDHS9, U1RXDHS8, U1RXDHS7, U1RXDHS6, U1RXDHS5, U1RXDHS4, U1RXDHS3, U1RXDHS2, U1RXDHS1, U1RXDHS0, U1RXDTE, U1RXSKS, U1RXSK, U1RXSHS3, U1RXSHS2, U1RXSHS1, U1RXSHS0, U1RE0D, U1RE1CN +, U1RE2D, U1RE3N, U1RXUPSE, U1RXVDE, U1RXVDHS3, U1RXVDHS2, U1RXVDHS1, U1RXVDHS0, U1SSTT, U1TDIS, U1TREQ, U1TDE0D3, U1TDE1CK, U1TDE2D0, U1TDE3D1, U1TDE4D2, U1TDE5D3, U1TDE6, U1TDE7, U1TXDHS31, U1TXDHS30 +, U1TXDHS29, U1TXDHS28, U1TXDHS27, U1TXDHS26, U1TXDHS25, U1TXDHS24, U1TXDHS23, U1TXDHS22, U1TXDHS21, U1TXDHS20, U1TXDHS19, U1TXDHS18, U1TXDHS17, U1TXDHS16, U1TXDHS15, U1TXDHS14, U1TXDHS13, U1TXDHS12, U1TXDHS11, U1TXDHS10, U1TXDHS9 +, U1TXDHS8, U1TXDHS7, U1TXDHS6, U1TXDHS5, U1TXDHS4, U1TXDHS3, U1TXDHS2, U1TXDHS1, U1TXDHS0, U1TXLPD, U1TXRYE, U1TXRY, U1TXRYSK, U1TXREQ, U1TXREQH, U1TXSK, U1TXTGE0, U1TXTGE1, U1TXTGE2, U1TXTGE3, U1TXUPSE +, U1TXUPSX, U1TXVDE, U1TXWVHS3, U1TXWVHS2, U1TXWVHS1, U1TXWVHS0, U1USAN, U2DIR, U2END2, U2ERCLP0, U2ERCLP1, U2ERCTRL, U2ERE, U2ERSTHS, U2ERSSHS, U2ERSE, U2FRXMD, U2FTXST, U2RXACHS, U2RXCKE, U2RXDE7 +, U2RXDE6, U2RXDE5, U2RXDE4, U2RXDE3, U2RXDE2, U2RXDE1, U2RXDE0, U2RXDHS15, U2RXDHS14, U2RXDHS13, U2RXDHS12, U2RXDHS11, U2RXDHS10, U2RXDHS9, U2RXDHS8, U2RXDHS7, U2RXDHS6, U2RXDHS5, U2RXDHS4, U2RXDHS3, U2RXDHS2 +, U2RXDHS1, U2RXDHS0, U2RPDTE, U2RXSK, U2RXSKC, U2RXSHS3, U2RXSHS2, U2RXSHS1, U2RXSHS0, U2RE0D2, U2RE1D2, U2RE2D3, U2RE3D3, U2RXUPSE, U2RXVDE, U2RXVDHS3, U2RXVDHS2, U2RXVDHS1, U2RXVDHS0, U2SSTT, U2TDIS +, U2TREQ, U2TDE0D0, U2TDE1D1, U2TDE2D2, U2TDE3D3, U2TDE4CK, U2TDE5D0, U2TDE6D1, U2TDE7D2, U2TXDHS31, U2TXDHS30, U2TXDHS29, U2TXDHS28, U2TXDHS27, U2TXDHS26, U2TXDHS25, U2TXDHS24, U2TXDHS23, U2TXDHS22, U2TXDHS21, U2TXDHS20 +, U2TXDHS19, U2TXDHS18, U2TXDHS17, U2TXDHS16, U2TXDHS15, U2TXDHS14, U2TXDHS13, U2TXDHS12, U2TXDHS11, U2TXDHS10, U2TXDHS9, U2TXDHS8, U2TXDHS7, U2TXDHS6, U2TXDHS5, U2TXDHS4, U2TXDHS3, U2TXDHS2, U2TXDHS1, U2TXDHS0, U2TPDTE +, U2TXRYE, U2TXRYH, U2TXRYSK, U2TXREQ, U2TXREQH, U2TXSKC, U2TXTGE0, U2TXTGE1, U2TXTGE2, U2TXTGE3, U2TXUPSE, U2TXUPSX, U2TXVDE, U2TXWVHS3, U2TXWVHS2, U2TXWVHS1, U2TXWVHS0, U2USAN, U3DIR, U3END3, U3ERCLP0 +, U3ERCLP1, U3ERCTRL, U3ERE, U3ERSTHS, U3ERSSHS, U3ERSE, U3FRXMD, U3FTXST, U3RXATHS, U3RXCKE, U3RXDE7, U3RXDE6, U3RXDE5, U3RXDE4, U3RXDE3, U3RXDE2, U3RXDE1, U3RXDE0, U3RXDHS15, U3RXDHS14, U3RXDHS13 +, U3RXDHS12, U3RXDHS11, U3RXDHS10, U3RXDHS9, U3RXDHS8, U3RXDHS7, U3RXDHS6, U3RXDHS5, U3RXDHS4, U3RXDHS3, U3RXDHS2, U3RXDHS1, U3RXDHS0, U3RPDTE, U3RXSK, U3RXSKC, U3RXSHS3, U3RXSHS2, U3RXSHS1, U3RXSHS0, U3RE0CK +, U3RE1CK, U3RE2, U3RE3, U3RXUPSE, U3RXVDE, U3RXVDHS3, U3RXVDHS2, U3RXVDHS1, U3RXVDHS0, U3SSTT, U3TDISD2, U3TREQD2, U3TDE0D3, U3TDE1D0, U3TDE2D1, U3TDE3D2, U3TDE4D3, U3TDE5CK, U3TDE6, U3TDE7, U3TXDHS31 +, U3TXDHS30, U3TXDHS29, U3TXDHS28, U3TXDHS27, U3TXDHS26, U3TXDHS25, U3TXDHS24, U3TXDHS23, U3TXDHS22, U3TXDHS21, U3TXDHS20, U3TXDHS19, U3TXDHS18, U3TXDHS17, U3TXDHS16, U3TXDHS15, U3TXDHS14, U3TXDHS13, U3TXDHS12, U3TXDHS11, U3TXDHS10 +, U3TXDHS9, U3TXDHS8, U3TXDHS7, U3TXDHS6, U3TXDHS5, U3TXDHS4, U3TXDHS3, U3TXDHS2, U3TXDHS1, U3TXDHS0, U3TXLPDT, U3TXRY, U3TXRYHS, U3TXRYSK, U3TXREQ, U3TXREQH, U3TXSKC, U3TXTGE0, U3TXTGE1, U3TXTGE2, U3TXTGE3 +, U3TXULPS, U3TXUPSX, U3TXVD3, U3TXWVHS3, U3TXWVHS2, U3TXWVHS1, U3TXWVHS0, U3USAN, UCENCK, UCRXCKAT, UCRXUCKN, UCSSTT, UCTXREQH, UCTXUPSC, UCTXUPSX, UCUSAN, SCANCLK, SCANRST, LMMICLK, LMMIOFFSET4, LMMIOFFSET3 +, LMMIOFFSET2, LMMIOFFSET1, LMMIOFFSET0, LMMIRDATA3, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIREQUEST, LMMIRESETN, LMMIWDATA3, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIWRRDN, LTSTEN, LTSTLANE1, LTSTLANE0, URWDCKHS, UTRNREQ +, UTWDCKHS, UCRXWCHS, OPCGLDCK, CLKLBACT); parameter GSR = "ENABLED"; parameter AUTO_PD_EN = "POWERED_UP"; parameter CFG_NUM_LANES = "ONE_LANE"; @@ -7014,7 +7141,9 @@ module DPHY_CORE (...); output CLKLBACT; endmodule -module DQSBUF_CORE (...); +module DQSBUF_CORE(BTDETECT, BURSTDETECT, DATAVALID, DQSI, DQSW, DQSWRD, PAUSE, RDCLKSEL3, RDCLKSEL2, RDCLKSEL1, RDCLKSEL0, RDDIR, RDLOADN, RDPNTR2, RDPNTR1, RDPNTR0, READ3, READ2, READ1, READ0, READCOUT +, READMOVE, RST, SCLK, SELCLK, DQSR90, DQSW270, WRCOUT, WRDIR, WRLOAD_N, WRLVCOUT, WRLVDIR, WRLVLOAD_N, WRLVMOVE, WRMOVE, WRPNTR2, WRPNTR1, WRPNTR0, ECLKIN, RSTSMCNT, DLLCODE8, DLLCODE7 +, DLLCODE6, DLLCODE5, DLLCODE4, DLLCODE3, DLLCODE2, DLLCODE1, DLLCODE0); parameter GSR = "ENABLED"; parameter ENABLE_FIFO = "DISABLED"; parameter FORCE_READ = "DISABLED"; @@ -7087,7 +7216,7 @@ module DQSBUF_CORE (...); input DLLCODE0; endmodule -module ECLKDIV_CORE (...); +module ECLKDIV_CORE(DIVOUT, DIVRST, ECLKIN, SLIP, TESTINP3, TESTINP2, TESTINP1, TESTINP0); parameter ECLK_DIV = "DISABLE"; parameter GSR = "ENABLED"; output DIVOUT; @@ -7100,14 +7229,15 @@ module ECLKDIV_CORE (...); input TESTINP0; endmodule -module ECLKSYNC_CORE (...); +module ECLKSYNC_CORE(ECLKIN, ECLKOUT, STOP); parameter STOP_EN = "DISABLE"; input ECLKIN; output ECLKOUT; input STOP; endmodule -module FBMUX_CORE (...); +module FBMUX_CORE(ENEXT, FBKCK, LGYRDYN, INTLOCK, WKUPSYNC, FBKCLK15, FBKCLK14, FBKCLK13, FBKCLK12, FBKCLK11, FBKCLK10, FBKCLK9, FBKCLK8, FBKCLK7, FBKCLK6, FBKCLK5, FBKCLK4, FBKCLK3, FBKCLK2, FBKCLK1, FBKCLK0 +); parameter INTFB = "IGNORED"; parameter SEL_FBK = "DIVA"; parameter CLKMUX_FB = "CMUX_CLKOP"; @@ -7135,7 +7265,9 @@ module FBMUX_CORE (...); input FBKCLK0; endmodule -module I2CFIFO_CORE (...); +module I2CFIFO_CORE(ALTSCLIN, ALTSCLOEN, ALTSCLOUT, ALTSDAIN, ALTSDAOEN, ALTSDAOUT, BUSBUSY, FIFORESET, I2CLSRRSTN, INSLEEP, IRQ, LMMICLK, LMMIOFFSET5, LMMIOFFSET4, LMMIOFFSET3, LMMIOFFSET2, LMMIOFFSET1, LMMIOFFSET0, LMMIRDATA7, LMMIRDATA6, LMMIRDATA5 +, LMMIRDATA4, LMMIRDATA3, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIREQUEST, LMMIRESETN, LMMIWDATA7, LMMIWDATA6, LMMIWDATA5, LMMIWDATA4, LMMIWDATA3, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIWRRDN, MRDCMPL, OPCGLOADCLK, RXFIFOAF +, RXFIFOE, RXFIFOF, SCANCLK, SCANRST, SCLIN, SCLOE, SCLOEN, SCLOUT, SDAIN, SDAOE, SDAOEN, SDAOUT, SLEEPCLKSELN, SLVADDRMATCH, SLVADDRMATCHSCL, SRDWR, TXFIFOAE, TXFIFOE, TXFIFOF); parameter BRNBASEDELAY = "0b0000"; parameter CR1CKDIS = "EN"; parameter CR1FIFOMODE = "REG"; @@ -7237,7 +7369,16 @@ module I2CFIFO_CORE (...); output TXFIFOF; endmodule -module LRAM_CORE (...); +module LRAM_CORE(ADA13, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, ADB13, ADB12, ADB11, ADB10, ADB9, ADB8, ADB7 +, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, BENA_N3, BENA_N2, BENA_N1, BENA_N0, BENB_N3, BENB_N2, BENB_N1, BENB_N0, CEA, CEB, CLK, CSA, CSB, DIA31 +, DIA30, DIA29, DIA28, DIA27, DIA26, DIA25, DIA24, DIA23, DIA22, DIA21, DIA20, DIA19, DIA18, DIA17, DIA16, DIA15, DIA14, DIA13, DIA12, DIA11, DIA10 +, DIA9, DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, DIB31, DIB30, DIB29, DIB28, DIB27, DIB26, DIB25, DIB24, DIB23, DIB22, DIB21 +, DIB20, DIB19, DIB18, DIB17, DIB16, DIB15, DIB14, DIB13, DIB12, DIB11, DIB10, DIB9, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0 +, DOA31, DOA30, DOA29, DOA28, DOA27, DOA26, DOA25, DOA24, DOA23, DOA22, DOA21, DOA20, DOA19, DOA18, DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11 +, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, DOB31, DOB30, DOB29, DOB28, DOB27, DOB26, DOB25, DOB24, DOB23, DOB22 +, DOB21, DOB20, DOB19, DOB18, DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1 +, DOB0, DPS, ERRDECA1, ERRDECA0, ERRDECB1, ERRDECB0, IGN, INITN, OCEA, OCEB, OEA, OEB, RSTA, RSTB, STDBYN, TBISTN, WEA, WEB, ERRDET, LRAMREADY, OPCGLOADCLK +, SCANCLK, SCANRST); parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; @@ -7571,7 +7712,12 @@ module LRAM_CORE (...); input SCANRST; endmodule -module MULT18_CORE (...); +module MULT18_CORE(SFTCTRL3, SFTCTRL2, SFTCTRL1, SFTCTRL0, ARHSIGN, BRHSIGN, ARH8, ARH7, ARH6, ARH5, ARH4, ARH3, ARH2, ARH1, ARH0, BRH8, BRH7, BRH6, BRH5, BRH4, BRH3 +, BRH2, BRH1, BRH0, ARL8, ARL7, ARL6, ARL5, ARL4, ARL3, ARL2, ARL1, ARL0, BRL8, BRL7, BRL6, BRL5, BRL4, BRL3, BRL2, BRL1, BRL0 +, PL1819, PL1818, PL1817, PL1816, PL1815, PL1814, PL1813, PL1812, PL1811, PL1810, PL189, PL188, PL187, PL186, PL185, PL184, PL183, PL182, PL181, PL180, PH1819 +, PH1818, PH1817, PH1816, PH1815, PH1814, PH1813, PH1812, PH1811, PH1810, PH189, PH188, PH187, PH186, PH185, PH184, PH183, PH182, PH181, PH180, SIGNED18, P3637 +, P3636, P3635, P3634, P3633, P3632, P3631, P3630, P3629, P3628, P3627, P3626, P3625, P3624, P3623, P3622, P3621, P3620, P3619, P3618, P3617, P3616 +, P3615, P3614, P3613, P3612, P3611, P3610, P369, P368, P367, P366, P365, P364, P363, P362, P361, P360, ROUNDEN); parameter SFTEN = "DISABLED"; parameter MULT18X18 = "ENABLED"; parameter ROUNDHALFUP = "DISABLED"; @@ -7701,7 +7847,14 @@ module MULT18_CORE (...); input ROUNDEN; endmodule -module MULT18X36_CORE (...); +module MULT18X36_CORE(SFTCTRL3, SFTCTRL2, SFTCTRL1, SFTCTRL0, PH3637, PH3636, PH3635, PH3634, PH3633, PH3632, PH3631, PH3630, PH3629, PH3628, PH3627, PH3626, PH3625, PH3624, PH3623, PH3622, PH3621 +, PH3620, PH3619, PH3618, PH3617, PH3616, PH3615, PH3614, PH3613, PH3612, PH3611, PH3610, PH369, PH368, PH367, PH366, PH365, PH364, PH363, PH362, PH361, PH360 +, PL3637, PL3636, PL3635, PL3634, PL3633, PL3632, PL3631, PL3630, PL3629, PL3628, PL3627, PL3626, PL3625, PL3624, PL3623, PL3622, PL3621, PL3620, PL3619, PL3618, PL3617 +, PL3616, PL3615, PL3614, PL3613, PL3612, PL3611, PL3610, PL369, PL368, PL367, PL366, PL365, PL364, PL363, PL362, PL361, PL360, SGNED18H, SGNED18L, P7272, P7271 +, P7270, P7269, P7268, P7267, P7266, P7265, P7264, P7263, P7262, P7261, P7260, P7259, P7258, P7257, P7256, P7255, P7254, P7253, P7252, P7251, P7250 +, P7249, P7248, P7247, P7246, P7245, P7244, P7243, P7242, P7241, P7240, P7239, P7238, P7237, P7236, P7235, P7234, P7233, P7232, P7231, P7230, P7229 +, P7228, P7227, P7226, P7225, P7224, P7223, P7222, P7221, P7220, P7219, P7218, P7217, P7216, P7215, P7214, P7213, P7212, P7211, P7210, P729, P728 +, P727, P726, P725, P724, P723, P722, P721, P720, ROUNDEN); parameter SFTEN = "DISABLED"; parameter MULT18X36 = "ENABLED"; parameter MULT36 = "DISABLED"; @@ -7867,7 +8020,20 @@ module MULT18X36_CORE (...); input ROUNDEN; endmodule -module MULT36_CORE (...); +module MULT36_CORE(PH7272, PH7271, PH7270, PH7269, PH7268, PH7267, PH7266, PH7265, PH7264, PH7263, PH7262, PH7261, PH7260, PH7259, PH7258, PH7257, PH7256, PH7255, PH7254, PH7253, PH7252 +, PH7251, PH7250, PH7249, PH7248, PH7247, PH7246, PH7245, PH7244, PH7243, PH7242, PH7241, PH7240, PH7239, PH7238, PH7237, PH7236, PH7235, PH7234, PH7233, PH7232, PH7231 +, PH7230, PH7229, PH7228, PH7227, PH7226, PH7225, PH7224, PH7223, PH7222, PH7221, PH7220, PH7219, PH7218, PH7217, PH7216, PH7215, PH7214, PH7213, PH7212, PH7211, PH7210 +, PH729, PH728, PH727, PH726, PH725, PH724, PH723, PH722, PH721, PH720, PL7272, PL7271, PL7270, PL7269, PL7268, PL7267, PL7266, PL7265, PL7264, PL7263, PL7262 +, PL7261, PL7260, PL7259, PL7258, PL7257, PL7256, PL7255, PL7254, PL7253, PL7252, PL7251, PL7250, PL7249, PL7248, PL7247, PL7246, PL7245, PL7244, PL7243, PL7242, PL7241 +, PL7240, PL7239, PL7238, PL7237, PL7236, PL7235, PL7234, PL7233, PL7232, PL7231, PL7230, PL7229, PL7228, PL7227, PL7226, PL7225, PL7224, PL7223, PL7222, PL7221, PL7220 +, PL7219, PL7218, PL7217, PL7216, PL7215, PL7214, PL7213, PL7212, PL7211, PL7210, PL729, PL728, PL727, PL726, PL725, PL724, PL723, PL722, PL721, PL720, PML7271 +, PML7270, PML7269, PML7268, PML7267, PML7266, PML7265, PML7264, PML7263, PML7262, PML7261, PML7260, PML7259, PML7258, PML7257, PML7256, PML7255, PML7254, PML7253, PML7252, PML7251, PML7250 +, PML7249, PML7248, PML7247, PML7246, PML7245, PML7244, PML7243, PML7242, PML7241, PML7240, PML7239, PML7238, PML7237, PML7236, PML7235, PML7234, PML7233, PML7232, PML7231, PML7230, PML7229 +, PML7228, PML7227, PML7226, PML7225, PML7224, PML7223, PML7222, PML7221, PML7220, PML7219, PML7218, PML7217, PML7216, PML7215, PML7214, PML7213, PML7212, PML7211, PML7210, PML729, PML728 +, PML727, PML726, PML725, PML724, PML723, PML722, PML721, PML720, PMH7271, PMH7270, PMH7269, PMH7268, PMH7267, PMH7266, PMH7265, PMH7264, PMH7263, PMH7262, PMH7261, PMH7260, PMH7259 +, PMH7258, PMH7257, PMH7256, PMH7255, PMH7254, PMH7253, PMH7252, PMH7251, PMH7250, PMH7249, PMH7248, PMH7247, PMH7246, PMH7245, PMH7244, PMH7243, PMH7242, PMH7241, PMH7240, PMH7239, PMH7238 +, PMH7237, PMH7236, PMH7235, PMH7234, PMH7233, PMH7232, PMH7231, PMH7230, PMH7229, PMH7228, PMH7227, PMH7226, PMH7225, PMH7224, PMH7223, PMH7222, PMH7221, PMH7220, PMH7219, PMH7218, PMH7217 +, PMH7216, PMH7215, PMH7214, PMH7213, PMH7212, PMH7211, PMH7210, PMH729, PMH728, PMH727, PMH726, PMH725, PMH724, PMH723, PMH722, PMH721, PMH720); parameter MULT36X36 = "ENABLED"; input PH7272; input PH7271; @@ -8161,7 +8327,11 @@ module MULT36_CORE (...); output PMH720; endmodule -module MULT9_CORE (...); +module MULT9_CORE(A8, A7, A6, A5, A4, A3, A2, A1, A0, ASIGNED, BR8, BR7, BR6, BR5, BR4, BR3, BR2, BR1, BR0, AS18, AS17 +, AS16, AS15, AS14, AS13, AS12, AS11, AS10, AS28, AS27, AS26, AS25, AS24, AS23, AS22, AS21, AS20, ASSIGNED1, ASSIGNED2, BRSIGNED, CLK, CEA +, RSTA, AO8, AO7, AO6, AO5, AO4, AO3, AO2, AO1, AO0, BO8, BO7, BO6, BO5, BO4, BO3, BO2, BO1, BO0, AOSIGNED, BOSIGNED +, AR8, AR7, AR6, AR5, AR4, AR3, AR2, AR1, AR0, ARSIGNED, P1819, P1818, P1817, P1816, P1815, P1814, P1813, P1812, P1811, P1810, P189 +, P188, P187, P186, P185, P184, P183, P182, P181, P180, CEP, RSTP); parameter SIGNEDSTATIC_EN = "DISABLED"; parameter ASIGNED_OPERAND_EN = "DISABLED"; parameter BYPASS_MULT9 = "USED"; @@ -8269,7 +8439,8 @@ module MULT9_CORE (...); input RSTP; endmodule -module OSC_CORE (...); +module OSC_CORE(HFCLKOUT, HFOUTEN, HFSDSCEN, HFTRMFAB8, HFTRMFAB7, HFTRMFAB6, HFTRMFAB5, HFTRMFAB4, HFTRMFAB3, HFTRMFAB2, HFTRMFAB1, HFTRMFAB0, LFCLKOUT, LFTRMFAB8, LFTRMFAB7, LFTRMFAB6, LFTRMFAB5, LFTRMFAB4, LFTRMFAB3, LFTRMFAB2, LFTRMFAB1 +, LFTRMFAB0, HFCLKCFG, HFSDCOUT); parameter DTR_EN = "ENABLED"; parameter HF_CLK_DIV = "1"; parameter HF_SED_SEC_DIV = "1"; @@ -8305,7 +8476,28 @@ module OSC_CORE (...); output HFSDCOUT; endmodule -module PCIE_CORE (...); +module PCIE_CORE(ACTACMD, ACTDR11, ACTEN, ACTHIGHZ, ACTMD, ACJNOUT, ACJPOUT, AUXCK, CKUSRI, CKUSRO, ECKIN, ECKIND2, ECKINDO, ERSTN, ERSTND2, ERXCKD2, ERXCKDO, ERXRSND2, ETXCKD2, ETXCKDO, ETXRSND2 +, FLR3, FLR2, FLR1, FLR0, FLRACK3, FLRACK2, FLRACK1, FLRACK0, MINTLEG3, MINTLEG2, MINTLEG1, MINTLEG0, MINTO, PERSTN, PMCTRL4, PMCTRL3, PMCTRL2, PMCTRL1, PMCTRL0, PMCTRLEN, PMDPAST4 +, PMDPAST3, PMDPAST2, PMDPAST1, PMDPAST0, PRMSGSD, PRNOSNP12, PRNOSNP11, PRNOSNP10, PRNOSNP9, PRNOSNP8, PRNOSNP7, PRNOSNP6, PRNOSNP5, PRNOSNP4, PRNOSNP3, PRNOSNP2, PRNOSNP1, PRNOSNP0, PRNSNPRE, PRSNOOP12, PRSNOOP11 +, PRSNOOP10, PRSNOOP9, PRSNOOP8, PRSNOOP7, PRSNOOP6, PRSNOOP5, PRSNOOP4, PRSNOOP3, PRSNOOP2, PRSNOOP1, PRSNOOP0, PRSNPRE, PPBDREG31, PPBDREG30, PPBDREG29, PPBDREG28, PPBDREG27, PPBDREG26, PPBDREG25, PPBDREG24, PPBDREG23 +, PPBDREG22, PPBDREG21, PPBDREG20, PPBDREG19, PPBDREG18, PPBDREG17, PPBDREG16, PPBDREG15, PPBDREG14, PPBDREG13, PPBDREG12, PPBDREG11, PPBDREG10, PPBDREG9, PPBDREG8, PPBDREG7, PPBDREG6, PPBDREG5, PPBDREG4, PPBDREG3, PPBDREG2 +, PPBDREG1, PPBDREG0, PPBDSEL7, PPBDSEL6, PPBDSEL5, PPBDSEL4, PPBDSEL3, PPBDSEL2, PPBDSEL1, PPBDSEL0, REXTCK, REXTRST, RSTUSRN, UDLLKUP, ULTSDIS, UPLLKUP, UTLLKUP, UCFGADDR11, UCFGADDR10, UCFGADDR9, UCFGADDR8 +, UCFGADDR7, UCFGADDR6, UCFGADDR5, UCFGADDR4, UCFGADDR3, UCFGADDR2, UCFGF2, UCFGF1, UCFGF0, UCFGRDD31, UCFGRDD30, UCFGRDD29, UCFGRDD28, UCFGRDD27, UCFGRDD26, UCFGRDD25, UCFGRDD24, UCFGRDD23, UCFGRDD22, UCFGRDD21, UCFGRDD20 +, UCFGRDD19, UCFGRDD18, UCFGRDD17, UCFGRDD16, UCFGRDD15, UCFGRDD14, UCFGRDD13, UCFGRDD12, UCFGRDD11, UCFGRDD10, UCFGRDD9, UCFGRDD8, UCFGRDD7, UCFGRDD6, UCFGRDD5, UCFGRDD4, UCFGRDD3, UCFGRDD2, UCFGRDD1, UCFGRDD0, UCFGRDE +, UCFGRDY, UCFGSERD, UCFGVD, UCFGWRBE3, UCFGWRBE2, UCFGWRBE1, UCFGWRBE0, UCFGWRD31, UCFGWRD30, UCFGWRD29, UCFGWRD28, UCFGWRD27, UCFGWRD26, UCFGWRD25, UCFGWRD24, UCFGWRD23, UCFGWRD22, UCFGWRD21, UCFGWRD20, UCFGWRD19, UCFGWRD18 +, UCFGWRD17, UCFGWRD16, UCFGWRD15, UCFGWRD14, UCFGWRD13, UCFGWRD12, UCFGWRD11, UCFGWRD10, UCFGWRD9, UCFGWRD8, UCFGWRD7, UCFGWRD6, UCFGWRD5, UCFGWRD4, UCFGWRD3, UCFGWRD2, UCFGWRD1, UCFGWRD0, UCFGWRDN, USERAUPD, USERTRS3 +, USERTRS2, USERTRS1, USERTRS0, LMMICLK, LMMIOFFSET16, LMMIOFFSET15, LMMIOFFSET14, LMMIOFFSET13, LMMIOFFSET12, LMMIOFFSET11, LMMIOFFSET10, LMMIOFFSET9, LMMIOFFSET8, LMMIOFFSET7, LMMIOFFSET6, LMMIOFFSET5, LMMIOFFSET4, LMMIOFFSET3, LMMIOFFSET2, LMMIRDATA31, LMMIRDATA30 +, LMMIRDATA29, LMMIRDATA28, LMMIRDATA27, LMMIRDATA26, LMMIRDATA25, LMMIRDATA24, LMMIRDATA23, LMMIRDATA22, LMMIRDATA21, LMMIRDATA20, LMMIRDATA19, LMMIRDATA18, LMMIRDATA17, LMMIRDATA16, LMMIRDATA15, LMMIRDATA14, LMMIRDATA13, LMMIRDATA12, LMMIRDATA11, LMMIRDATA10, LMMIRDATA9 +, LMMIRDATA8, LMMIRDATA7, LMMIRDATA6, LMMIRDATA5, LMMIRDATA4, LMMIRDATA3, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIREQUEST, LMMIRESETN, LMMIWDATA31, LMMIWDATA30, LMMIWDATA29, LMMIWDATA28, LMMIWDATA27, LMMIWDATA26, LMMIWDATA25, LMMIWDATA24 +, LMMIWDATA23, LMMIWDATA22, LMMIWDATA21, LMMIWDATA20, LMMIWDATA19, LMMIWDATA18, LMMIWDATA17, LMMIWDATA16, LMMIWDATA15, LMMIWDATA14, LMMIWDATA13, LMMIWDATA12, LMMIWDATA11, LMMIWDATA10, LMMIWDATA9, LMMIWDATA8, LMMIWDATA7, LMMIWDATA6, LMMIWDATA5, LMMIWDATA4, LMMIWDATA3 +, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIWRRDN, VRXCMDD12, VRXCMDD11, VRXCMDD10, VRXCMDD9, VRXCMDD8, VRXCMDD7, VRXCMDD6, VRXCMDD5, VRXCMDD4, VRXCMDD3, VRXCMDD2, VRXCMDD1, VRXCMDD0, VRXCINIT, VRXCNH11, VRXCNH10, VRXCNH9 +, VRXCNH8, VRXCNH7, VRXCNH6, VRXCNH5, VRXCNH4, VRXCNH3, VRXCNH2, VRXCNH1, VRXCNH0, VRXCNINF, VRXCRRE, VRXD31, VRXD30, VRXD29, VRXD28, VRXD27, VRXD26, VRXD25, VRXD24, VRXD23, VRXD22 +, VRXD21, VRXD20, VRXD19, VRXD18, VRXD17, VRXD16, VRXD15, VRXD14, VRXD13, VRXD12, VRXD11, VRXD10, VRXD9, VRXD8, VRXD7, VRXD6, VRXD5, VRXD4, VRXD3, VRXD2, VRXD1 +, VRXD0, VRXDP3, VRXDP2, VRXDP1, VRXDP0, VRXEOP, VRXERR, VRXF1, VRXF0, VRXRDY, VRXSEL1, VRXSEL0, VRXSOP, VRXVD, VXCDINIT, VXCDNH11, VXCDNH10, VXCDNH9, VXCDNH8, VXCDNH7, VXCDNH6 +, VXCDNH5, VXCDNH4, VXCDNH3, VXCDNH2, VXCDNH1, VXCDNH0, VTXCRRE, VXD31, VXD30, VXD29, VXD28, VXD27, VXD26, VXD25, VXD24, VXD23, VXD22, VXD21, VXD20, VXD19, VXD18 +, VXD17, VXD16, VXD15, VXD14, VXD13, VXD12, VXD11, VXD10, VXD9, VXD8, VXD7, VXD6, VXD5, VXD4, VXD3, VXD2, VXD1, VXD0, VXDP3, VXDP2, VXDP1 +, VXDP0, VXEOP, VXEOPN, VXRDY, VXSOP, VXVD, TESTOUT7, TESTOUT6, TESTOUT5, TESTOUT4, TESTOUT3, TESTOUT2, TESTOUT1, TESTOUT0, REFCLKNA, S0REFCKN, S0REFCKP, S0REFRET, S0REXT, S0RXN, S0RXP +, S0TXN, S0TXP, CLKREQI, CLKREQO, CLKREQOE, SCANCLK, SCANRST, OPCGLDCK, ALTCLKIN); parameter ENABLE_USER_CFG = "DISABLED"; parameter PWDN_N = "DISABLED"; parameter GSR = "ENABLED"; @@ -9820,7 +10012,11 @@ module PCIE_CORE (...); input ALTCLKIN; endmodule -module PLL_CORE (...); +module PLL_CORE(CIBDIR, CIBDSEL2, CIBDSEL1, CIBDSEL0, CIBLDREG, CIBROT, CLKOP, CLKOS, CLKOS2, CLKOS3, CLKOS4, CLKOS5, ENEXT, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, ENCLKOS4, ENCLKOS5, FBKCK, INTFBK5 +, INTFBK4, INTFBK3, INTFBK2, INTFBK1, INTFBK0, INTLOCK, LEGACY, LEGRDYN, LMMICLK, LMMIOFFSET6, LMMIOFFSET5, LMMIOFFSET4, LMMIOFFSET3, LMMIOFFSET2, LMMIOFFSET1, LMMIOFFSET0, LMMIRDATA7, LMMIRDATA6, LMMIRDATA5, LMMIRDATA4, LMMIRDATA3 +, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIREQUEST, LMMIRESETN, LMMIWDATA7, LMMIWDATA6, LMMIWDATA5, LMMIWDATA4, LMMIWDATA3, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIWRRDN, LOCK, PFDDN, PFDUP, PLLRESET, REFCK +, STDBY, ZRSEL3, REFMUXCK, PLLPDN, REGQA, REGQB, REGQB1, CLKOUTDL, ROTDEL, DIRDEL, ROTDELP1, GRAYTEST4, GRAYTEST3, GRAYTEST2, GRAYTEST1, GRAYTEST0, BINTEST1, BINTEST0, DIRDELP1, GRAYACT4, GRAYACT3 +, GRAYACT2, GRAYACT1, GRAYACT0, BINACT1, BINACT0, OPCGLDCK, SCANRST, SCANCLK); parameter BW_CTL_BIAS = "0b0101"; parameter CLKOP_TRIM = "0b0000"; parameter CLKOS_TRIM = "0b0000"; @@ -10032,7 +10228,11 @@ module PLL_CORE (...); input SCANCLK; endmodule -module PREADD9_CORE (...); +module PREADD9_CORE(B8, B7, B6, B5, B4, B3, B2, B1, B0, BSIGNED, C9, C8, C7, C6, C5, C4, C3, C2, C1, C0, BRS18 +, BRS17, BRS16, BRS15, BRS14, BRS13, BRS12, BRS11, BRS10, BRS28, BRS27, BRS26, BRS25, BRS24, BRS23, BRS22, BRS21, BRS20, BLS18, BLS17, BLS16, BLS15 +, BLS14, BLS13, BLS12, BLS11, BLS10, BLS28, BLS27, BLS26, BLS25, BLS24, BLS23, BLS22, BLS21, BLS20, BRSS1, BRSS2, BLSS1, BLSS2, PRCASIN, CLK, RSTB +, CEB, RSTCL, CECL, BRSO8, BRSO7, BRSO6, BRSO5, BRSO4, BRSO3, BRSO2, BRSO1, BRSO0, BLSO8, BLSO7, BLSO6, BLSO5, BLSO4, BLSO3, BLSO2, BLSO1, BLSO0 +, BRSOSGND, BLSOSGND, PRCASOUT, BR8, BR7, BR6, BR5, BR4, BR3, BR2, BR1, BR0, BRSIGNED); parameter SIGNEDSTATIC_EN = "DISABLED"; parameter SUBSTRACT_EN = "SUBTRACTION"; parameter CSIGNED = "DISABLED"; @@ -10147,7 +10347,7 @@ module PREADD9_CORE (...); output BRSIGNED; endmodule -module REFMUX_CORE (...); +module REFMUX_CORE(REFCK, ZRSEL3, REFSEL, REFCLK17, REFCLK16, REFCLK15, REFCLK14, REFCLK13, REFCLK12, REFCLK11, REFCLK10, REFCLK27, REFCLK26, REFCLK25, REFCLK24, REFCLK23, REFCLK22, REFCLK21, REFCLK20); parameter REFSEL_ATT = "MC1"; parameter SEL1 = "SELECT_REFCLK1"; parameter SEL_REF2 = "REFCLK2_0"; @@ -10173,7 +10373,8 @@ module REFMUX_CORE (...); input REFCLK20; endmodule -module REG18_CORE (...); +module REG18_CORE(PM17, PM16, PM15, PM14, PM13, PM12, PM11, PM10, PM9, PM8, PM7, PM6, PM5, PM4, PM3, PM2, PM1, PM0, PP17, PP16, PP15 +, PP14, PP13, PP12, PP11, PP10, PP9, PP8, PP7, PP6, PP5, PP4, PP3, PP2, PP1, PP0, CEP, RSTP, CLK); parameter REGBYPS = "REGISTER"; parameter GSR = "ENABLED"; parameter RESET = "SYNC"; @@ -10218,7 +10419,7 @@ module REG18_CORE (...); input CLK; endmodule -module SEIO18_CORE (...); +module SEIO18_CORE(I, DOLP, B, O, INLP, T, INADC); parameter MIPI_ID = "0"; parameter PULLMODE = "DOWN"; parameter MIPI = "DISABLED"; @@ -10233,7 +10434,7 @@ module SEIO18_CORE (...); output INADC; endmodule -module SEIO33_CORE (...); +module SEIO33_CORE(B, O, I, T, I3CRESEN, I3CWKPU); parameter PULLMODE = "DOWN"; (* iopad_external_pin *) inout B; @@ -10244,7 +10445,9 @@ module SEIO33_CORE (...); input I3CWKPU; endmodule -module SGMIICDR_CORE (...); +module SGMIICDR_CORE(DCALIRST, DFACQRST, RRST, SPCLK, SRCLK, SRXD9, SRXD8, SRXD7, SRXD6, SRXD5, SRXD4, SRXD3, SRXD2, SRXD1, SRXD0, LMMICLK, LMMIREQUEST, LMMIWRRDN, LMMIOFFSET3, LMMIOFFSET2, LMMIOFFSET1 +, LMMIOFFSET0, LMMIWDATA7, LMMIWDATA6, LMMIWDATA5, LMMIWDATA4, LMMIWDATA3, LMMIWDATA2, LMMIWDATA1, LMMIWDATA0, LMMIRDATA7, LMMIRDATA6, LMMIRDATA5, LMMIRDATA4, LMMIRDATA3, LMMIRDATA2, LMMIRDATA1, LMMIRDATA0, LMMIRDATAVALID, LMMIREADY, LMMIRESETN, RSTBFBW +, RSTBRXF, SGMIIIN, SREFCLK, CDRLOL, OPCGLOADCLK, SCANCLK, SCANRST); parameter GSR = "ENABLED"; parameter DCOITUNE4LSB = "0_PERCENT"; parameter DCOCTLGI = "0_PERCENT"; @@ -10330,20 +10533,20 @@ module SGMIICDR_CORE (...); input SCANRST; endmodule -module GSR (...); +module GSR(GSR_N, CLK); parameter SYNCMODE = "ASYNC"; input GSR_N; input CLK; endmodule -module DCC (...); +module DCC(CE, CLKI, CLKO); parameter DCCEN = "0"; input CE; input CLKI; output CLKO; endmodule -module DCS (...); +module DCS(CLK0, CLK1, DCSOUT, SEL, SELFORCE); parameter DCSMODE = "GND"; input CLK0; input CLK1; @@ -10352,7 +10555,7 @@ module DCS (...); input SELFORCE; endmodule -module GSR_CORE (...); +module GSR_CORE(GSROUT, CLK, GSR_N); parameter GSR = "ENABLED"; parameter GSR_SYNC = "ASYNC"; output GSROUT; @@ -10360,7 +10563,7 @@ module GSR_CORE (...); input GSR_N; endmodule -module PCLKDIV (...); +module PCLKDIV(CLKIN, CLKOUT, LSRPDIV, PCLKDIVTESTINP2, PCLKDIVTESTINP1, PCLKDIVTESTINP0); parameter DIV_PCLKDIV = "X1"; parameter GSR = "ENABLED"; parameter TESTEN_PCLKDIV = "0"; @@ -10374,12 +10577,12 @@ module PCLKDIV (...); endmodule (* keep *) -module PUR (...); +module PUR(PUR); parameter RST_PULSE = "1"; input PUR; endmodule -module PCLKDIVSP (...); +module PCLKDIVSP(CLKIN, CLKOUT, LSRPDIV); parameter DIV_PCLKDIV = "X1"; parameter GSR = "ENABLED"; input CLKIN; diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v index fdf8331b7..ad0b3da14 100644 --- a/techlibs/lattice/cells_bb_xo2.v +++ b/techlibs/lattice/cells_bb_xo2.v @@ -1,18 +1,21 @@ // Created by cells_xtra.py from Lattice models (* blackbox *) (* keep *) -module GSR (...); +module GSR(GSR); input GSR; endmodule (* blackbox *) (* keep *) -module SGSR (...); +module SGSR(GSR, CLK); input GSR; input CLK; endmodule (* blackbox *) -module DP8KC (...); +module DP8KC(DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1 +, ADA0, CEA, OCEA, CLKA, WEA, CSA2, CSA1, CSA0, RSTA, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, ADB12, ADB11, ADB10 +, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, CEB, OCEB, CLKB, WEB, CSB2, CSB1, CSB0, RSTB, DOA8, DOA7, DOA6 +, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0); parameter DATA_WIDTH_A = 9; parameter DATA_WIDTH_B = 9; parameter REGMODE_A = "NOREG"; @@ -138,7 +141,10 @@ module DP8KC (...); endmodule (* blackbox *) -module PDPW8KC (...); +module PDPW8KC(DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, ADW8, ADW7, ADW6 +, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5 +, ADR4, ADR3, ADR2, ADR1, ADR0, CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9 +, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; parameter REGMODE = "NOREG"; @@ -255,7 +261,8 @@ module PDPW8KC (...); endmodule (* blackbox *) -module SP8KC (...); +module SP8KC(DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1 +, AD0, CE, OCE, CLK, WE, CS2, CS1, CS0, RST, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0); parameter DATA_WIDTH = 9; parameter REGMODE = "NOREG"; parameter CSDECODE = "0b000"; @@ -338,7 +345,9 @@ module SP8KC (...); endmodule (* blackbox *) -module FIFO8KB (...); +module FIFO8KB(DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, CSW0, CSW1, CSR0 +, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10 +, DO11, DO12, DO13, DO14, DO15, DO16, DO17, EF, AEF, AFF, FF); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; parameter REGMODE = "NOREG"; @@ -409,7 +418,7 @@ module FIFO8KB (...); endmodule (* blackbox *) -module CLKDIVC (...); +module CLKDIVC(RST, CLKI, ALIGNWD, CDIV1, CDIVX); parameter GSR = "DISABLED"; parameter DIV = "2.0"; input RST; @@ -420,7 +429,7 @@ module CLKDIVC (...); endmodule (* blackbox *) -module DCMA (...); +module DCMA(CLK0, CLK1, SEL, DCMOUT); input CLK0; input CLK1; input SEL; @@ -428,14 +437,14 @@ module DCMA (...); endmodule (* blackbox *) -module ECLKSYNCA (...); +module ECLKSYNCA(ECLKI, STOP, ECLKO); input ECLKI; input STOP; output ECLKO; endmodule (* blackbox *) -module ECLKBRIDGECS (...); +module ECLKBRIDGECS(CLK0, CLK1, SEL, ECSOUT); input CLK0; input CLK1; input SEL; @@ -443,19 +452,21 @@ module ECLKBRIDGECS (...); endmodule (* blackbox *) -module DCCA (...); +module DCCA(CLKI, CE, CLKO); input CLKI; input CE; output CLKO; endmodule (* blackbox *) (* keep *) -module START (...); +module START(STARTCLK); input STARTCLK; endmodule (* blackbox *) -module EHXPLLJ (...); +module EHXPLLJ(CLKI, CLKFB, PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE +, PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, PLLDATO7 +, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, DPHSRC, CLKINTFB); parameter CLKI_DIV = 1; parameter CLKFB_DIV = 1; parameter CLKOP_DIV = 8; @@ -557,7 +568,7 @@ module EHXPLLJ (...); endmodule (* blackbox *) -module OSCH (...); +module OSCH(STDBY, OSC, SEDSTDBY); parameter NOM_FREQ = "2.08"; input STDBY; output OSC; @@ -565,7 +576,7 @@ module OSCH (...); endmodule (* blackbox *) (* keep *) -module TSALL (...); +module TSALL(TSALL); input TSALL; endmodule diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v index fdf8331b7..ad0b3da14 100644 --- a/techlibs/lattice/cells_bb_xo3.v +++ b/techlibs/lattice/cells_bb_xo3.v @@ -1,18 +1,21 @@ // Created by cells_xtra.py from Lattice models (* blackbox *) (* keep *) -module GSR (...); +module GSR(GSR); input GSR; endmodule (* blackbox *) (* keep *) -module SGSR (...); +module SGSR(GSR, CLK); input GSR; input CLK; endmodule (* blackbox *) -module DP8KC (...); +module DP8KC(DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1 +, ADA0, CEA, OCEA, CLKA, WEA, CSA2, CSA1, CSA0, RSTA, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, ADB12, ADB11, ADB10 +, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, CEB, OCEB, CLKB, WEB, CSB2, CSB1, CSB0, RSTB, DOA8, DOA7, DOA6 +, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0); parameter DATA_WIDTH_A = 9; parameter DATA_WIDTH_B = 9; parameter REGMODE_A = "NOREG"; @@ -138,7 +141,10 @@ module DP8KC (...); endmodule (* blackbox *) -module PDPW8KC (...); +module PDPW8KC(DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, ADW8, ADW7, ADW6 +, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5 +, ADR4, ADR3, ADR2, ADR1, ADR0, CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9 +, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; parameter REGMODE = "NOREG"; @@ -255,7 +261,8 @@ module PDPW8KC (...); endmodule (* blackbox *) -module SP8KC (...); +module SP8KC(DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1 +, AD0, CE, OCE, CLK, WE, CS2, CS1, CS0, RST, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0); parameter DATA_WIDTH = 9; parameter REGMODE = "NOREG"; parameter CSDECODE = "0b000"; @@ -338,7 +345,9 @@ module SP8KC (...); endmodule (* blackbox *) -module FIFO8KB (...); +module FIFO8KB(DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, CSW0, CSW1, CSR0 +, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10 +, DO11, DO12, DO13, DO14, DO15, DO16, DO17, EF, AEF, AFF, FF); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; parameter REGMODE = "NOREG"; @@ -409,7 +418,7 @@ module FIFO8KB (...); endmodule (* blackbox *) -module CLKDIVC (...); +module CLKDIVC(RST, CLKI, ALIGNWD, CDIV1, CDIVX); parameter GSR = "DISABLED"; parameter DIV = "2.0"; input RST; @@ -420,7 +429,7 @@ module CLKDIVC (...); endmodule (* blackbox *) -module DCMA (...); +module DCMA(CLK0, CLK1, SEL, DCMOUT); input CLK0; input CLK1; input SEL; @@ -428,14 +437,14 @@ module DCMA (...); endmodule (* blackbox *) -module ECLKSYNCA (...); +module ECLKSYNCA(ECLKI, STOP, ECLKO); input ECLKI; input STOP; output ECLKO; endmodule (* blackbox *) -module ECLKBRIDGECS (...); +module ECLKBRIDGECS(CLK0, CLK1, SEL, ECSOUT); input CLK0; input CLK1; input SEL; @@ -443,19 +452,21 @@ module ECLKBRIDGECS (...); endmodule (* blackbox *) -module DCCA (...); +module DCCA(CLKI, CE, CLKO); input CLKI; input CE; output CLKO; endmodule (* blackbox *) (* keep *) -module START (...); +module START(STARTCLK); input STARTCLK; endmodule (* blackbox *) -module EHXPLLJ (...); +module EHXPLLJ(CLKI, CLKFB, PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE +, PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, PLLDATO7 +, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, DPHSRC, CLKINTFB); parameter CLKI_DIV = 1; parameter CLKFB_DIV = 1; parameter CLKOP_DIV = 8; @@ -557,7 +568,7 @@ module EHXPLLJ (...); endmodule (* blackbox *) -module OSCH (...); +module OSCH(STDBY, OSC, SEDSTDBY); parameter NOM_FREQ = "2.08"; input STDBY; output OSC; @@ -565,7 +576,7 @@ module OSCH (...); endmodule (* blackbox *) (* keep *) -module TSALL (...); +module TSALL(TSALL); input TSALL; endmodule diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v index 84d7d9601..e6208e6b4 100644 --- a/techlibs/lattice/cells_bb_xo3d.v +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -1,18 +1,21 @@ // Created by cells_xtra.py from Lattice models (* blackbox *) (* keep *) -module GSR (...); +module GSR(GSR); input GSR; endmodule (* blackbox *) (* keep *) -module SGSR (...); +module SGSR(GSR, CLK); input GSR; input CLK; endmodule (* blackbox *) -module DP8KC (...); +module DP8KC(DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1 +, ADA0, CEA, OCEA, CLKA, WEA, CSA2, CSA1, CSA0, RSTA, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, ADB12, ADB11, ADB10 +, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, CEB, OCEB, CLKB, WEB, CSB2, CSB1, CSB0, RSTB, DOA8, DOA7, DOA6 +, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0); parameter DATA_WIDTH_A = 9; parameter DATA_WIDTH_B = 9; parameter REGMODE_A = "NOREG"; @@ -138,7 +141,10 @@ module DP8KC (...); endmodule (* blackbox *) -module PDPW8KC (...); +module PDPW8KC(DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, ADW8, ADW7, ADW6 +, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5 +, ADR4, ADR3, ADR2, ADR1, ADR0, CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9 +, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; parameter REGMODE = "NOREG"; @@ -255,7 +261,8 @@ module PDPW8KC (...); endmodule (* blackbox *) -module SP8KC (...); +module SP8KC(DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1 +, AD0, CE, OCE, CLK, WE, CS2, CS1, CS0, RST, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0); parameter DATA_WIDTH = 9; parameter REGMODE = "NOREG"; parameter CSDECODE = "0b000"; @@ -338,7 +345,9 @@ module SP8KC (...); endmodule (* blackbox *) -module FIFO8KB (...); +module FIFO8KB(DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, CSW0, CSW1, CSR0 +, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10 +, DO11, DO12, DO13, DO14, DO15, DO16, DO17, EF, AEF, AFF, FF); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; parameter REGMODE = "NOREG"; @@ -409,7 +418,7 @@ module FIFO8KB (...); endmodule (* blackbox *) -module CLKDIVC (...); +module CLKDIVC(RST, CLKI, ALIGNWD, CDIV1, CDIVX); parameter GSR = "DISABLED"; parameter DIV = "2.0"; input RST; @@ -420,7 +429,7 @@ module CLKDIVC (...); endmodule (* blackbox *) -module DCMA (...); +module DCMA(CLK0, CLK1, SEL, DCMOUT); input CLK0; input CLK1; input SEL; @@ -428,14 +437,14 @@ module DCMA (...); endmodule (* blackbox *) -module ECLKSYNCA (...); +module ECLKSYNCA(ECLKI, STOP, ECLKO); input ECLKI; input STOP; output ECLKO; endmodule (* blackbox *) -module ECLKBRIDGECS (...); +module ECLKBRIDGECS(CLK0, CLK1, SEL, ECSOUT); input CLK0; input CLK1; input SEL; @@ -443,19 +452,21 @@ module ECLKBRIDGECS (...); endmodule (* blackbox *) -module DCCA (...); +module DCCA(CLKI, CE, CLKO); input CLKI; input CE; output CLKO; endmodule (* blackbox *) (* keep *) -module START (...); +module START(STARTCLK); input STARTCLK; endmodule (* blackbox *) -module EHXPLLJ (...); +module EHXPLLJ(CLKI, CLKFB, PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE +, PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, PLLDATO7 +, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, DPHSRC, CLKINTFB); parameter CLKI_DIV = 1; parameter CLKFB_DIV = 1; parameter CLKOP_DIV = 8; @@ -557,7 +568,7 @@ module EHXPLLJ (...); endmodule (* blackbox *) -module OSCJ (...); +module OSCJ(STDBY, OSC, SEDSTDBY, OSCESB); parameter NOM_FREQ = "2.08"; input STDBY; output OSC; @@ -566,7 +577,7 @@ module OSCJ (...); endmodule (* blackbox *) (* keep *) -module TSALL (...); +module TSALL(TSALL); input TSALL; endmodule diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index 744beb650..382dae3d8 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -402,8 +402,10 @@ struct SynthLatticePass : public ScriptPass if (check_label("coarse")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten"); + } run("tribuf -logic"); run("deminout"); run("opt_expr"); diff --git a/techlibs/microchip/synth_microchip.cc b/techlibs/microchip/synth_microchip.cc index e1d3c393a..218ed310f 100644 --- a/techlibs/microchip/synth_microchip.cc +++ b/techlibs/microchip/synth_microchip.cc @@ -267,8 +267,10 @@ struct SynthMicrochipPass : public ScriptPass { if (check_label("prepare")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten", "(with '-flatten')"); + } if (active_design) active_design->scratchpad_unset("tribuf.added_something"); run("tribuf -logic"); diff --git a/techlibs/nanoxplore/synth_nanoxplore.cc b/techlibs/nanoxplore/synth_nanoxplore.cc index 3445ea1be..0b87c98c7 100644 --- a/techlibs/nanoxplore/synth_nanoxplore.cc +++ b/techlibs/nanoxplore/synth_nanoxplore.cc @@ -250,8 +250,10 @@ struct SynthNanoXplorePass : public ScriptPass if (check_label("coarse")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten", "(skip if -noflatten)"); + } run("tribuf -logic"); run("deminout"); run("opt_expr"); diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index ade6f944c..e65be1c58 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -212,8 +212,10 @@ struct SynthQuickLogicPass : public ScriptPass { if (check_label("prepare")) { run("proc"); - if (flatten) + if (flatten) { + run("check"); run("flatten", "(unless -noflatten)"); + } if (help_mode || family == "pp3") { run("tribuf -logic", " (for pp3)"); } @@ -236,6 +238,7 @@ struct SynthQuickLogicPass : public ScriptPass { run("ql_dsp_macc"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=20 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=11 -D DSP_B_MINWIDTH=10 -D DSP_NAME=$__QL_MUL20X18"); + run("chtype -set $mul t:$__soft_mul"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=10 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=$__QL_MUL10X9"); run("chtype -set $mul t:$__soft_mul"); diff --git a/techlibs/sf2/NOTES.txt b/techlibs/sf2/NOTES.txt index 67784b546..6204d8fee 100644 --- a/techlibs/sf2/NOTES.txt +++ b/techlibs/sf2/NOTES.txt @@ -12,7 +12,7 @@ You'd better to write a simple script, like this one (assuming the top module is top): ----------- run_yosys.sh -------------- -#!/bin/sh +#!/usr/bin/env sh set -e diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index ad335536b..7a7f87466 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -172,6 +172,7 @@ struct SynthSf2Pass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { run("proc"); + run("check"); run("flatten"); run("tribuf -logic"); run("deminout"); diff --git a/techlibs/xilinx/brams_xc6v_map.v b/techlibs/xilinx/brams_xc6v_map.v index b2698a3aa..dfd6dfc9e 100644 --- a/techlibs/xilinx/brams_xc6v_map.v +++ b/techlibs/xilinx/brams_xc6v_map.v @@ -275,7 +275,7 @@ end else if (OPTION_MODE == "FULL") begin .DIADI(DI[31:0]), .DIBDI(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]), .DIPADIP(DIP[3:0]), - .DIPBDIP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]), + .DIPBDIP(PORT_W_WIDTH == 72 ? DIP[7:4] : DIP[3:0]), ); end diff --git a/techlibs/xilinx/brams_xcu_map.v b/techlibs/xilinx/brams_xcu_map.v index d48c21a59..01ee8a953 100644 --- a/techlibs/xilinx/brams_xcu_map.v +++ b/techlibs/xilinx/brams_xcu_map.v @@ -215,7 +215,7 @@ end else if (OPTION_MODE == "FULL") begin .DINADIN(DI[31:0]), .DINBDIN(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]), .DINPADINP(DIP[3:0]), - .DINPBDINP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]), + .DINPBDINP(PORT_W_WIDTH == 72 ? DIP[7:4] : DIP[3:0]), ); end diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index 8dc74b16e..e1736b14e 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -1,6 +1,6 @@ // Created by cells_xtra.py from Xilinx models -module RAMB4_S1 (...); +module RAMB4_S1(DO, ADDR, DI, EN, CLK, WE, RST); parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -27,7 +27,7 @@ module RAMB4_S1 (...); input RST; endmodule -module RAMB4_S2 (...); +module RAMB4_S2(DO, ADDR, DI, EN, CLK, WE, RST); parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -54,7 +54,7 @@ module RAMB4_S2 (...); input RST; endmodule -module RAMB4_S4 (...); +module RAMB4_S4(DO, ADDR, DI, EN, CLK, WE, RST); parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -81,7 +81,7 @@ module RAMB4_S4 (...); input RST; endmodule -module RAMB4_S8 (...); +module RAMB4_S8(DO, ADDR, DI, EN, CLK, WE, RST); parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -108,7 +108,7 @@ module RAMB4_S8 (...); input RST; endmodule -module RAMB4_S16 (...); +module RAMB4_S16(DO, ADDR, DI, EN, CLK, WE, RST); parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -135,7 +135,7 @@ module RAMB4_S16 (...); input RST; endmodule -module RAMB4_S1_S1 (...); +module RAMB4_S1_S1(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -171,7 +171,7 @@ module RAMB4_S1_S1 (...); input RSTB; endmodule -module RAMB4_S1_S2 (...); +module RAMB4_S1_S2(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -207,7 +207,7 @@ module RAMB4_S1_S2 (...); input RSTB; endmodule -module RAMB4_S1_S4 (...); +module RAMB4_S1_S4(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -243,7 +243,7 @@ module RAMB4_S1_S4 (...); input RSTB; endmodule -module RAMB4_S1_S8 (...); +module RAMB4_S1_S8(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -279,7 +279,7 @@ module RAMB4_S1_S8 (...); input RSTB; endmodule -module RAMB4_S1_S16 (...); +module RAMB4_S1_S16(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -315,7 +315,7 @@ module RAMB4_S1_S16 (...); input RSTB; endmodule -module RAMB4_S2_S2 (...); +module RAMB4_S2_S2(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -351,7 +351,7 @@ module RAMB4_S2_S2 (...); input RSTB; endmodule -module RAMB4_S2_S4 (...); +module RAMB4_S2_S4(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -387,7 +387,7 @@ module RAMB4_S2_S4 (...); input RSTB; endmodule -module RAMB4_S2_S8 (...); +module RAMB4_S2_S8(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -423,7 +423,7 @@ module RAMB4_S2_S8 (...); input RSTB; endmodule -module RAMB4_S2_S16 (...); +module RAMB4_S2_S16(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -459,7 +459,7 @@ module RAMB4_S2_S16 (...); input RSTB; endmodule -module RAMB4_S4_S4 (...); +module RAMB4_S4_S4(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -495,7 +495,7 @@ module RAMB4_S4_S4 (...); input RSTB; endmodule -module RAMB4_S4_S8 (...); +module RAMB4_S4_S8(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -531,7 +531,7 @@ module RAMB4_S4_S8 (...); input RSTB; endmodule -module RAMB4_S4_S16 (...); +module RAMB4_S4_S16(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -567,7 +567,7 @@ module RAMB4_S4_S16 (...); input RSTB; endmodule -module RAMB4_S8_S8 (...); +module RAMB4_S8_S8(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -603,7 +603,7 @@ module RAMB4_S8_S8 (...); input RSTB; endmodule -module RAMB4_S8_S16 (...); +module RAMB4_S8_S16(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -639,7 +639,7 @@ module RAMB4_S8_S16 (...); input RSTB; endmodule -module RAMB4_S16_S16 (...); +module RAMB4_S16_S16(DOA, ADDRA, DIA, ENA, CLKA, WEA, RSTA, DOB, ADDRB, DIB, ENB, CLKB, WEB, RSTB); parameter SIM_COLLISION_CHECK = "ALL"; parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -675,7 +675,7 @@ module RAMB4_S16_S16 (...); input RSTB; endmodule -module RAMB16_S1 (...); +module RAMB16_S1(DO, ADDR, DI, EN, CLK, WE, SSR); parameter [0:0] INIT = 1'h0; parameter [0:0] SRVAL = 1'h0; parameter WRITE_MODE = "WRITE_FIRST"; @@ -753,7 +753,7 @@ module RAMB16_S1 (...); input SSR; endmodule -module RAMB16_S2 (...); +module RAMB16_S2(DO, ADDR, DI, EN, CLK, WE, SSR); parameter [1:0] INIT = 2'h0; parameter [1:0] SRVAL = 2'h0; parameter WRITE_MODE = "WRITE_FIRST"; @@ -831,7 +831,7 @@ module RAMB16_S2 (...); input SSR; endmodule -module RAMB16_S4 (...); +module RAMB16_S4(DO, ADDR, DI, EN, CLK, WE, SSR); parameter [3:0] INIT = 4'h0; parameter [3:0] SRVAL = 4'h0; parameter WRITE_MODE = "WRITE_FIRST"; @@ -909,7 +909,7 @@ module RAMB16_S4 (...); input SSR; endmodule -module RAMB16_S9 (...); +module RAMB16_S9(DO, DOP, ADDR, DI, DIP, EN, CLK, WE, SSR); parameter [8:0] INIT = 9'h0; parameter [8:0] SRVAL = 9'h0; parameter WRITE_MODE = "WRITE_FIRST"; @@ -997,7 +997,7 @@ module RAMB16_S9 (...); input SSR; endmodule -module RAMB16_S18 (...); +module RAMB16_S18(DO, DOP, ADDR, DI, DIP, EN, CLK, WE, SSR); parameter [17:0] INIT = 18'h0; parameter [17:0] SRVAL = 18'h0; parameter WRITE_MODE = "WRITE_FIRST"; @@ -1085,7 +1085,7 @@ module RAMB16_S18 (...); input SSR; endmodule -module RAMB16_S36 (...); +module RAMB16_S36(DO, DOP, ADDR, DI, DIP, EN, CLK, WE, SSR); parameter [35:0] INIT = 36'h0; parameter [35:0] SRVAL = 36'h0; parameter WRITE_MODE = "WRITE_FIRST"; @@ -1173,7 +1173,7 @@ module RAMB16_S36 (...); input SSR; endmodule -module RAMB16_S1_S1 (...); +module RAMB16_S1_S1(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, ADDRB, DIB, ENB, CLKB, WEB, SSRB); parameter [0:0] INIT_A = 1'h0; parameter [0:0] INIT_B = 1'h0; parameter [0:0] SRVAL_A = 1'h0; @@ -1263,7 +1263,7 @@ module RAMB16_S1_S1 (...); input SSRB; endmodule -module RAMB16_S1_S2 (...); +module RAMB16_S1_S2(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, ADDRB, DIB, ENB, CLKB, WEB, SSRB); parameter [0:0] INIT_A = 1'h0; parameter [1:0] INIT_B = 2'h0; parameter [0:0] SRVAL_A = 1'h0; @@ -1353,7 +1353,7 @@ module RAMB16_S1_S2 (...); input SSRB; endmodule -module RAMB16_S1_S4 (...); +module RAMB16_S1_S4(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, ADDRB, DIB, ENB, CLKB, WEB, SSRB); parameter [0:0] INIT_A = 1'h0; parameter [3:0] INIT_B = 4'h0; parameter [0:0] SRVAL_A = 1'h0; @@ -1443,7 +1443,7 @@ module RAMB16_S1_S4 (...); input SSRB; endmodule -module RAMB16_S1_S9 (...); +module RAMB16_S1_S9(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [0:0] INIT_A = 1'h0; parameter [8:0] INIT_B = 9'h0; parameter [0:0] SRVAL_A = 1'h0; @@ -1543,7 +1543,7 @@ module RAMB16_S1_S9 (...); input SSRB; endmodule -module RAMB16_S1_S18 (...); +module RAMB16_S1_S18(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [0:0] INIT_A = 1'h0; parameter [17:0] INIT_B = 18'h0; parameter [0:0] SRVAL_A = 1'h0; @@ -1643,7 +1643,7 @@ module RAMB16_S1_S18 (...); input SSRB; endmodule -module RAMB16_S1_S36 (...); +module RAMB16_S1_S36(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [0:0] INIT_A = 1'h0; parameter [35:0] INIT_B = 36'h0; parameter [0:0] SRVAL_A = 1'h0; @@ -1743,7 +1743,7 @@ module RAMB16_S1_S36 (...); input SSRB; endmodule -module RAMB16_S2_S2 (...); +module RAMB16_S2_S2(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, ADDRB, DIB, ENB, CLKB, WEB, SSRB); parameter [1:0] INIT_A = 2'h0; parameter [1:0] INIT_B = 2'h0; parameter [1:0] SRVAL_A = 2'h0; @@ -1833,7 +1833,7 @@ module RAMB16_S2_S2 (...); input SSRB; endmodule -module RAMB16_S2_S4 (...); +module RAMB16_S2_S4(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, ADDRB, DIB, ENB, CLKB, WEB, SSRB); parameter [1:0] INIT_A = 2'h0; parameter [3:0] INIT_B = 4'h0; parameter [1:0] SRVAL_A = 2'h0; @@ -1923,7 +1923,7 @@ module RAMB16_S2_S4 (...); input SSRB; endmodule -module RAMB16_S2_S9 (...); +module RAMB16_S2_S9(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [1:0] INIT_A = 2'h0; parameter [8:0] INIT_B = 9'h0; parameter [1:0] SRVAL_A = 2'h0; @@ -2023,7 +2023,7 @@ module RAMB16_S2_S9 (...); input SSRB; endmodule -module RAMB16_S2_S18 (...); +module RAMB16_S2_S18(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [1:0] INIT_A = 2'h0; parameter [17:0] INIT_B = 18'h0; parameter [1:0] SRVAL_A = 2'h0; @@ -2123,7 +2123,7 @@ module RAMB16_S2_S18 (...); input SSRB; endmodule -module RAMB16_S2_S36 (...); +module RAMB16_S2_S36(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [1:0] INIT_A = 2'h0; parameter [35:0] INIT_B = 36'h0; parameter [1:0] SRVAL_A = 2'h0; @@ -2223,7 +2223,7 @@ module RAMB16_S2_S36 (...); input SSRB; endmodule -module RAMB16_S4_S4 (...); +module RAMB16_S4_S4(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, ADDRB, DIB, ENB, CLKB, WEB, SSRB); parameter [3:0] INIT_A = 4'h0; parameter [3:0] INIT_B = 4'h0; parameter [3:0] SRVAL_A = 4'h0; @@ -2313,7 +2313,7 @@ module RAMB16_S4_S4 (...); input SSRB; endmodule -module RAMB16_S4_S9 (...); +module RAMB16_S4_S9(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [3:0] INIT_A = 4'h0; parameter [8:0] INIT_B = 9'h0; parameter [3:0] SRVAL_A = 4'h0; @@ -2413,7 +2413,7 @@ module RAMB16_S4_S9 (...); input SSRB; endmodule -module RAMB16_S4_S18 (...); +module RAMB16_S4_S18(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [3:0] INIT_A = 4'h0; parameter [17:0] INIT_B = 18'h0; parameter [3:0] SRVAL_A = 4'h0; @@ -2513,7 +2513,7 @@ module RAMB16_S4_S18 (...); input SSRB; endmodule -module RAMB16_S4_S36 (...); +module RAMB16_S4_S36(DOA, ADDRA, DIA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [3:0] INIT_A = 4'h0; parameter [35:0] INIT_B = 36'h0; parameter [3:0] SRVAL_A = 4'h0; @@ -2613,7 +2613,7 @@ module RAMB16_S4_S36 (...); input SSRB; endmodule -module RAMB16_S9_S9 (...); +module RAMB16_S9_S9(DOA, DOPA, ADDRA, DIA, DIPA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [8:0] INIT_A = 9'h0; parameter [8:0] INIT_B = 9'h0; parameter [8:0] SRVAL_A = 9'h0; @@ -2715,7 +2715,7 @@ module RAMB16_S9_S9 (...); input SSRB; endmodule -module RAMB16_S9_S18 (...); +module RAMB16_S9_S18(DOA, DOPA, ADDRA, DIA, DIPA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [8:0] INIT_A = 9'h0; parameter [17:0] INIT_B = 18'h0; parameter [8:0] SRVAL_A = 9'h0; @@ -2817,7 +2817,7 @@ module RAMB16_S9_S18 (...); input SSRB; endmodule -module RAMB16_S9_S36 (...); +module RAMB16_S9_S36(DOA, DOPA, ADDRA, DIA, DIPA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [8:0] INIT_A = 9'h0; parameter [35:0] INIT_B = 36'h0; parameter [8:0] SRVAL_A = 9'h0; @@ -2919,7 +2919,7 @@ module RAMB16_S9_S36 (...); input SSRB; endmodule -module RAMB16_S18_S18 (...); +module RAMB16_S18_S18(DOA, DOPA, ADDRA, DIA, DIPA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [17:0] INIT_A = 18'h0; parameter [17:0] INIT_B = 18'h0; parameter [17:0] SRVAL_A = 18'h0; @@ -3021,7 +3021,7 @@ module RAMB16_S18_S18 (...); input SSRB; endmodule -module RAMB16_S18_S36 (...); +module RAMB16_S18_S36(DOA, DOPA, ADDRA, DIA, DIPA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [17:0] INIT_A = 18'h0; parameter [35:0] INIT_B = 36'h0; parameter [17:0] SRVAL_A = 18'h0; @@ -3123,7 +3123,7 @@ module RAMB16_S18_S36 (...); input SSRB; endmodule -module RAMB16_S36_S36 (...); +module RAMB16_S36_S36(DOA, DOPA, ADDRA, DIA, DIPA, ENA, CLKA, WEA, SSRA, DOB, DOPB, ADDRB, DIB, DIPB, ENB, CLKB, WEB, SSRB); parameter [35:0] INIT_A = 36'h0; parameter [35:0] INIT_B = 36'h0; parameter [35:0] SRVAL_A = 36'h0; @@ -3225,7 +3225,7 @@ module RAMB16_S36_S36 (...); input SSRB; endmodule -module RAMB16BWE_S18 (...); +module RAMB16BWE_S18(DO, DOP, CLK, EN, SSR, WE, DI, DIP, ADDR); parameter [17:0] INIT = 18'h0; parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; @@ -3313,7 +3313,7 @@ module RAMB16BWE_S18 (...); input [9:0] ADDR; endmodule -module RAMB16BWE_S36 (...); +module RAMB16BWE_S36(DO, DOP, CLK, EN, SSR, WE, DI, DIP, ADDR); parameter [35:0] INIT = 36'h0; parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; @@ -3401,7 +3401,7 @@ module RAMB16BWE_S36 (...); input [8:0] ADDR; endmodule -module RAMB16BWE_S18_S9 (...); +module RAMB16BWE_S18_S9(DOA, DOB, DOPA, DOPB, CLKA, CLKB, ENA, ENB, SSRA, SSRB, WEB, WEA, DIA, DIB, DIPA, DIPB, ADDRA, ADDRB); parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; parameter [255:0] INITP_02 = 256'h0; @@ -3503,7 +3503,7 @@ module RAMB16BWE_S18_S9 (...); input [10:0] ADDRB; endmodule -module RAMB16BWE_S18_S18 (...); +module RAMB16BWE_S18_S18(DOA, DOB, DOPA, DOPB, CLKA, CLKB, ENA, ENB, SSRA, SSRB, WEB, WEA, DIA, DIB, DIPA, DIPB, ADDRA, ADDRB); parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; parameter [255:0] INITP_02 = 256'h0; @@ -3605,7 +3605,7 @@ module RAMB16BWE_S18_S18 (...); input [9:0] ADDRB; endmodule -module RAMB16BWE_S36_S9 (...); +module RAMB16BWE_S36_S9(DOA, DOPA, DOB, DOPB, CLKA, CLKB, ENA, ENB, SSRA, SSRB, WEA, WEB, DIA, DIPA, DIB, DIPB, ADDRA, ADDRB); parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; parameter [255:0] INITP_02 = 256'h0; @@ -3707,7 +3707,7 @@ module RAMB16BWE_S36_S9 (...); input [10:0] ADDRB; endmodule -module RAMB16BWE_S36_S18 (...); +module RAMB16BWE_S36_S18(DOA, DOPA, DOB, DOPB, CLKA, CLKB, ENA, ENB, SSRA, SSRB, WEA, WEB, DIA, DIPA, DIB, DIPB, ADDRA, ADDRB); parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; parameter [255:0] INITP_02 = 256'h0; @@ -3809,7 +3809,7 @@ module RAMB16BWE_S36_S18 (...); input [9:0] ADDRB; endmodule -module RAMB16BWE_S36_S36 (...); +module RAMB16BWE_S36_S36(DOA, DOPA, DOB, DOPB, CLKA, CLKB, ENA, ENB, SSRA, SSRB, WEA, WEB, DIA, DIPA, DIB, DIPB, ADDRA, ADDRB); parameter [255:0] INITP_00 = 256'h0; parameter [255:0] INITP_01 = 256'h0; parameter [255:0] INITP_02 = 256'h0; @@ -3911,7 +3911,7 @@ module RAMB16BWE_S36_S36 (...); input [8:0] ADDRB; endmodule -module RAMB16BWER (...); +module RAMB16BWER(DOA, DOB, DOPA, DOPB, ADDRA, ADDRB, CLKA, CLKB, DIA, DIB, DIPA, DIPB, ENA, ENB, REGCEA, REGCEB, RSTA, RSTB, WEA, WEB); parameter integer DATA_WIDTH_A = 0; parameter integer DATA_WIDTH_B = 0; parameter integer DOA_REG = 0; @@ -4028,7 +4028,7 @@ module RAMB16BWER (...); input [3:0] WEB; endmodule -module RAMB8BWER (...); +module RAMB8BWER(DOADO, DOBDO, DOPADOP, DOPBDOP, ADDRAWRADDR, ADDRBRDADDR, CLKAWRCLK, CLKBRDCLK, DIADI, DIBDI, DIPADIP, DIPBDIP, ENAWREN, ENBRDEN, REGCEA, REGCEBREGCE, RSTA, RSTBRST, WEAWEL, WEBWEU); parameter integer DATA_WIDTH_A = 0; parameter integer DATA_WIDTH_B = 0; parameter integer DOA_REG = 0; @@ -4109,7 +4109,7 @@ module RAMB8BWER (...); input [1:0] WEBWEU; endmodule -module FIFO16 (...); +module FIFO16(ALMOSTEMPTY, ALMOSTFULL, DO, DOP, EMPTY, FULL, RDCOUNT, RDERR, WRCOUNT, WRERR, DI, DIP, RDCLK, RDEN, RST, WRCLK, WREN); parameter [11:0] ALMOST_FULL_OFFSET = 12'h080; parameter [11:0] ALMOST_EMPTY_OFFSET = 12'h080; parameter integer DATA_WIDTH = 36; @@ -4135,7 +4135,8 @@ module FIFO16 (...); input WREN; endmodule -module RAMB16 (...); +module RAMB16(CASCADEOUTA, CASCADEOUTB, DOA, DOB, DOPA, DOPB, ENA, CLKA, SSRA, CASCADEINA, REGCEA, ENB, CLKB, SSRB, CASCADEINB, REGCEB, ADDRA, ADDRB, DIA, DIB, DIPA +, DIPB, WEA, WEB); parameter integer DOA_REG = 0; parameter integer DOB_REG = 0; parameter [255:0] INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -4254,7 +4255,7 @@ module RAMB16 (...); input [3:0] WEB; endmodule -module RAMB32_S64_ECC (...); +module RAMB32_S64_ECC(STATUS, DO, RDCLK, RDEN, SSR, WRCLK, WREN, DI, RDADDR, WRADDR); parameter DO_REG = 0; parameter SIM_COLLISION_CHECK = "ALL"; output [1:0] STATUS; @@ -4271,7 +4272,7 @@ module RAMB32_S64_ECC (...); input [8:0] WRADDR; endmodule -module FIFO18 (...); +module FIFO18(ALMOSTEMPTY, ALMOSTFULL, DO, DOP, EMPTY, FULL, RDCOUNT, RDERR, WRCOUNT, WRERR, DI, DIP, RDCLK, RDEN, RST, WRCLK, WREN); parameter [11:0] ALMOST_EMPTY_OFFSET = 12'h080; parameter [11:0] ALMOST_FULL_OFFSET = 12'h080; parameter integer DATA_WIDTH = 4; @@ -4300,7 +4301,7 @@ module FIFO18 (...); input WREN; endmodule -module FIFO18_36 (...); +module FIFO18_36(ALMOSTEMPTY, ALMOSTFULL, DO, DOP, EMPTY, FULL, RDCOUNT, RDERR, WRCOUNT, WRERR, DI, DIP, RDCLK, RDEN, RST, WRCLK, WREN); parameter [8:0] ALMOST_EMPTY_OFFSET = 9'h080; parameter [8:0] ALMOST_FULL_OFFSET = 9'h080; parameter integer DO_REG = 1; @@ -4328,7 +4329,7 @@ module FIFO18_36 (...); input WREN; endmodule -module FIFO36 (...); +module FIFO36(ALMOSTEMPTY, ALMOSTFULL, DO, DOP, EMPTY, FULL, RDCOUNT, RDERR, WRCOUNT, WRERR, DI, DIP, RDCLK, RDEN, RST, WRCLK, WREN); parameter [12:0] ALMOST_EMPTY_OFFSET = 13'h080; parameter [12:0] ALMOST_FULL_OFFSET = 13'h080; parameter integer DATA_WIDTH = 4; @@ -4357,7 +4358,7 @@ module FIFO36 (...); input WREN; endmodule -module FIFO36_72 (...); +module FIFO36_72(ALMOSTEMPTY, ALMOSTFULL, DBITERR, DO, DOP, ECCPARITY, EMPTY, FULL, RDCOUNT, RDERR, SBITERR, WRCOUNT, WRERR, DI, DIP, RDCLK, RDEN, RST, WRCLK, WREN); parameter [8:0] ALMOST_EMPTY_OFFSET = 9'h080; parameter [8:0] ALMOST_FULL_OFFSET = 9'h080; parameter integer DO_REG = 1; @@ -4390,7 +4391,7 @@ module FIFO36_72 (...); input WREN; endmodule -module RAMB18 (...); +module RAMB18(DOA, DOB, DOPA, DOPB, ENA, CLKA, SSRA, REGCEA, ENB, CLKB, SSRB, REGCEB, ADDRA, ADDRB, DIA, DIB, DIPA, DIPB, WEA, WEB); parameter integer DOA_REG = 0; parameter integer DOB_REG = 0; parameter [255:0] INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -4502,7 +4503,8 @@ module RAMB18 (...); input [1:0] WEB; endmodule -module RAMB36 (...); +module RAMB36(CASCADEOUTLATA, CASCADEOUTREGA, CASCADEOUTLATB, CASCADEOUTREGB, DOA, DOB, DOPA, DOPB, ENA, CLKA, SSRA, CASCADEINLATA, CASCADEINREGA, REGCEA, ENB, CLKB, SSRB, CASCADEINLATB, CASCADEINREGB, REGCEB, ADDRA +, ADDRB, DIA, DIB, DIPA, DIPB, WEA, WEB); parameter integer DOA_REG = 0; parameter integer DOB_REG = 0; parameter [255:0] INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -4696,7 +4698,7 @@ module RAMB36 (...); input [3:0] WEB; endmodule -module RAMB18SDP (...); +module RAMB18SDP(DO, DOP, RDCLK, RDEN, REGCE, SSR, WRCLK, WREN, WRADDR, RDADDR, DI, DIP, WE); parameter integer DO_REG = 0; parameter [35:0] INIT = 36'h0; parameter [255:0] INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; @@ -4792,7 +4794,7 @@ module RAMB18SDP (...); input [3:0] WE; endmodule -module RAMB36SDP (...); +module RAMB36SDP(DBITERR, SBITERR, DO, DOP, ECCPARITY, RDCLK, RDEN, REGCE, SSR, WRCLK, WREN, WRADDR, RDADDR, DI, DIP, WE); parameter integer DO_REG = 0; parameter EN_ECC_READ = "FALSE"; parameter EN_ECC_SCRUB = "FALSE"; @@ -4966,7 +4968,7 @@ module RAMB36SDP (...); input [7:0] WE; endmodule -module FIFO18E1 (...); +module FIFO18E1(ALMOSTEMPTY, ALMOSTFULL, DO, DOP, EMPTY, FULL, RDCOUNT, RDERR, WRCOUNT, WRERR, DI, DIP, RDCLK, RDEN, REGCE, RST, RSTREG, WRCLK, WREN); parameter ALMOST_EMPTY_OFFSET = 13'h0080; parameter ALMOST_FULL_OFFSET = 13'h0080; parameter integer DATA_WIDTH = 4; @@ -5012,7 +5014,8 @@ module FIFO18E1 (...); input WREN; endmodule -module FIFO36E1 (...); +module FIFO36E1(ALMOSTEMPTY, ALMOSTFULL, DBITERR, DO, DOP, ECCPARITY, EMPTY, FULL, RDCOUNT, RDERR, SBITERR, WRCOUNT, WRERR, DI, DIP, INJECTDBITERR, INJECTSBITERR, RDCLK, RDEN, REGCE, RST +, RSTREG, WRCLK, WREN); parameter ALMOST_EMPTY_OFFSET = 13'h0080; parameter ALMOST_FULL_OFFSET = 13'h0080; parameter integer DATA_WIDTH = 4; @@ -5065,7 +5068,8 @@ module FIFO36E1 (...); input WREN; endmodule -module FIFO18E2 (...); +module FIFO18E2(CASDOUT, CASDOUTP, CASNXTEMPTY, CASPRVRDEN, DOUT, DOUTP, EMPTY, FULL, PROGEMPTY, PROGFULL, RDCOUNT, RDERR, RDRSTBUSY, WRCOUNT, WRERR, WRRSTBUSY, CASDIN, CASDINP, CASDOMUX, CASDOMUXEN, CASNXTRDEN +, CASOREGIMUX, CASOREGIMUXEN, CASPRVEMPTY, DIN, DINP, RDCLK, RDEN, REGCE, RST, RSTREG, SLEEP, WRCLK, WREN); parameter CASCADE_ORDER = "NONE"; parameter CLOCK_DOMAINS = "INDEPENDENT"; parameter FIRST_WORD_FALL_THROUGH = "FALSE"; @@ -5130,7 +5134,8 @@ module FIFO18E2 (...); input WREN; endmodule -module FIFO36E2 (...); +module FIFO36E2(CASDOUT, CASDOUTP, CASNXTEMPTY, CASPRVRDEN, DBITERR, DOUT, DOUTP, ECCPARITY, EMPTY, FULL, PROGEMPTY, PROGFULL, RDCOUNT, RDERR, RDRSTBUSY, SBITERR, WRCOUNT, WRERR, WRRSTBUSY, CASDIN, CASDINP +, CASDOMUX, CASDOMUXEN, CASNXTRDEN, CASOREGIMUX, CASOREGIMUXEN, CASPRVEMPTY, DIN, DINP, INJECTDBITERR, INJECTSBITERR, RDCLK, RDEN, REGCE, RST, RSTREG, SLEEP, WRCLK, WREN); parameter CASCADE_ORDER = "NONE"; parameter CLOCK_DOMAINS = "INDEPENDENT"; parameter EN_ECC_PIPE = "FALSE"; @@ -5203,7 +5208,9 @@ module FIFO36E2 (...); input WREN; endmodule -module RAMB18E2 (...); +module RAMB18E2(CASDOUTA, CASDOUTB, CASDOUTPA, CASDOUTPB, DOUTADOUT, DOUTBDOUT, DOUTPADOUTP, DOUTPBDOUTP, ADDRARDADDR, ADDRBWRADDR, ADDRENA, ADDRENB, CASDIMUXA, CASDIMUXB, CASDINA, CASDINB, CASDINPA, CASDINPB, CASDOMUXA, CASDOMUXB, CASDOMUXEN_A +, CASDOMUXEN_B, CASOREGIMUXA, CASOREGIMUXB, CASOREGIMUXEN_A, CASOREGIMUXEN_B, CLKARDCLK, CLKBWRCLK, DINADIN, DINBDIN, DINPADINP, DINPBDINP, ENARDEN, ENBWREN, REGCEAREGCE, REGCEB, RSTRAMARSTRAM, RSTRAMB, RSTREGARSTREG, RSTREGB, SLEEP, WEA +, WEBWE); parameter CASCADE_ORDER_A = "NONE"; parameter CASCADE_ORDER_B = "NONE"; parameter CLOCK_DOMAINS = "INDEPENDENT"; @@ -5363,7 +5370,9 @@ module RAMB18E2 (...); input [3:0] WEBWE; endmodule -module RAMB36E2 (...); +module RAMB36E2(CASDOUTA, CASDOUTB, CASDOUTPA, CASDOUTPB, CASOUTDBITERR, CASOUTSBITERR, DBITERR, DOUTADOUT, DOUTBDOUT, DOUTPADOUTP, DOUTPBDOUTP, ECCPARITY, RDADDRECC, SBITERR, ADDRARDADDR, ADDRBWRADDR, ADDRENA, ADDRENB, CASDIMUXA, CASDIMUXB, CASDINA +, CASDINB, CASDINPA, CASDINPB, CASDOMUXA, CASDOMUXB, CASDOMUXEN_A, CASDOMUXEN_B, CASINDBITERR, CASINSBITERR, CASOREGIMUXA, CASOREGIMUXB, CASOREGIMUXEN_A, CASOREGIMUXEN_B, CLKARDCLK, CLKBWRCLK, DINADIN, DINBDIN, DINPADINP, DINPBDINP, ECCPIPECE, ENARDEN +, ENBWREN, INJECTDBITERR, INJECTSBITERR, REGCEAREGCE, REGCEB, RSTRAMARSTRAM, RSTRAMB, RSTREGARSTREG, RSTREGB, SLEEP, WEA, WEBWE); parameter CASCADE_ORDER_A = "NONE"; parameter CASCADE_ORDER_B = "NONE"; parameter CLOCK_DOMAINS = "INDEPENDENT"; @@ -5609,7 +5618,10 @@ module RAMB36E2 (...); input [7:0] WEBWE; endmodule -module URAM288 (...); +module URAM288(CAS_OUT_ADDR_A, CAS_OUT_ADDR_B, CAS_OUT_BWE_A, CAS_OUT_BWE_B, CAS_OUT_DBITERR_A, CAS_OUT_DBITERR_B, CAS_OUT_DIN_A, CAS_OUT_DIN_B, CAS_OUT_DOUT_A, CAS_OUT_DOUT_B, CAS_OUT_EN_A, CAS_OUT_EN_B, CAS_OUT_RDACCESS_A, CAS_OUT_RDACCESS_B, CAS_OUT_RDB_WR_A, CAS_OUT_RDB_WR_B, CAS_OUT_SBITERR_A, CAS_OUT_SBITERR_B, DBITERR_A, DBITERR_B, DOUT_A +, DOUT_B, RDACCESS_A, RDACCESS_B, SBITERR_A, SBITERR_B, ADDR_A, ADDR_B, BWE_A, BWE_B, CAS_IN_ADDR_A, CAS_IN_ADDR_B, CAS_IN_BWE_A, CAS_IN_BWE_B, CAS_IN_DBITERR_A, CAS_IN_DBITERR_B, CAS_IN_DIN_A, CAS_IN_DIN_B, CAS_IN_DOUT_A, CAS_IN_DOUT_B, CAS_IN_EN_A, CAS_IN_EN_B +, CAS_IN_RDACCESS_A, CAS_IN_RDACCESS_B, CAS_IN_RDB_WR_A, CAS_IN_RDB_WR_B, CAS_IN_SBITERR_A, CAS_IN_SBITERR_B, CLK, DIN_A, DIN_B, EN_A, EN_B, INJECT_DBITERR_A, INJECT_DBITERR_B, INJECT_SBITERR_A, INJECT_SBITERR_B, OREG_CE_A, OREG_CE_B, OREG_ECC_CE_A, OREG_ECC_CE_B, RDB_WR_A, RDB_WR_B +, RST_A, RST_B, SLEEP); parameter integer AUTO_SLEEP_LATENCY = 8; parameter integer AVG_CONS_INACTIVE_CYCLES = 10; parameter BWE_MODE_A = "PARITY_INTERLEAVED"; @@ -5724,7 +5736,8 @@ module URAM288 (...); input SLEEP; endmodule -module URAM288_BASE (...); +module URAM288_BASE(DBITERR_A, DBITERR_B, DOUT_A, DOUT_B, SBITERR_A, SBITERR_B, ADDR_A, ADDR_B, BWE_A, BWE_B, CLK, DIN_A, DIN_B, EN_A, EN_B, INJECT_DBITERR_A, INJECT_DBITERR_B, INJECT_SBITERR_A, INJECT_SBITERR_B, OREG_CE_A, OREG_CE_B +, OREG_ECC_CE_A, OREG_ECC_CE_B, RDB_WR_A, RDB_WR_B, RST_A, RST_B, SLEEP); parameter integer AUTO_SLEEP_LATENCY = 8; parameter integer AVG_CONS_INACTIVE_CYCLES = 10; parameter BWE_MODE_A = "PARITY_INTERLEAVED"; @@ -5789,7 +5802,9 @@ module URAM288_BASE (...); input SLEEP; endmodule -module DSP48E (...); +module DSP48E(ACOUT, BCOUT, CARRYCASCOUT, CARRYOUT, MULTSIGNOUT, OVERFLOW, P, PATTERNBDETECT, PATTERNDETECT, PCOUT, UNDERFLOW, A, ACIN, ALUMODE, B, BCIN, C, CARRYCASCIN, CARRYIN, CARRYINSEL, CEA1 +, CEA2, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL, CEM, CEMULTCARRYIN, CEP, CLK, MULTSIGNIN, OPMODE, PCIN, RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTM +, RSTP); parameter SIM_MODE = "SAFE"; parameter integer ACASCREG = 1; parameter integer ALUMODEREG = 1; @@ -5861,7 +5876,9 @@ module DSP48E (...); input RSTP; endmodule -module DSP48E2 (...); +module DSP48E2(ACOUT, BCOUT, CARRYCASCOUT, CARRYOUT, MULTSIGNOUT, OVERFLOW, P, PATTERNBDETECT, PATTERNDETECT, PCOUT, UNDERFLOW, XOROUT, A, ACIN, ALUMODE, B, BCIN, C, CARRYCASCIN, CARRYIN, CARRYINSEL +, CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL, CED, CEINMODE, CEM, CEP, CLK, D, INMODE, MULTSIGNIN, OPMODE, PCIN, RSTA, RSTALLCARRYIN +, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP); parameter integer ACASCREG = 1; parameter integer ADREG = 1; parameter integer ALUMODEREG = 1; @@ -5976,7 +5993,7 @@ module DSP48E2 (...); input RSTP; endmodule -module FDDRCPE (...); +module FDDRCPE(C0, C1, CE, D0, D1, CLR, PRE, Q); parameter INIT = 1'b0; (* clkbuf_sink *) input C0; @@ -5990,7 +6007,7 @@ module FDDRCPE (...); output Q; endmodule -module FDDRRSE (...); +module FDDRRSE(Q, C0, C1, CE, D0, D1, R, S); parameter INIT = 1'b0; output Q; (* clkbuf_sink *) @@ -6004,7 +6021,7 @@ module FDDRRSE (...); input S; endmodule -module IFDDRCPE (...); +module IFDDRCPE(Q0, Q1, C0, C1, CE, CLR, D, PRE); output Q0; output Q1; (* clkbuf_sink *) @@ -6018,7 +6035,7 @@ module IFDDRCPE (...); input PRE; endmodule -module IFDDRRSE (...); +module IFDDRRSE(Q0, Q1, C0, C1, CE, D, R, S); output Q0; output Q1; (* clkbuf_sink *) @@ -6032,7 +6049,7 @@ module IFDDRRSE (...); input S; endmodule -module OFDDRCPE (...); +module OFDDRCPE(Q, C0, C1, CE, CLR, D0, D1, PRE); (* iopad_external_pin *) output Q; (* clkbuf_sink *) @@ -6046,7 +6063,7 @@ module OFDDRCPE (...); input PRE; endmodule -module OFDDRRSE (...); +module OFDDRRSE(Q, C0, C1, CE, D0, D1, R, S); (* iopad_external_pin *) output Q; (* clkbuf_sink *) @@ -6060,7 +6077,7 @@ module OFDDRRSE (...); input S; endmodule -module OFDDRTCPE (...); +module OFDDRTCPE(O, C0, C1, CE, CLR, D0, D1, PRE, T); (* iopad_external_pin *) output O; (* clkbuf_sink *) @@ -6075,7 +6092,7 @@ module OFDDRTCPE (...); input T; endmodule -module OFDDRTRSE (...); +module OFDDRTRSE(O, C0, C1, CE, D0, D1, R, S, T); (* iopad_external_pin *) output O; (* clkbuf_sink *) @@ -6090,7 +6107,7 @@ module OFDDRTRSE (...); input T; endmodule -module IDDR2 (...); +module IDDR2(Q0, Q1, C0, C1, CE, D, R, S); parameter DDR_ALIGNMENT = "NONE"; parameter [0:0] INIT_Q0 = 1'b0; parameter [0:0] INIT_Q1 = 1'b0; @@ -6107,7 +6124,7 @@ module IDDR2 (...); input S; endmodule -module ODDR2 (...); +module ODDR2(Q, C0, C1, CE, D0, D1, R, S); parameter DDR_ALIGNMENT = "NONE"; parameter [0:0] INIT = 1'b0; parameter SRTYPE = "SYNC"; @@ -6123,7 +6140,7 @@ module ODDR2 (...); input S; endmodule -module IDDR (...); +module IDDR(Q1, Q2, C, CE, D, R, S); parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; parameter INIT_Q1 = 1'b0; parameter INIT_Q2 = 1'b0; @@ -6144,7 +6161,7 @@ module IDDR (...); input S; endmodule -module IDDR_2CLK (...); +module IDDR_2CLK(Q1, Q2, C, CB, CE, D, R, S); parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; parameter INIT_Q1 = 1'b0; parameter INIT_Q2 = 1'b0; @@ -6167,7 +6184,7 @@ module IDDR_2CLK (...); input S; endmodule -module ODDR (...); +module ODDR(Q, C, CE, D1, D2, R, S); parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; parameter INIT = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; @@ -6190,7 +6207,7 @@ module ODDR (...); endmodule (* keep *) -module IDELAYCTRL (...); +module IDELAYCTRL(RDY, REFCLK, RST); parameter SIM_DEVICE = "7SERIES"; output RDY; (* clkbuf_sink *) @@ -6198,7 +6215,7 @@ module IDELAYCTRL (...); input RST; endmodule -module IDELAY (...); +module IDELAY(O, C, CE, I, INC, RST); parameter IOBDELAY_TYPE = "DEFAULT"; parameter integer IOBDELAY_VALUE = 0; output O; @@ -6210,7 +6227,8 @@ module IDELAY (...); input RST; endmodule -module ISERDES (...); +module ISERDES(O, Q1, Q2, Q3, Q4, Q5, Q6, SHIFTOUT1, SHIFTOUT2, BITSLIP, CE1, CE2, CLK, CLKDIV, D, DLYCE, DLYINC, DLYRST, OCLK, REV, SHIFTIN1 +, SHIFTIN2, SR); parameter BITSLIP_ENABLE = "FALSE"; parameter DATA_RATE = "DDR"; parameter integer DATA_WIDTH = 4; @@ -6259,7 +6277,8 @@ module ISERDES (...); input SR; endmodule -module OSERDES (...); +module OSERDES(OQ, SHIFTOUT1, SHIFTOUT2, TQ, CLK, CLKDIV, D1, D2, D3, D4, D5, D6, OCE, REV, SHIFTIN1, SHIFTIN2, SR, T1, T2, T3, T4 +, TCE); parameter DATA_RATE_OQ = "DDR"; parameter DATA_RATE_TQ = "DDR"; parameter integer DATA_WIDTH = 4; @@ -6295,7 +6314,7 @@ module OSERDES (...); input TCE; endmodule -module IODELAY (...); +module IODELAY(DATAOUT, C, CE, DATAIN, IDATAIN, INC, ODATAIN, RST, T); parameter DELAY_SRC = "I"; parameter HIGH_PERFORMANCE_MODE = "TRUE"; parameter IDELAY_TYPE = "DEFAULT"; @@ -6315,7 +6334,7 @@ module IODELAY (...); input T; endmodule -module ISERDES_NODELAY (...); +module ISERDES_NODELAY(Q1, Q2, Q3, Q4, Q5, Q6, SHIFTOUT1, SHIFTOUT2, BITSLIP, CE1, CE2, CLK, CLKB, CLKDIV, D, OCLK, RST, SHIFTIN1, SHIFTIN2); parameter BITSLIP_ENABLE = "FALSE"; parameter DATA_RATE = "DDR"; parameter integer DATA_WIDTH = 4; @@ -6351,7 +6370,7 @@ module ISERDES_NODELAY (...); input SHIFTIN2; endmodule -module IODELAYE1 (...); +module IODELAYE1(CNTVALUEOUT, DATAOUT, C, CE, CINVCTRL, CLKIN, CNTVALUEIN, DATAIN, IDATAIN, INC, ODATAIN, RST, T); parameter CINVCTRL_SEL = "FALSE"; parameter DELAY_SRC = "I"; parameter HIGH_PERFORMANCE_MODE = "FALSE"; @@ -6377,7 +6396,8 @@ module IODELAYE1 (...); input T; endmodule -module ISERDESE1 (...); +module ISERDESE1(O, Q1, Q2, Q3, Q4, Q5, Q6, SHIFTOUT1, SHIFTOUT2, BITSLIP, CE1, CE2, CLK, CLKB, CLKDIV, D, DDLY, DYNCLKDIVSEL, DYNCLKSEL, OCLK, OFB +, RST, SHIFTIN1, SHIFTIN2); parameter DATA_RATE = "DDR"; parameter integer DATA_WIDTH = 4; parameter DYN_CLKDIV_INV_EN = "FALSE"; @@ -6425,7 +6445,8 @@ module ISERDESE1 (...); input SHIFTIN2; endmodule -module OSERDESE1 (...); +module OSERDESE1(OCBEXTEND, OFB, OQ, SHIFTOUT1, SHIFTOUT2, TFB, TQ, CLK, CLKDIV, CLKPERF, CLKPERFDELAY, D1, D2, D3, D4, D5, D6, OCE, ODV, RST, SHIFTIN1 +, SHIFTIN2, T1, T2, T3, T4, TCE, WC); parameter DATA_RATE_OQ = "DDR"; parameter DATA_RATE_TQ = "DDR"; parameter integer DATA_WIDTH = 4; @@ -6470,7 +6491,7 @@ module OSERDESE1 (...); input WC; endmodule -module IDELAYE2 (...); +module IDELAYE2(CNTVALUEOUT, DATAOUT, C, CE, CINVCTRL, CNTVALUEIN, DATAIN, IDATAIN, INC, LD, LDPIPEEN, REGRST); parameter CINVCTRL_SEL = "FALSE"; parameter DELAY_SRC = "IDATAIN"; parameter HIGH_PERFORMANCE_MODE = "FALSE"; @@ -6501,7 +6522,7 @@ module IDELAYE2 (...); input REGRST; endmodule -module ODELAYE2 (...); +module ODELAYE2(CNTVALUEOUT, DATAOUT, C, CE, CINVCTRL, CLKIN, CNTVALUEIN, INC, LD, LDPIPEEN, ODATAIN, REGRST); parameter CINVCTRL_SEL = "FALSE"; parameter DELAY_SRC = "ODATAIN"; parameter HIGH_PERFORMANCE_MODE = "FALSE"; @@ -6530,7 +6551,8 @@ module ODELAYE2 (...); input REGRST; endmodule -module ISERDESE2 (...); +module ISERDESE2(O, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, SHIFTOUT1, SHIFTOUT2, BITSLIP, CE1, CE2, CLK, CLKB, CLKDIV, CLKDIVP, D, DDLY, DYNCLKDIVSEL +, DYNCLKSEL, OCLK, OCLKB, OFB, RST, SHIFTIN1, SHIFTIN2); parameter DATA_RATE = "DDR"; parameter integer DATA_WIDTH = 4; parameter DYN_CLKDIV_INV_EN = "FALSE"; @@ -6598,7 +6620,8 @@ module ISERDESE2 (...); input SHIFTIN2; endmodule -module OSERDESE2 (...); +module OSERDESE2(OFB, OQ, SHIFTOUT1, SHIFTOUT2, TBYTEOUT, TFB, TQ, CLK, CLKDIV, D1, D2, D3, D4, D5, D6, D7, D8, OCE, RST, SHIFTIN1, SHIFTIN2 +, T1, T2, T3, T4, TBYTEIN, TCE); parameter DATA_RATE_OQ = "DDR"; parameter DATA_RATE_TQ = "DDR"; parameter integer DATA_WIDTH = 4; @@ -6670,7 +6693,7 @@ module OSERDESE2 (...); endmodule (* keep *) -module PHASER_IN (...); +module PHASER_IN(FINEOVERFLOW, ICLK, ICLKDIV, ISERDESRST, RCLK, COUNTERREADVAL, COUNTERLOADEN, COUNTERREADEN, DIVIDERST, EDGEADV, FINEENABLE, FINEINC, FREQREFCLK, MEMREFCLK, PHASEREFCLK, RST, SYNCIN, SYSCLK, RANKSEL, COUNTERLOADVAL); parameter integer CLKOUT_DIV = 4; parameter DQS_BIAS_MODE = "FALSE"; parameter EN_ISERDES_RST = "FALSE"; @@ -6707,7 +6730,8 @@ module PHASER_IN (...); endmodule (* keep *) -module PHASER_IN_PHY (...); +module PHASER_IN_PHY(DQSFOUND, DQSOUTOFRANGE, FINEOVERFLOW, ICLK, ICLKDIV, ISERDESRST, PHASELOCKED, RCLK, WRENABLE, COUNTERREADVAL, BURSTPENDINGPHY, COUNTERLOADEN, COUNTERREADEN, FINEENABLE, FINEINC, FREQREFCLK, MEMREFCLK, PHASEREFCLK, RST, RSTDQSFIND, SYNCIN +, SYSCLK, ENCALIBPHY, RANKSELPHY, COUNTERLOADVAL); parameter BURST_MODE = "FALSE"; parameter integer CLKOUT_DIV = 4; parameter [0:0] DQS_AUTO_RECAL = 1'b1; @@ -6752,7 +6776,8 @@ module PHASER_IN_PHY (...); endmodule (* keep *) -module PHASER_OUT (...); +module PHASER_OUT(COARSEOVERFLOW, FINEOVERFLOW, OCLK, OCLKDELAYED, OCLKDIV, OSERDESRST, COUNTERREADVAL, COARSEENABLE, COARSEINC, COUNTERLOADEN, COUNTERREADEN, DIVIDERST, EDGEADV, FINEENABLE, FINEINC, FREQREFCLK, MEMREFCLK, PHASEREFCLK, RST, SELFINEOCLKDELAY, SYNCIN +, SYSCLK, COUNTERLOADVAL); parameter integer CLKOUT_DIV = 4; parameter COARSE_BYPASS = "FALSE"; parameter integer COARSE_DELAY = 0; @@ -6794,7 +6819,8 @@ module PHASER_OUT (...); endmodule (* keep *) -module PHASER_OUT_PHY (...); +module PHASER_OUT_PHY(COARSEOVERFLOW, FINEOVERFLOW, OCLK, OCLKDELAYED, OCLKDIV, OSERDESRST, RDENABLE, CTSBUS, DQSBUS, DTSBUS, COUNTERREADVAL, BURSTPENDINGPHY, COARSEENABLE, COARSEINC, COUNTERLOADEN, COUNTERREADEN, FINEENABLE, FINEINC, FREQREFCLK, MEMREFCLK, PHASEREFCLK +, RST, SELFINEOCLKDELAY, SYNCIN, SYSCLK, ENCALIBPHY, COUNTERLOADVAL); parameter integer CLKOUT_DIV = 4; parameter COARSE_BYPASS = "FALSE"; parameter integer COARSE_DELAY = 0; @@ -6841,7 +6867,7 @@ module PHASER_OUT_PHY (...); endmodule (* keep *) -module PHASER_REF (...); +module PHASER_REF(LOCKED, CLKIN, PWRDWN, RST); parameter [0:0] IS_RST_INVERTED = 1'b0; parameter [0:0] IS_PWRDWN_INVERTED = 1'b0; output LOCKED; @@ -6853,7 +6879,8 @@ module PHASER_REF (...); endmodule (* keep *) -module PHY_CONTROL (...); +module PHY_CONTROL(PHYCTLALMOSTFULL, PHYCTLEMPTY, PHYCTLFULL, PHYCTLREADY, INRANKA, INRANKB, INRANKC, INRANKD, PCENABLECALIB, AUXOUTPUT, INBURSTPENDING, OUTBURSTPENDING, MEMREFCLK, PHYCLK, PHYCTLMSTREMPTY, PHYCTLWRENABLE, PLLLOCK, READCALIBENABLE, REFDLLLOCK, RESET, SYNCIN +, WRITECALIBENABLE, PHYCTLWD); parameter integer AO_TOGGLE = 0; parameter [3:0] AO_WRLVL_EN = 4'b0000; parameter BURST_MODE = "FALSE"; @@ -6913,7 +6940,7 @@ module PHY_CONTROL (...); input [31:0] PHYCTLWD; endmodule -module IDDRE1 (...); +module IDDRE1(Q1, Q2, C, CB, D, R); parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; parameter [0:0] IS_CB_INVERTED = 1'b0; parameter [0:0] IS_C_INVERTED = 1'b0; @@ -6929,7 +6956,7 @@ module IDDRE1 (...); input R; endmodule -module ODDRE1 (...); +module ODDRE1(Q, C, D1, D2, SR); parameter [0:0] IS_C_INVERTED = 1'b0; parameter [0:0] IS_D1_INVERTED = 1'b0; parameter [0:0] IS_D2_INVERTED = 1'b0; @@ -6946,7 +6973,7 @@ module ODDRE1 (...); input SR; endmodule -module IDELAYE3 (...); +module IDELAYE3(CASC_OUT, CNTVALUEOUT, DATAOUT, CASC_IN, CASC_RETURN, CE, CLK, CNTVALUEIN, DATAIN, EN_VTC, IDATAIN, INC, LOAD, RST); parameter CASCADE = "NONE"; parameter DELAY_FORMAT = "TIME"; parameter DELAY_SRC = "IDATAIN"; @@ -6978,7 +7005,7 @@ module IDELAYE3 (...); input RST; endmodule -module ODELAYE3 (...); +module ODELAYE3(CASC_OUT, CNTVALUEOUT, DATAOUT, CASC_IN, CASC_RETURN, CE, CLK, CNTVALUEIN, EN_VTC, INC, LOAD, ODATAIN, RST); parameter CASCADE = "NONE"; parameter DELAY_FORMAT = "TIME"; parameter DELAY_TYPE = "FIXED"; @@ -7007,7 +7034,7 @@ module ODELAYE3 (...); input RST; endmodule -module ISERDESE3 (...); +module ISERDESE3(FIFO_EMPTY, INTERNAL_DIVCLK, Q, CLK, CLKDIV, CLK_B, D, FIFO_RD_CLK, FIFO_RD_EN, RST); parameter integer DATA_WIDTH = 8; parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; parameter FIFO_ENABLE = "FALSE"; @@ -7037,7 +7064,7 @@ module ISERDESE3 (...); input RST; endmodule -module OSERDESE3 (...); +module OSERDESE3(OQ, T_OUT, CLK, CLKDIV, D, RST, T); parameter integer DATA_WIDTH = 8; parameter [0:0] INIT = 1'b0; parameter [0:0] IS_CLKDIV_INVERTED = 1'b0; @@ -7063,7 +7090,9 @@ module OSERDESE3 (...); endmodule (* keep *) -module BITSLICE_CONTROL (...); +module BITSLICE_CONTROL(CLK_TO_EXT_NORTH, CLK_TO_EXT_SOUTH, DLY_RDY, DYN_DCI, NCLK_NIBBLE_OUT, PCLK_NIBBLE_OUT, RIU_RD_DATA, RIU_VALID, RX_BIT_CTRL_OUT0, RX_BIT_CTRL_OUT1, RX_BIT_CTRL_OUT2, RX_BIT_CTRL_OUT3, RX_BIT_CTRL_OUT4, RX_BIT_CTRL_OUT5, RX_BIT_CTRL_OUT6, TX_BIT_CTRL_OUT0, TX_BIT_CTRL_OUT1, TX_BIT_CTRL_OUT2, TX_BIT_CTRL_OUT3, TX_BIT_CTRL_OUT4, TX_BIT_CTRL_OUT5 +, TX_BIT_CTRL_OUT6, TX_BIT_CTRL_OUT_TRI, VTC_RDY, CLK_FROM_EXT, EN_VTC, NCLK_NIBBLE_IN, PCLK_NIBBLE_IN, PHY_RDCS0, PHY_RDCS1, PHY_RDEN, PHY_WRCS0, PHY_WRCS1, PLL_CLK, REFCLK, RIU_ADDR, RIU_CLK, RIU_NIBBLE_SEL, RIU_WR_DATA, RIU_WR_EN, RST, RX_BIT_CTRL_IN0 +, RX_BIT_CTRL_IN1, RX_BIT_CTRL_IN2, RX_BIT_CTRL_IN3, RX_BIT_CTRL_IN4, RX_BIT_CTRL_IN5, RX_BIT_CTRL_IN6, TBYTE_IN, TX_BIT_CTRL_IN0, TX_BIT_CTRL_IN1, TX_BIT_CTRL_IN2, TX_BIT_CTRL_IN3, TX_BIT_CTRL_IN4, TX_BIT_CTRL_IN5, TX_BIT_CTRL_IN6, TX_BIT_CTRL_IN_TRI); parameter CTRL_CLK = "EXTERNAL"; parameter DIV_MODE = "DIV2"; parameter EN_CLK_TO_EXT_NORTH = "DISABLE"; @@ -7148,7 +7177,7 @@ module BITSLICE_CONTROL (...); endmodule (* keep *) -module RIU_OR (...); +module RIU_OR(RIU_RD_DATA, RIU_RD_VALID, RIU_RD_DATA_LOW, RIU_RD_DATA_UPP, RIU_RD_VALID_LOW, RIU_RD_VALID_UPP); parameter SIM_DEVICE = "ULTRASCALE"; parameter real SIM_VERSION = 2.0; output [15:0] RIU_RD_DATA; @@ -7159,7 +7188,8 @@ module RIU_OR (...); input RIU_RD_VALID_UPP; endmodule -module RX_BITSLICE (...); +module RX_BITSLICE(CNTVALUEOUT, CNTVALUEOUT_EXT, FIFO_EMPTY, FIFO_WRCLK_OUT, Q, RX_BIT_CTRL_OUT, TX_BIT_CTRL_OUT, CE, CE_EXT, CLK, CLK_EXT, CNTVALUEIN, CNTVALUEIN_EXT, DATAIN, EN_VTC, EN_VTC_EXT, FIFO_RD_CLK, FIFO_RD_EN, INC, INC_EXT, LOAD +, LOAD_EXT, RST, RST_DLY, RST_DLY_EXT, RX_BIT_CTRL_IN, TX_BIT_CTRL_IN); parameter CASCADE = "TRUE"; parameter DATA_TYPE = "NONE"; parameter integer DATA_WIDTH = 8; @@ -7212,7 +7242,8 @@ module RX_BITSLICE (...); input [39:0] TX_BIT_CTRL_IN; endmodule -module RXTX_BITSLICE (...); +module RXTX_BITSLICE(FIFO_EMPTY, FIFO_WRCLK_OUT, O, Q, RX_BIT_CTRL_OUT, RX_CNTVALUEOUT, TX_BIT_CTRL_OUT, TX_CNTVALUEOUT, T_OUT, D, DATAIN, FIFO_RD_CLK, FIFO_RD_EN, RX_BIT_CTRL_IN, RX_CE, RX_CLK, RX_CNTVALUEIN, RX_EN_VTC, RX_INC, RX_LOAD, RX_RST +, RX_RST_DLY, T, TBYTE_IN, TX_BIT_CTRL_IN, TX_CE, TX_CLK, TX_CNTVALUEIN, TX_EN_VTC, TX_INC, TX_LOAD, TX_RST, TX_RST_DLY); parameter FIFO_SYNC_MODE = "FALSE"; parameter [0:0] INIT = 1'b1; parameter [0:0] IS_RX_CLK_INVERTED = 1'b0; @@ -7282,7 +7313,7 @@ module RXTX_BITSLICE (...); input TX_RST_DLY; endmodule -module TX_BITSLICE (...); +module TX_BITSLICE(CNTVALUEOUT, O, RX_BIT_CTRL_OUT, TX_BIT_CTRL_OUT, T_OUT, CE, CLK, CNTVALUEIN, D, EN_VTC, INC, LOAD, RST, RST_DLY, RX_BIT_CTRL_IN, T, TBYTE_IN, TX_BIT_CTRL_IN); parameter integer DATA_WIDTH = 8; parameter DELAY_FORMAT = "TIME"; parameter DELAY_TYPE = "FIXED"; @@ -7322,7 +7353,7 @@ module TX_BITSLICE (...); input [39:0] TX_BIT_CTRL_IN; endmodule -module TX_BITSLICE_TRI (...); +module TX_BITSLICE_TRI(BIT_CTRL_OUT, CNTVALUEOUT, TRI_OUT, BIT_CTRL_IN, CE, CLK, CNTVALUEIN, EN_VTC, INC, LOAD, RST, RST_DLY); parameter integer DATA_WIDTH = 8; parameter DELAY_FORMAT = "TIME"; parameter DELAY_TYPE = "FIXED"; @@ -7354,7 +7385,7 @@ module TX_BITSLICE_TRI (...); input RST_DLY; endmodule -module IODELAY2 (...); +module IODELAY2(BUSY, DATAOUT2, DATAOUT, DOUT, TOUT, CAL, CE, CLK, IDATAIN, INC, IOCLK0, IOCLK1, ODATAIN, RST, T); parameter COUNTER_WRAPAROUND = "WRAPAROUND"; parameter DATA_RATE = "SDR"; parameter DELAY_SRC = "IO"; @@ -7385,7 +7416,7 @@ module IODELAY2 (...); input T; endmodule -module IODRP2 (...); +module IODRP2(DATAOUT2, DATAOUT, DOUT, SDO, TOUT, ADD, BKST, CLK, CS, IDATAIN, IOCLK0, IOCLK1, ODATAIN, SDI, T); parameter DATA_RATE = "SDR"; parameter integer SIM_TAPDELAY_VALUE = 75; output DATAOUT2; @@ -7408,7 +7439,8 @@ module IODRP2 (...); input T; endmodule -module IODRP2_MCB (...); +module IODRP2_MCB(AUXSDO, DATAOUT2, DATAOUT, DOUT, DQSOUTN, DQSOUTP, SDO, TOUT, ADD, AUXSDOIN, BKST, CLK, CS, IDATAIN, IOCLK0, IOCLK1, MEMUPDATE, ODATAIN, SDI, T, AUXADDR +); parameter DATA_RATE = "SDR"; parameter integer IDELAY_VALUE = 0; parameter integer MCB_ADDRESS = 0; @@ -7441,7 +7473,7 @@ module IODRP2_MCB (...); input [4:0] AUXADDR; endmodule -module ISERDES2 (...); +module ISERDES2(CFB0, CFB1, DFB, FABRICOUT, INCDEC, Q1, Q2, Q3, Q4, SHIFTOUT, VALID, BITSLIP, CE0, CLK0, CLK1, CLKDIV, D, IOCE, RST, SHIFTIN); parameter BITSLIP_ENABLE = "FALSE"; parameter DATA_RATE = "SDR"; parameter integer DATA_WIDTH = 1; @@ -7472,7 +7504,8 @@ module ISERDES2 (...); input SHIFTIN; endmodule -module OSERDES2 (...); +module OSERDES2(OQ, SHIFTOUT1, SHIFTOUT2, SHIFTOUT3, SHIFTOUT4, TQ, CLK0, CLK1, CLKDIV, D1, D2, D3, D4, IOCE, OCE, RST, SHIFTIN1, SHIFTIN2, SHIFTIN3, SHIFTIN4, T1 +, T2, T3, T4, TCE, TRAIN); parameter BYPASS_GCLK_FF = "FALSE"; parameter DATA_RATE_OQ = "DDR"; parameter DATA_RATE_OT = "DDR"; @@ -7511,7 +7544,7 @@ module OSERDES2 (...); input TRAIN; endmodule -module IBUF_DLY_ADJ (...); +module IBUF_DLY_ADJ(O, I, S); parameter DELAY_OFFSET = "OFF"; parameter IOSTANDARD = "DEFAULT"; output O; @@ -7520,7 +7553,7 @@ module IBUF_DLY_ADJ (...); input [2:0] S; endmodule -module IBUF_IBUFDISABLE (...); +module IBUF_IBUFDISABLE(O, I, IBUFDISABLE); parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; parameter SIM_DEVICE = "7SERIES"; @@ -7531,7 +7564,7 @@ module IBUF_IBUFDISABLE (...); input IBUFDISABLE; endmodule -module IBUF_INTERMDISABLE (...); +module IBUF_INTERMDISABLE(O, I, IBUFDISABLE, INTERMDISABLE); parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; parameter SIM_DEVICE = "7SERIES"; @@ -7543,13 +7576,13 @@ module IBUF_INTERMDISABLE (...); input INTERMDISABLE; endmodule -module IBUF_ANALOG (...); +module IBUF_ANALOG(O, I); output O; (* iopad_external_pin *) input I; endmodule -module IBUFE3 (...); +module IBUFE3(O, I, IBUFDISABLE, OSC, OSC_EN, VREF); parameter CCIO_EN = "TRUE"; parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; @@ -7565,7 +7598,7 @@ module IBUFE3 (...); input VREF; endmodule -module IBUFDS (...); +module IBUFDS(O, I, IB); parameter CAPACITANCE = "DONT_CARE"; parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; @@ -7580,7 +7613,7 @@ module IBUFDS (...); input IB; endmodule -module IBUFDS_DLY_ADJ (...); +module IBUFDS_DLY_ADJ(O, I, IB, S); parameter DELAY_OFFSET = "OFF"; parameter DIFF_TERM = "FALSE"; parameter IOSTANDARD = "DEFAULT"; @@ -7592,7 +7625,7 @@ module IBUFDS_DLY_ADJ (...); input [2:0] S; endmodule -module IBUFDS_IBUFDISABLE (...); +module IBUFDS_IBUFDISABLE(O, I, IB, IBUFDISABLE); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7607,7 +7640,7 @@ module IBUFDS_IBUFDISABLE (...); input IBUFDISABLE; endmodule -module IBUFDS_INTERMDISABLE (...); +module IBUFDS_INTERMDISABLE(O, I, IB, IBUFDISABLE, INTERMDISABLE); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7623,7 +7656,7 @@ module IBUFDS_INTERMDISABLE (...); input INTERMDISABLE; endmodule -module IBUFDS_DIFF_OUT (...); +module IBUFDS_DIFF_OUT(O, OB, I, IB); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7636,7 +7669,7 @@ module IBUFDS_DIFF_OUT (...); input IB; endmodule -module IBUFDS_DIFF_OUT_IBUFDISABLE (...); +module IBUFDS_DIFF_OUT_IBUFDISABLE(O, OB, I, IB, IBUFDISABLE); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7652,7 +7685,7 @@ module IBUFDS_DIFF_OUT_IBUFDISABLE (...); input IBUFDISABLE; endmodule -module IBUFDS_DIFF_OUT_INTERMDISABLE (...); +module IBUFDS_DIFF_OUT_INTERMDISABLE(O, OB, I, IB, IBUFDISABLE, INTERMDISABLE); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7669,7 +7702,7 @@ module IBUFDS_DIFF_OUT_INTERMDISABLE (...); input INTERMDISABLE; endmodule -module IBUFDSE3 (...); +module IBUFDSE3(O, I, IB, IBUFDISABLE, OSC, OSC_EN); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7686,7 +7719,7 @@ module IBUFDSE3 (...); input [1:0] OSC_EN; endmodule -module IBUFDS_DPHY (...); +module IBUFDS_DPHY(HSRX_O, LPRX_O_N, LPRX_O_P, HSRX_DISABLE, I, IB, LPRX_DISABLE); parameter DIFF_TERM = "TRUE"; parameter IOSTANDARD = "DEFAULT"; output HSRX_O; @@ -7700,7 +7733,7 @@ module IBUFDS_DPHY (...); input LPRX_DISABLE; endmodule -module IBUFGDS (...); +module IBUFGDS(O, I, IB); parameter CAPACITANCE = "DONT_CARE"; parameter DIFF_TERM = "FALSE"; parameter IBUF_DELAY_VALUE = "0"; @@ -7713,7 +7746,7 @@ module IBUFGDS (...); input IB; endmodule -module IBUFGDS_DIFF_OUT (...); +module IBUFGDS_DIFF_OUT(O, OB, I, IB); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7726,7 +7759,7 @@ module IBUFGDS_DIFF_OUT (...); input IB; endmodule -module IOBUF_DCIEN (...); +module IOBUF_DCIEN(O, IO, DCITERMDISABLE, I, IBUFDISABLE, T); parameter integer DRIVE = 12; parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; @@ -7742,7 +7775,7 @@ module IOBUF_DCIEN (...); input T; endmodule -module IOBUF_INTERMDISABLE (...); +module IOBUF_INTERMDISABLE(O, IO, I, IBUFDISABLE, INTERMDISABLE, T); parameter integer DRIVE = 12; parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; @@ -7758,7 +7791,7 @@ module IOBUF_INTERMDISABLE (...); input T; endmodule -module IOBUFE3 (...); +module IOBUFE3(O, IO, DCITERMDISABLE, I, IBUFDISABLE, OSC, OSC_EN, T, VREF); parameter integer DRIVE = 12; parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; @@ -7777,7 +7810,7 @@ module IOBUFE3 (...); input VREF; endmodule -module IOBUFDS (...); +module IOBUFDS(O, IO, IOB, I, T); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7792,7 +7825,7 @@ module IOBUFDS (...); input T; endmodule -module IOBUFDS_DCIEN (...); +module IOBUFDS_DCIEN(O, IO, IOB, DCITERMDISABLE, I, IBUFDISABLE, T); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7811,7 +7844,7 @@ module IOBUFDS_DCIEN (...); input T; endmodule -module IOBUFDS_INTERMDISABLE (...); +module IOBUFDS_INTERMDISABLE(O, IO, IOB, I, IBUFDISABLE, INTERMDISABLE, T); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7830,7 +7863,7 @@ module IOBUFDS_INTERMDISABLE (...); input T; endmodule -module IOBUFDS_DIFF_OUT (...); +module IOBUFDS_DIFF_OUT(O, OB, IO, IOB, I, TM, TS); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7846,7 +7879,7 @@ module IOBUFDS_DIFF_OUT (...); input TS; endmodule -module IOBUFDS_DIFF_OUT_DCIEN (...); +module IOBUFDS_DIFF_OUT_DCIEN(O, OB, IO, IOB, DCITERMDISABLE, I, IBUFDISABLE, TM, TS); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7866,7 +7899,7 @@ module IOBUFDS_DIFF_OUT_DCIEN (...); input TS; endmodule -module IOBUFDS_DIFF_OUT_INTERMDISABLE (...); +module IOBUFDS_DIFF_OUT_INTERMDISABLE(O, OB, IO, IOB, I, IBUFDISABLE, INTERMDISABLE, TM, TS); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7886,7 +7919,7 @@ module IOBUFDS_DIFF_OUT_INTERMDISABLE (...); input TS; endmodule -module IOBUFDSE3 (...); +module IOBUFDSE3(O, IO, IOB, DCITERMDISABLE, I, IBUFDISABLE, OSC, OSC_EN, T); parameter DIFF_TERM = "FALSE"; parameter DQS_BIAS = "FALSE"; parameter IBUF_LOW_PWR = "TRUE"; @@ -7906,7 +7939,7 @@ module IOBUFDSE3 (...); input T; endmodule -module OBUFDS (...); +module OBUFDS(O, OB, I); parameter CAPACITANCE = "DONT_CARE"; parameter IOSTANDARD = "DEFAULT"; parameter SLEW = "SLOW"; @@ -7917,7 +7950,7 @@ module OBUFDS (...); input I; endmodule -module OBUFDS_DPHY (...); +module OBUFDS_DPHY(O, OB, HSTX_I, HSTX_T, LPTX_I_N, LPTX_I_P, LPTX_T); parameter IOSTANDARD = "DEFAULT"; (* iopad_external_pin *) output O; @@ -7930,7 +7963,7 @@ module OBUFDS_DPHY (...); input LPTX_T; endmodule -module OBUFTDS (...); +module OBUFTDS(O, OB, I, T); parameter CAPACITANCE = "DONT_CARE"; parameter IOSTANDARD = "DEFAULT"; parameter SLEW = "SLOW"; @@ -7942,32 +7975,32 @@ module OBUFTDS (...); input T; endmodule -module KEEPER (...); +module KEEPER(O); inout O; endmodule -module PULLDOWN (...); +module PULLDOWN(O); output O; endmodule -module PULLUP (...); +module PULLUP(O); output O; endmodule (* keep *) -module DCIRESET (...); +module DCIRESET(LOCKED, RST); output LOCKED; input RST; endmodule (* keep *) -module HPIO_VREF (...); +module HPIO_VREF(VREF, FABRIC_VREF_TUNE); parameter VREF_CNTR = "OFF"; output VREF; input [6:0] FABRIC_VREF_TUNE; endmodule -module BUFGCE (...); +module BUFGCE(O, CE, I); parameter CE_TYPE = "SYNC"; parameter [0:0] IS_CE_INVERTED = 1'b0; parameter [0:0] IS_I_INVERTED = 1'b0; @@ -7981,14 +8014,14 @@ module BUFGCE (...); input I; endmodule -module BUFGCE_1 (...); +module BUFGCE_1(O, CE, I); (* clkbuf_driver *) output O; input CE; input I; endmodule -module BUFGMUX (...); +module BUFGMUX(O, I0, I1, S); parameter CLK_SEL_TYPE = "SYNC"; (* clkbuf_driver *) output O; @@ -7997,7 +8030,7 @@ module BUFGMUX (...); input S; endmodule -module BUFGMUX_1 (...); +module BUFGMUX_1(O, I0, I1, S); parameter CLK_SEL_TYPE = "SYNC"; (* clkbuf_driver *) output O; @@ -8006,7 +8039,7 @@ module BUFGMUX_1 (...); input S; endmodule -module BUFGMUX_CTRL (...); +module BUFGMUX_CTRL(O, I0, I1, S); (* clkbuf_driver *) output O; input I0; @@ -8014,7 +8047,7 @@ module BUFGMUX_CTRL (...); input S; endmodule -module BUFGMUX_VIRTEX4 (...); +module BUFGMUX_VIRTEX4(O, I0, I1, S); (* clkbuf_driver *) output O; input I0; @@ -8022,7 +8055,7 @@ module BUFGMUX_VIRTEX4 (...); input S; endmodule -module BUFG_GT (...); +module BUFG_GT(O, CE, CEMASK, CLR, CLRMASK, DIV, I); parameter SIM_DEVICE = "ULTRASCALE"; parameter STARTUP_SYNC = "FALSE"; (* clkbuf_driver *) @@ -8035,7 +8068,7 @@ module BUFG_GT (...); input I; endmodule -module BUFG_GT_SYNC (...); +module BUFG_GT_SYNC(CESYNC, CLRSYNC, CE, CLK, CLR); output CESYNC; output CLRSYNC; input CE; @@ -8043,7 +8076,7 @@ module BUFG_GT_SYNC (...); input CLR; endmodule -module BUFG_PS (...); +module BUFG_PS(O, I); parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter STARTUP_SYNC = "FALSE"; (* clkbuf_driver *) @@ -8051,7 +8084,7 @@ module BUFG_PS (...); input I; endmodule -module BUFGCE_DIV (...); +module BUFGCE_DIV(O, CE, CLR, I); parameter integer BUFGCE_DIVIDE = 1; parameter CE_TYPE = "SYNC"; parameter HARDSYNC_CLR = "FALSE"; @@ -8070,13 +8103,13 @@ module BUFGCE_DIV (...); input I; endmodule -module BUFH (...); +module BUFH(O, I); (* clkbuf_driver *) output O; input I; endmodule -module BUFIO2 (...); +module BUFIO2(DIVCLK, IOCLK, SERDESSTROBE, I); parameter DIVIDE_BYPASS = "TRUE"; parameter integer DIVIDE = 1; parameter I_INVERT = "FALSE"; @@ -8089,7 +8122,7 @@ module BUFIO2 (...); input I; endmodule -module BUFIO2_2CLK (...); +module BUFIO2_2CLK(DIVCLK, IOCLK, SERDESSTROBE, I, IB); parameter integer DIVIDE = 2; (* clkbuf_driver *) output DIVCLK; @@ -8100,14 +8133,14 @@ module BUFIO2_2CLK (...); input IB; endmodule -module BUFIO2FB (...); +module BUFIO2FB(O, I); parameter DIVIDE_BYPASS = "TRUE"; (* clkbuf_driver *) output O; input I; endmodule -module BUFPLL (...); +module BUFPLL(IOCLK, LOCK, SERDESSTROBE, GCLK, LOCKED, PLLIN); parameter integer DIVIDE = 1; parameter ENABLE_SYNC = "TRUE"; (* clkbuf_driver *) @@ -8119,7 +8152,7 @@ module BUFPLL (...); input PLLIN; endmodule -module BUFPLL_MCB (...); +module BUFPLL_MCB(IOCLK0, IOCLK1, LOCK, SERDESSTROBE0, SERDESSTROBE1, GCLK, LOCKED, PLLIN0, PLLIN1); parameter integer DIVIDE = 2; parameter LOCK_SRC = "LOCK_TO_0"; (* clkbuf_driver *) @@ -8135,13 +8168,13 @@ module BUFPLL_MCB (...); input PLLIN1; endmodule -module BUFIO (...); +module BUFIO(O, I); (* clkbuf_driver *) output O; input I; endmodule -module BUFIODQS (...); +module BUFIODQS(O, DQSMASK, I); parameter DQSMASK_ENABLE = "FALSE"; (* clkbuf_driver *) output O; @@ -8149,7 +8182,7 @@ module BUFIODQS (...); input I; endmodule -module BUFR (...); +module BUFR(O, CE, CLR, I); parameter BUFR_DIVIDE = "BYPASS"; parameter SIM_DEVICE = "7SERIES"; (* clkbuf_driver *) @@ -8159,13 +8192,13 @@ module BUFR (...); input I; endmodule -module BUFMR (...); +module BUFMR(O, I); (* clkbuf_driver *) output O; input I; endmodule -module BUFMRCE (...); +module BUFMRCE(O, CE, I); parameter CE_TYPE = "SYNC"; parameter integer INIT_OUT = 0; parameter [0:0] IS_CE_INVERTED = 1'b0; @@ -8176,7 +8209,7 @@ module BUFMRCE (...); input I; endmodule -module DCM (...); +module DCM(CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST, CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90, CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS); parameter real CLKDV_DIVIDE = 2.0; parameter integer CLKFX_DIVIDE = 1; parameter integer CLKFX_MULTIPLY = 4; @@ -8214,7 +8247,7 @@ module DCM (...); output [7:0] STATUS; endmodule -module DCM_SP (...); +module DCM_SP(CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST, CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90, CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS); parameter real CLKDV_DIVIDE = 2.0; parameter integer CLKFX_DIVIDE = 1; parameter integer CLKFX_MULTIPLY = 4; @@ -8251,7 +8284,7 @@ module DCM_SP (...); output [7:0] STATUS; endmodule -module DCM_CLKGEN (...); +module DCM_CLKGEN(CLKFX180, CLKFX, CLKFXDV, LOCKED, PROGDONE, STATUS, CLKIN, FREEZEDCM, PROGCLK, PROGDATA, PROGEN, RST); parameter SPREAD_SPECTRUM = "NONE"; parameter STARTUP_WAIT = "FALSE"; parameter integer CLKFXDV_DIVIDE = 2; @@ -8273,7 +8306,8 @@ module DCM_CLKGEN (...); input RST; endmodule -module DCM_ADV (...); +module DCM_ADV(CLK0, CLK180, CLK270, CLK2X180, CLK2X, CLK90, CLKDV, CLKFX180, CLKFX, DRDY, LOCKED, PSDONE, DO, CLKFB, CLKIN, DCLK, DEN, DWE, PSCLK, PSEN, PSINCDEC +, RST, DI, DADDR); parameter real CLKDV_DIVIDE = 2.0; parameter integer CLKFX_DIVIDE = 1; parameter integer CLKFX_MULTIPLY = 4; @@ -8317,7 +8351,7 @@ module DCM_ADV (...); input [6:0] DADDR; endmodule -module DCM_BASE (...); +module DCM_BASE(CLK0, CLK180, CLK270, CLK2X180, CLK2X, CLK90, CLKDV, CLKFX180, CLKFX, LOCKED, CLKFB, CLKIN, RST); parameter real CLKDV_DIVIDE = 2.0; parameter integer CLKFX_DIVIDE = 1; parameter integer CLKFX_MULTIPLY = 4; @@ -8349,7 +8383,7 @@ module DCM_BASE (...); input RST; endmodule -module DCM_PS (...); +module DCM_PS(CLK0, CLK180, CLK270, CLK2X180, CLK2X, CLK90, CLKDV, CLKFX180, CLKFX, LOCKED, PSDONE, DO, CLKFB, CLKIN, PSCLK, PSEN, PSINCDEC, RST); parameter real CLKDV_DIVIDE = 2.0; parameter integer CLKFX_DIVIDE = 1; parameter integer CLKFX_MULTIPLY = 4; @@ -8386,7 +8420,7 @@ module DCM_PS (...); input RST; endmodule -module PMCD (...); +module PMCD(CLKA1, CLKA1D2, CLKA1D4, CLKA1D8, CLKB1, CLKC1, CLKD1, CLKA, CLKB, CLKC, CLKD, REL, RST); parameter EN_REL = "FALSE"; parameter RST_DEASSERT_CLK = "CLKA"; output CLKA1; @@ -8404,7 +8438,8 @@ module PMCD (...); input RST; endmodule -module PLL_ADV (...); +module PLL_ADV(CLKFBDCM, CLKFBOUT, CLKOUT0, CLKOUT1, CLKOUT2, CLKOUT3, CLKOUT4, CLKOUT5, CLKOUTDCM0, CLKOUTDCM1, CLKOUTDCM2, CLKOUTDCM3, CLKOUTDCM4, CLKOUTDCM5, DRDY, LOCKED, DO, CLKFBIN, CLKIN1, CLKIN2, CLKINSEL +, DCLK, DEN, DWE, REL, RST, DI, DADDR); parameter BANDWIDTH = "OPTIMIZED"; parameter CLK_FEEDBACK = "CLKFBOUT"; parameter CLKFBOUT_DESKEW_ADJUST = "NONE"; @@ -8480,7 +8515,7 @@ module PLL_ADV (...); input [4:0] DADDR; endmodule -module PLL_BASE (...); +module PLL_BASE(CLKFBOUT, CLKOUT0, CLKOUT1, CLKOUT2, CLKOUT3, CLKOUT4, CLKOUT5, LOCKED, CLKFBIN, CLKIN, RST); parameter BANDWIDTH = "OPTIMIZED"; parameter integer CLKFBOUT_MULT = 1; parameter real CLKFBOUT_PHASE = 0.0; @@ -8521,7 +8556,8 @@ module PLL_BASE (...); input RST; endmodule -module MMCM_ADV (...); +module MMCM_ADV(CLKFBOUT, CLKFBOUTB, CLKFBSTOPPED, CLKINSTOPPED, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, DRDY, LOCKED, PSDONE, DO, CLKFBIN, CLKIN1 +, CLKIN2, CLKINSEL, DCLK, DEN, DWE, PSCLK, PSEN, PSINCDEC, PWRDWN, RST, DI, DADDR); parameter BANDWIDTH = "OPTIMIZED"; parameter CLKFBOUT_USE_FINE_PS = "FALSE"; parameter CLKOUT0_USE_FINE_PS = "FALSE"; @@ -8604,7 +8640,7 @@ module MMCM_ADV (...); input [6:0] DADDR; endmodule -module MMCM_BASE (...); +module MMCM_BASE(CLKFBOUT, CLKFBOUTB, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, LOCKED, CLKFBIN, CLKIN1, PWRDWN, RST); parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; @@ -8655,7 +8691,8 @@ module MMCM_BASE (...); input RST; endmodule -module MMCME2_ADV (...); +module MMCME2_ADV(CLKFBOUT, CLKFBOUTB, CLKFBSTOPPED, CLKINSTOPPED, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, DO, DRDY, LOCKED, PSDONE, CLKFBIN, CLKIN1 +, CLKIN2, CLKINSEL, DADDR, DCLK, DEN, DI, DWE, PSCLK, PSEN, PSINCDEC, PWRDWN, RST); parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 10.000; parameter real CLKPFD_FREQ_MAX = 550.000; @@ -8750,7 +8787,7 @@ module MMCME2_ADV (...); input RST; endmodule -module MMCME2_BASE (...); +module MMCME2_BASE(CLKFBOUT, CLKFBOUTB, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, LOCKED, CLKFBIN, CLKIN1, PWRDWN, RST); parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; @@ -8800,7 +8837,8 @@ module MMCME2_BASE (...); input RST; endmodule -module PLLE2_ADV (...); +module PLLE2_ADV(CLKFBOUT, CLKOUT0, CLKOUT1, CLKOUT2, CLKOUT3, CLKOUT4, CLKOUT5, DRDY, LOCKED, DO, CLKFBIN, CLKIN1, CLKIN2, CLKINSEL, DCLK, DEN, DWE, PWRDWN, RST, DI, DADDR +); parameter BANDWIDTH = "OPTIMIZED"; parameter COMPENSATION = "ZHOLD"; parameter STARTUP_WAIT = "FALSE"; @@ -8864,7 +8902,7 @@ module PLLE2_ADV (...); input [6:0] DADDR; endmodule -module PLLE2_BASE (...); +module PLLE2_BASE(CLKFBOUT, CLKOUT0, CLKOUT1, CLKOUT2, CLKOUT3, CLKOUT4, CLKOUT5, LOCKED, CLKFBIN, CLKIN1, PWRDWN, RST); parameter BANDWIDTH = "OPTIMIZED"; parameter integer CLKFBOUT_MULT = 5; parameter real CLKFBOUT_PHASE = 0.000; @@ -8904,7 +8942,8 @@ module PLLE2_BASE (...); input RST; endmodule -module MMCME3_ADV (...); +module MMCME3_ADV(CDDCDONE, CLKFBOUT, CLKFBOUTB, CLKFBSTOPPED, CLKINSTOPPED, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, DO, DRDY, LOCKED, PSDONE, CDDCREQ +, CLKFBIN, CLKIN1, CLKIN2, CLKINSEL, DADDR, DCLK, DEN, DI, DWE, PSCLK, PSEN, PSINCDEC, PWRDWN, RST); parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 10.000; parameter real CLKPFD_FREQ_MAX = 550.000; @@ -9007,7 +9046,7 @@ module MMCME3_ADV (...); input RST; endmodule -module MMCME3_BASE (...); +module MMCME3_BASE(CLKFBOUT, CLKFBOUTB, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, LOCKED, CLKFBIN, CLKIN1, PWRDWN, RST); parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; @@ -9065,7 +9104,7 @@ module MMCME3_BASE (...); input RST; endmodule -module PLLE3_ADV (...); +module PLLE3_ADV(CLKFBOUT, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUTPHY, DO, DRDY, LOCKED, CLKFBIN, CLKIN, CLKOUTPHYEN, DADDR, DCLK, DEN, DI, DWE, PWRDWN, RST); parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 70.000; parameter real CLKPFD_FREQ_MAX = 667.500; @@ -9115,7 +9154,7 @@ module PLLE3_ADV (...); input RST; endmodule -module PLLE3_BASE (...); +module PLLE3_BASE(CLKFBOUT, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUTPHY, LOCKED, CLKFBIN, CLKIN, CLKOUTPHYEN, PWRDWN, RST); parameter integer CLKFBOUT_MULT = 5; parameter real CLKFBOUT_PHASE = 0.000; parameter real CLKIN_PERIOD = 0.000; @@ -9151,7 +9190,8 @@ module PLLE3_BASE (...); input RST; endmodule -module MMCME4_ADV (...); +module MMCME4_ADV(CDDCDONE, CLKFBOUT, CLKFBOUTB, CLKFBSTOPPED, CLKINSTOPPED, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, DO, DRDY, LOCKED, PSDONE, CDDCREQ +, CLKFBIN, CLKIN1, CLKIN2, CLKINSEL, DADDR, DCLK, DEN, DI, DWE, PSCLK, PSEN, PSINCDEC, PWRDWN, RST); parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 10.000; parameter real CLKPFD_FREQ_MAX = 550.000; @@ -9254,7 +9294,7 @@ module MMCME4_ADV (...); input RST; endmodule -module MMCME4_BASE (...); +module MMCME4_BASE(CLKFBOUT, CLKFBOUTB, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUT2, CLKOUT2B, CLKOUT3, CLKOUT3B, CLKOUT4, CLKOUT5, CLKOUT6, LOCKED, CLKFBIN, CLKIN1, PWRDWN, RST); parameter BANDWIDTH = "OPTIMIZED"; parameter real CLKFBOUT_MULT_F = 5.000; parameter real CLKFBOUT_PHASE = 0.000; @@ -9312,7 +9352,7 @@ module MMCME4_BASE (...); input RST; endmodule -module PLLE4_ADV (...); +module PLLE4_ADV(CLKFBOUT, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUTPHY, DO, DRDY, LOCKED, CLKFBIN, CLKIN, CLKOUTPHYEN, DADDR, DCLK, DEN, DI, DWE, PWRDWN, RST); parameter real CLKIN_FREQ_MAX = 1066.000; parameter real CLKIN_FREQ_MIN = 70.000; parameter real CLKPFD_FREQ_MAX = 667.500; @@ -9362,7 +9402,7 @@ module PLLE4_ADV (...); input RST; endmodule -module PLLE4_BASE (...); +module PLLE4_BASE(CLKFBOUT, CLKOUT0, CLKOUT0B, CLKOUT1, CLKOUT1B, CLKOUTPHY, LOCKED, CLKFBIN, CLKIN, CLKOUTPHYEN, PWRDWN, RST); parameter integer CLKFBOUT_MULT = 5; parameter real CLKFBOUT_PHASE = 0.000; parameter real CLKIN_PERIOD = 0.000; @@ -9398,13 +9438,14 @@ module PLLE4_BASE (...); input RST; endmodule -module BUFT (...); +module BUFT(O, I, T); output O; input I; input T; endmodule -module IN_FIFO (...); +module IN_FIFO(ALMOSTEMPTY, ALMOSTFULL, EMPTY, FULL, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, RDCLK, RDEN, RESET, WRCLK, WREN, D0, D1 +, D2, D3, D4, D7, D8, D9, D5, D6); parameter integer ALMOST_EMPTY_VALUE = 1; parameter integer ALMOST_FULL_VALUE = 1; parameter ARRAY_MODE = "ARRAY_MODE_4_X_8"; @@ -9442,7 +9483,8 @@ module IN_FIFO (...); input [7:0] D6; endmodule -module OUT_FIFO (...); +module OUT_FIFO(ALMOSTEMPTY, ALMOSTFULL, EMPTY, FULL, Q0, Q1, Q2, Q3, Q4, Q7, Q8, Q9, Q5, Q6, RDCLK, RDEN, RESET, WRCLK, WREN, D0, D1 +, D2, D3, D4, D5, D6, D7, D8, D9); parameter integer ALMOST_EMPTY_VALUE = 1; parameter integer ALMOST_FULL_VALUE = 1; parameter ARRAY_MODE = "ARRAY_MODE_8_X_4"; @@ -9481,7 +9523,7 @@ module OUT_FIFO (...); input [7:0] D9; endmodule -module HARD_SYNC (...); +module HARD_SYNC(DOUT, CLK, DIN); parameter [0:0] INIT = 1'b0; parameter [0:0] IS_CLK_INVERTED = 1'b0; parameter integer LATENCY = 2; @@ -9493,14 +9535,14 @@ module HARD_SYNC (...); endmodule (* keep *) -module STARTUP_SPARTAN3 (...); +module STARTUP_SPARTAN3(CLK, GSR, GTS); input CLK; input GSR; input GTS; endmodule (* keep *) -module STARTUP_SPARTAN3E (...); +module STARTUP_SPARTAN3E(CLK, GSR, GTS, MBT); input CLK; input GSR; input GTS; @@ -9508,14 +9550,14 @@ module STARTUP_SPARTAN3E (...); endmodule (* keep *) -module STARTUP_SPARTAN3A (...); +module STARTUP_SPARTAN3A(CLK, GSR, GTS); input CLK; input GSR; input GTS; endmodule (* keep *) -module STARTUP_SPARTAN6 (...); +module STARTUP_SPARTAN6(CFGCLK, CFGMCLK, EOS, CLK, GSR, GTS, KEYCLEARB); output CFGCLK; output CFGMCLK; output EOS; @@ -9526,7 +9568,7 @@ module STARTUP_SPARTAN6 (...); endmodule (* keep *) -module STARTUP_VIRTEX4 (...); +module STARTUP_VIRTEX4(EOS, CLK, GSR, GTS, USRCCLKO, USRCCLKTS, USRDONEO, USRDONETS); output EOS; input CLK; input GSR; @@ -9538,7 +9580,7 @@ module STARTUP_VIRTEX4 (...); endmodule (* keep *) -module STARTUP_VIRTEX5 (...); +module STARTUP_VIRTEX5(CFGCLK, CFGMCLK, DINSPI, EOS, TCKSPI, CLK, GSR, GTS, USRCCLKO, USRCCLKTS, USRDONEO, USRDONETS); output CFGCLK; output CFGMCLK; output DINSPI; @@ -9554,7 +9596,7 @@ module STARTUP_VIRTEX5 (...); endmodule (* keep *) -module STARTUP_VIRTEX6 (...); +module STARTUP_VIRTEX6(CFGCLK, CFGMCLK, DINSPI, EOS, PREQ, TCKSPI, CLK, GSR, GTS, KEYCLEARB, PACK, USRCCLKO, USRCCLKTS, USRDONEO, USRDONETS); parameter PROG_USR = "FALSE"; output CFGCLK; output CFGMCLK; @@ -9574,7 +9616,7 @@ module STARTUP_VIRTEX6 (...); endmodule (* keep *) -module STARTUPE2 (...); +module STARTUPE2(CFGCLK, CFGMCLK, EOS, PREQ, CLK, GSR, GTS, KEYCLEARB, PACK, USRCCLKO, USRCCLKTS, USRDONEO, USRDONETS); parameter PROG_USR = "FALSE"; parameter real SIM_CCLK_FREQ = 0.0; output CFGCLK; @@ -9593,7 +9635,7 @@ module STARTUPE2 (...); endmodule (* keep *) -module STARTUPE3 (...); +module STARTUPE3(CFGCLK, CFGMCLK, DI, EOS, PREQ, DO, DTS, FCSBO, FCSBTS, GSR, GTS, KEYCLEARB, PACK, USRCCLKO, USRCCLKTS, USRDONEO, USRDONETS); parameter PROG_USR = "FALSE"; parameter real SIM_CCLK_FREQ = 0.0; output CFGCLK; @@ -9616,49 +9658,49 @@ module STARTUPE3 (...); endmodule (* keep *) -module CAPTURE_SPARTAN3 (...); +module CAPTURE_SPARTAN3(CAP, CLK); parameter ONESHOT = "FALSE"; input CAP; input CLK; endmodule (* keep *) -module CAPTURE_SPARTAN3A (...); +module CAPTURE_SPARTAN3A(CAP, CLK); parameter ONESHOT = "TRUE"; input CAP; input CLK; endmodule (* keep *) -module CAPTURE_VIRTEX4 (...); +module CAPTURE_VIRTEX4(CAP, CLK); parameter ONESHOT = "TRUE"; input CAP; input CLK; endmodule (* keep *) -module CAPTURE_VIRTEX5 (...); +module CAPTURE_VIRTEX5(CAP, CLK); parameter ONESHOT = "TRUE"; input CAP; input CLK; endmodule (* keep *) -module CAPTURE_VIRTEX6 (...); +module CAPTURE_VIRTEX6(CAP, CLK); parameter ONESHOT = "TRUE"; input CAP; input CLK; endmodule (* keep *) -module CAPTUREE2 (...); +module CAPTUREE2(CAP, CLK); parameter ONESHOT = "TRUE"; input CAP; input CLK; endmodule (* keep *) -module ICAP_SPARTAN3A (...); +module ICAP_SPARTAN3A(BUSY, O, CE, CLK, WRITE, I); output BUSY; output [7:0] O; input CE; @@ -9668,7 +9710,7 @@ module ICAP_SPARTAN3A (...); endmodule (* keep *) -module ICAP_SPARTAN6 (...); +module ICAP_SPARTAN6(BUSY, O, CLK, CE, WRITE, I); parameter DEVICE_ID = 32'h04000093; parameter SIM_CFG_FILE_NAME = "NONE"; output BUSY; @@ -9680,7 +9722,7 @@ module ICAP_SPARTAN6 (...); endmodule (* keep *) -module ICAP_VIRTEX4 (...); +module ICAP_VIRTEX4(BUSY, O, CE, CLK, WRITE, I); parameter ICAP_WIDTH = "X8"; output BUSY; output [31:0] O; @@ -9691,7 +9733,7 @@ module ICAP_VIRTEX4 (...); endmodule (* keep *) -module ICAP_VIRTEX5 (...); +module ICAP_VIRTEX5(BUSY, O, CE, CLK, WRITE, I); parameter ICAP_WIDTH = "X8"; output BUSY; output [31:0] O; @@ -9702,7 +9744,7 @@ module ICAP_VIRTEX5 (...); endmodule (* keep *) -module ICAP_VIRTEX6 (...); +module ICAP_VIRTEX6(BUSY, O, CLK, CSB, RDWRB, I); parameter [31:0] DEVICE_ID = 32'h04244093; parameter ICAP_WIDTH = "X8"; parameter SIM_CFG_FILE_NAME = "NONE"; @@ -9715,7 +9757,7 @@ module ICAP_VIRTEX6 (...); endmodule (* keep *) -module ICAPE2 (...); +module ICAPE2(O, CLK, CSIB, RDWRB, I); parameter [31:0] DEVICE_ID = 32'h04244093; parameter ICAP_WIDTH = "X32"; parameter SIM_CFG_FILE_NAME = "NONE"; @@ -9727,7 +9769,7 @@ module ICAPE2 (...); endmodule (* keep *) -module ICAPE3 (...); +module ICAPE3(AVAIL, O, PRDONE, PRERROR, CLK, CSIB, RDWRB, I); parameter [31:0] DEVICE_ID = 32'h03628093; parameter ICAP_AUTO_SWITCH = "DISABLE"; parameter SIM_CFG_FILE_NAME = "NONE"; @@ -9742,7 +9784,7 @@ module ICAPE3 (...); endmodule (* keep *) -module BSCAN_SPARTAN3 (...); +module BSCAN_SPARTAN3(CAPTURE, DRCK1, DRCK2, RESET, SEL1, SEL2, SHIFT, TDI, UPDATE, TDO1, TDO2); output CAPTURE; output DRCK1; output DRCK2; @@ -9757,7 +9799,7 @@ module BSCAN_SPARTAN3 (...); endmodule (* keep *) -module BSCAN_SPARTAN3A (...); +module BSCAN_SPARTAN3A(CAPTURE, DRCK1, DRCK2, RESET, SEL1, SEL2, SHIFT, TCK, TDI, TMS, UPDATE, TDO1, TDO2); output CAPTURE; output DRCK1; output DRCK2; @@ -9774,7 +9816,7 @@ module BSCAN_SPARTAN3A (...); endmodule (* keep *) -module BSCAN_SPARTAN6 (...); +module BSCAN_SPARTAN6(CAPTURE, DRCK, RESET, RUNTEST, SEL, SHIFT, TCK, TDI, TMS, UPDATE, TDO); parameter integer JTAG_CHAIN = 1; output CAPTURE; output DRCK; @@ -9790,7 +9832,7 @@ module BSCAN_SPARTAN6 (...); endmodule (* keep *) -module BSCAN_VIRTEX4 (...); +module BSCAN_VIRTEX4(CAPTURE, DRCK, RESET, SEL, SHIFT, TDI, UPDATE, TDO); parameter integer JTAG_CHAIN = 1; output CAPTURE; output DRCK; @@ -9803,7 +9845,7 @@ module BSCAN_VIRTEX4 (...); endmodule (* keep *) -module BSCAN_VIRTEX5 (...); +module BSCAN_VIRTEX5(CAPTURE, DRCK, RESET, SEL, SHIFT, TDI, UPDATE, TDO); parameter integer JTAG_CHAIN = 1; output CAPTURE; output DRCK; @@ -9816,7 +9858,7 @@ module BSCAN_VIRTEX5 (...); endmodule (* keep *) -module BSCAN_VIRTEX6 (...); +module BSCAN_VIRTEX6(CAPTURE, DRCK, RESET, RUNTEST, SEL, SHIFT, TCK, TDI, TMS, UPDATE, TDO); parameter DISABLE_JTAG = "FALSE"; parameter integer JTAG_CHAIN = 1; output CAPTURE; @@ -9833,7 +9875,7 @@ module BSCAN_VIRTEX6 (...); endmodule (* keep *) -module BSCANE2 (...); +module BSCANE2(CAPTURE, DRCK, RESET, RUNTEST, SEL, SHIFT, TCK, TDI, TMS, UPDATE, TDO); parameter DISABLE_JTAG = "FALSE"; parameter integer JTAG_CHAIN = 1; output CAPTURE; @@ -9849,7 +9891,7 @@ module BSCANE2 (...); input TDO; endmodule -module DNA_PORT (...); +module DNA_PORT(DOUT, CLK, DIN, READ, SHIFT); parameter [56:0] SIM_DNA_VALUE = 57'h0; output DOUT; input CLK; @@ -9858,7 +9900,7 @@ module DNA_PORT (...); input SHIFT; endmodule -module DNA_PORTE2 (...); +module DNA_PORTE2(DOUT, CLK, DIN, READ, SHIFT); parameter [95:0] SIM_DNA_VALUE = 96'h000000000000000000000000; output DOUT; input CLK; @@ -9867,20 +9909,20 @@ module DNA_PORTE2 (...); input SHIFT; endmodule -module FRAME_ECC_VIRTEX4 (...); +module FRAME_ECC_VIRTEX4(ERROR, SYNDROME, SYNDROMEVALID); output ERROR; output [11:0] SYNDROME; output SYNDROMEVALID; endmodule -module FRAME_ECC_VIRTEX5 (...); +module FRAME_ECC_VIRTEX5(CRCERROR, ECCERROR, SYNDROMEVALID, SYNDROME); output CRCERROR; output ECCERROR; output SYNDROMEVALID; output [11:0] SYNDROME; endmodule -module FRAME_ECC_VIRTEX6 (...); +module FRAME_ECC_VIRTEX6(CRCERROR, ECCERROR, ECCERRORSINGLE, SYNDROMEVALID, SYNDROME, FAR, SYNBIT, SYNWORD); parameter FARSRC = "EFAR"; parameter FRAME_RBT_IN_FILENAME = "NONE"; output CRCERROR; @@ -9893,7 +9935,7 @@ module FRAME_ECC_VIRTEX6 (...); output [6:0] SYNWORD; endmodule -module FRAME_ECCE2 (...); +module FRAME_ECCE2(CRCERROR, ECCERROR, ECCERRORSINGLE, SYNDROMEVALID, SYNDROME, FAR, SYNBIT, SYNWORD); parameter FARSRC = "EFAR"; parameter FRAME_RBT_IN_FILENAME = "NONE"; output CRCERROR; @@ -9906,7 +9948,7 @@ module FRAME_ECCE2 (...); output [6:0] SYNWORD; endmodule -module FRAME_ECCE3 (...); +module FRAME_ECCE3(CRCERROR, ECCERRORNOTSINGLE, ECCERRORSINGLE, ENDOFFRAME, ENDOFSCAN, FAR, FARSEL, ICAPBOTCLK, ICAPTOPCLK); output CRCERROR; output ECCERRORNOTSINGLE; output ECCERRORSINGLE; @@ -9918,7 +9960,7 @@ module FRAME_ECCE3 (...); input ICAPTOPCLK; endmodule -module FRAME_ECCE4 (...); +module FRAME_ECCE4(CRCERROR, ECCERRORNOTSINGLE, ECCERRORSINGLE, ENDOFFRAME, ENDOFSCAN, FAR, FARSEL, ICAPBOTCLK, ICAPTOPCLK); output CRCERROR; output ECCERRORNOTSINGLE; output ECCERRORSINGLE; @@ -9930,47 +9972,47 @@ module FRAME_ECCE4 (...); input ICAPTOPCLK; endmodule -module USR_ACCESS_VIRTEX4 (...); +module USR_ACCESS_VIRTEX4(DATA, DATAVALID); output [31:0] DATA; output DATAVALID; endmodule -module USR_ACCESS_VIRTEX5 (...); +module USR_ACCESS_VIRTEX5(CFGCLK, DATA, DATAVALID); output CFGCLK; output [31:0] DATA; output DATAVALID; endmodule -module USR_ACCESS_VIRTEX6 (...); +module USR_ACCESS_VIRTEX6(CFGCLK, DATA, DATAVALID); output CFGCLK; output [31:0] DATA; output DATAVALID; endmodule -module USR_ACCESSE2 (...); +module USR_ACCESSE2(CFGCLK, DATAVALID, DATA); output CFGCLK; output DATAVALID; output [31:0] DATA; endmodule -module POST_CRC_INTERNAL (...); +module POST_CRC_INTERNAL(CRCERROR); output CRCERROR; endmodule (* keep *) -module SUSPEND_SYNC (...); +module SUSPEND_SYNC(SREQ, CLK, SACK); output SREQ; input CLK; input SACK; endmodule (* keep *) -module KEY_CLEAR (...); +module KEY_CLEAR(KEYCLEARB); input KEYCLEARB; endmodule (* keep *) -module MASTER_JTAG (...); +module MASTER_JTAG(TDO, TCK, TDI, TMS); output TDO; input TCK; input TDI; @@ -9978,7 +10020,7 @@ module MASTER_JTAG (...); endmodule (* keep *) -module SPI_ACCESS (...); +module SPI_ACCESS(MISO, CLK, CSB, MOSI); parameter SIM_DELAY_TYPE = "SCALED"; parameter SIM_DEVICE = "3S1400AN"; parameter SIM_FACTORY_ID = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -9990,13 +10032,14 @@ module SPI_ACCESS (...); input MOSI; endmodule -module EFUSE_USR (...); +module EFUSE_USR(EFUSEUSR); parameter [31:0] SIM_EFUSE_VALUE = 32'h00000000; output [31:0] EFUSEUSR; endmodule (* keep *) -module SYSMON (...); +module SYSMON(BUSY, DRDY, EOC, EOS, JTAGBUSY, JTAGLOCKED, JTAGMODIFIED, OT, DO, ALM, CHANNEL, CONVST, CONVSTCLK, DCLK, DEN, DWE, RESET, VN, VP, DI, VAUXN +, VAUXP, DADDR); parameter [15:0] INIT_40 = 16'h0; parameter [15:0] INIT_41 = 16'h0; parameter [15:0] INIT_42 = 16'h0800; @@ -10049,7 +10092,8 @@ module SYSMON (...); endmodule (* keep *) -module XADC (...); +module XADC(BUSY, DRDY, EOC, EOS, JTAGBUSY, JTAGLOCKED, JTAGMODIFIED, OT, DO, ALM, CHANNEL, MUXADDR, CONVST, CONVSTCLK, DCLK, DEN, DWE, RESET, VN, VP, DI +, VAUXN, VAUXP, DADDR); parameter [15:0] INIT_40 = 16'h0; parameter [15:0] INIT_41 = 16'h0; parameter [15:0] INIT_42 = 16'h0800; @@ -10115,7 +10159,8 @@ module XADC (...); endmodule (* keep *) -module SYSMONE1 (...); +module SYSMONE1(ALM, BUSY, CHANNEL, DO, DRDY, EOC, EOS, I2C_SCLK_TS, I2C_SDA_TS, JTAGBUSY, JTAGLOCKED, JTAGMODIFIED, MUXADDR, OT, CONVST, CONVSTCLK, DADDR, DCLK, DEN, DI, DWE +, I2C_SCLK, I2C_SDA, RESET, VAUXN, VAUXP, VN, VP); parameter [15:0] INIT_40 = 16'h0; parameter [15:0] INIT_41 = 16'h0; parameter [15:0] INIT_42 = 16'h0; @@ -10224,7 +10269,8 @@ module SYSMONE1 (...); endmodule (* keep *) -module SYSMONE4 (...); +module SYSMONE4(ADC_DATA, ALM, BUSY, CHANNEL, DO, DRDY, EOC, EOS, I2C_SCLK_TS, I2C_SDA_TS, JTAGBUSY, JTAGLOCKED, JTAGMODIFIED, MUXADDR, OT, SMBALERT_TS, CONVST, CONVSTCLK, DADDR, DCLK, DEN +, DI, DWE, I2C_SCLK, I2C_SDA, RESET, VAUXN, VAUXP, VN, VP); parameter [15:0] COMMON_N_SOURCE = 16'hFFFF; parameter [15:0] INIT_40 = 16'h0000; parameter [15:0] INIT_41 = 16'h0000; @@ -10336,7 +10382,17 @@ module SYSMONE4 (...); input VP; endmodule -module GTPA1_DUAL (...); +module GTPA1_DUAL(DRDY, PHYSTATUS0, PHYSTATUS1, PLLLKDET0, PLLLKDET1, REFCLKOUT0, REFCLKOUT1, REFCLKPLL0, REFCLKPLL1, RESETDONE0, RESETDONE1, RXBYTEISALIGNED0, RXBYTEISALIGNED1, RXBYTEREALIGN0, RXBYTEREALIGN1, RXCHANBONDSEQ0, RXCHANBONDSEQ1, RXCHANISALIGNED0, RXCHANISALIGNED1, RXCHANREALIGN0, RXCHANREALIGN1 +, RXCOMMADET0, RXCOMMADET1, RXELECIDLE0, RXELECIDLE1, RXPRBSERR0, RXPRBSERR1, RXRECCLK0, RXRECCLK1, RXVALID0, RXVALID1, TXN0, TXN1, TXOUTCLK0, TXOUTCLK1, TXP0, TXP1, DRPDO, GTPCLKFBEAST, GTPCLKFBWEST, GTPCLKOUT0, GTPCLKOUT1 +, RXLOSSOFSYNC0, RXLOSSOFSYNC1, TXBUFSTATUS0, TXBUFSTATUS1, RXBUFSTATUS0, RXBUFSTATUS1, RXCHBONDO, RXCLKCORCNT0, RXCLKCORCNT1, RXSTATUS0, RXSTATUS1, RXDATA0, RXDATA1, RXCHARISCOMMA0, RXCHARISCOMMA1, RXCHARISK0, RXCHARISK1, RXDISPERR0, RXDISPERR1, RXNOTINTABLE0, RXNOTINTABLE1 +, RXRUNDISP0, RXRUNDISP1, TXKERR0, TXKERR1, TXRUNDISP0, TXRUNDISP1, RCALOUTEAST, RCALOUTWEST, TSTOUT0, TSTOUT1, CLK00, CLK01, CLK10, CLK11, CLKINEAST0, CLKINEAST1, CLKINWEST0, CLKINWEST1, DCLK, DEN, DWE +, GATERXELECIDLE0, GATERXELECIDLE1, GCLK00, GCLK01, GCLK10, GCLK11, GTPRESET0, GTPRESET1, IGNORESIGDET0, IGNORESIGDET1, INTDATAWIDTH0, INTDATAWIDTH1, PLLCLK00, PLLCLK01, PLLCLK10, PLLCLK11, PLLLKDETEN0, PLLLKDETEN1, PLLPOWERDOWN0, PLLPOWERDOWN1, PRBSCNTRESET0 +, PRBSCNTRESET1, REFCLKPWRDNB0, REFCLKPWRDNB1, RXBUFRESET0, RXBUFRESET1, RXCDRRESET0, RXCDRRESET1, RXCHBONDMASTER0, RXCHBONDMASTER1, RXCHBONDSLAVE0, RXCHBONDSLAVE1, RXCOMMADETUSE0, RXCOMMADETUSE1, RXDEC8B10BUSE0, RXDEC8B10BUSE1, RXENCHANSYNC0, RXENCHANSYNC1, RXENMCOMMAALIGN0, RXENMCOMMAALIGN1, RXENPCOMMAALIGN0, RXENPCOMMAALIGN1 +, RXENPMAPHASEALIGN0, RXENPMAPHASEALIGN1, RXN0, RXN1, RXP0, RXP1, RXPMASETPHASE0, RXPMASETPHASE1, RXPOLARITY0, RXPOLARITY1, RXRESET0, RXRESET1, RXSLIDE0, RXSLIDE1, RXUSRCLK0, RXUSRCLK1, RXUSRCLK20, RXUSRCLK21, TSTCLK0, TSTCLK1, TXCOMSTART0 +, TXCOMSTART1, TXCOMTYPE0, TXCOMTYPE1, TXDETECTRX0, TXDETECTRX1, TXELECIDLE0, TXELECIDLE1, TXENC8B10BUSE0, TXENC8B10BUSE1, TXENPMAPHASEALIGN0, TXENPMAPHASEALIGN1, TXINHIBIT0, TXINHIBIT1, TXPDOWNASYNCH0, TXPDOWNASYNCH1, TXPMASETPHASE0, TXPMASETPHASE1, TXPOLARITY0, TXPOLARITY1, TXPRBSFORCEERR0, TXPRBSFORCEERR1 +, TXRESET0, TXRESET1, TXUSRCLK0, TXUSRCLK1, TXUSRCLK20, TXUSRCLK21, USRCODEERR0, USRCODEERR1, TSTIN0, TSTIN1, DI, GTPCLKFBSEL0EAST, GTPCLKFBSEL0WEST, GTPCLKFBSEL1EAST, GTPCLKFBSEL1WEST, RXDATAWIDTH0, RXDATAWIDTH1, RXEQMIX0, RXEQMIX1, RXPOWERDOWN0, RXPOWERDOWN1 +, TXDATAWIDTH0, TXDATAWIDTH1, TXPOWERDOWN0, TXPOWERDOWN1, LOOPBACK0, LOOPBACK1, REFSELDYPLL0, REFSELDYPLL1, RXCHBONDI, RXENPRBSTST0, RXENPRBSTST1, TXBUFDIFFCTRL0, TXBUFDIFFCTRL1, TXENPRBSTST0, TXENPRBSTST1, TXPREEMPHASIS0, TXPREEMPHASIS1, TXDATA0, TXDATA1, TXBYPASS8B10B0, TXBYPASS8B10B1 +, TXCHARDISPMODE0, TXCHARDISPMODE1, TXCHARDISPVAL0, TXCHARDISPVAL1, TXCHARISK0, TXCHARISK1, TXDIFFCTRL0, TXDIFFCTRL1, RCALINEAST, RCALINWEST, DADDR, GTPTEST0, GTPTEST1); parameter AC_CAP_DIS_0 = "TRUE"; parameter AC_CAP_DIS_1 = "TRUE"; parameter integer ALIGN_COMMA_WORD_0 = 1; @@ -10788,7 +10844,11 @@ module GTPA1_DUAL (...); input [7:0] GTPTEST1; endmodule -module GT11_CUSTOM (...); +module GT11_CUSTOM(DRDY, RXBUFERR, RXCALFAIL, RXCOMMADET, RXCYCLELIMIT, RXLOCK, RXMCLK, RXPCSHCLKOUT, RXREALIGN, RXRECCLK1, RXRECCLK2, RXSIGDET, TX1N, TX1P, TXBUFERR, TXCALFAIL, TXCYCLELIMIT, TXLOCK, TXOUTCLK1, TXOUTCLK2, TXPCSHCLKOUT +, DO, RXLOSSOFSYNC, RXCRCOUT, TXCRCOUT, CHBONDO, RXSTATUS, RXDATA, RXCHARISCOMMA, RXCHARISK, RXDISPERR, RXNOTINTABLE, RXRUNDISP, TXKERR, TXRUNDISP, DCLK, DEN, DWE, ENCHANSYNC, ENMCOMMAALIGN, ENPCOMMAALIGN, GREFCLK +, POWERDOWN, REFCLK1, REFCLK2, RX1N, RX1P, RXBLOCKSYNC64B66BUSE, RXCLKSTABLE, RXCOMMADETUSE, RXCRCCLK, RXCRCDATAVALID, RXCRCINIT, RXCRCINTCLK, RXCRCPD, RXCRCRESET, RXDEC64B66BUSE, RXDEC8B10BUSE, RXDESCRAM64B66BUSE, RXIGNOREBTF, RXPMARESET, RXPOLARITY, RXRESET +, RXSLIDE, RXSYNC, RXUSRCLK2, RXUSRCLK, TXCLKSTABLE, TXCRCCLK, TXCRCDATAVALID, TXCRCINIT, TXCRCINTCLK, TXCRCPD, TXCRCRESET, TXENC64B66BUSE, TXENC8B10BUSE, TXENOOB, TXGEARBOX64B66BUSE, TXINHIBIT, TXPMARESET, TXPOLARITY, TXRESET, TXSCRAM64B66BUSE, TXSYNC +, TXUSRCLK2, TXUSRCLK, DI, LOOPBACK, RXDATAWIDTH, RXINTDATAWIDTH, TXDATAWIDTH, TXINTDATAWIDTH, RXCRCDATAWIDTH, TXCRCDATAWIDTH, CHBONDI, RXCRCIN, TXCRCIN, TXDATA, DADDR, TXBYPASS8B10B, TXCHARDISPMODE, TXCHARDISPVAL, TXCHARISK); parameter ALIGN_COMMA_WORD = 1; parameter BANDGAPSEL = "FALSE"; parameter BIASRESSEL = "TRUE"; @@ -11060,7 +11120,16 @@ module GT11_CUSTOM (...); input [7:0] TXCHARISK; endmodule -module GT11_DUAL (...); +module GT11_DUAL(DRDYA, DRDYB, RXBUFERRA, RXBUFERRB, RXCALFAILA, RXCALFAILB, RXCOMMADETA, RXCOMMADETB, RXCYCLELIMITA, RXCYCLELIMITB, RXLOCKA, RXLOCKB, RXMCLKA, RXMCLKB, RXPCSHCLKOUTA, RXPCSHCLKOUTB, RXREALIGNA, RXREALIGNB, RXRECCLK1A, RXRECCLK1B, RXRECCLK2A +, RXRECCLK2B, RXSIGDETA, RXSIGDETB, TX1NA, TX1NB, TX1PA, TX1PB, TXBUFERRA, TXBUFERRB, TXCALFAILA, TXCALFAILB, TXCYCLELIMITA, TXCYCLELIMITB, TXLOCKA, TXLOCKB, TXOUTCLK1A, TXOUTCLK1B, TXOUTCLK2A, TXOUTCLK2B, TXPCSHCLKOUTA, TXPCSHCLKOUTB +, DOA, DOB, RXLOSSOFSYNCA, RXLOSSOFSYNCB, RXCRCOUTA, RXCRCOUTB, TXCRCOUTA, TXCRCOUTB, CHBONDOA, CHBONDOB, RXSTATUSA, RXSTATUSB, RXDATAA, RXDATAB, RXCHARISCOMMAA, RXCHARISCOMMAB, RXCHARISKA, RXCHARISKB, RXDISPERRA, RXDISPERRB, RXNOTINTABLEA +, RXNOTINTABLEB, RXRUNDISPA, RXRUNDISPB, TXKERRA, TXKERRB, TXRUNDISPA, TXRUNDISPB, DCLKA, DCLKB, DENA, DENB, DWEA, DWEB, ENCHANSYNCA, ENCHANSYNCB, ENMCOMMAALIGNA, ENMCOMMAALIGNB, ENPCOMMAALIGNA, ENPCOMMAALIGNB, GREFCLKA, GREFCLKB +, POWERDOWNA, POWERDOWNB, REFCLK1A, REFCLK1B, REFCLK2A, REFCLK2B, RX1NA, RX1NB, RX1PA, RX1PB, RXBLOCKSYNC64B66BUSEA, RXBLOCKSYNC64B66BUSEB, RXCLKSTABLEA, RXCLKSTABLEB, RXCOMMADETUSEA, RXCOMMADETUSEB, RXCRCCLKA, RXCRCCLKB, RXCRCDATAVALIDA, RXCRCDATAVALIDB, RXCRCINITA +, RXCRCINITB, RXCRCINTCLKA, RXCRCINTCLKB, RXCRCPDA, RXCRCPDB, RXCRCRESETA, RXCRCRESETB, RXDEC64B66BUSEA, RXDEC64B66BUSEB, RXDEC8B10BUSEA, RXDEC8B10BUSEB, RXDESCRAM64B66BUSEA, RXDESCRAM64B66BUSEB, RXIGNOREBTFA, RXIGNOREBTFB, RXPMARESETA, RXPMARESETB, RXPOLARITYA, RXPOLARITYB, RXRESETA, RXRESETB +, RXSLIDEA, RXSLIDEB, RXSYNCA, RXSYNCB, RXUSRCLK2A, RXUSRCLK2B, RXUSRCLKA, RXUSRCLKB, TXCLKSTABLEA, TXCLKSTABLEB, TXCRCCLKA, TXCRCCLKB, TXCRCDATAVALIDA, TXCRCDATAVALIDB, TXCRCINITA, TXCRCINITB, TXCRCINTCLKA, TXCRCINTCLKB, TXCRCPDA, TXCRCPDB, TXCRCRESETA +, TXCRCRESETB, TXENC64B66BUSEA, TXENC64B66BUSEB, TXENC8B10BUSEA, TXENC8B10BUSEB, TXENOOBA, TXENOOBB, TXGEARBOX64B66BUSEA, TXGEARBOX64B66BUSEB, TXINHIBITA, TXINHIBITB, TXPMARESETA, TXPMARESETB, TXPOLARITYA, TXPOLARITYB, TXRESETA, TXRESETB, TXSCRAM64B66BUSEA, TXSCRAM64B66BUSEB, TXSYNCA, TXSYNCB +, TXUSRCLK2A, TXUSRCLK2B, TXUSRCLKA, TXUSRCLKB, DIA, DIB, LOOPBACKA, LOOPBACKB, RXDATAWIDTHA, RXDATAWIDTHB, RXINTDATAWIDTHA, RXINTDATAWIDTHB, TXDATAWIDTHA, TXDATAWIDTHB, TXINTDATAWIDTHA, TXINTDATAWIDTHB, RXCRCDATAWIDTHA, RXCRCDATAWIDTHB, TXCRCDATAWIDTHA, TXCRCDATAWIDTHB, CHBONDIA +, CHBONDIB, RXCRCINA, RXCRCINB, TXCRCINA, TXCRCINB, TXDATAA, TXDATAB, DADDRA, DADDRB, TXBYPASS8B10BA, TXBYPASS8B10BB, TXCHARDISPMODEA, TXCHARDISPMODEB, TXCHARDISPVALA, TXCHARDISPVALB, TXCHARISKA, TXCHARISKB); parameter ALIGN_COMMA_WORD_A = 1; parameter ALIGN_COMMA_WORD_B = 1; parameter BANDGAPSEL_A = "FALSE"; @@ -11601,7 +11670,7 @@ module GT11_DUAL (...); input [7:0] TXCHARISKB; endmodule -module GT11CLK (...); +module GT11CLK(SYNCLK1OUT, SYNCLK2OUT, MGTCLKN, MGTCLKP, REFCLK, RXBCLK, SYNCLK1IN, SYNCLK2IN); parameter REFCLKSEL = "MGTCLK"; parameter SYNCLK1OUTEN = "ENABLE"; parameter SYNCLK2OUTEN = "DISABLE"; @@ -11615,7 +11684,7 @@ module GT11CLK (...); input SYNCLK2IN; endmodule -module GT11CLK_MGT (...); +module GT11CLK_MGT(SYNCLK1OUT, SYNCLK2OUT, MGTCLKN, MGTCLKP); parameter SYNCLK1OUTEN = "ENABLE"; parameter SYNCLK2OUTEN = "DISABLE"; output SYNCLK1OUT; @@ -11624,7 +11693,15 @@ module GT11CLK_MGT (...); input MGTCLKP; endmodule -module GTP_DUAL (...); +module GTP_DUAL(DRDY, PHYSTATUS0, PHYSTATUS1, PLLLKDET, REFCLKOUT, RESETDONE0, RESETDONE1, RXBYTEISALIGNED0, RXBYTEISALIGNED1, RXBYTEREALIGN0, RXBYTEREALIGN1, RXCHANBONDSEQ0, RXCHANBONDSEQ1, RXCHANISALIGNED0, RXCHANISALIGNED1, RXCHANREALIGN0, RXCHANREALIGN1, RXCOMMADET0, RXCOMMADET1, RXELECIDLE0, RXELECIDLE1 +, RXOVERSAMPLEERR0, RXOVERSAMPLEERR1, RXPRBSERR0, RXPRBSERR1, RXRECCLK0, RXRECCLK1, RXVALID0, RXVALID1, TXN0, TXN1, TXOUTCLK0, TXOUTCLK1, TXP0, TXP1, DO, RXDATA0, RXDATA1, RXCHARISCOMMA0, RXCHARISCOMMA1, RXCHARISK0, RXCHARISK1 +, RXDISPERR0, RXDISPERR1, RXLOSSOFSYNC0, RXLOSSOFSYNC1, RXNOTINTABLE0, RXNOTINTABLE1, RXRUNDISP0, RXRUNDISP1, TXBUFSTATUS0, TXBUFSTATUS1, TXKERR0, TXKERR1, TXRUNDISP0, TXRUNDISP1, RXBUFSTATUS0, RXBUFSTATUS1, RXCHBONDO0, RXCHBONDO1, RXCLKCORCNT0, RXCLKCORCNT1, RXSTATUS0 +, RXSTATUS1, CLKIN, DCLK, DEN, DWE, GTPRESET, INTDATAWIDTH, PLLLKDETEN, PLLPOWERDOWN, PRBSCNTRESET0, PRBSCNTRESET1, REFCLKPWRDNB, RXBUFRESET0, RXBUFRESET1, RXCDRRESET0, RXCDRRESET1, RXCOMMADETUSE0, RXCOMMADETUSE1, RXDATAWIDTH0, RXDATAWIDTH1, RXDEC8B10BUSE0 +, RXDEC8B10BUSE1, RXELECIDLERESET0, RXELECIDLERESET1, RXENCHANSYNC0, RXENCHANSYNC1, RXENELECIDLERESETB, RXENEQB0, RXENEQB1, RXENMCOMMAALIGN0, RXENMCOMMAALIGN1, RXENPCOMMAALIGN0, RXENPCOMMAALIGN1, RXENSAMPLEALIGN0, RXENSAMPLEALIGN1, RXN0, RXN1, RXP0, RXP1, RXPMASETPHASE0, RXPMASETPHASE1, RXPOLARITY0 +, RXPOLARITY1, RXRESET0, RXRESET1, RXSLIDE0, RXSLIDE1, RXUSRCLK0, RXUSRCLK1, RXUSRCLK20, RXUSRCLK21, TXCOMSTART0, TXCOMSTART1, TXCOMTYPE0, TXCOMTYPE1, TXDATAWIDTH0, TXDATAWIDTH1, TXDETECTRX0, TXDETECTRX1, TXELECIDLE0, TXELECIDLE1, TXENC8B10BUSE0, TXENC8B10BUSE1 +, TXENPMAPHASEALIGN, TXINHIBIT0, TXINHIBIT1, TXPMASETPHASE, TXPOLARITY0, TXPOLARITY1, TXRESET0, TXRESET1, TXUSRCLK0, TXUSRCLK1, TXUSRCLK20, TXUSRCLK21, DI, TXDATA0, TXDATA1, RXENPRBSTST0, RXENPRBSTST1, RXEQMIX0, RXEQMIX1, RXPOWERDOWN0, RXPOWERDOWN1 +, TXBYPASS8B10B0, TXBYPASS8B10B1, TXCHARDISPMODE0, TXCHARDISPMODE1, TXCHARDISPVAL0, TXCHARDISPVAL1, TXCHARISK0, TXCHARISK1, TXENPRBSTST0, TXENPRBSTST1, TXPOWERDOWN0, TXPOWERDOWN1, LOOPBACK0, LOOPBACK1, RXCHBONDI0, RXCHBONDI1, TXBUFDIFFCTRL0, TXBUFDIFFCTRL1, TXDIFFCTRL0, TXDIFFCTRL1, TXPREEMPHASIS0 +, TXPREEMPHASIS1, GTPTEST, RXEQPOLE0, RXEQPOLE1, DADDR); parameter AC_CAP_DIS_0 = "TRUE"; parameter AC_CAP_DIS_1 = "TRUE"; parameter CHAN_BOND_MODE_0 = "OFF"; @@ -11981,7 +12058,17 @@ module GTP_DUAL (...); input [6:0] DADDR; endmodule -module GTX_DUAL (...); +module GTX_DUAL(DRDY, PHYSTATUS0, PHYSTATUS1, PLLLKDET, REFCLKOUT, RESETDONE0, RESETDONE1, RXBYTEISALIGNED0, RXBYTEISALIGNED1, RXBYTEREALIGN0, RXBYTEREALIGN1, RXCHANBONDSEQ0, RXCHANBONDSEQ1, RXCHANISALIGNED0, RXCHANISALIGNED1, RXCHANREALIGN0, RXCHANREALIGN1, RXCOMMADET0, RXCOMMADET1, RXDATAVALID0, RXDATAVALID1 +, RXELECIDLE0, RXELECIDLE1, RXHEADERVALID0, RXHEADERVALID1, RXOVERSAMPLEERR0, RXOVERSAMPLEERR1, RXPRBSERR0, RXPRBSERR1, RXRECCLK0, RXRECCLK1, RXSTARTOFSEQ0, RXSTARTOFSEQ1, RXVALID0, RXVALID1, TXGEARBOXREADY0, TXGEARBOXREADY1, TXN0, TXN1, TXOUTCLK0, TXOUTCLK1, TXP0 +, TXP1, DO, RXLOSSOFSYNC0, RXLOSSOFSYNC1, TXBUFSTATUS0, TXBUFSTATUS1, DFESENSCAL0, DFESENSCAL1, RXBUFSTATUS0, RXBUFSTATUS1, RXCLKCORCNT0, RXCLKCORCNT1, RXHEADER0, RXHEADER1, RXSTATUS0, RXSTATUS1, RXDATA0, RXDATA1, DFETAP3MONITOR0, DFETAP3MONITOR1, DFETAP4MONITOR0 +, DFETAP4MONITOR1, RXCHARISCOMMA0, RXCHARISCOMMA1, RXCHARISK0, RXCHARISK1, RXCHBONDO0, RXCHBONDO1, RXDISPERR0, RXDISPERR1, RXNOTINTABLE0, RXNOTINTABLE1, RXRUNDISP0, RXRUNDISP1, TXKERR0, TXKERR1, TXRUNDISP0, TXRUNDISP1, DFEEYEDACMONITOR0, DFEEYEDACMONITOR1, DFETAP1MONITOR0, DFETAP1MONITOR1 +, DFETAP2MONITOR0, DFETAP2MONITOR1, DFECLKDLYADJMONITOR0, DFECLKDLYADJMONITOR1, CLKIN, DCLK, DEN, DWE, GTXRESET, INTDATAWIDTH, PLLLKDETEN, PLLPOWERDOWN, PRBSCNTRESET0, PRBSCNTRESET1, REFCLKPWRDNB, RXBUFRESET0, RXBUFRESET1, RXCDRRESET0, RXCDRRESET1, RXCOMMADETUSE0, RXCOMMADETUSE1 +, RXDEC8B10BUSE0, RXDEC8B10BUSE1, RXENCHANSYNC0, RXENCHANSYNC1, RXENEQB0, RXENEQB1, RXENMCOMMAALIGN0, RXENMCOMMAALIGN1, RXENPCOMMAALIGN0, RXENPCOMMAALIGN1, RXENPMAPHASEALIGN0, RXENPMAPHASEALIGN1, RXENSAMPLEALIGN0, RXENSAMPLEALIGN1, RXGEARBOXSLIP0, RXGEARBOXSLIP1, RXN0, RXN1, RXP0, RXP1, RXPMASETPHASE0 +, RXPMASETPHASE1, RXPOLARITY0, RXPOLARITY1, RXRESET0, RXRESET1, RXSLIDE0, RXSLIDE1, RXUSRCLK0, RXUSRCLK1, RXUSRCLK20, RXUSRCLK21, TXCOMSTART0, TXCOMSTART1, TXCOMTYPE0, TXCOMTYPE1, TXDETECTRX0, TXDETECTRX1, TXELECIDLE0, TXELECIDLE1, TXENC8B10BUSE0, TXENC8B10BUSE1 +, TXENPMAPHASEALIGN0, TXENPMAPHASEALIGN1, TXINHIBIT0, TXINHIBIT1, TXPMASETPHASE0, TXPMASETPHASE1, TXPOLARITY0, TXPOLARITY1, TXRESET0, TXRESET1, TXSTARTSEQ0, TXSTARTSEQ1, TXUSRCLK0, TXUSRCLK1, TXUSRCLK20, TXUSRCLK21, GTXTEST, DI, RXDATAWIDTH0, RXDATAWIDTH1, RXENPRBSTST0 +, RXENPRBSTST1, RXEQMIX0, RXEQMIX1, RXPOWERDOWN0, RXPOWERDOWN1, TXDATAWIDTH0, TXDATAWIDTH1, TXENPRBSTST0, TXENPRBSTST1, TXPOWERDOWN0, TXPOWERDOWN1, LOOPBACK0, LOOPBACK1, TXBUFDIFFCTRL0, TXBUFDIFFCTRL1, TXDIFFCTRL0, TXDIFFCTRL1, TXHEADER0, TXHEADER1, TXDATA0, TXDATA1 +, DFETAP30, DFETAP31, DFETAP40, DFETAP41, RXCHBONDI0, RXCHBONDI1, RXEQPOLE0, RXEQPOLE1, TXBYPASS8B10B0, TXBYPASS8B10B1, TXCHARDISPMODE0, TXCHARDISPMODE1, TXCHARDISPVAL0, TXCHARDISPVAL1, TXCHARISK0, TXCHARISK1, TXPREEMPHASIS0, TXPREEMPHASIS1, DFETAP10, DFETAP11, DFETAP20 +, DFETAP21, DFECLKDLYADJ0, DFECLKDLYADJ1, DADDR, TXSEQUENCE0, TXSEQUENCE1); parameter STEPPING = "0"; parameter AC_CAP_DIS_0 = "TRUE"; parameter AC_CAP_DIS_1 = "TRUE"; @@ -12417,7 +12504,7 @@ module GTX_DUAL (...); input [6:0] TXSEQUENCE1; endmodule -module CRC32 (...); +module CRC32(CRCOUT, CRCCLK, CRCDATAVALID, CRCDATAWIDTH, CRCIN, CRCRESET); parameter CRC_INIT = 32'hFFFFFFFF; output [31:0] CRCOUT; (* clkbuf_sink *) @@ -12428,7 +12515,7 @@ module CRC32 (...); input CRCRESET; endmodule -module CRC64 (...); +module CRC64(CRCOUT, CRCCLK, CRCDATAVALID, CRCDATAWIDTH, CRCIN, CRCRESET); parameter CRC_INIT = 32'hFFFFFFFF; output [31:0] CRCOUT; (* clkbuf_sink *) @@ -12439,7 +12526,15 @@ module CRC64 (...); input CRCRESET; endmodule -module GTHE1_QUAD (...); +module GTHE1_QUAD(DRDY, GTHINITDONE, MGMTPCSRDACK, RXCTRLACK0, RXCTRLACK1, RXCTRLACK2, RXCTRLACK3, RXDATATAP0, RXDATATAP1, RXDATATAP2, RXDATATAP3, RXPCSCLKSMPL0, RXPCSCLKSMPL1, RXPCSCLKSMPL2, RXPCSCLKSMPL3, RXUSERCLKOUT0, RXUSERCLKOUT1, RXUSERCLKOUT2, RXUSERCLKOUT3, TSTPATH, TSTREFCLKFAB +, TSTREFCLKOUT, TXCTRLACK0, TXCTRLACK1, TXCTRLACK2, TXCTRLACK3, TXDATATAP10, TXDATATAP11, TXDATATAP12, TXDATATAP13, TXDATATAP20, TXDATATAP21, TXDATATAP22, TXDATATAP23, TXN0, TXN1, TXN2, TXN3, TXP0, TXP1, TXP2, TXP3 +, TXPCSCLKSMPL0, TXPCSCLKSMPL1, TXPCSCLKSMPL2, TXPCSCLKSMPL3, TXUSERCLKOUT0, TXUSERCLKOUT1, TXUSERCLKOUT2, TXUSERCLKOUT3, DRPDO, MGMTPCSRDDATA, RXDATA0, RXDATA1, RXDATA2, RXDATA3, RXCODEERR0, RXCODEERR1, RXCODEERR2, RXCODEERR3, RXCTRL0, RXCTRL1, RXCTRL2 +, RXCTRL3, RXDISPERR0, RXDISPERR1, RXDISPERR2, RXDISPERR3, RXVALID0, RXVALID1, RXVALID2, RXVALID3, DCLK, DEN, DFETRAINCTRL0, DFETRAINCTRL1, DFETRAINCTRL2, DFETRAINCTRL3, DISABLEDRP, DWE, GTHINIT, GTHRESET, GTHX2LANE01, GTHX2LANE23 +, GTHX4LANE, MGMTPCSREGRD, MGMTPCSREGWR, POWERDOWN0, POWERDOWN1, POWERDOWN2, POWERDOWN3, REFCLK, RXBUFRESET0, RXBUFRESET1, RXBUFRESET2, RXBUFRESET3, RXENCOMMADET0, RXENCOMMADET1, RXENCOMMADET2, RXENCOMMADET3, RXN0, RXN1, RXN2, RXN3, RXP0 +, RXP1, RXP2, RXP3, RXPOLARITY0, RXPOLARITY1, RXPOLARITY2, RXPOLARITY3, RXSLIP0, RXSLIP1, RXSLIP2, RXSLIP3, RXUSERCLKIN0, RXUSERCLKIN1, RXUSERCLKIN2, RXUSERCLKIN3, TXBUFRESET0, TXBUFRESET1, TXBUFRESET2, TXBUFRESET3, TXDEEMPH0, TXDEEMPH1 +, TXDEEMPH2, TXDEEMPH3, TXUSERCLKIN0, TXUSERCLKIN1, TXUSERCLKIN2, TXUSERCLKIN3, DADDR, DI, MGMTPCSREGADDR, MGMTPCSWRDATA, RXPOWERDOWN0, RXPOWERDOWN1, RXPOWERDOWN2, RXPOWERDOWN3, RXRATE0, RXRATE1, RXRATE2, RXRATE3, TXPOWERDOWN0, TXPOWERDOWN1, TXPOWERDOWN2 +, TXPOWERDOWN3, TXRATE0, TXRATE1, TXRATE2, TXRATE3, PLLREFCLKSEL, SAMPLERATE0, SAMPLERATE1, SAMPLERATE2, SAMPLERATE3, TXMARGIN0, TXMARGIN1, TXMARGIN2, TXMARGIN3, MGMTPCSLANESEL, MGMTPCSMMDADDR, PLLPCSCLKDIV, TXDATA0, TXDATA1, TXDATA2, TXDATA3 +, TXCTRL0, TXCTRL1, TXCTRL2, TXCTRL3, TXDATAMSB0, TXDATAMSB1, TXDATAMSB2, TXDATAMSB3); parameter [15:0] BER_CONST_PTRN0 = 16'h0000; parameter [15:0] BER_CONST_PTRN1 = 16'h0000; parameter [15:0] BUFFER_CONFIG_LANE0 = 16'h4004; @@ -12907,7 +13002,15 @@ module GTHE1_QUAD (...); input [7:0] TXDATAMSB3; endmodule -module GTXE1 (...); +module GTXE1(COMFINISH, COMINITDET, COMSASDET, COMWAKEDET, DRDY, PHYSTATUS, RXBYTEISALIGNED, RXBYTEREALIGN, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCOMMADET, RXDATAVALID, RXELECIDLE, RXHEADERVALID, RXOVERSAMPLEERR, RXPLLLKDET, RXPRBSERR, RXRATEDONE, RXRECCLK, RXRECCLKPCS +, RXRESETDONE, RXSTARTOFSEQ, RXVALID, TXGEARBOXREADY, TXN, TXOUTCLK, TXOUTCLKPCS, TXP, TXPLLLKDET, TXRATEDONE, TXRESETDONE, DRPDO, MGTREFCLKFAB, RXLOSSOFSYNC, TXBUFSTATUS, DFESENSCAL, RXBUFSTATUS, RXCLKCORCNT, RXHEADER, RXSTATUS, RXDATA +, DFETAP3MONITOR, DFETAP4MONITOR, RXCHARISCOMMA, RXCHARISK, RXCHBONDO, RXDISPERR, RXNOTINTABLE, RXRUNDISP, TXKERR, TXRUNDISP, DFEEYEDACMON, DFETAP1MONITOR, DFETAP2MONITOR, DFECLKDLYADJMON, RXDLYALIGNMONITOR, TXDLYALIGNMONITOR, TSTOUT, DCLK, DEN, DFEDLYOVRD, DFETAPOVRD +, DWE, GATERXELECIDLE, GREFCLKRX, GREFCLKTX, GTXRXRESET, GTXTXRESET, IGNORESIGDET, PERFCLKRX, PERFCLKTX, PLLRXRESET, PLLTXRESET, PRBSCNTRESET, RXBUFRESET, RXCDRRESET, RXCHBONDMASTER, RXCHBONDSLAVE, RXCOMMADETUSE, RXDEC8B10BUSE, RXDLYALIGNDISABLE, RXDLYALIGNMONENB, RXDLYALIGNOVERRIDE +, RXDLYALIGNRESET, RXDLYALIGNSWPPRECURB, RXDLYALIGNUPDSW, RXENCHANSYNC, RXENMCOMMAALIGN, RXENPCOMMAALIGN, RXENPMAPHASEALIGN, RXENSAMPLEALIGN, RXGEARBOXSLIP, RXN, RXP, RXPLLLKDETEN, RXPLLPOWERDOWN, RXPMASETPHASE, RXPOLARITY, RXRESET, RXSLIDE, RXUSRCLK2, RXUSRCLK, TSTCLK0, TSTCLK1 +, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXDEEMPH, TXDETECTRX, TXDLYALIGNDISABLE, TXDLYALIGNMONENB, TXDLYALIGNOVERRIDE, TXDLYALIGNRESET, TXDLYALIGNUPDSW, TXELECIDLE, TXENC8B10BUSE, TXENPMAPHASEALIGN, TXINHIBIT, TXPDOWNASYNCH, TXPLLLKDETEN, TXPLLPOWERDOWN, TXPMASETPHASE, TXPOLARITY, TXPRBSFORCEERR, TXRESET +, TXSTARTSEQ, TXSWING, TXUSRCLK2, TXUSRCLK, USRCODEERR, GTXTEST, DI, TSTIN, MGTREFCLKRX, MGTREFCLKTX, NORTHREFCLKRX, NORTHREFCLKTX, RXPOWERDOWN, RXRATE, SOUTHREFCLKRX, SOUTHREFCLKTX, TXPOWERDOWN, TXRATE, LOOPBACK, RXCHBONDLEVEL, RXENPRBSTST +, RXPLLREFSELDY, TXBUFDIFFCTRL, TXENPRBSTST, TXHEADER, TXMARGIN, TXPLLREFSELDY, TXDATA, DFETAP3, DFETAP4, RXCHBONDI, TXBYPASS8B10B, TXCHARDISPMODE, TXCHARDISPVAL, TXCHARISK, TXDIFFCTRL, TXPREEMPHASIS, DFETAP1, DFETAP2, TXPOSTEMPHASIS, DFECLKDLYADJ, TXSEQUENCE +, DADDR, RXEQMIX); parameter AC_CAP_DIS = "TRUE"; parameter integer ALIGN_COMMA_WORD = 1; parameter [1:0] BGTEST_CFG = 2'b00; @@ -13259,7 +13362,7 @@ module GTXE1 (...); input [9:0] RXEQMIX; endmodule -module IBUFDS_GTXE1 (...); +module IBUFDS_GTXE1(O, ODIV2, CEB, I, IB); parameter CLKCM_CFG = "TRUE"; parameter CLKRCV_TRST = "TRUE"; parameter [9:0] REFCLKOUT_DLY = 10'b0000000000; @@ -13272,7 +13375,7 @@ module IBUFDS_GTXE1 (...); input IB; endmodule -module IBUFDS_GTHE1 (...); +module IBUFDS_GTHE1(O, I, IB); output O; (* iopad_external_pin *) input I; @@ -13280,7 +13383,20 @@ module IBUFDS_GTHE1 (...); input IB; endmodule -module GTHE2_CHANNEL (...); +module GTHE2_CHANNEL(CPLLFBCLKLOST, CPLLLOCK, CPLLREFCLKLOST, DRPRDY, EYESCANDATAERROR, GTHTXN, GTHTXP, GTREFCLKMONITOR, PHYSTATUS, RSOSINTDONE, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCOMINITDET, RXCOMMADET, RXCOMSASDET, RXCOMWAKEDET, RXDFESLIDETAPSTARTED +, RXDFESLIDETAPSTROBEDONE, RXDFESLIDETAPSTROBESTARTED, RXDFESTADAPTDONE, RXDLYSRESETDONE, RXELECIDLE, RXOSINTSTARTED, RXOSINTSTROBEDONE, RXOSINTSTROBESTARTED, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE, RXPMARESETDONE, RXPRBSERR, RXQPISENN, RXQPISENP, RXRATEDONE, RXRESETDONE, RXSYNCDONE, RXSYNCOUT, RXVALID +, TXCOMFINISH, TXDLYSRESETDONE, TXGEARBOXREADY, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE, TXPHINITDONE, TXPMARESETDONE, TXQPISENN, TXQPISENP, TXRATEDONE, TXRESETDONE, TXSYNCDONE, TXSYNCOUT, DMONITOROUT, DRPDO, PCSRSVDOUT, RXCLKCORCNT, RXDATAVALID, RXHEADERVALID +, RXSTARTOFSEQ, TXBUFSTATUS, RXBUFSTATUS, RXSTATUS, RXCHBONDO, RXPHMONITOR, RXPHSLIPMONITOR, RXHEADER, RXDATA, RXMONITOROUT, RXCHARISCOMMA, RXCHARISK, RXDISPERR, RXNOTINTABLE, CFGRESET, CLKRSVD0, CLKRSVD1, CPLLLOCKDETCLK, CPLLLOCKEN, CPLLPD, CPLLRESET +, DMONFIFORESET, DMONITORCLK, DRPCLK, DRPEN, DRPWE, EYESCANMODE, EYESCANRESET, EYESCANTRIGGER, GTGREFCLK, GTHRXN, GTHRXP, GTNORTHREFCLK0, GTNORTHREFCLK1, GTREFCLK0, GTREFCLK1, GTRESETSEL, GTRXRESET, GTSOUTHREFCLK0, GTSOUTHREFCLK1, GTTXRESET, QPLLCLK +, QPLLREFCLK, RESETOVRD, RX8B10BEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCDRRESETRSV, RXCHBONDEN, RXCHBONDMASTER, RXCHBONDSLAVE, RXCOMMADETEN, RXDDIEN, RXDFEAGCHOLD, RXDFEAGCOVRDEN, RXDFECM1EN, RXDFELFHOLD, RXDFELFOVRDEN, RXDFELPMRESET, RXDFESLIDETAPADAPTEN +, RXDFESLIDETAPHOLD, RXDFESLIDETAPINITOVRDEN, RXDFESLIDETAPONLYADAPTEN, RXDFESLIDETAPOVRDEN, RXDFESLIDETAPSTROBE, RXDFETAP2HOLD, RXDFETAP2OVRDEN, RXDFETAP3HOLD, RXDFETAP3OVRDEN, RXDFETAP4HOLD, RXDFETAP4OVRDEN, RXDFETAP5HOLD, RXDFETAP5OVRDEN, RXDFETAP6HOLD, RXDFETAP6OVRDEN, RXDFETAP7HOLD, RXDFETAP7OVRDEN, RXDFEUTHOLD, RXDFEUTOVRDEN, RXDFEVPHOLD, RXDFEVPOVRDEN +, RXDFEVSEN, RXDFEXYDEN, RXDLYBYPASS, RXDLYEN, RXDLYOVRDEN, RXDLYSRESET, RXGEARBOXSLIP, RXLPMEN, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFKLOVRDEN, RXMCOMMAALIGNEN, RXOOBRESET, RXOSCALRESET, RXOSHOLD, RXOSINTEN, RXOSINTHOLD, RXOSINTNTRLEN, RXOSINTOVRDEN, RXOSINTSTROBE +, RXOSINTTESTOVRDEN, RXOSOVRDEN, RXPCOMMAALIGNEN, RXPCSRESET, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPHOVRDEN, RXPMARESET, RXPOLARITY, RXPRBSCNTRESET, RXQPIEN, RXRATEMODE, RXSLIDE, RXSYNCALLIN, RXSYNCIN, RXSYNCMODE, RXUSERRDY, RXUSRCLK2, RXUSRCLK +, SETERRSTATUS, SIGVALIDCLK, TX8B10BEN, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXDEEMPH, TXDETECTRX, TXDIFFPD, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE, TXINHIBIT, TXPCSRESET, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN +, TXPHDLYPD, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPIPPMEN, TXPIPPMOVRDEN, TXPIPPMPD, TXPIPPMSEL, TXPISOPD, TXPMARESET, TXPOLARITY, TXPOSTCURSORINV, TXPRBSFORCEERR, TXPRECURSORINV, TXQPIBIASEN, TXQPISTRONGPDOWN, TXQPIWEAKPUP, TXRATEMODE, TXSTARTSEQ, TXSWING +, TXSYNCALLIN, TXSYNCIN, TXSYNCMODE, TXUSERRDY, TXUSRCLK2, TXUSRCLK, RXADAPTSELTEST, DRPDI, GTRSVD, PCSRSVDIN, TSTIN, RXELECIDLEMODE, RXMONITORSEL, RXPD, RXSYSCLKSEL, TXPD, TXSYSCLKSEL, CPLLREFCLKSEL, LOOPBACK, RXCHBONDLEVEL, RXOUTCLKSEL +, RXPRBSSEL, RXRATE, TXBUFDIFFCTRL, TXHEADER, TXMARGIN, TXOUTCLKSEL, TXPRBSSEL, TXRATE, RXOSINTCFG, RXOSINTID0, TXDIFFCTRL, PCSRSVDIN2, PMARSVDIN, RXCHBONDI, RXDFEAGCTRL, RXDFESLIDETAP, TXPIPPMSTEPSIZE, TXPOSTCURSOR, TXPRECURSOR, RXDFESLIDETAPID, TXDATA +, TXMAINCURSOR, TXSEQUENCE, TX8B10BBYPASS, TXCHARDISPMODE, TXCHARDISPVAL, TXCHARISK, DRPADDR); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; @@ -13843,7 +13959,8 @@ module GTHE2_CHANNEL (...); input [8:0] DRPADDR; endmodule -module GTHE2_COMMON (...); +module GTHE2_COMMON(DRPRDY, QPLLFBCLKLOST, QPLLLOCK, QPLLOUTCLK, QPLLOUTREFCLK, QPLLREFCLKLOST, REFCLKOUTMONITOR, DRPDO, PMARSVDOUT, QPLLDMONITOR, BGBYPASSB, BGMONITORENB, BGPDB, BGRCALOVRDENB, DRPCLK, DRPEN, DRPWE, GTGREFCLK, GTNORTHREFCLK0, GTNORTHREFCLK1, GTREFCLK0 +, GTREFCLK1, GTSOUTHREFCLK0, GTSOUTHREFCLK1, QPLLLOCKDETCLK, QPLLLOCKEN, QPLLOUTRESET, QPLLPD, QPLLRESET, RCALENB, DRPDI, QPLLRSVD1, QPLLREFCLKSEL, BGRCALOVRD, QPLLRSVD2, DRPADDR, PMARSVD); parameter [63:0] BIAS_CFG = 64'h0000040000001000; parameter [31:0] COMMON_CFG = 32'h0000001C; parameter [0:0] IS_DRPCLK_INVERTED = 1'b0; @@ -13913,7 +14030,17 @@ module GTHE2_COMMON (...); input [7:0] PMARSVD; endmodule -module GTPE2_CHANNEL (...); +module GTPE2_CHANNEL(DRPRDY, EYESCANDATAERROR, GTPTXN, GTPTXP, PHYSTATUS, PMARSVDOUT0, PMARSVDOUT1, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCOMINITDET, RXCOMMADET, RXCOMSASDET, RXCOMWAKEDET, RXDLYSRESETDONE, RXELECIDLE, RXHEADERVALID, RXOSINTDONE +, RXOSINTSTARTED, RXOSINTSTROBEDONE, RXOSINTSTROBESTARTED, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE, RXPMARESETDONE, RXPRBSERR, RXRATEDONE, RXRESETDONE, RXSYNCDONE, RXSYNCOUT, RXVALID, TXCOMFINISH, TXDLYSRESETDONE, TXGEARBOXREADY, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE +, TXPHINITDONE, TXPMARESETDONE, TXRATEDONE, TXRESETDONE, TXSYNCDONE, TXSYNCOUT, DMONITOROUT, DRPDO, PCSRSVDOUT, RXCLKCORCNT, RXDATAVALID, RXSTARTOFSEQ, TXBUFSTATUS, RXBUFSTATUS, RXHEADER, RXSTATUS, RXDATA, RXCHARISCOMMA, RXCHARISK, RXCHBONDO, RXDISPERR +, RXNOTINTABLE, RXPHMONITOR, RXPHSLIPMONITOR, CFGRESET, CLKRSVD0, CLKRSVD1, DMONFIFORESET, DMONITORCLK, DRPCLK, DRPEN, DRPWE, EYESCANMODE, EYESCANRESET, EYESCANTRIGGER, GTPRXN, GTPRXP, GTRESETSEL, GTRXRESET, GTTXRESET, PLL0CLK, PLL0REFCLK +, PLL1CLK, PLL1REFCLK, PMARSVDIN0, PMARSVDIN1, PMARSVDIN2, PMARSVDIN3, PMARSVDIN4, RESETOVRD, RX8B10BEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCDRRESETRSV, RXCHBONDEN, RXCHBONDMASTER, RXCHBONDSLAVE, RXCOMMADETEN, RXDDIEN, RXDFEXYDEN +, RXDLYBYPASS, RXDLYEN, RXDLYOVRDEN, RXDLYSRESET, RXGEARBOXSLIP, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFOVRDEN, RXLPMOSINTNTRLEN, RXLPMRESET, RXMCOMMAALIGNEN, RXOOBRESET, RXOSCALRESET, RXOSHOLD, RXOSINTEN, RXOSINTHOLD, RXOSINTNTRLEN, RXOSINTOVRDEN, RXOSINTPD, RXOSINTSTROBE +, RXOSINTTESTOVRDEN, RXOSOVRDEN, RXPCOMMAALIGNEN, RXPCSRESET, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPHOVRDEN, RXPMARESET, RXPOLARITY, RXPRBSCNTRESET, RXRATEMODE, RXSLIDE, RXSYNCALLIN, RXSYNCIN, RXSYNCMODE, RXUSERRDY, RXUSRCLK2, RXUSRCLK, SETERRSTATUS +, SIGVALIDCLK, TX8B10BEN, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXDEEMPH, TXDETECTRX, TXDIFFPD, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE, TXINHIBIT, TXPCSRESET, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN, TXPHDLYPD +, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPIPPMEN, TXPIPPMOVRDEN, TXPIPPMPD, TXPIPPMSEL, TXPISOPD, TXPMARESET, TXPOLARITY, TXPOSTCURSORINV, TXPRBSFORCEERR, TXPRECURSORINV, TXRATEMODE, TXSTARTSEQ, TXSWING, TXSYNCALLIN, TXSYNCIN, TXSYNCMODE, TXUSERRDY +, TXUSRCLK2, TXUSRCLK, RXADAPTSELTEST, DRPDI, GTRSVD, PCSRSVDIN, TSTIN, RXELECIDLEMODE, RXPD, RXSYSCLKSEL, TXPD, TXSYSCLKSEL, LOOPBACK, RXCHBONDLEVEL, RXOUTCLKSEL, RXPRBSSEL, RXRATE, TXBUFDIFFCTRL, TXHEADER, TXMARGIN, TXOUTCLKSEL +, TXPRBSSEL, TXRATE, TXDATA, RXCHBONDI, RXOSINTCFG, RXOSINTID0, TX8B10BBYPASS, TXCHARDISPMODE, TXCHARDISPVAL, TXCHARISK, TXDIFFCTRL, TXPIPPMSTEPSIZE, TXPOSTCURSOR, TXPRECURSOR, TXMAINCURSOR, TXSEQUENCE, DRPADDR); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; @@ -14395,7 +14522,9 @@ module GTPE2_CHANNEL (...); input [8:0] DRPADDR; endmodule -module GTPE2_COMMON (...); +module GTPE2_COMMON(DRPRDY, PLL0FBCLKLOST, PLL0LOCK, PLL0OUTCLK, PLL0OUTREFCLK, PLL0REFCLKLOST, PLL1FBCLKLOST, PLL1LOCK, PLL1OUTCLK, PLL1OUTREFCLK, PLL1REFCLKLOST, REFCLKOUTMONITOR0, REFCLKOUTMONITOR1, DRPDO, PMARSVDOUT, DMONITOROUT, BGBYPASSB, BGMONITORENB, BGPDB, BGRCALOVRDENB, DRPCLK +, DRPEN, DRPWE, GTEASTREFCLK0, GTEASTREFCLK1, GTGREFCLK0, GTGREFCLK1, GTREFCLK0, GTREFCLK1, GTWESTREFCLK0, GTWESTREFCLK1, PLL0LOCKDETCLK, PLL0LOCKEN, PLL0PD, PLL0RESET, PLL1LOCKDETCLK, PLL1LOCKEN, PLL1PD, PLL1RESET, RCALENB, DRPDI, PLLRSVD1 +, PLL0REFCLKSEL, PLL1REFCLKSEL, BGRCALOVRD, PLLRSVD2, DRPADDR, PMARSVD); parameter [63:0] BIAS_CFG = 64'h0000000000000000; parameter [31:0] COMMON_CFG = 32'h00000000; parameter [0:0] IS_DRPCLK_INVERTED = 1'b0; @@ -14479,7 +14608,17 @@ module GTPE2_COMMON (...); input [7:0] PMARSVD; endmodule -module GTXE2_CHANNEL (...); +module GTXE2_CHANNEL(CPLLFBCLKLOST, CPLLLOCK, CPLLREFCLKLOST, DRPRDY, EYESCANDATAERROR, GTREFCLKMONITOR, GTXTXN, GTXTXP, PHYSTATUS, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCOMINITDET, RXCOMMADET, RXCOMSASDET, RXCOMWAKEDET, RXDATAVALID, RXDLYSRESETDONE +, RXELECIDLE, RXHEADERVALID, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE, RXPRBSERR, RXQPISENN, RXQPISENP, RXRATEDONE, RXRESETDONE, RXSTARTOFSEQ, RXVALID, TXCOMFINISH, TXDLYSRESETDONE, TXGEARBOXREADY, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE, TXPHINITDONE +, TXQPISENN, TXQPISENP, TXRATEDONE, TXRESETDONE, DRPDO, PCSRSVDOUT, RXCLKCORCNT, TXBUFSTATUS, RXBUFSTATUS, RXHEADER, RXSTATUS, RXCHBONDO, RXPHMONITOR, RXPHSLIPMONITOR, RXDATA, RXMONITOROUT, DMONITOROUT, RXCHARISCOMMA, RXCHARISK, RXDISPERR, RXNOTINTABLE +, TSTOUT, CFGRESET, CPLLLOCKDETCLK, CPLLLOCKEN, CPLLPD, CPLLRESET, DRPCLK, DRPEN, DRPWE, EYESCANMODE, EYESCANRESET, EYESCANTRIGGER, GTGREFCLK, GTNORTHREFCLK0, GTNORTHREFCLK1, GTREFCLK0, GTREFCLK1, GTRESETSEL, GTRXRESET, GTSOUTHREFCLK0, GTSOUTHREFCLK1 +, GTTXRESET, GTXRXN, GTXRXP, QPLLCLK, QPLLREFCLK, RESETOVRD, RX8B10BEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCDRRESETRSV, RXCHBONDEN, RXCHBONDMASTER, RXCHBONDSLAVE, RXCOMMADETEN, RXDDIEN, RXDFEAGCHOLD, RXDFEAGCOVRDEN, RXDFECM1EN +, RXDFELFHOLD, RXDFELFOVRDEN, RXDFELPMRESET, RXDFETAP2HOLD, RXDFETAP2OVRDEN, RXDFETAP3HOLD, RXDFETAP3OVRDEN, RXDFETAP4HOLD, RXDFETAP4OVRDEN, RXDFETAP5HOLD, RXDFETAP5OVRDEN, RXDFEUTHOLD, RXDFEUTOVRDEN, RXDFEVPHOLD, RXDFEVPOVRDEN, RXDFEVSEN, RXDFEXYDEN, RXDFEXYDHOLD, RXDFEXYDOVRDEN, RXDLYBYPASS, RXDLYEN +, RXDLYOVRDEN, RXDLYSRESET, RXGEARBOXSLIP, RXLPMEN, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFKLOVRDEN, RXMCOMMAALIGNEN, RXOOBRESET, RXOSHOLD, RXOSOVRDEN, RXPCOMMAALIGNEN, RXPCSRESET, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPHOVRDEN, RXPMARESET, RXPOLARITY +, RXPRBSCNTRESET, RXQPIEN, RXSLIDE, RXUSERRDY, RXUSRCLK2, RXUSRCLK, SETERRSTATUS, TX8B10BEN, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXDEEMPH, TXDETECTRX, TXDIFFPD, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE +, TXINHIBIT, TXPCSRESET, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN, TXPHDLYPD, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPISOPD, TXPMARESET, TXPOLARITY, TXPOSTCURSORINV, TXPRBSFORCEERR, TXPRECURSORINV, TXQPIBIASEN, TXQPISTRONGPDOWN, TXQPIWEAKPUP, TXSTARTSEQ, TXSWING +, TXUSERRDY, TXUSRCLK2, TXUSRCLK, DRPDI, GTRSVD, PCSRSVDIN, TSTIN, RXELECIDLEMODE, RXMONITORSEL, RXPD, RXSYSCLKSEL, TXPD, TXSYSCLKSEL, CPLLREFCLKSEL, LOOPBACK, RXCHBONDLEVEL, RXOUTCLKSEL, RXPRBSSEL, RXRATE, TXBUFDIFFCTRL, TXHEADER +, TXMARGIN, TXOUTCLKSEL, TXPRBSSEL, TXRATE, CLKRSVD, TXDIFFCTRL, PCSRSVDIN2, PMARSVDIN2, PMARSVDIN, RXCHBONDI, TXPOSTCURSOR, TXPRECURSOR, TXDATA, TXMAINCURSOR, TXSEQUENCE, TX8B10BBYPASS, TXCHARDISPMODE, TXCHARDISPVAL, TXCHARISK, DRPADDR); parameter ALIGN_COMMA_DOUBLE = "FALSE"; parameter [9:0] ALIGN_COMMA_ENABLE = 10'b0001111111; parameter integer ALIGN_COMMA_WORD = 1; @@ -14927,7 +15066,8 @@ module GTXE2_CHANNEL (...); input [8:0] DRPADDR; endmodule -module GTXE2_COMMON (...); +module GTXE2_COMMON(DRPRDY, QPLLFBCLKLOST, QPLLLOCK, QPLLOUTCLK, QPLLOUTREFCLK, QPLLREFCLKLOST, REFCLKOUTMONITOR, DRPDO, QPLLDMONITOR, BGBYPASSB, BGMONITORENB, BGPDB, DRPCLK, DRPEN, DRPWE, GTGREFCLK, GTNORTHREFCLK0, GTNORTHREFCLK1, GTREFCLK0, GTREFCLK1, GTSOUTHREFCLK0 +, GTSOUTHREFCLK1, QPLLLOCKDETCLK, QPLLLOCKEN, QPLLOUTRESET, QPLLPD, QPLLRESET, RCALENB, DRPDI, QPLLRSVD1, QPLLREFCLKSEL, BGRCALOVRD, QPLLRSVD2, DRPADDR, PMARSVD); parameter [63:0] BIAS_CFG = 64'h0000040000001000; parameter [31:0] COMMON_CFG = 32'h00000000; parameter [0:0] IS_DRPCLK_INVERTED = 1'b0; @@ -14990,7 +15130,7 @@ module GTXE2_COMMON (...); input [7:0] PMARSVD; endmodule -module IBUFDS_GTE2 (...); +module IBUFDS_GTE2(O, ODIV2, CEB, I, IB); parameter CLKCM_CFG = "TRUE"; parameter CLKRCV_TRST = "TRUE"; parameter CLKSWING_CFG = "TRUE"; @@ -15003,7 +15143,22 @@ module IBUFDS_GTE2 (...); input IB; endmodule -module GTHE3_CHANNEL (...); +module GTHE3_CHANNEL(BUFGTCE, BUFGTCEMASK, BUFGTDIV, BUFGTRESET, BUFGTRSTMASK, CPLLFBCLKLOST, CPLLLOCK, CPLLREFCLKLOST, DMONITOROUT, DRPDO, DRPRDY, EYESCANDATAERROR, GTHTXN, GTHTXP, GTPOWERGOOD, GTREFCLKMONITOR, PCIERATEGEN3, PCIERATEIDLE, PCIERATEQPLLPD, PCIERATEQPLLRESET, PCIESYNCTXSYNCDONE +, PCIEUSERGEN3RDY, PCIEUSERPHYSTATUSRST, PCIEUSERRATESTART, PCSRSVDOUT, PHYSTATUS, PINRSRVDAS, RESETEXCEPTION, RXBUFSTATUS, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCDRPHDONE, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCHBONDO, RXCLKCORCNT, RXCOMINITDET, RXCOMMADET, RXCOMSASDET, RXCOMWAKEDET +, RXCTRL0, RXCTRL1, RXCTRL2, RXCTRL3, RXDATA, RXDATAEXTENDRSVD, RXDATAVALID, RXDLYSRESETDONE, RXELECIDLE, RXHEADER, RXHEADERVALID, RXMONITOROUT, RXOSINTDONE, RXOSINTSTARTED, RXOSINTSTROBEDONE, RXOSINTSTROBESTARTED, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE, RXPHALIGNERR +, RXPMARESETDONE, RXPRBSERR, RXPRBSLOCKED, RXPRGDIVRESETDONE, RXQPISENN, RXQPISENP, RXRATEDONE, RXRECCLKOUT, RXRESETDONE, RXSLIDERDY, RXSLIPDONE, RXSLIPOUTCLKRDY, RXSLIPPMARDY, RXSTARTOFSEQ, RXSTATUS, RXSYNCDONE, RXSYNCOUT, RXVALID, TXBUFSTATUS, TXCOMFINISH, TXDLYSRESETDONE +, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE, TXPHINITDONE, TXPMARESETDONE, TXPRGDIVRESETDONE, TXQPISENN, TXQPISENP, TXRATEDONE, TXRESETDONE, TXSYNCDONE, TXSYNCOUT, CFGRESET, CLKRSVD0, CLKRSVD1, CPLLLOCKDETCLK, CPLLLOCKEN, CPLLPD, CPLLREFCLKSEL, CPLLRESET +, DMONFIFORESET, DMONITORCLK, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, EVODDPHICALDONE, EVODDPHICALSTART, EVODDPHIDRDEN, EVODDPHIDWREN, EVODDPHIXRDEN, EVODDPHIXWREN, EYESCANMODE, EYESCANRESET, EYESCANTRIGGER, GTGREFCLK, GTHRXN, GTHRXP, GTNORTHREFCLK0, GTNORTHREFCLK1 +, GTREFCLK0, GTREFCLK1, GTRESETSEL, GTRSVD, GTRXRESET, GTSOUTHREFCLK0, GTSOUTHREFCLK1, GTTXRESET, LOOPBACK, LPBKRXTXSEREN, LPBKTXRXSEREN, PCIEEQRXEQADAPTDONE, PCIERSTIDLE, PCIERSTTXSYNCSTART, PCIEUSERRATEDONE, PCSRSVDIN, PCSRSVDIN2, PMARSVDIN, QPLL0CLK, QPLL0REFCLK, QPLL1CLK +, QPLL1REFCLK, RESETOVRD, RSTCLKENTX, RX8B10BEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCDRRESETRSV, RXCHBONDEN, RXCHBONDI, RXCHBONDLEVEL, RXCHBONDMASTER, RXCHBONDSLAVE, RXCOMMADETEN, RXDFEAGCCTRL, RXDFEAGCHOLD, RXDFEAGCOVRDEN, RXDFELFHOLD, RXDFELFOVRDEN +, RXDFELPMRESET, RXDFETAP10HOLD, RXDFETAP10OVRDEN, RXDFETAP11HOLD, RXDFETAP11OVRDEN, RXDFETAP12HOLD, RXDFETAP12OVRDEN, RXDFETAP13HOLD, RXDFETAP13OVRDEN, RXDFETAP14HOLD, RXDFETAP14OVRDEN, RXDFETAP15HOLD, RXDFETAP15OVRDEN, RXDFETAP2HOLD, RXDFETAP2OVRDEN, RXDFETAP3HOLD, RXDFETAP3OVRDEN, RXDFETAP4HOLD, RXDFETAP4OVRDEN, RXDFETAP5HOLD, RXDFETAP5OVRDEN +, RXDFETAP6HOLD, RXDFETAP6OVRDEN, RXDFETAP7HOLD, RXDFETAP7OVRDEN, RXDFETAP8HOLD, RXDFETAP8OVRDEN, RXDFETAP9HOLD, RXDFETAP9OVRDEN, RXDFEUTHOLD, RXDFEUTOVRDEN, RXDFEVPHOLD, RXDFEVPOVRDEN, RXDFEVSEN, RXDFEXYDEN, RXDLYBYPASS, RXDLYEN, RXDLYOVRDEN, RXDLYSRESET, RXELECIDLEMODE, RXGEARBOXSLIP, RXLATCLK +, RXLPMEN, RXLPMGCHOLD, RXLPMGCOVRDEN, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFKLOVRDEN, RXLPMOSHOLD, RXLPMOSOVRDEN, RXMCOMMAALIGNEN, RXMONITORSEL, RXOOBRESET, RXOSCALRESET, RXOSHOLD, RXOSINTCFG, RXOSINTEN, RXOSINTHOLD, RXOSINTOVRDEN, RXOSINTSTROBE, RXOSINTTESTOVRDEN, RXOSOVRDEN +, RXOUTCLKSEL, RXPCOMMAALIGNEN, RXPCSRESET, RXPD, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPHOVRDEN, RXPLLCLKSEL, RXPMARESET, RXPOLARITY, RXPRBSCNTRESET, RXPRBSSEL, RXPROGDIVRESET, RXQPIEN, RXRATE, RXRATEMODE, RXSLIDE, RXSLIPOUTCLK, RXSLIPPMA +, RXSYNCALLIN, RXSYNCIN, RXSYNCMODE, RXSYSCLKSEL, RXUSERRDY, RXUSRCLK, RXUSRCLK2, SIGVALIDCLK, TSTIN, TX8B10BBYPASS, TX8B10BEN, TXBUFDIFFCTRL, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXCTRL0, TXCTRL1, TXCTRL2, TXDATA, TXDATAEXTENDRSVD, TXDEEMPH +, TXDETECTRX, TXDIFFCTRL, TXDIFFPD, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE, TXHEADER, TXINHIBIT, TXLATCLK, TXMAINCURSOR, TXMARGIN, TXOUTCLKSEL, TXPCSRESET, TXPD, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN +, TXPHDLYPD, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPIPPMEN, TXPIPPMOVRDEN, TXPIPPMPD, TXPIPPMSEL, TXPIPPMSTEPSIZE, TXPISOPD, TXPLLCLKSEL, TXPMARESET, TXPOLARITY, TXPOSTCURSOR, TXPOSTCURSORINV, TXPRBSFORCEERR, TXPRBSSEL, TXPRECURSOR, TXPRECURSORINV, TXPROGDIVRESET +, TXQPIBIASEN, TXQPISTRONGPDOWN, TXQPIWEAKPUP, TXRATE, TXRATEMODE, TXSEQUENCE, TXSWING, TXSYNCALLIN, TXSYNCIN, TXSYNCMODE, TXSYSCLKSEL, TXUSERRDY, TXUSRCLK, TXUSRCLK2); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; @@ -15723,7 +15878,10 @@ module GTHE3_CHANNEL (...); input TXUSRCLK2; endmodule -module GTHE3_COMMON (...); +module GTHE3_COMMON(DRPDO, DRPRDY, PMARSVDOUT0, PMARSVDOUT1, QPLL0FBCLKLOST, QPLL0LOCK, QPLL0OUTCLK, QPLL0OUTREFCLK, QPLL0REFCLKLOST, QPLL1FBCLKLOST, QPLL1LOCK, QPLL1OUTCLK, QPLL1OUTREFCLK, QPLL1REFCLKLOST, QPLLDMONITOR0, QPLLDMONITOR1, REFCLKOUTMONITOR0, REFCLKOUTMONITOR1, RXRECCLK0_SEL, RXRECCLK1_SEL, BGBYPASSB +, BGMONITORENB, BGPDB, BGRCALOVRD, BGRCALOVRDENB, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, GTGREFCLK0, GTGREFCLK1, GTNORTHREFCLK00, GTNORTHREFCLK01, GTNORTHREFCLK10, GTNORTHREFCLK11, GTREFCLK00, GTREFCLK01, GTREFCLK10, GTREFCLK11, GTSOUTHREFCLK00, GTSOUTHREFCLK01 +, GTSOUTHREFCLK10, GTSOUTHREFCLK11, PMARSVD0, PMARSVD1, QPLL0CLKRSVD0, QPLL0CLKRSVD1, QPLL0LOCKDETCLK, QPLL0LOCKEN, QPLL0PD, QPLL0REFCLKSEL, QPLL0RESET, QPLL1CLKRSVD0, QPLL1CLKRSVD1, QPLL1LOCKDETCLK, QPLL1LOCKEN, QPLL1PD, QPLL1REFCLKSEL, QPLL1RESET, QPLLRSVD1, QPLLRSVD2, QPLLRSVD3 +, QPLLRSVD4, RCALENB); parameter [15:0] BIAS_CFG0 = 16'h0000; parameter [15:0] BIAS_CFG1 = 16'h0000; parameter [15:0] BIAS_CFG2 = 16'h0000; @@ -15865,7 +16023,22 @@ module GTHE3_COMMON (...); input RCALENB; endmodule -module GTYE3_CHANNEL (...); +module GTYE3_CHANNEL(BUFGTCE, BUFGTCEMASK, BUFGTDIV, BUFGTRESET, BUFGTRSTMASK, CPLLFBCLKLOST, CPLLLOCK, CPLLREFCLKLOST, DMONITOROUT, DRPDO, DRPRDY, EYESCANDATAERROR, GTPOWERGOOD, GTREFCLKMONITOR, GTYTXN, GTYTXP, PCIERATEGEN3, PCIERATEIDLE, PCIERATEQPLLPD, PCIERATEQPLLRESET, PCIESYNCTXSYNCDONE +, PCIEUSERGEN3RDY, PCIEUSERPHYSTATUSRST, PCIEUSERRATESTART, PCSRSVDOUT, PHYSTATUS, PINRSRVDAS, RESETEXCEPTION, RXBUFSTATUS, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCDRPHDONE, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCHBONDO, RXCKCALDONE, RXCLKCORCNT, RXCOMINITDET, RXCOMMADET, RXCOMSASDET +, RXCOMWAKEDET, RXCTRL0, RXCTRL1, RXCTRL2, RXCTRL3, RXDATA, RXDATAEXTENDRSVD, RXDATAVALID, RXDLYSRESETDONE, RXELECIDLE, RXHEADER, RXHEADERVALID, RXMONITOROUT, RXOSINTDONE, RXOSINTSTARTED, RXOSINTSTROBEDONE, RXOSINTSTROBESTARTED, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE +, RXPHALIGNERR, RXPMARESETDONE, RXPRBSERR, RXPRBSLOCKED, RXPRGDIVRESETDONE, RXRATEDONE, RXRECCLKOUT, RXRESETDONE, RXSLIDERDY, RXSLIPDONE, RXSLIPOUTCLKRDY, RXSLIPPMARDY, RXSTARTOFSEQ, RXSTATUS, RXSYNCDONE, RXSYNCOUT, RXVALID, TXBUFSTATUS, TXCOMFINISH, TXDCCDONE, TXDLYSRESETDONE +, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE, TXPHINITDONE, TXPMARESETDONE, TXPRGDIVRESETDONE, TXRATEDONE, TXRESETDONE, TXSYNCDONE, TXSYNCOUT, CDRSTEPDIR, CDRSTEPSQ, CDRSTEPSX, CFGRESET, CLKRSVD0, CLKRSVD1, CPLLLOCKDETCLK, CPLLLOCKEN, CPLLPD, CPLLREFCLKSEL +, CPLLRESET, DMONFIFORESET, DMONITORCLK, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, ELPCALDVORWREN, ELPCALPAORWREN, EVODDPHICALDONE, EVODDPHICALSTART, EVODDPHIDRDEN, EVODDPHIDWREN, EVODDPHIXRDEN, EVODDPHIXWREN, EYESCANMODE, EYESCANRESET, EYESCANTRIGGER, GTGREFCLK, GTNORTHREFCLK0 +, GTNORTHREFCLK1, GTREFCLK0, GTREFCLK1, GTRESETSEL, GTRSVD, GTRXRESET, GTSOUTHREFCLK0, GTSOUTHREFCLK1, GTTXRESET, GTYRXN, GTYRXP, LOOPBACK, LOOPRSVD, LPBKRXTXSEREN, LPBKTXRXSEREN, PCIEEQRXEQADAPTDONE, PCIERSTIDLE, PCIERSTTXSYNCSTART, PCIEUSERRATEDONE, PCSRSVDIN, PCSRSVDIN2 +, PMARSVDIN, QPLL0CLK, QPLL0REFCLK, QPLL1CLK, QPLL1REFCLK, RESETOVRD, RSTCLKENTX, RX8B10BEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCDRRESETRSV, RXCHBONDEN, RXCHBONDI, RXCHBONDLEVEL, RXCHBONDMASTER, RXCHBONDSLAVE, RXCKCALRESET, RXCOMMADETEN +, RXDCCFORCESTART, RXDFEAGCHOLD, RXDFEAGCOVRDEN, RXDFELFHOLD, RXDFELFOVRDEN, RXDFELPMRESET, RXDFETAP10HOLD, RXDFETAP10OVRDEN, RXDFETAP11HOLD, RXDFETAP11OVRDEN, RXDFETAP12HOLD, RXDFETAP12OVRDEN, RXDFETAP13HOLD, RXDFETAP13OVRDEN, RXDFETAP14HOLD, RXDFETAP14OVRDEN, RXDFETAP15HOLD, RXDFETAP15OVRDEN, RXDFETAP2HOLD, RXDFETAP2OVRDEN, RXDFETAP3HOLD +, RXDFETAP3OVRDEN, RXDFETAP4HOLD, RXDFETAP4OVRDEN, RXDFETAP5HOLD, RXDFETAP5OVRDEN, RXDFETAP6HOLD, RXDFETAP6OVRDEN, RXDFETAP7HOLD, RXDFETAP7OVRDEN, RXDFETAP8HOLD, RXDFETAP8OVRDEN, RXDFETAP9HOLD, RXDFETAP9OVRDEN, RXDFEUTHOLD, RXDFEUTOVRDEN, RXDFEVPHOLD, RXDFEVPOVRDEN, RXDFEVSEN, RXDFEXYDEN, RXDLYBYPASS, RXDLYEN +, RXDLYOVRDEN, RXDLYSRESET, RXELECIDLEMODE, RXGEARBOXSLIP, RXLATCLK, RXLPMEN, RXLPMGCHOLD, RXLPMGCOVRDEN, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFKLOVRDEN, RXLPMOSHOLD, RXLPMOSOVRDEN, RXMCOMMAALIGNEN, RXMONITORSEL, RXOOBRESET, RXOSCALRESET, RXOSHOLD, RXOSINTCFG, RXOSINTEN +, RXOSINTHOLD, RXOSINTOVRDEN, RXOSINTSTROBE, RXOSINTTESTOVRDEN, RXOSOVRDEN, RXOUTCLKSEL, RXPCOMMAALIGNEN, RXPCSRESET, RXPD, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPHOVRDEN, RXPLLCLKSEL, RXPMARESET, RXPOLARITY, RXPRBSCNTRESET, RXPRBSSEL, RXPROGDIVRESET, RXRATE +, RXRATEMODE, RXSLIDE, RXSLIPOUTCLK, RXSLIPPMA, RXSYNCALLIN, RXSYNCIN, RXSYNCMODE, RXSYSCLKSEL, RXUSERRDY, RXUSRCLK, RXUSRCLK2, SIGVALIDCLK, TSTIN, TX8B10BBYPASS, TX8B10BEN, TXBUFDIFFCTRL, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXCTRL0, TXCTRL1 +, TXCTRL2, TXDATA, TXDATAEXTENDRSVD, TXDCCFORCESTART, TXDCCRESET, TXDEEMPH, TXDETECTRX, TXDIFFCTRL, TXDIFFPD, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE, TXELFORCESTART, TXHEADER, TXINHIBIT, TXLATCLK, TXMAINCURSOR +, TXMARGIN, TXOUTCLKSEL, TXPCSRESET, TXPD, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN, TXPHDLYPD, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPIPPMEN, TXPIPPMOVRDEN, TXPIPPMPD, TXPIPPMSEL, TXPIPPMSTEPSIZE, TXPISOPD, TXPLLCLKSEL, TXPMARESET, TXPOLARITY +, TXPOSTCURSOR, TXPRBSFORCEERR, TXPRBSSEL, TXPRECURSOR, TXPROGDIVRESET, TXRATE, TXRATEMODE, TXSEQUENCE, TXSWING, TXSYNCALLIN, TXSYNCIN, TXSYNCMODE, TXSYSCLKSEL, TXUSERRDY, TXUSRCLK, TXUSRCLK2); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; @@ -16666,7 +16839,10 @@ module GTYE3_CHANNEL (...); input TXUSRCLK2; endmodule -module GTYE3_COMMON (...); +module GTYE3_COMMON(DRPDO, DRPRDY, PMARSVDOUT0, PMARSVDOUT1, QPLL0FBCLKLOST, QPLL0LOCK, QPLL0OUTCLK, QPLL0OUTREFCLK, QPLL0REFCLKLOST, QPLL1FBCLKLOST, QPLL1LOCK, QPLL1OUTCLK, QPLL1OUTREFCLK, QPLL1REFCLKLOST, QPLLDMONITOR0, QPLLDMONITOR1, REFCLKOUTMONITOR0, REFCLKOUTMONITOR1, RXRECCLK0_SEL, RXRECCLK1_SEL, SDM0FINALOUT +, SDM0TESTDATA, SDM1FINALOUT, SDM1TESTDATA, BGBYPASSB, BGMONITORENB, BGPDB, BGRCALOVRD, BGRCALOVRDENB, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, GTGREFCLK0, GTGREFCLK1, GTNORTHREFCLK00, GTNORTHREFCLK01, GTNORTHREFCLK10, GTNORTHREFCLK11, GTREFCLK00, GTREFCLK01 +, GTREFCLK10, GTREFCLK11, GTSOUTHREFCLK00, GTSOUTHREFCLK01, GTSOUTHREFCLK10, GTSOUTHREFCLK11, PMARSVD0, PMARSVD1, QPLL0CLKRSVD0, QPLL0LOCKDETCLK, QPLL0LOCKEN, QPLL0PD, QPLL0REFCLKSEL, QPLL0RESET, QPLL1CLKRSVD0, QPLL1LOCKDETCLK, QPLL1LOCKEN, QPLL1PD, QPLL1REFCLKSEL, QPLL1RESET, QPLLRSVD1 +, QPLLRSVD2, QPLLRSVD3, QPLLRSVD4, RCALENB, SDM0DATA, SDM0RESET, SDM0WIDTH, SDM1DATA, SDM1RESET, SDM1WIDTH); parameter [15:0] A_SDM1DATA1_0 = 16'b0000000000000000; parameter [8:0] A_SDM1DATA1_1 = 9'b000000000; parameter [15:0] BIAS_CFG0 = 16'h0000; @@ -16814,7 +16990,7 @@ module GTYE3_COMMON (...); input [1:0] SDM1WIDTH; endmodule -module IBUFDS_GTE3 (...); +module IBUFDS_GTE3(O, ODIV2, CEB, I, IB); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [1:0] REFCLK_HROW_CK_SEL = 2'b00; parameter [1:0] REFCLK_ICNTL_RX = 2'b00; @@ -16827,7 +17003,7 @@ module IBUFDS_GTE3 (...); input IB; endmodule -module OBUFDS_GTE3 (...); +module OBUFDS_GTE3(O, OB, CEB, I); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; (* iopad_external_pin *) @@ -16838,7 +17014,7 @@ module OBUFDS_GTE3 (...); input I; endmodule -module OBUFDS_GTE3_ADV (...); +module OBUFDS_GTE3_ADV(O, OB, CEB, I, RXRECCLK_SEL); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; (* iopad_external_pin *) @@ -16850,7 +17026,23 @@ module OBUFDS_GTE3_ADV (...); input [1:0] RXRECCLK_SEL; endmodule -module GTHE4_CHANNEL (...); +module GTHE4_CHANNEL(BUFGTCE, BUFGTCEMASK, BUFGTDIV, BUFGTRESET, BUFGTRSTMASK, CPLLFBCLKLOST, CPLLLOCK, CPLLREFCLKLOST, DMONITOROUT, DMONITOROUTCLK, DRPDO, DRPRDY, EYESCANDATAERROR, GTHTXN, GTHTXP, GTPOWERGOOD, GTREFCLKMONITOR, PCIERATEGEN3, PCIERATEIDLE, PCIERATEQPLLPD, PCIERATEQPLLRESET +, PCIESYNCTXSYNCDONE, PCIEUSERGEN3RDY, PCIEUSERPHYSTATUSRST, PCIEUSERRATESTART, PCSRSVDOUT, PHYSTATUS, PINRSRVDAS, POWERPRESENT, RESETEXCEPTION, RXBUFSTATUS, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCDRPHDONE, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCHBONDO, RXCKCALDONE, RXCLKCORCNT, RXCOMINITDET +, RXCOMMADET, RXCOMSASDET, RXCOMWAKEDET, RXCTRL0, RXCTRL1, RXCTRL2, RXCTRL3, RXDATA, RXDATAEXTENDRSVD, RXDATAVALID, RXDLYSRESETDONE, RXELECIDLE, RXHEADER, RXHEADERVALID, RXLFPSTRESETDET, RXLFPSU2LPEXITDET, RXLFPSU3WAKEDET, RXMONITOROUT, RXOSINTDONE, RXOSINTSTARTED, RXOSINTSTROBEDONE +, RXOSINTSTROBESTARTED, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE, RXPHALIGNERR, RXPMARESETDONE, RXPRBSERR, RXPRBSLOCKED, RXPRGDIVRESETDONE, RXQPISENN, RXQPISENP, RXRATEDONE, RXRECCLKOUT, RXRESETDONE, RXSLIDERDY, RXSLIPDONE, RXSLIPOUTCLKRDY, RXSLIPPMARDY, RXSTARTOFSEQ, RXSTATUS +, RXSYNCDONE, RXSYNCOUT, RXVALID, TXBUFSTATUS, TXCOMFINISH, TXDCCDONE, TXDLYSRESETDONE, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE, TXPHINITDONE, TXPMARESETDONE, TXPRGDIVRESETDONE, TXQPISENN, TXQPISENP, TXRATEDONE, TXRESETDONE, TXSYNCDONE, TXSYNCOUT, CDRSTEPDIR +, CDRSTEPSQ, CDRSTEPSX, CFGRESET, CLKRSVD0, CLKRSVD1, CPLLFREQLOCK, CPLLLOCKDETCLK, CPLLLOCKEN, CPLLPD, CPLLREFCLKSEL, CPLLRESET, DMONFIFORESET, DMONITORCLK, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPRST, DRPWE, EYESCANRESET, EYESCANTRIGGER +, FREQOS, GTGREFCLK, GTHRXN, GTHRXP, GTNORTHREFCLK0, GTNORTHREFCLK1, GTREFCLK0, GTREFCLK1, GTRSVD, GTRXRESET, GTRXRESETSEL, GTSOUTHREFCLK0, GTSOUTHREFCLK1, GTTXRESET, GTTXRESETSEL, INCPCTRL, LOOPBACK, PCIEEQRXEQADAPTDONE, PCIERSTIDLE, PCIERSTTXSYNCSTART, PCIEUSERRATEDONE +, PCSRSVDIN, QPLL0CLK, QPLL0FREQLOCK, QPLL0REFCLK, QPLL1CLK, QPLL1FREQLOCK, QPLL1REFCLK, RESETOVRD, RX8B10BEN, RXAFECFOKEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCHBONDEN, RXCHBONDI, RXCHBONDLEVEL, RXCHBONDMASTER, RXCHBONDSLAVE, RXCKCALRESET +, RXCKCALSTART, RXCOMMADETEN, RXDFEAGCCTRL, RXDFEAGCHOLD, RXDFEAGCOVRDEN, RXDFECFOKFCNUM, RXDFECFOKFEN, RXDFECFOKFPULSE, RXDFECFOKHOLD, RXDFECFOKOVREN, RXDFEKHHOLD, RXDFEKHOVRDEN, RXDFELFHOLD, RXDFELFOVRDEN, RXDFELPMRESET, RXDFETAP10HOLD, RXDFETAP10OVRDEN, RXDFETAP11HOLD, RXDFETAP11OVRDEN, RXDFETAP12HOLD, RXDFETAP12OVRDEN +, RXDFETAP13HOLD, RXDFETAP13OVRDEN, RXDFETAP14HOLD, RXDFETAP14OVRDEN, RXDFETAP15HOLD, RXDFETAP15OVRDEN, RXDFETAP2HOLD, RXDFETAP2OVRDEN, RXDFETAP3HOLD, RXDFETAP3OVRDEN, RXDFETAP4HOLD, RXDFETAP4OVRDEN, RXDFETAP5HOLD, RXDFETAP5OVRDEN, RXDFETAP6HOLD, RXDFETAP6OVRDEN, RXDFETAP7HOLD, RXDFETAP7OVRDEN, RXDFETAP8HOLD, RXDFETAP8OVRDEN, RXDFETAP9HOLD +, RXDFETAP9OVRDEN, RXDFEUTHOLD, RXDFEUTOVRDEN, RXDFEVPHOLD, RXDFEVPOVRDEN, RXDFEXYDEN, RXDLYBYPASS, RXDLYEN, RXDLYOVRDEN, RXDLYSRESET, RXELECIDLEMODE, RXEQTRAINING, RXGEARBOXSLIP, RXLATCLK, RXLPMEN, RXLPMGCHOLD, RXLPMGCOVRDEN, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFKLOVRDEN +, RXLPMOSHOLD, RXLPMOSOVRDEN, RXMCOMMAALIGNEN, RXMONITORSEL, RXOOBRESET, RXOSCALRESET, RXOSHOLD, RXOSOVRDEN, RXOUTCLKSEL, RXPCOMMAALIGNEN, RXPCSRESET, RXPD, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPHOVRDEN, RXPLLCLKSEL, RXPMARESET, RXPOLARITY, RXPRBSCNTRESET +, RXPRBSSEL, RXPROGDIVRESET, RXQPIEN, RXRATE, RXRATEMODE, RXSLIDE, RXSLIPOUTCLK, RXSLIPPMA, RXSYNCALLIN, RXSYNCIN, RXSYNCMODE, RXSYSCLKSEL, RXTERMINATION, RXUSERRDY, RXUSRCLK, RXUSRCLK2, SIGVALIDCLK, TSTIN, TX8B10BBYPASS, TX8B10BEN, TXCOMINIT +, TXCOMSAS, TXCOMWAKE, TXCTRL0, TXCTRL1, TXCTRL2, TXDATA, TXDATAEXTENDRSVD, TXDCCFORCESTART, TXDCCRESET, TXDEEMPH, TXDETECTRX, TXDIFFCTRL, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE, TXHEADER, TXINHIBIT +, TXLATCLK, TXLFPSTRESET, TXLFPSU2LPEXIT, TXLFPSU3WAKE, TXMAINCURSOR, TXMARGIN, TXMUXDCDEXHOLD, TXMUXDCDORWREN, TXONESZEROS, TXOUTCLKSEL, TXPCSRESET, TXPD, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN, TXPHDLYPD, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPIPPMEN +, TXPIPPMOVRDEN, TXPIPPMPD, TXPIPPMSEL, TXPIPPMSTEPSIZE, TXPISOPD, TXPLLCLKSEL, TXPMARESET, TXPOLARITY, TXPOSTCURSOR, TXPRBSFORCEERR, TXPRBSSEL, TXPRECURSOR, TXPROGDIVRESET, TXQPIBIASEN, TXQPIWEAKPUP, TXRATE, TXRATEMODE, TXSEQUENCE, TXSWING, TXSYNCALLIN, TXSYNCIN +, TXSYNCMODE, TXSYSCLKSEL, TXUSERRDY, TXUSRCLK, TXUSRCLK2); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; @@ -17698,7 +17890,11 @@ module GTHE4_CHANNEL (...); input TXUSRCLK2; endmodule -module GTHE4_COMMON (...); +module GTHE4_COMMON(DRPDO, DRPRDY, PMARSVDOUT0, PMARSVDOUT1, QPLL0FBCLKLOST, QPLL0LOCK, QPLL0OUTCLK, QPLL0OUTREFCLK, QPLL0REFCLKLOST, QPLL1FBCLKLOST, QPLL1LOCK, QPLL1OUTCLK, QPLL1OUTREFCLK, QPLL1REFCLKLOST, QPLLDMONITOR0, QPLLDMONITOR1, REFCLKOUTMONITOR0, REFCLKOUTMONITOR1, RXRECCLK0SEL, RXRECCLK1SEL, SDM0FINALOUT +, SDM0TESTDATA, SDM1FINALOUT, SDM1TESTDATA, TCONGPO, TCONRSVDOUT0, BGBYPASSB, BGMONITORENB, BGPDB, BGRCALOVRD, BGRCALOVRDENB, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, GTGREFCLK0, GTGREFCLK1, GTNORTHREFCLK00, GTNORTHREFCLK01, GTNORTHREFCLK10, GTNORTHREFCLK11 +, GTREFCLK00, GTREFCLK01, GTREFCLK10, GTREFCLK11, GTSOUTHREFCLK00, GTSOUTHREFCLK01, GTSOUTHREFCLK10, GTSOUTHREFCLK11, PCIERATEQPLL0, PCIERATEQPLL1, PMARSVD0, PMARSVD1, QPLL0CLKRSVD0, QPLL0CLKRSVD1, QPLL0FBDIV, QPLL0LOCKDETCLK, QPLL0LOCKEN, QPLL0PD, QPLL0REFCLKSEL, QPLL0RESET, QPLL1CLKRSVD0 +, QPLL1CLKRSVD1, QPLL1FBDIV, QPLL1LOCKDETCLK, QPLL1LOCKEN, QPLL1PD, QPLL1REFCLKSEL, QPLL1RESET, QPLLRSVD1, QPLLRSVD2, QPLLRSVD3, QPLLRSVD4, RCALENB, SDM0DATA, SDM0RESET, SDM0TOGGLE, SDM0WIDTH, SDM1DATA, SDM1RESET, SDM1TOGGLE, SDM1WIDTH, TCONGPI +, TCONPOWERUP, TCONRESET, TCONRSVDIN1); parameter [0:0] AEN_QPLL0_FBDIV = 1'b1; parameter [0:0] AEN_QPLL1_FBDIV = 1'b1; parameter [0:0] AEN_SDM0TOGGLE = 1'b0; @@ -17870,7 +18066,22 @@ module GTHE4_COMMON (...); input [1:0] TCONRSVDIN1; endmodule -module GTYE4_CHANNEL (...); +module GTYE4_CHANNEL(BUFGTCE, BUFGTCEMASK, BUFGTDIV, BUFGTRESET, BUFGTRSTMASK, CPLLFBCLKLOST, CPLLLOCK, CPLLREFCLKLOST, DMONITOROUT, DMONITOROUTCLK, DRPDO, DRPRDY, EYESCANDATAERROR, GTPOWERGOOD, GTREFCLKMONITOR, GTYTXN, GTYTXP, PCIERATEGEN3, PCIERATEIDLE, PCIERATEQPLLPD, PCIERATEQPLLRESET +, PCIESYNCTXSYNCDONE, PCIEUSERGEN3RDY, PCIEUSERPHYSTATUSRST, PCIEUSERRATESTART, PCSRSVDOUT, PHYSTATUS, PINRSRVDAS, POWERPRESENT, RESETEXCEPTION, RXBUFSTATUS, RXBYTEISALIGNED, RXBYTEREALIGN, RXCDRLOCK, RXCDRPHDONE, RXCHANBONDSEQ, RXCHANISALIGNED, RXCHANREALIGN, RXCHBONDO, RXCKCALDONE, RXCLKCORCNT, RXCOMINITDET +, RXCOMMADET, RXCOMSASDET, RXCOMWAKEDET, RXCTRL0, RXCTRL1, RXCTRL2, RXCTRL3, RXDATA, RXDATAEXTENDRSVD, RXDATAVALID, RXDLYSRESETDONE, RXELECIDLE, RXHEADER, RXHEADERVALID, RXLFPSTRESETDET, RXLFPSU2LPEXITDET, RXLFPSU3WAKEDET, RXMONITOROUT, RXOSINTDONE, RXOSINTSTARTED, RXOSINTSTROBEDONE +, RXOSINTSTROBESTARTED, RXOUTCLK, RXOUTCLKFABRIC, RXOUTCLKPCS, RXPHALIGNDONE, RXPHALIGNERR, RXPMARESETDONE, RXPRBSERR, RXPRBSLOCKED, RXPRGDIVRESETDONE, RXRATEDONE, RXRECCLKOUT, RXRESETDONE, RXSLIDERDY, RXSLIPDONE, RXSLIPOUTCLKRDY, RXSLIPPMARDY, RXSTARTOFSEQ, RXSTATUS, RXSYNCDONE, RXSYNCOUT +, RXVALID, TXBUFSTATUS, TXCOMFINISH, TXDCCDONE, TXDLYSRESETDONE, TXOUTCLK, TXOUTCLKFABRIC, TXOUTCLKPCS, TXPHALIGNDONE, TXPHINITDONE, TXPMARESETDONE, TXPRGDIVRESETDONE, TXRATEDONE, TXRESETDONE, TXSYNCDONE, TXSYNCOUT, CDRSTEPDIR, CDRSTEPSQ, CDRSTEPSX, CFGRESET, CLKRSVD0 +, CLKRSVD1, CPLLFREQLOCK, CPLLLOCKDETCLK, CPLLLOCKEN, CPLLPD, CPLLREFCLKSEL, CPLLRESET, DMONFIFORESET, DMONITORCLK, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPRST, DRPWE, EYESCANRESET, EYESCANTRIGGER, FREQOS, GTGREFCLK, GTNORTHREFCLK0, GTNORTHREFCLK1 +, GTREFCLK0, GTREFCLK1, GTRSVD, GTRXRESET, GTRXRESETSEL, GTSOUTHREFCLK0, GTSOUTHREFCLK1, GTTXRESET, GTTXRESETSEL, GTYRXN, GTYRXP, INCPCTRL, LOOPBACK, PCIEEQRXEQADAPTDONE, PCIERSTIDLE, PCIERSTTXSYNCSTART, PCIEUSERRATEDONE, PCSRSVDIN, QPLL0CLK, QPLL0FREQLOCK, QPLL0REFCLK +, QPLL1CLK, QPLL1FREQLOCK, QPLL1REFCLK, RESETOVRD, RX8B10BEN, RXAFECFOKEN, RXBUFRESET, RXCDRFREQRESET, RXCDRHOLD, RXCDROVRDEN, RXCDRRESET, RXCHBONDEN, RXCHBONDI, RXCHBONDLEVEL, RXCHBONDMASTER, RXCHBONDSLAVE, RXCKCALRESET, RXCKCALSTART, RXCOMMADETEN, RXDFEAGCHOLD, RXDFEAGCOVRDEN +, RXDFECFOKFCNUM, RXDFECFOKFEN, RXDFECFOKFPULSE, RXDFECFOKHOLD, RXDFECFOKOVREN, RXDFEKHHOLD, RXDFEKHOVRDEN, RXDFELFHOLD, RXDFELFOVRDEN, RXDFELPMRESET, RXDFETAP10HOLD, RXDFETAP10OVRDEN, RXDFETAP11HOLD, RXDFETAP11OVRDEN, RXDFETAP12HOLD, RXDFETAP12OVRDEN, RXDFETAP13HOLD, RXDFETAP13OVRDEN, RXDFETAP14HOLD, RXDFETAP14OVRDEN, RXDFETAP15HOLD +, RXDFETAP15OVRDEN, RXDFETAP2HOLD, RXDFETAP2OVRDEN, RXDFETAP3HOLD, RXDFETAP3OVRDEN, RXDFETAP4HOLD, RXDFETAP4OVRDEN, RXDFETAP5HOLD, RXDFETAP5OVRDEN, RXDFETAP6HOLD, RXDFETAP6OVRDEN, RXDFETAP7HOLD, RXDFETAP7OVRDEN, RXDFETAP8HOLD, RXDFETAP8OVRDEN, RXDFETAP9HOLD, RXDFETAP9OVRDEN, RXDFEUTHOLD, RXDFEUTOVRDEN, RXDFEVPHOLD, RXDFEVPOVRDEN +, RXDFEXYDEN, RXDLYBYPASS, RXDLYEN, RXDLYOVRDEN, RXDLYSRESET, RXELECIDLEMODE, RXEQTRAINING, RXGEARBOXSLIP, RXLATCLK, RXLPMEN, RXLPMGCHOLD, RXLPMGCOVRDEN, RXLPMHFHOLD, RXLPMHFOVRDEN, RXLPMLFHOLD, RXLPMLFKLOVRDEN, RXLPMOSHOLD, RXLPMOSOVRDEN, RXMCOMMAALIGNEN, RXMONITORSEL, RXOOBRESET +, RXOSCALRESET, RXOSHOLD, RXOSOVRDEN, RXOUTCLKSEL, RXPCOMMAALIGNEN, RXPCSRESET, RXPD, RXPHALIGN, RXPHALIGNEN, RXPHDLYPD, RXPHDLYRESET, RXPLLCLKSEL, RXPMARESET, RXPOLARITY, RXPRBSCNTRESET, RXPRBSSEL, RXPROGDIVRESET, RXRATE, RXRATEMODE, RXSLIDE, RXSLIPOUTCLK +, RXSLIPPMA, RXSYNCALLIN, RXSYNCIN, RXSYNCMODE, RXSYSCLKSEL, RXTERMINATION, RXUSERRDY, RXUSRCLK, RXUSRCLK2, SIGVALIDCLK, TSTIN, TX8B10BBYPASS, TX8B10BEN, TXCOMINIT, TXCOMSAS, TXCOMWAKE, TXCTRL0, TXCTRL1, TXCTRL2, TXDATA, TXDATAEXTENDRSVD +, TXDCCFORCESTART, TXDCCRESET, TXDEEMPH, TXDETECTRX, TXDIFFCTRL, TXDLYBYPASS, TXDLYEN, TXDLYHOLD, TXDLYOVRDEN, TXDLYSRESET, TXDLYUPDOWN, TXELECIDLE, TXHEADER, TXINHIBIT, TXLATCLK, TXLFPSTRESET, TXLFPSU2LPEXIT, TXLFPSU3WAKE, TXMAINCURSOR, TXMARGIN, TXMUXDCDEXHOLD +, TXMUXDCDORWREN, TXONESZEROS, TXOUTCLKSEL, TXPCSRESET, TXPD, TXPDELECIDLEMODE, TXPHALIGN, TXPHALIGNEN, TXPHDLYPD, TXPHDLYRESET, TXPHDLYTSTCLK, TXPHINIT, TXPHOVRDEN, TXPIPPMEN, TXPIPPMOVRDEN, TXPIPPMPD, TXPIPPMSEL, TXPIPPMSTEPSIZE, TXPISOPD, TXPLLCLKSEL, TXPMARESET +, TXPOLARITY, TXPOSTCURSOR, TXPRBSFORCEERR, TXPRBSSEL, TXPRECURSOR, TXPROGDIVRESET, TXRATE, TXRATEMODE, TXSEQUENCE, TXSWING, TXSYNCALLIN, TXSYNCIN, TXSYNCMODE, TXSYSCLKSEL, TXUSERRDY, TXUSRCLK, TXUSRCLK2); parameter [0:0] ACJTAG_DEBUG_MODE = 1'b0; parameter [0:0] ACJTAG_MODE = 1'b0; parameter [0:0] ACJTAG_RESET = 1'b0; @@ -18696,7 +18907,11 @@ module GTYE4_CHANNEL (...); input TXUSRCLK2; endmodule -module GTYE4_COMMON (...); +module GTYE4_COMMON(DRPDO, DRPRDY, PMARSVDOUT0, PMARSVDOUT1, QPLL0FBCLKLOST, QPLL0LOCK, QPLL0OUTCLK, QPLL0OUTREFCLK, QPLL0REFCLKLOST, QPLL1FBCLKLOST, QPLL1LOCK, QPLL1OUTCLK, QPLL1OUTREFCLK, QPLL1REFCLKLOST, QPLLDMONITOR0, QPLLDMONITOR1, REFCLKOUTMONITOR0, REFCLKOUTMONITOR1, RXRECCLK0SEL, RXRECCLK1SEL, SDM0FINALOUT +, SDM0TESTDATA, SDM1FINALOUT, SDM1TESTDATA, UBDADDR, UBDEN, UBDI, UBDWE, UBMDMTDO, UBRSVDOUT, UBTXUART, BGBYPASSB, BGMONITORENB, BGPDB, BGRCALOVRD, BGRCALOVRDENB, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, GTGREFCLK0 +, GTGREFCLK1, GTNORTHREFCLK00, GTNORTHREFCLK01, GTNORTHREFCLK10, GTNORTHREFCLK11, GTREFCLK00, GTREFCLK01, GTREFCLK10, GTREFCLK11, GTSOUTHREFCLK00, GTSOUTHREFCLK01, GTSOUTHREFCLK10, GTSOUTHREFCLK11, PCIERATEQPLL0, PCIERATEQPLL1, PMARSVD0, PMARSVD1, QPLL0CLKRSVD0, QPLL0CLKRSVD1, QPLL0FBDIV, QPLL0LOCKDETCLK +, QPLL0LOCKEN, QPLL0PD, QPLL0REFCLKSEL, QPLL0RESET, QPLL1CLKRSVD0, QPLL1CLKRSVD1, QPLL1FBDIV, QPLL1LOCKDETCLK, QPLL1LOCKEN, QPLL1PD, QPLL1REFCLKSEL, QPLL1RESET, QPLLRSVD1, QPLLRSVD2, QPLLRSVD3, QPLLRSVD4, RCALENB, SDM0DATA, SDM0RESET, SDM0TOGGLE, SDM0WIDTH +, SDM1DATA, SDM1RESET, SDM1TOGGLE, SDM1WIDTH, UBCFGSTREAMEN, UBDO, UBDRDY, UBENABLE, UBGPI, UBINTR, UBIOLMBRST, UBMBRST, UBMDMCAPTURE, UBMDMDBGRST, UBMDMDBGUPDATE, UBMDMREGEN, UBMDMSHIFT, UBMDMSYSRST, UBMDMTCK, UBMDMTDI); parameter [0:0] AEN_QPLL0_FBDIV = 1'b1; parameter [0:0] AEN_QPLL1_FBDIV = 1'b1; parameter [0:0] AEN_SDM0TOGGLE = 1'b0; @@ -18892,7 +19107,7 @@ module GTYE4_COMMON (...); input UBMDMTDI; endmodule -module IBUFDS_GTE4 (...); +module IBUFDS_GTE4(O, ODIV2, CEB, I, IB); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [1:0] REFCLK_HROW_CK_SEL = 2'b00; parameter [1:0] REFCLK_ICNTL_RX = 2'b00; @@ -18905,7 +19120,7 @@ module IBUFDS_GTE4 (...); input IB; endmodule -module OBUFDS_GTE4 (...); +module OBUFDS_GTE4(O, OB, CEB, I); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; (* iopad_external_pin *) @@ -18916,7 +19131,7 @@ module OBUFDS_GTE4 (...); input I; endmodule -module OBUFDS_GTE4_ADV (...); +module OBUFDS_GTE4_ADV(O, OB, CEB, I, RXRECCLK_SEL); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter [4:0] REFCLK_ICNTL_TX = 5'b00000; (* iopad_external_pin *) @@ -18928,7 +19143,20 @@ module OBUFDS_GTE4_ADV (...); input [1:0] RXRECCLK_SEL; endmodule -module GTM_DUAL (...); +module GTM_DUAL(CH0_AXISTDATA, CH0_AXISTLAST, CH0_AXISTVALID, CH0_DMONITOROUT, CH0_DMONITOROUTCLK, CH0_GTMTXN, CH0_GTMTXP, CH0_PCSRSVDOUT, CH0_PMARSVDOUT, CH0_RESETEXCEPTION, CH0_RXBUFSTATUS, CH0_RXDATA, CH0_RXDATAFLAGS, CH0_RXDATAISAM, CH0_RXDATASTART, CH0_RXOUTCLK, CH0_RXPMARESETDONE, CH0_RXPRBSERR, CH0_RXPRBSLOCKED, CH0_RXPRGDIVRESETDONE, CH0_RXPROGDIVCLK +, CH0_RXRESETDONE, CH0_TXBUFSTATUS, CH0_TXOUTCLK, CH0_TXPMARESETDONE, CH0_TXPRGDIVRESETDONE, CH0_TXPROGDIVCLK, CH0_TXRESETDONE, CH1_AXISTDATA, CH1_AXISTLAST, CH1_AXISTVALID, CH1_DMONITOROUT, CH1_DMONITOROUTCLK, CH1_GTMTXN, CH1_GTMTXP, CH1_PCSRSVDOUT, CH1_PMARSVDOUT, CH1_RESETEXCEPTION, CH1_RXBUFSTATUS, CH1_RXDATA, CH1_RXDATAFLAGS, CH1_RXDATAISAM +, CH1_RXDATASTART, CH1_RXOUTCLK, CH1_RXPMARESETDONE, CH1_RXPRBSERR, CH1_RXPRBSLOCKED, CH1_RXPRGDIVRESETDONE, CH1_RXPROGDIVCLK, CH1_RXRESETDONE, CH1_TXBUFSTATUS, CH1_TXOUTCLK, CH1_TXPMARESETDONE, CH1_TXPRGDIVRESETDONE, CH1_TXPROGDIVCLK, CH1_TXRESETDONE, CLKTESTSIG2PAD, DMONITOROUTPLLCLK, DRPDO, DRPRDY, FECRX0ALIGNED, FECRX0CORRCWINC, FECRX0CWINC +, FECRX0UNCORRCWINC, FECRX1ALIGNED, FECRX1CORRCWINC, FECRX1CWINC, FECRX1UNCORRCWINC, FECRXLN0BITERR0TO1INC, FECRXLN0BITERR1TO0INC, FECRXLN0DLY, FECRXLN0ERRCNTINC, FECRXLN0MAPPING, FECRXLN1BITERR0TO1INC, FECRXLN1BITERR1TO0INC, FECRXLN1DLY, FECRXLN1ERRCNTINC, FECRXLN1MAPPING, FECRXLN2BITERR0TO1INC, FECRXLN2BITERR1TO0INC, FECRXLN2DLY, FECRXLN2ERRCNTINC, FECRXLN2MAPPING, FECRXLN3BITERR0TO1INC +, FECRXLN3BITERR1TO0INC, FECRXLN3DLY, FECRXLN3ERRCNTINC, FECRXLN3MAPPING, FECTRXLN0LOCK, FECTRXLN1LOCK, FECTRXLN2LOCK, FECTRXLN3LOCK, GTPOWERGOOD, PLLFBCLKLOST, PLLLOCK, PLLREFCLKLOST, PLLREFCLKMONITOR, PLLRESETDONE, PLLRSVDOUT, RCALCMP, RCALOUT, RXRECCLK0, RXRECCLK1, BGBYPASSB, BGMONITORENB +, BGPDB, BGRCALOVRD, BGRCALOVRDENB, CH0_AXISEN, CH0_AXISRST, CH0_AXISTRDY, CH0_CFGRESET, CH0_DMONFIFORESET, CH0_DMONITORCLK, CH0_GTMRXN, CH0_GTMRXP, CH0_GTRXRESET, CH0_GTTXRESET, CH0_LOOPBACK, CH0_PCSRSVDIN, CH0_PMARSVDIN, CH0_RESETOVRD, CH0_RXADAPTRESET, CH0_RXADCCALRESET, CH0_RXADCCLKGENRESET, CH0_RXBUFRESET +, CH0_RXCDRFREQOS, CH0_RXCDRFRRESET, CH0_RXCDRHOLD, CH0_RXCDRINCPCTRL, CH0_RXCDROVRDEN, CH0_RXCDRPHRESET, CH0_RXDFERESET, CH0_RXDSPRESET, CH0_RXEQTRAINING, CH0_RXEYESCANRESET, CH0_RXFECRESET, CH0_RXOUTCLKSEL, CH0_RXPCSRESET, CH0_RXPCSRESETMASK, CH0_RXPMARESET, CH0_RXPMARESETMASK, CH0_RXPOLARITY, CH0_RXPRBSCNTSTOP, CH0_RXPRBSCSCNTRST, CH0_RXPRBSPTN, CH0_RXPROGDIVRESET +, CH0_RXQPRBSEN, CH0_RXRESETMODE, CH0_RXSPCSEQADV, CH0_RXUSRCLK, CH0_RXUSRCLK2, CH0_RXUSRRDY, CH0_RXUSRSTART, CH0_RXUSRSTOP, CH0_TXCKALRESET, CH0_TXCTLFIRDAT, CH0_TXDATA, CH0_TXDATASTART, CH0_TXDRVAMP, CH0_TXEMPMAIN, CH0_TXEMPPOST, CH0_TXEMPPRE, CH0_TXEMPPRE2, CH0_TXFECRESET, CH0_TXINHIBIT, CH0_TXMUXDCDEXHOLD, CH0_TXMUXDCDORWREN +, CH0_TXOUTCLKSEL, CH0_TXPCSRESET, CH0_TXPCSRESETMASK, CH0_TXPMARESET, CH0_TXPMARESETMASK, CH0_TXPOLARITY, CH0_TXPRBSINERR, CH0_TXPRBSPTN, CH0_TXPROGDIVRESET, CH0_TXQPRBSEN, CH0_TXRESETMODE, CH0_TXSPCSEQADV, CH0_TXUSRCLK, CH0_TXUSRCLK2, CH0_TXUSRRDY, CH1_AXISEN, CH1_AXISRST, CH1_AXISTRDY, CH1_CFGRESET, CH1_DMONFIFORESET, CH1_DMONITORCLK +, CH1_GTMRXN, CH1_GTMRXP, CH1_GTRXRESET, CH1_GTTXRESET, CH1_LOOPBACK, CH1_PCSRSVDIN, CH1_PMARSVDIN, CH1_RESETOVRD, CH1_RXADAPTRESET, CH1_RXADCCALRESET, CH1_RXADCCLKGENRESET, CH1_RXBUFRESET, CH1_RXCDRFREQOS, CH1_RXCDRFRRESET, CH1_RXCDRHOLD, CH1_RXCDRINCPCTRL, CH1_RXCDROVRDEN, CH1_RXCDRPHRESET, CH1_RXDFERESET, CH1_RXDSPRESET, CH1_RXEQTRAINING +, CH1_RXEYESCANRESET, CH1_RXFECRESET, CH1_RXOUTCLKSEL, CH1_RXPCSRESET, CH1_RXPCSRESETMASK, CH1_RXPMARESET, CH1_RXPMARESETMASK, CH1_RXPOLARITY, CH1_RXPRBSCNTSTOP, CH1_RXPRBSCSCNTRST, CH1_RXPRBSPTN, CH1_RXPROGDIVRESET, CH1_RXQPRBSEN, CH1_RXRESETMODE, CH1_RXSPCSEQADV, CH1_RXUSRCLK, CH1_RXUSRCLK2, CH1_RXUSRRDY, CH1_RXUSRSTART, CH1_RXUSRSTOP, CH1_TXCKALRESET +, CH1_TXCTLFIRDAT, CH1_TXDATA, CH1_TXDATASTART, CH1_TXDRVAMP, CH1_TXEMPMAIN, CH1_TXEMPPOST, CH1_TXEMPPRE, CH1_TXEMPPRE2, CH1_TXFECRESET, CH1_TXINHIBIT, CH1_TXMUXDCDEXHOLD, CH1_TXMUXDCDORWREN, CH1_TXOUTCLKSEL, CH1_TXPCSRESET, CH1_TXPCSRESETMASK, CH1_TXPMARESET, CH1_TXPMARESETMASK, CH1_TXPOLARITY, CH1_TXPRBSINERR, CH1_TXPRBSPTN, CH1_TXPROGDIVRESET +, CH1_TXQPRBSEN, CH1_TXRESETMODE, CH1_TXSPCSEQADV, CH1_TXUSRCLK, CH1_TXUSRCLK2, CH1_TXUSRRDY, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPRST, DRPWE, FECCTRLRX0BITSLIPFS, FECCTRLRX1BITSLIPFS, GTGREFCLK2PLL, GTNORTHREFCLK, GTREFCLK, GTSOUTHREFCLK, PLLFBDIV, PLLMONCLK, PLLPD +, PLLREFCLKSEL, PLLRESET, PLLRESETBYPASSMODE, PLLRESETMASK, PLLRSVDIN, RCALENB, SDMDATA, SDMTOGGLE); parameter [15:0] A_CFG = 16'b0000100001000000; parameter [15:0] A_SDM_DATA_CFG0 = 16'b0000000011010000; parameter [15:0] A_SDM_DATA_CFG1 = 16'b0000000011010000; @@ -19575,7 +19803,7 @@ module GTM_DUAL (...); input SDMTOGGLE; endmodule -module IBUFDS_GTM (...); +module IBUFDS_GTM(O, ODIV2, CEB, I, IB); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter integer REFCLK_HROW_CK_SEL = 0; parameter integer REFCLK_ICNTL_RX = 0; @@ -19588,7 +19816,7 @@ module IBUFDS_GTM (...); input IB; endmodule -module OBUFDS_GTM (...); +module OBUFDS_GTM(O, OB, CEB, I); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter integer REFCLK_ICNTL_TX = 0; (* iopad_external_pin *) @@ -19599,7 +19827,7 @@ module OBUFDS_GTM (...); input I; endmodule -module OBUFDS_GTM_ADV (...); +module OBUFDS_GTM_ADV(O, OB, CEB, I); parameter [0:0] REFCLK_EN_TX_PATH = 1'b0; parameter integer REFCLK_ICNTL_TX = 0; parameter [1:0] RXRECCLK_SEL = 2'b00; @@ -19611,7 +19839,9 @@ module OBUFDS_GTM_ADV (...); input [3:0] I; endmodule -module HSDAC (...); +module HSDAC(CLK_DAC, DOUT, DRDY, PLL_DMON_OUT, PLL_REFCLK_OUT, STATUS_COMMON, STATUS_DAC0, STATUS_DAC1, STATUS_DAC2, STATUS_DAC3, SYSREF_OUT_NORTH, SYSREF_OUT_SOUTH, VOUT0_N, VOUT0_P, VOUT1_N, VOUT1_P, VOUT2_N, VOUT2_P, VOUT3_N, VOUT3_P, CLK_FIFO_LM +, CONTROL_COMMON, CONTROL_DAC0, CONTROL_DAC1, CONTROL_DAC2, CONTROL_DAC3, DAC_CLK_N, DAC_CLK_P, DADDR, DATA_DAC0, DATA_DAC1, DATA_DAC2, DATA_DAC3, DCLK, DEN, DI, DWE, FABRIC_CLK, PLL_MONCLK, PLL_REFCLK_IN, SYSREF_IN_NORTH, SYSREF_IN_SOUTH +, SYSREF_N, SYSREF_P); parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter integer XPA_CFG0 = 0; parameter integer XPA_CFG1 = 0; @@ -19665,7 +19895,9 @@ module HSDAC (...); input SYSREF_P; endmodule -module HSADC (...); +module HSADC(CLK_ADC, DATA_ADC0, DATA_ADC1, DATA_ADC2, DATA_ADC3, DOUT, DRDY, PLL_DMON_OUT, PLL_REFCLK_OUT, STATUS_ADC0, STATUS_ADC1, STATUS_ADC2, STATUS_ADC3, STATUS_COMMON, SYSREF_OUT_NORTH, SYSREF_OUT_SOUTH, ADC_CLK_N, ADC_CLK_P, CLK_FIFO_LM, CONTROL_ADC0, CONTROL_ADC1 +, CONTROL_ADC2, CONTROL_ADC3, CONTROL_COMMON, DADDR, DCLK, DEN, DI, DWE, FABRIC_CLK, PLL_MONCLK, PLL_REFCLK_IN, SYSREF_IN_NORTH, SYSREF_IN_SOUTH, SYSREF_N, SYSREF_P, VIN0_N, VIN0_P, VIN1_N, VIN1_P, VIN2_N, VIN2_P +, VIN3_N, VIN3_P, VIN_I01_N, VIN_I01_P, VIN_I23_N, VIN_I23_P); parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter integer XPA_CFG0 = 0; parameter integer XPA_CFG1 = 0; @@ -19723,7 +19955,9 @@ module HSADC (...); input VIN_I23_P; endmodule -module RFDAC (...); +module RFDAC(CLK_DAC, CLK_DIST_OUT_NORTH, CLK_DIST_OUT_SOUTH, DOUT, DRDY, PLL_DMON_OUT, PLL_REFCLK_OUT, STATUS_COMMON, STATUS_DAC0, STATUS_DAC1, STATUS_DAC2, STATUS_DAC3, SYSREF_OUT_NORTH, SYSREF_OUT_SOUTH, T1_ALLOWED_SOUTH, VOUT0_N, VOUT0_P, VOUT1_N, VOUT1_P, VOUT2_N, VOUT2_P +, VOUT3_N, VOUT3_P, CLK_DIST_IN_NORTH, CLK_DIST_IN_SOUTH, CLK_FIFO_LM, CONTROL_COMMON, CONTROL_DAC0, CONTROL_DAC1, CONTROL_DAC2, CONTROL_DAC3, DAC_CLK_N, DAC_CLK_P, DADDR, DATA_DAC0, DATA_DAC1, DATA_DAC2, DATA_DAC3, DCLK, DEN, DI, DWE +, FABRIC_CLK, PLL_MONCLK, PLL_REFCLK_IN, SYSREF_IN_NORTH, SYSREF_IN_SOUTH, SYSREF_N, SYSREF_P, T1_ALLOWED_NORTH); parameter integer LD_DEVICE = 0; parameter integer OPT_CLK_DIST = 0; parameter SIM_DEVICE = "ULTRASCALE_PLUS"; @@ -19787,7 +20021,9 @@ module RFDAC (...); input T1_ALLOWED_NORTH; endmodule -module RFADC (...); +module RFADC(CLK_ADC, CLK_DIST_OUT_NORTH, CLK_DIST_OUT_SOUTH, DATA_ADC0, DATA_ADC1, DATA_ADC2, DATA_ADC3, DOUT, DRDY, PLL_DMON_OUT, PLL_REFCLK_OUT, STATUS_ADC0, STATUS_ADC1, STATUS_ADC2, STATUS_ADC3, STATUS_COMMON, SYSREF_OUT_NORTH, SYSREF_OUT_SOUTH, T1_ALLOWED_SOUTH, ADC_CLK_N, ADC_CLK_P +, CLK_DIST_IN_NORTH, CLK_DIST_IN_SOUTH, CLK_FIFO_LM, CONTROL_ADC0, CONTROL_ADC1, CONTROL_ADC2, CONTROL_ADC3, CONTROL_COMMON, DADDR, DCLK, DEN, DI, DWE, FABRIC_CLK, PLL_MONCLK, PLL_REFCLK_IN, SYSREF_IN_NORTH, SYSREF_IN_SOUTH, SYSREF_N, SYSREF_P, T1_ALLOWED_NORTH +, VIN0_N, VIN0_P, VIN1_N, VIN1_P, VIN2_N, VIN2_P, VIN3_N, VIN3_P, VIN_I01_N, VIN_I01_P, VIN_I23_N, VIN_I23_P); parameter integer LD_DEVICE = 0; parameter integer OPT_ANALOG = 0; parameter integer OPT_CLK_DIST = 0; @@ -19856,7 +20092,14 @@ module RFADC (...); input VIN_I23_P; endmodule -module PCIE_A1 (...); +module PCIE_A1(CFGCOMMANDBUSMASTERENABLE, CFGCOMMANDINTERRUPTDISABLE, CFGCOMMANDIOENABLE, CFGCOMMANDMEMENABLE, CFGCOMMANDSERREN, CFGDEVCONTROLAUXPOWEREN, CFGDEVCONTROLCORRERRREPORTINGEN, CFGDEVCONTROLENABLERO, CFGDEVCONTROLEXTTAGEN, CFGDEVCONTROLFATALERRREPORTINGEN, CFGDEVCONTROLNONFATALREPORTINGEN, CFGDEVCONTROLNOSNOOPEN, CFGDEVCONTROLPHANTOMEN, CFGDEVCONTROLURERRREPORTINGEN, CFGDEVSTATUSCORRERRDETECTED, CFGDEVSTATUSFATALERRDETECTED, CFGDEVSTATUSNONFATALERRDETECTED, CFGDEVSTATUSURDETECTED, CFGERRCPLRDYN, CFGINTERRUPTMSIENABLE, CFGINTERRUPTRDYN +, CFGLINKCONTOLRCB, CFGLINKCONTROLCOMMONCLOCK, CFGLINKCONTROLEXTENDEDSYNC, CFGRDWRDONEN, CFGTOTURNOFFN, DBGBADDLLPSTATUS, DBGBADTLPLCRC, DBGBADTLPSEQNUM, DBGBADTLPSTATUS, DBGDLPROTOCOLSTATUS, DBGFCPROTOCOLERRSTATUS, DBGMLFRMDLENGTH, DBGMLFRMDMPS, DBGMLFRMDTCVC, DBGMLFRMDTLPSTATUS, DBGMLFRMDUNRECTYPE, DBGPOISTLPSTATUS, DBGRCVROVERFLOWSTATUS, DBGREGDETECTEDCORRECTABLE, DBGREGDETECTEDFATAL, DBGREGDETECTEDNONFATAL +, DBGREGDETECTEDUNSUPPORTED, DBGRPLYROLLOVERSTATUS, DBGRPLYTIMEOUTSTATUS, DBGURNOBARHIT, DBGURPOISCFGWR, DBGURSTATUS, DBGURUNSUPMSG, MIMRXREN, MIMRXWEN, MIMTXREN, MIMTXWEN, PIPEGTTXELECIDLEA, PIPEGTTXELECIDLEB, PIPERXPOLARITYA, PIPERXPOLARITYB, PIPERXRESETA, PIPERXRESETB, PIPETXRCVRDETA, PIPETXRCVRDETB, RECEIVEDHOTRESET, TRNLNKUPN +, TRNREOFN, TRNRERRFWDN, TRNRSOFN, TRNRSRCDSCN, TRNRSRCRDYN, TRNTCFGREQN, TRNTDSTRDYN, TRNTERRDROPN, USERRSTN, MIMRXRADDR, MIMRXWADDR, MIMTXRADDR, MIMTXWADDR, TRNFCCPLD, TRNFCNPD, TRNFCPD, PIPETXDATAA, PIPETXDATAB, CFGLINKCONTROLASPMCONTROL, PIPEGTPOWERDOWNA, PIPEGTPOWERDOWNB +, PIPETXCHARDISPMODEA, PIPETXCHARDISPMODEB, PIPETXCHARDISPVALA, PIPETXCHARDISPVALB, PIPETXCHARISKA, PIPETXCHARISKB, CFGDEVCONTROLMAXPAYLOAD, CFGDEVCONTROLMAXREADREQ, CFGFUNCTIONNUMBER, CFGINTERRUPTMMENABLE, CFGPCIELINKSTATEN, CFGDO, TRNRD, MIMRXWDATA, MIMTXWDATA, CFGDEVICENUMBER, CFGLTSSMSTATE, TRNTBUFAV, TRNRBARHITN, CFGBUSNUMBER, CFGINTERRUPTDO +, TRNFCCPLH, TRNFCNPH, TRNFCPH, CFGERRCORN, CFGERRCPLABORTN, CFGERRCPLTIMEOUTN, CFGERRECRCN, CFGERRLOCKEDN, CFGERRPOSTEDN, CFGERRURN, CFGINTERRUPTASSERTN, CFGINTERRUPTN, CFGPMWAKEN, CFGRDENN, CFGTRNPENDINGN, CFGTURNOFFOKN, CLOCKLOCKED, MGTCLK, PIPEGTRESETDONEA, PIPEGTRESETDONEB, PIPEPHYSTATUSA +, PIPEPHYSTATUSB, PIPERXENTERELECIDLEA, PIPERXENTERELECIDLEB, SYSRESETN, TRNRDSTRDYN, TRNRNPOKN, TRNTCFGGNTN, TRNTEOFN, TRNTERRFWDN, TRNTSOFN, TRNTSRCDSCN, TRNTSRCRDYN, TRNTSTRN, USERCLK, CFGDEVID, CFGSUBSYSID, CFGSUBSYSVENID, CFGVENID, PIPERXDATAA, PIPERXDATAB, PIPERXCHARISKA +, PIPERXCHARISKB, PIPERXSTATUSA, PIPERXSTATUSB, TRNFCSEL, TRNTD, MIMRXRDATA, MIMTXRDATA, CFGERRTLPCPLHEADER, CFGDSN, CFGINTERRUPTDI, CFGREVID, CFGDWADDR); parameter [31:0] BAR0 = 32'h00000000; parameter [31:0] BAR1 = 32'h00000000; parameter [31:0] BAR2 = 32'h00000000; @@ -20099,7 +20342,20 @@ module PCIE_A1 (...); input [9:0] CFGDWADDR; endmodule -module PCIE_EP (...); +module PCIE_EP(BUSMASTERENABLE, CRMDOHOTRESETN, CRMPWRSOFTRESETN, DLLTXPMDLLPOUTSTANDING, INTERRUPTDISABLE, IOSPACEENABLE, L0CFGLOOPBACKACK, L0DLLRXACKOUTSTANDING, L0DLLTXNONFCOUTSTANDING, L0DLLTXOUTSTANDING, L0FIRSTCFGWRITEOCCURRED, L0MACENTEREDL0, L0MACLINKTRAINING, L0MACLINKUP, L0MACNEWSTATEACK, L0MACRXL0SSTATE, L0MSIENABLE0, L0PMEACK, L0PMEEN, L0PMEREQOUT, L0PWRL1STATE +, L0PWRL23READYSTATE, L0PWRTURNOFFREQ, L0PWRTXL0SSTATE, L0RXDLLPM, L0STATSCFGOTHERRECEIVED, L0STATSCFGOTHERTRANSMITTED, L0STATSCFGRECEIVED, L0STATSCFGTRANSMITTED, L0STATSDLLPRECEIVED, L0STATSDLLPTRANSMITTED, L0STATSOSRECEIVED, L0STATSOSTRANSMITTED, L0STATSTLPRECEIVED, L0STATSTLPTRANSMITTED, L0UNLOCKRECEIVED, LLKRXEOFN, LLKRXEOPN, LLKRXSOFN, LLKRXSOPN, LLKRXSRCLASTREQN, LLKRXSRCRDYN +, LLKTXCONFIGREADYN, LLKTXDSTRDYN, MEMSPACEENABLE, MIMDLLBREN, MIMDLLBWEN, MIMRXBREN, MIMRXBWEN, MIMTXBREN, MIMTXBWEN, PARITYERRORRESPONSE, PIPEDESKEWLANESL0, PIPEDESKEWLANESL1, PIPEDESKEWLANESL2, PIPEDESKEWLANESL3, PIPEDESKEWLANESL4, PIPEDESKEWLANESL5, PIPEDESKEWLANESL6, PIPEDESKEWLANESL7, PIPERESETL0, PIPERESETL1, PIPERESETL2 +, PIPERESETL3, PIPERESETL4, PIPERESETL5, PIPERESETL6, PIPERESETL7, PIPERXPOLARITYL0, PIPERXPOLARITYL1, PIPERXPOLARITYL2, PIPERXPOLARITYL3, PIPERXPOLARITYL4, PIPERXPOLARITYL5, PIPERXPOLARITYL6, PIPERXPOLARITYL7, PIPETXCOMPLIANCEL0, PIPETXCOMPLIANCEL1, PIPETXCOMPLIANCEL2, PIPETXCOMPLIANCEL3, PIPETXCOMPLIANCEL4, PIPETXCOMPLIANCEL5, PIPETXCOMPLIANCEL6, PIPETXCOMPLIANCEL7 +, PIPETXDATAKL0, PIPETXDATAKL1, PIPETXDATAKL2, PIPETXDATAKL3, PIPETXDATAKL4, PIPETXDATAKL5, PIPETXDATAKL6, PIPETXDATAKL7, PIPETXDETECTRXLOOPBACKL0, PIPETXDETECTRXLOOPBACKL1, PIPETXDETECTRXLOOPBACKL2, PIPETXDETECTRXLOOPBACKL3, PIPETXDETECTRXLOOPBACKL4, PIPETXDETECTRXLOOPBACKL5, PIPETXDETECTRXLOOPBACKL6, PIPETXDETECTRXLOOPBACKL7, PIPETXELECIDLEL0, PIPETXELECIDLEL1, PIPETXELECIDLEL2, PIPETXELECIDLEL3, PIPETXELECIDLEL4 +, PIPETXELECIDLEL5, PIPETXELECIDLEL6, PIPETXELECIDLEL7, SERRENABLE, URREPORTINGENABLE, MGMTSTATSCREDIT, MIMDLLBRADD, MIMDLLBWADD, L0COMPLETERID, MIMRXBRADD, MIMRXBWADD, MIMTXBRADD, MIMTXBWADD, LLKRXPREFERREDTYPE, MGMTPSO, L0PWRSTATE0, L0RXMACLINKERROR, LLKRXVALIDN, PIPEPOWERDOWNL0, PIPEPOWERDOWNL1, PIPEPOWERDOWNL2 +, PIPEPOWERDOWNL3, PIPEPOWERDOWNL4, PIPEPOWERDOWNL5, PIPEPOWERDOWNL6, PIPEPOWERDOWNL7, L0MULTIMSGEN0, L0RXDLLPMTYPE, MAXPAYLOADSIZE, MAXREADREQUESTSIZE, MGMTRDATA, L0LTSSMSTATE, L0MACNEGOTIATEDLINKWIDTH, LLKRXDATA, MIMDLLBWDATA, MIMRXBWDATA, MIMTXBWDATA, L0DLLERRORVECTOR, L0DLLVCSTATUS, L0DLUPDOWN, LLKRXCHCOMPLETIONAVAILABLEN, LLKRXCHNONPOSTEDAVAILABLEN +, LLKRXCHPOSTEDAVAILABLEN, LLKTCSTATUS, LLKTXCHCOMPLETIONREADYN, LLKTXCHNONPOSTEDREADYN, LLKTXCHPOSTEDREADYN, PIPETXDATAL0, PIPETXDATAL1, PIPETXDATAL2, PIPETXDATAL3, PIPETXDATAL4, PIPETXDATAL5, PIPETXDATAL6, PIPETXDATAL7, LLKTXCHANSPACE, AUXPOWER, COMPLIANCEAVOID, CRMCORECLK, CRMCORECLKDLO, CRMCORECLKRXO, CRMCORECLKTXO, CRMLINKRSTN +, CRMMACRSTN, CRMMGMTRSTN, CRMNVRSTN, CRMURSTN, CRMUSERCFGRSTN, CRMUSERCLK, CRMUSERCLKRXO, CRMUSERCLKTXO, L0CFGDISABLESCRAMBLE, L0CFGLOOPBACKMASTER, L0LEGACYINTFUNCT0, L0PMEREQIN, L0SETCOMPLETERABORTERROR, L0SETCOMPLETIONTIMEOUTCORRERROR, L0SETCOMPLETIONTIMEOUTUNCORRERROR, L0SETDETECTEDCORRERROR, L0SETDETECTEDFATALERROR, L0SETDETECTEDNONFATALERROR, L0SETUNEXPECTEDCOMPLETIONCORRERROR, L0SETUNEXPECTEDCOMPLETIONUNCORRERROR, L0SETUNSUPPORTEDREQUESTNONPOSTEDERROR +, L0SETUNSUPPORTEDREQUESTOTHERERROR, L0SETUSERDETECTEDPARITYERROR, L0SETUSERMASTERDATAPARITY, L0SETUSERRECEIVEDMASTERABORT, L0SETUSERRECEIVEDTARGETABORT, L0SETUSERSIGNALLEDTARGETABORT, L0SETUSERSYSTEMERROR, L0TRANSACTIONSPENDING, LLKRXDSTCONTREQN, LLKRXDSTREQN, LLKTXEOFN, LLKTXEOPN, LLKTXSOFN, LLKTXSOPN, LLKTXSRCDSCN, LLKTXSRCRDYN, MGMTRDEN, MGMTWREN, PIPEPHYSTATUSL0, PIPEPHYSTATUSL1, PIPEPHYSTATUSL2 +, PIPEPHYSTATUSL3, PIPEPHYSTATUSL4, PIPEPHYSTATUSL5, PIPEPHYSTATUSL6, PIPEPHYSTATUSL7, PIPERXCHANISALIGNEDL0, PIPERXCHANISALIGNEDL1, PIPERXCHANISALIGNEDL2, PIPERXCHANISALIGNEDL3, PIPERXCHANISALIGNEDL4, PIPERXCHANISALIGNEDL5, PIPERXCHANISALIGNEDL6, PIPERXCHANISALIGNEDL7, PIPERXDATAKL0, PIPERXDATAKL1, PIPERXDATAKL2, PIPERXDATAKL3, PIPERXDATAKL4, PIPERXDATAKL5, PIPERXDATAKL6, PIPERXDATAKL7 +, PIPERXELECIDLEL0, PIPERXELECIDLEL1, PIPERXELECIDLEL2, PIPERXELECIDLEL3, PIPERXELECIDLEL4, PIPERXELECIDLEL5, PIPERXELECIDLEL6, PIPERXELECIDLEL7, PIPERXVALIDL0, PIPERXVALIDL1, PIPERXVALIDL2, PIPERXVALIDL3, PIPERXVALIDL4, PIPERXVALIDL5, PIPERXVALIDL6, PIPERXVALIDL7, MGMTADDR, L0PACKETHEADERFROMUSER, LLKRXCHFIFO, LLKTXCHFIFO, LLKTXENABLEN +, LLKRXCHTC, LLKTXCHTC, PIPERXSTATUSL0, PIPERXSTATUSL1, PIPERXSTATUSL2, PIPERXSTATUSL3, PIPERXSTATUSL4, PIPERXSTATUSL5, PIPERXSTATUSL6, PIPERXSTATUSL7, MGMTWDATA, L0MSIREQUEST0, MGMTBWREN, LLKTXDATA, MIMDLLBRDATA, MIMRXBRDATA, MIMTXBRDATA, MGMTSTATSCREDITSEL, PIPERXDATAL0, PIPERXDATAL1, PIPERXDATAL2 +, PIPERXDATAL3, PIPERXDATAL4, PIPERXDATAL5, PIPERXDATAL6, PIPERXDATAL7); parameter BAR0EXIST = "TRUE"; parameter BAR0PREFETCHABLE = "TRUE"; parameter BAR1EXIST = "FALSE"; @@ -20540,7 +20796,23 @@ module PCIE_EP (...); input [7:0] PIPERXDATAL7; endmodule -module PCIE_2_0 (...); +module PCIE_2_0(CFGAERECRCCHECKEN, CFGAERECRCGENEN, CFGCOMMANDBUSMASTERENABLE, CFGCOMMANDINTERRUPTDISABLE, CFGCOMMANDIOENABLE, CFGCOMMANDMEMENABLE, CFGCOMMANDSERREN, CFGDEVCONTROL2CPLTIMEOUTDIS, CFGDEVCONTROLAUXPOWEREN, CFGDEVCONTROLCORRERRREPORTINGEN, CFGDEVCONTROLENABLERO, CFGDEVCONTROLEXTTAGEN, CFGDEVCONTROLFATALERRREPORTINGEN, CFGDEVCONTROLNONFATALREPORTINGEN, CFGDEVCONTROLNOSNOOPEN, CFGDEVCONTROLPHANTOMEN, CFGDEVCONTROLURERRREPORTINGEN, CFGDEVSTATUSCORRERRDETECTED, CFGDEVSTATUSFATALERRDETECTED, CFGDEVSTATUSNONFATALERRDETECTED, CFGDEVSTATUSURDETECTED +, CFGERRAERHEADERLOGSETN, CFGERRCPLRDYN, CFGINTERRUPTMSIENABLE, CFGINTERRUPTMSIXENABLE, CFGINTERRUPTMSIXFM, CFGINTERRUPTRDYN, CFGLINKCONTROLAUTOBANDWIDTHINTEN, CFGLINKCONTROLBANDWIDTHINTEN, CFGLINKCONTROLCLOCKPMEN, CFGLINKCONTROLCOMMONCLOCK, CFGLINKCONTROLEXTENDEDSYNC, CFGLINKCONTROLHWAUTOWIDTHDIS, CFGLINKCONTROLLINKDISABLE, CFGLINKCONTROLRCB, CFGLINKCONTROLRETRAINLINK, CFGLINKSTATUSAUTOBANDWIDTHSTATUS, CFGLINKSTATUSBANDWITHSTATUS, CFGLINKSTATUSDLLACTIVE, CFGLINKSTATUSLINKTRAINING, CFGMSGRECEIVED, CFGMSGRECEIVEDASSERTINTA +, CFGMSGRECEIVEDASSERTINTB, CFGMSGRECEIVEDASSERTINTC, CFGMSGRECEIVEDASSERTINTD, CFGMSGRECEIVEDDEASSERTINTA, CFGMSGRECEIVEDDEASSERTINTB, CFGMSGRECEIVEDDEASSERTINTC, CFGMSGRECEIVEDDEASSERTINTD, CFGMSGRECEIVEDERRCOR, CFGMSGRECEIVEDERRFATAL, CFGMSGRECEIVEDERRNONFATAL, CFGMSGRECEIVEDPMASNAK, CFGMSGRECEIVEDPMETO, CFGMSGRECEIVEDPMETOACK, CFGMSGRECEIVEDPMPME, CFGMSGRECEIVEDSETSLOTPOWERLIMIT, CFGMSGRECEIVEDUNLOCK, CFGPMCSRPMEEN, CFGPMCSRPMESTATUS, CFGPMRCVASREQL1N, CFGPMRCVENTERL1N, CFGPMRCVENTERL23N +, CFGPMRCVREQACKN, CFGRDWRDONEN, CFGSLOTCONTROLELECTROMECHILCTLPULSE, CFGTRANSACTION, CFGTRANSACTIONTYPE, DBGSCLRA, DBGSCLRB, DBGSCLRC, DBGSCLRD, DBGSCLRE, DBGSCLRF, DBGSCLRG, DBGSCLRH, DBGSCLRI, DBGSCLRJ, DBGSCLRK, DRPDRDY, LL2BADDLLPERRN, LL2BADTLPERRN, LL2PROTOCOLERRN, LL2REPLAYROERRN +, LL2REPLAYTOERRN, LL2SUSPENDOKN, LL2TFCINIT1SEQN, LL2TFCINIT2SEQN, LNKCLKEN, MIMRXRCE, MIMRXREN, MIMRXWEN, MIMTXRCE, MIMTXREN, MIMTXWEN, PIPERX0POLARITY, PIPERX1POLARITY, PIPERX2POLARITY, PIPERX3POLARITY, PIPERX4POLARITY, PIPERX5POLARITY, PIPERX6POLARITY, PIPERX7POLARITY, PIPETX0COMPLIANCE, PIPETX0ELECIDLE +, PIPETX1COMPLIANCE, PIPETX1ELECIDLE, PIPETX2COMPLIANCE, PIPETX2ELECIDLE, PIPETX3COMPLIANCE, PIPETX3ELECIDLE, PIPETX4COMPLIANCE, PIPETX4ELECIDLE, PIPETX5COMPLIANCE, PIPETX5ELECIDLE, PIPETX6COMPLIANCE, PIPETX6ELECIDLE, PIPETX7COMPLIANCE, PIPETX7ELECIDLE, PIPETXDEEMPH, PIPETXRATE, PIPETXRCVRDET, PIPETXRESET, PL2LINKUPN, PL2RECEIVERERRN, PL2RECOVERYN +, PL2RXELECIDLE, PL2SUSPENDOK, PLLINKGEN2CAP, PLLINKPARTNERGEN2SUPPORTED, PLLINKUPCFGCAP, PLPHYLNKUPN, PLRECEIVEDHOTRST, PLSELLNKRATE, RECEIVEDFUNCLVLRSTN, TL2ASPMSUSPENDCREDITCHECKOKN, TL2ASPMSUSPENDREQN, TL2PPMSUSPENDOKN, TRNLNKUPN, TRNRDLLPSRCRDYN, TRNRECRCERRN, TRNREOFN, TRNRERRFWDN, TRNRREMN, TRNRSOFN, TRNRSRCDSCN, TRNRSRCRDYN +, TRNTCFGREQN, TRNTDLLPDSTRDYN, TRNTDSTRDYN, TRNTERRDROPN, USERRSTN, DBGVECC, PLDBGVEC, TRNFCCPLD, TRNFCNPD, TRNFCPD, MIMRXRADDR, MIMRXWADDR, MIMTXRADDR, MIMTXWADDR, CFGMSGDATA, DRPDO, PIPETX0DATA, PIPETX1DATA, PIPETX2DATA, PIPETX3DATA, PIPETX4DATA +, PIPETX5DATA, PIPETX6DATA, PIPETX7DATA, CFGLINKCONTROLASPMCONTROL, CFGLINKSTATUSCURRENTSPEED, CFGPMCSRPOWERSTATE, PIPETX0CHARISK, PIPETX0POWERDOWN, PIPETX1CHARISK, PIPETX1POWERDOWN, PIPETX2CHARISK, PIPETX2POWERDOWN, PIPETX3CHARISK, PIPETX3POWERDOWN, PIPETX4CHARISK, PIPETX4POWERDOWN, PIPETX5CHARISK, PIPETX5POWERDOWN, PIPETX6CHARISK, PIPETX6POWERDOWN, PIPETX7CHARISK +, PIPETX7POWERDOWN, PLLANEREVERSALMODE, PLRXPMSTATE, PLSELLNKWIDTH, CFGDEVCONTROLMAXPAYLOAD, CFGDEVCONTROLMAXREADREQ, CFGINTERRUPTMMENABLE, CFGPCIELINKSTATE, PIPETXMARGIN, PLINITIALLINKWIDTH, PLTXPMSTATE, CFGDO, TRNRDLLPDATA, CFGDEVCONTROL2CPLTIMEOUTVAL, CFGLINKSTATUSNEGOTIATEDWIDTH, PLLTSSMSTATE, TRNTBUFAV, DBGVECA, DBGVECB, TRNRD, MIMRXWDATA +, MIMTXWDATA, CFGTRANSACTIONADDR, CFGVCTCVCMAP, TRNRBARHITN, CFGINTERRUPTDO, TRNFCCPLH, TRNFCNPH, TRNFCPH, CFGERRACSN, CFGERRCORN, CFGERRCPLABORTN, CFGERRCPLTIMEOUTN, CFGERRCPLUNEXPECTN, CFGERRECRCN, CFGERRLOCKEDN, CFGERRPOSTEDN, CFGERRURN, CFGINTERRUPTASSERTN, CFGINTERRUPTN, CFGPMDIRECTASPML1N, CFGPMSENDPMACKN +, CFGPMSENDPMETON, CFGPMSENDPMNAKN, CFGPMTURNOFFOKN, CFGPMWAKEN, CFGRDENN, CFGTRNPENDINGN, CFGWRENN, CFGWRREADONLYN, CFGWRRW1CASRWN, CMRSTN, CMSTICKYRSTN, DBGSUBMODE, DLRSTN, DRPCLK, DRPDEN, DRPDWE, FUNCLVLRSTN, LL2SENDASREQL1N, LL2SENDENTERL1N, LL2SENDENTERL23N, LL2SUSPENDNOWN +, LL2TLPRCVN, PIPECLK, PIPERX0CHANISALIGNED, PIPERX0ELECIDLE, PIPERX0PHYSTATUS, PIPERX0VALID, PIPERX1CHANISALIGNED, PIPERX1ELECIDLE, PIPERX1PHYSTATUS, PIPERX1VALID, PIPERX2CHANISALIGNED, PIPERX2ELECIDLE, PIPERX2PHYSTATUS, PIPERX2VALID, PIPERX3CHANISALIGNED, PIPERX3ELECIDLE, PIPERX3PHYSTATUS, PIPERX3VALID, PIPERX4CHANISALIGNED, PIPERX4ELECIDLE, PIPERX4PHYSTATUS +, PIPERX4VALID, PIPERX5CHANISALIGNED, PIPERX5ELECIDLE, PIPERX5PHYSTATUS, PIPERX5VALID, PIPERX6CHANISALIGNED, PIPERX6ELECIDLE, PIPERX6PHYSTATUS, PIPERX6VALID, PIPERX7CHANISALIGNED, PIPERX7ELECIDLE, PIPERX7PHYSTATUS, PIPERX7VALID, PLDIRECTEDLINKAUTON, PLDIRECTEDLINKSPEED, PLDOWNSTREAMDEEMPHSOURCE, PLRSTN, PLTRANSMITHOTRST, PLUPSTREAMPREFERDEEMPH, SYSRSTN, TL2ASPMSUSPENDCREDITCHECKN +, TL2PPMSUSPENDREQN, TLRSTN, TRNRDSTRDYN, TRNRNPOKN, TRNTCFGGNTN, TRNTDLLPSRCRDYN, TRNTECRCGENN, TRNTEOFN, TRNTERRFWDN, TRNTREMN, TRNTSOFN, TRNTSRCDSCN, TRNTSRCRDYN, TRNTSTRN, USERCLK, CFGERRAERHEADERLOG, DRPDI, PIPERX0DATA, PIPERX1DATA, PIPERX2DATA, PIPERX3DATA +, PIPERX4DATA, PIPERX5DATA, PIPERX6DATA, PIPERX7DATA, DBGMODE, PIPERX0CHARISK, PIPERX1CHARISK, PIPERX2CHARISK, PIPERX3CHARISK, PIPERX4CHARISK, PIPERX5CHARISK, PIPERX6CHARISK, PIPERX7CHARISK, PLDIRECTEDLINKCHANGE, PLDIRECTEDLINKWIDTH, CFGDSFUNCTIONNUMBER, PIPERX0STATUS, PIPERX1STATUS, PIPERX2STATUS, PIPERX3STATUS, PIPERX4STATUS +, PIPERX5STATUS, PIPERX6STATUS, PIPERX7STATUS, PLDBGMODE, TRNFCSEL, CFGDI, TRNTDLLPDATA, CFGBYTEENN, CFGERRTLPCPLHEADER, CFGDSDEVICENUMBER, PL2DIRECTEDLSTATE, CFGDSN, TRNTD, MIMRXRDATA, MIMTXRDATA, CFGDSBUSNUMBER, CFGINTERRUPTDI, CFGPORTNUMBER, DRPDADDR, CFGDWADDR); parameter [11:0] AER_BASE_PTR = 12'h128; parameter AER_CAP_ECRC_CHECK_CAPABLE = "FALSE"; parameter AER_CAP_ECRC_GEN_CAPABLE = "FALSE"; @@ -21135,7 +21407,26 @@ module PCIE_2_0 (...); input [9:0] CFGDWADDR; endmodule -module PCIE_2_1 (...); +module PCIE_2_1(CFGAERECRCCHECKEN, CFGAERECRCGENEN, CFGAERROOTERRCORRERRRECEIVED, CFGAERROOTERRCORRERRREPORTINGEN, CFGAERROOTERRFATALERRRECEIVED, CFGAERROOTERRFATALERRREPORTINGEN, CFGAERROOTERRNONFATALERRRECEIVED, CFGAERROOTERRNONFATALERRREPORTINGEN, CFGBRIDGESERREN, CFGCOMMANDBUSMASTERENABLE, CFGCOMMANDINTERRUPTDISABLE, CFGCOMMANDIOENABLE, CFGCOMMANDMEMENABLE, CFGCOMMANDSERREN, CFGDEVCONTROL2ARIFORWARDEN, CFGDEVCONTROL2ATOMICEGRESSBLOCK, CFGDEVCONTROL2ATOMICREQUESTEREN, CFGDEVCONTROL2CPLTIMEOUTDIS, CFGDEVCONTROL2IDOCPLEN, CFGDEVCONTROL2IDOREQEN, CFGDEVCONTROL2LTREN +, CFGDEVCONTROL2TLPPREFIXBLOCK, CFGDEVCONTROLAUXPOWEREN, CFGDEVCONTROLCORRERRREPORTINGEN, CFGDEVCONTROLENABLERO, CFGDEVCONTROLEXTTAGEN, CFGDEVCONTROLFATALERRREPORTINGEN, CFGDEVCONTROLNONFATALREPORTINGEN, CFGDEVCONTROLNOSNOOPEN, CFGDEVCONTROLPHANTOMEN, CFGDEVCONTROLURERRREPORTINGEN, CFGDEVSTATUSCORRERRDETECTED, CFGDEVSTATUSFATALERRDETECTED, CFGDEVSTATUSNONFATALERRDETECTED, CFGDEVSTATUSURDETECTED, CFGERRAERHEADERLOGSETN, CFGERRCPLRDYN, CFGINTERRUPTMSIENABLE, CFGINTERRUPTMSIXENABLE, CFGINTERRUPTMSIXFM, CFGINTERRUPTRDYN, CFGLINKCONTROLAUTOBANDWIDTHINTEN +, CFGLINKCONTROLBANDWIDTHINTEN, CFGLINKCONTROLCLOCKPMEN, CFGLINKCONTROLCOMMONCLOCK, CFGLINKCONTROLEXTENDEDSYNC, CFGLINKCONTROLHWAUTOWIDTHDIS, CFGLINKCONTROLLINKDISABLE, CFGLINKCONTROLRCB, CFGLINKCONTROLRETRAINLINK, CFGLINKSTATUSAUTOBANDWIDTHSTATUS, CFGLINKSTATUSBANDWIDTHSTATUS, CFGLINKSTATUSDLLACTIVE, CFGLINKSTATUSLINKTRAINING, CFGMGMTRDWRDONEN, CFGMSGRECEIVED, CFGMSGRECEIVEDASSERTINTA, CFGMSGRECEIVEDASSERTINTB, CFGMSGRECEIVEDASSERTINTC, CFGMSGRECEIVEDASSERTINTD, CFGMSGRECEIVEDDEASSERTINTA, CFGMSGRECEIVEDDEASSERTINTB, CFGMSGRECEIVEDDEASSERTINTC +, CFGMSGRECEIVEDDEASSERTINTD, CFGMSGRECEIVEDERRCOR, CFGMSGRECEIVEDERRFATAL, CFGMSGRECEIVEDERRNONFATAL, CFGMSGRECEIVEDPMASNAK, CFGMSGRECEIVEDPMETO, CFGMSGRECEIVEDPMETOACK, CFGMSGRECEIVEDPMPME, CFGMSGRECEIVEDSETSLOTPOWERLIMIT, CFGMSGRECEIVEDUNLOCK, CFGPMCSRPMEEN, CFGPMCSRPMESTATUS, CFGPMRCVASREQL1N, CFGPMRCVENTERL1N, CFGPMRCVENTERL23N, CFGPMRCVREQACKN, CFGROOTCONTROLPMEINTEN, CFGROOTCONTROLSYSERRCORRERREN, CFGROOTCONTROLSYSERRFATALERREN, CFGROOTCONTROLSYSERRNONFATALERREN, CFGSLOTCONTROLELECTROMECHILCTLPULSE +, CFGTRANSACTION, CFGTRANSACTIONTYPE, DBGSCLRA, DBGSCLRB, DBGSCLRC, DBGSCLRD, DBGSCLRE, DBGSCLRF, DBGSCLRG, DBGSCLRH, DBGSCLRI, DBGSCLRJ, DBGSCLRK, DRPRDY, LL2BADDLLPERR, LL2BADTLPERR, LL2PROTOCOLERR, LL2RECEIVERERR, LL2REPLAYROERR, LL2REPLAYTOERR, LL2SUSPENDOK +, LL2TFCINIT1SEQ, LL2TFCINIT2SEQ, LL2TXIDLE, LNKCLKEN, MIMRXREN, MIMRXWEN, MIMTXREN, MIMTXWEN, PIPERX0POLARITY, PIPERX1POLARITY, PIPERX2POLARITY, PIPERX3POLARITY, PIPERX4POLARITY, PIPERX5POLARITY, PIPERX6POLARITY, PIPERX7POLARITY, PIPETX0COMPLIANCE, PIPETX0ELECIDLE, PIPETX1COMPLIANCE, PIPETX1ELECIDLE, PIPETX2COMPLIANCE +, PIPETX2ELECIDLE, PIPETX3COMPLIANCE, PIPETX3ELECIDLE, PIPETX4COMPLIANCE, PIPETX4ELECIDLE, PIPETX5COMPLIANCE, PIPETX5ELECIDLE, PIPETX6COMPLIANCE, PIPETX6ELECIDLE, PIPETX7COMPLIANCE, PIPETX7ELECIDLE, PIPETXDEEMPH, PIPETXRATE, PIPETXRCVRDET, PIPETXRESET, PL2L0REQ, PL2LINKUP, PL2RECEIVERERR, PL2RECOVERY, PL2RXELECIDLE, PL2SUSPENDOK +, PLDIRECTEDCHANGEDONE, PLLINKGEN2CAP, PLLINKPARTNERGEN2SUPPORTED, PLLINKUPCFGCAP, PLPHYLNKUPN, PLRECEIVEDHOTRST, PLSELLNKRATE, RECEIVEDFUNCLVLRSTN, TL2ASPMSUSPENDCREDITCHECKOK, TL2ASPMSUSPENDREQ, TL2ERRFCPE, TL2ERRMALFORMED, TL2ERRRXOVERFLOW, TL2PPMSUSPENDOK, TRNLNKUP, TRNRECRCERR, TRNREOF, TRNRERRFWD, TRNRSOF, TRNRSRCDSC, TRNRSRCRDY +, TRNTCFGREQ, TRNTDLLPDSTRDY, TRNTERRDROP, USERRSTN, DBGVECC, PLDBGVEC, TRNFCCPLD, TRNFCNPD, TRNFCPD, TRNRD, MIMRXRADDR, MIMRXWADDR, MIMTXRADDR, MIMTXWADDR, CFGMSGDATA, DRPDO, PIPETX0DATA, PIPETX1DATA, PIPETX2DATA, PIPETX3DATA, PIPETX4DATA +, PIPETX5DATA, PIPETX6DATA, PIPETX7DATA, CFGLINKCONTROLASPMCONTROL, CFGLINKSTATUSCURRENTSPEED, CFGPMCSRPOWERSTATE, PIPETX0CHARISK, PIPETX0POWERDOWN, PIPETX1CHARISK, PIPETX1POWERDOWN, PIPETX2CHARISK, PIPETX2POWERDOWN, PIPETX3CHARISK, PIPETX3POWERDOWN, PIPETX4CHARISK, PIPETX4POWERDOWN, PIPETX5CHARISK, PIPETX5POWERDOWN, PIPETX6CHARISK, PIPETX6POWERDOWN, PIPETX7CHARISK +, PIPETX7POWERDOWN, PL2RXPMSTATE, PLLANEREVERSALMODE, PLRXPMSTATE, PLSELLNKWIDTH, TRNRDLLPSRCRDY, TRNRREM, CFGDEVCONTROLMAXPAYLOAD, CFGDEVCONTROLMAXREADREQ, CFGINTERRUPTMMENABLE, CFGPCIELINKSTATE, PIPETXMARGIN, PLINITIALLINKWIDTH, PLTXPMSTATE, CFGMGMTDO, CFGDEVCONTROL2CPLTIMEOUTVAL, CFGLINKSTATUSNEGOTIATEDWIDTH, TRNTDSTRDY, LL2LINKSTATUS, PLLTSSMSTATE, TRNTBUFAV +, DBGVECA, DBGVECB, TL2ERRHDR, TRNRDLLPDATA, MIMRXWDATA, MIMTXWDATA, CFGTRANSACTIONADDR, CFGVCTCVCMAP, CFGINTERRUPTDO, TRNFCCPLH, TRNFCNPH, TRNFCPH, TRNRBARHIT, CFGERRACSN, CFGERRATOMICEGRESSBLOCKEDN, CFGERRCORN, CFGERRCPLABORTN, CFGERRCPLTIMEOUTN, CFGERRCPLUNEXPECTN, CFGERRECRCN, CFGERRINTERNALCORN +, CFGERRINTERNALUNCORN, CFGERRLOCKEDN, CFGERRMALFORMEDN, CFGERRMCBLOCKEDN, CFGERRNORECOVERYN, CFGERRPOISONEDN, CFGERRPOSTEDN, CFGERRURN, CFGFORCECOMMONCLOCKOFF, CFGFORCEEXTENDEDSYNCON, CFGINTERRUPTASSERTN, CFGINTERRUPTN, CFGINTERRUPTSTATN, CFGMGMTRDENN, CFGMGMTWRENN, CFGMGMTWRREADONLYN, CFGMGMTWRRW1CASRWN, CFGPMFORCESTATEENN, CFGPMHALTASPML0SN, CFGPMHALTASPML1N, CFGPMSENDPMETON +, CFGPMTURNOFFOKN, CFGPMWAKEN, CFGTRNPENDINGN, CMRSTN, CMSTICKYRSTN, DBGSUBMODE, DLRSTN, DRPCLK, DRPEN, DRPWE, FUNCLVLRSTN, LL2SENDASREQL1, LL2SENDENTERL1, LL2SENDENTERL23, LL2SENDPMACK, LL2SUSPENDNOW, LL2TLPRCV, PIPECLK, PIPERX0CHANISALIGNED, PIPERX0ELECIDLE, PIPERX0PHYSTATUS +, PIPERX0VALID, PIPERX1CHANISALIGNED, PIPERX1ELECIDLE, PIPERX1PHYSTATUS, PIPERX1VALID, PIPERX2CHANISALIGNED, PIPERX2ELECIDLE, PIPERX2PHYSTATUS, PIPERX2VALID, PIPERX3CHANISALIGNED, PIPERX3ELECIDLE, PIPERX3PHYSTATUS, PIPERX3VALID, PIPERX4CHANISALIGNED, PIPERX4ELECIDLE, PIPERX4PHYSTATUS, PIPERX4VALID, PIPERX5CHANISALIGNED, PIPERX5ELECIDLE, PIPERX5PHYSTATUS, PIPERX5VALID +, PIPERX6CHANISALIGNED, PIPERX6ELECIDLE, PIPERX6PHYSTATUS, PIPERX6VALID, PIPERX7CHANISALIGNED, PIPERX7ELECIDLE, PIPERX7PHYSTATUS, PIPERX7VALID, PLDIRECTEDLINKAUTON, PLDIRECTEDLINKSPEED, PLDIRECTEDLTSSMNEWVLD, PLDIRECTEDLTSSMSTALL, PLDOWNSTREAMDEEMPHSOURCE, PLRSTN, PLTRANSMITHOTRST, PLUPSTREAMPREFERDEEMPH, SYSRSTN, TL2ASPMSUSPENDCREDITCHECK, TL2PPMSUSPENDREQ, TLRSTN, TRNRDSTRDY +, TRNRFCPRET, TRNRNPOK, TRNRNPREQ, TRNTCFGGNT, TRNTDLLPSRCRDY, TRNTECRCGEN, TRNTEOF, TRNTERRFWD, TRNTSOF, TRNTSRCDSC, TRNTSRCRDY, TRNTSTR, USERCLK2, USERCLK, CFGERRAERHEADERLOG, TRNTD, CFGDEVID, CFGSUBSYSID, CFGSUBSYSVENDID, CFGVENDID, DRPDI +, PIPERX0DATA, PIPERX1DATA, PIPERX2DATA, PIPERX3DATA, PIPERX4DATA, PIPERX5DATA, PIPERX6DATA, PIPERX7DATA, CFGPMFORCESTATE, DBGMODE, PIPERX0CHARISK, PIPERX1CHARISK, PIPERX2CHARISK, PIPERX3CHARISK, PIPERX4CHARISK, PIPERX5CHARISK, PIPERX6CHARISK, PIPERX7CHARISK, PLDIRECTEDLINKCHANGE, PLDIRECTEDLINKWIDTH, TRNTREM +, CFGDSFUNCTIONNUMBER, CFGFORCEMPS, PIPERX0STATUS, PIPERX1STATUS, PIPERX2STATUS, PIPERX3STATUS, PIPERX4STATUS, PIPERX5STATUS, PIPERX6STATUS, PIPERX7STATUS, PLDBGMODE, TRNFCSEL, CFGMGMTDI, TRNTDLLPDATA, CFGMGMTBYTEENN, CFGERRTLPCPLHEADER, CFGAERINTERRUPTMSGNUM, CFGDSDEVICENUMBER, CFGPCIECAPINTERRUPTMSGNUM, PL2DIRECTEDLSTATE, PLDIRECTEDLTSSMNEW +, CFGDSN, MIMRXRDATA, MIMTXRDATA, CFGDSBUSNUMBER, CFGINTERRUPTDI, CFGPORTNUMBER, CFGREVID, DRPADDR, CFGMGMTDWADDR); parameter [11:0] AER_BASE_PTR = 12'h140; parameter AER_CAP_ECRC_CHECK_CAPABLE = "FALSE"; parameter AER_CAP_ECRC_GEN_CAPABLE = "FALSE"; @@ -21830,7 +22121,29 @@ module PCIE_2_1 (...); input [9:0] CFGMGMTDWADDR; endmodule -module PCIE_3_0 (...); +module PCIE_3_0(CFGERRCOROUT, CFGERRFATALOUT, CFGERRNONFATALOUT, CFGEXTREADRECEIVED, CFGEXTWRITERECEIVED, CFGHOTRESETOUT, CFGINPUTUPDATEDONE, CFGINTERRUPTAOUTPUT, CFGINTERRUPTBOUTPUT, CFGINTERRUPTCOUTPUT, CFGINTERRUPTDOUTPUT, CFGINTERRUPTMSIFAIL, CFGINTERRUPTMSIMASKUPDATE, CFGINTERRUPTMSISENT, CFGINTERRUPTMSIXFAIL, CFGINTERRUPTMSIXSENT, CFGINTERRUPTSENT, CFGLOCALERROR, CFGLTRENABLE, CFGMCUPDATEDONE, CFGMGMTREADWRITEDONE +, CFGMSGRECEIVED, CFGMSGTRANSMITDONE, CFGPERFUNCTIONUPDATEDONE, CFGPHYLINKDOWN, CFGPLSTATUSCHANGE, CFGPOWERSTATECHANGEINTERRUPT, CFGTPHSTTREADENABLE, CFGTPHSTTWRITEENABLE, DRPRDY, MAXISCQTLAST, MAXISCQTVALID, MAXISRCTLAST, MAXISRCTVALID, PCIERQSEQNUMVLD, PCIERQTAGVLD, PIPERX0POLARITY, PIPERX1POLARITY, PIPERX2POLARITY, PIPERX3POLARITY, PIPERX4POLARITY, PIPERX5POLARITY +, PIPERX6POLARITY, PIPERX7POLARITY, PIPETX0COMPLIANCE, PIPETX0DATAVALID, PIPETX0ELECIDLE, PIPETX0STARTBLOCK, PIPETX1COMPLIANCE, PIPETX1DATAVALID, PIPETX1ELECIDLE, PIPETX1STARTBLOCK, PIPETX2COMPLIANCE, PIPETX2DATAVALID, PIPETX2ELECIDLE, PIPETX2STARTBLOCK, PIPETX3COMPLIANCE, PIPETX3DATAVALID, PIPETX3ELECIDLE, PIPETX3STARTBLOCK, PIPETX4COMPLIANCE, PIPETX4DATAVALID, PIPETX4ELECIDLE +, PIPETX4STARTBLOCK, PIPETX5COMPLIANCE, PIPETX5DATAVALID, PIPETX5ELECIDLE, PIPETX5STARTBLOCK, PIPETX6COMPLIANCE, PIPETX6DATAVALID, PIPETX6ELECIDLE, PIPETX6STARTBLOCK, PIPETX7COMPLIANCE, PIPETX7DATAVALID, PIPETX7ELECIDLE, PIPETX7STARTBLOCK, PIPETXDEEMPH, PIPETXRCVRDET, PIPETXRESET, PIPETXSWING, PLEQINPROGRESS, CFGFCCPLD, CFGFCNPD, CFGFCPD +, CFGVFSTATUS, MIREPLAYRAMWRITEDATA, MIREQUESTRAMWRITEDATA, CFGPERFUNCSTATUSDATA, DBGDATAOUT, DRPDO, CFGVFPOWERSTATE, CFGVFTPHSTMODE, CFGDPASUBSTATECHANGE, CFGFLRINPROCESS, CFGINTERRUPTMSIENABLE, CFGINTERRUPTMSIXENABLE, CFGINTERRUPTMSIXMASK, CFGLINKPOWERSTATE, CFGOBFFENABLE, CFGPHYLINKSTATUS, CFGRCBSTATUS, CFGTPHREQUESTERENABLE, MIREPLAYRAMREADENABLE, MIREPLAYRAMWRITEENABLE, PCIERQTAGAV +, PCIETFCNPDAV, PCIETFCNPHAV, PIPERX0EQCONTROL, PIPERX1EQCONTROL, PIPERX2EQCONTROL, PIPERX3EQCONTROL, PIPERX4EQCONTROL, PIPERX5EQCONTROL, PIPERX6EQCONTROL, PIPERX7EQCONTROL, PIPETX0CHARISK, PIPETX0EQCONTROL, PIPETX0POWERDOWN, PIPETX0SYNCHEADER, PIPETX1CHARISK, PIPETX1EQCONTROL, PIPETX1POWERDOWN, PIPETX1SYNCHEADER, PIPETX2CHARISK, PIPETX2EQCONTROL, PIPETX2POWERDOWN +, PIPETX2SYNCHEADER, PIPETX3CHARISK, PIPETX3EQCONTROL, PIPETX3POWERDOWN, PIPETX3SYNCHEADER, PIPETX4CHARISK, PIPETX4EQCONTROL, PIPETX4POWERDOWN, PIPETX4SYNCHEADER, PIPETX5CHARISK, PIPETX5EQCONTROL, PIPETX5POWERDOWN, PIPETX5SYNCHEADER, PIPETX6CHARISK, PIPETX6EQCONTROL, PIPETX6POWERDOWN, PIPETX6SYNCHEADER, PIPETX7CHARISK, PIPETX7EQCONTROL, PIPETX7POWERDOWN, PIPETX7SYNCHEADER +, PIPETXRATE, PLEQPHASE, MAXISCQTDATA, MAXISRCTDATA, CFGCURRENTSPEED, CFGMAXPAYLOAD, CFGMAXREADREQ, CFGTPHFUNCTIONNUM, PIPERX0EQPRESET, PIPERX1EQPRESET, PIPERX2EQPRESET, PIPERX3EQPRESET, PIPERX4EQPRESET, PIPERX5EQPRESET, PIPERX6EQPRESET, PIPERX7EQPRESET, PIPETXMARGIN, CFGEXTWRITEDATA, CFGINTERRUPTMSIDATA, CFGMGMTREADDATA, CFGTPHSTTWRITEDATA +, PIPETX0DATA, PIPETX1DATA, PIPETX2DATA, PIPETX3DATA, PIPETX4DATA, PIPETX5DATA, PIPETX6DATA, PIPETX7DATA, CFGEXTWRITEBYTEENABLE, CFGNEGOTIATEDWIDTH, CFGTPHSTTWRITEBYTEVALID, MICOMPLETIONRAMREADENABLEL, MICOMPLETIONRAMREADENABLEU, MICOMPLETIONRAMWRITEENABLEL, MICOMPLETIONRAMWRITEENABLEU, MIREQUESTRAMREADENABLE, MIREQUESTRAMWRITEENABLE, PCIERQSEQNUM, PIPERX0EQLPTXPRESET, PIPERX1EQLPTXPRESET, PIPERX2EQLPTXPRESET +, PIPERX3EQLPTXPRESET, PIPERX4EQLPTXPRESET, PIPERX5EQLPTXPRESET, PIPERX6EQLPTXPRESET, PIPERX7EQLPTXPRESET, PIPETX0EQPRESET, PIPETX1EQPRESET, PIPETX2EQPRESET, PIPETX3EQPRESET, PIPETX4EQPRESET, PIPETX5EQPRESET, PIPETX6EQPRESET, PIPETX7EQPRESET, SAXISCCTREADY, SAXISRQTREADY, CFGMSGRECEIVEDTYPE, CFGTPHSTTADDRESS, CFGFUNCTIONPOWERSTATE, CFGINTERRUPTMSIMMENABLE, CFGINTERRUPTMSIVFENABLE, CFGINTERRUPTMSIXVFENABLE +, CFGINTERRUPTMSIXVFMASK, CFGLTSSMSTATE, CFGTPHSTMODE, CFGVFFLRINPROCESS, CFGVFTPHREQUESTERENABLE, PCIECQNPREQCOUNT, PCIERQTAG, PIPERX0EQLPLFFS, PIPERX1EQLPLFFS, PIPERX2EQLPLFFS, PIPERX3EQLPLFFS, PIPERX4EQLPLFFS, PIPERX5EQLPLFFS, PIPERX6EQLPLFFS, PIPERX7EQLPLFFS, PIPETX0EQDEEMPH, PIPETX1EQDEEMPH, PIPETX2EQDEEMPH, PIPETX3EQDEEMPH, PIPETX4EQDEEMPH, PIPETX5EQDEEMPH +, PIPETX6EQDEEMPH, PIPETX7EQDEEMPH, MICOMPLETIONRAMWRITEDATAL, MICOMPLETIONRAMWRITEDATAU, MAXISRCTUSER, CFGEXTFUNCTIONNUMBER, CFGFCCPLH, CFGFCNPH, CFGFCPH, CFGFUNCTIONSTATUS, CFGMSGRECEIVEDDATA, MAXISCQTKEEP, MAXISRCTKEEP, PLGEN3PCSRXSLIDE, MAXISCQTUSER, MIREPLAYRAMADDRESS, MIREQUESTRAMREADADDRESSA, MIREQUESTRAMREADADDRESSB, MIREQUESTRAMWRITEADDRESSA, MIREQUESTRAMWRITEADDRESSB, CFGEXTREGISTERNUMBER +, MICOMPLETIONRAMREADADDRESSAL, MICOMPLETIONRAMREADADDRESSAU, MICOMPLETIONRAMREADADDRESSBL, MICOMPLETIONRAMREADADDRESSBU, MICOMPLETIONRAMWRITEADDRESSAL, MICOMPLETIONRAMWRITEADDRESSAU, MICOMPLETIONRAMWRITEADDRESSBL, MICOMPLETIONRAMWRITEADDRESSBU, CFGCONFIGSPACEENABLE, CFGERRCORIN, CFGERRUNCORIN, CFGEXTREADDATAVALID, CFGHOTRESETIN, CFGINPUTUPDATEREQUEST, CFGINTERRUPTMSITPHPRESENT, CFGINTERRUPTMSIXINT, CFGLINKTRAININGENABLE, CFGMCUPDATEREQUEST, CFGMGMTREAD, CFGMGMTTYPE1CFGREGACCESS, CFGMGMTWRITE +, CFGMSGTRANSMIT, CFGPERFUNCTIONOUTPUTREQUEST, CFGPOWERSTATECHANGEACK, CFGREQPMTRANSITIONL23READY, CFGTPHSTTREADDATAVALID, CORECLK, CORECLKMICOMPLETIONRAML, CORECLKMICOMPLETIONRAMU, CORECLKMIREPLAYRAM, CORECLKMIREQUESTRAM, DRPCLK, DRPEN, DRPWE, MGMTRESETN, MGMTSTICKYRESETN, PCIECQNPREQ, PIPECLK, PIPERESETN, PIPERX0DATAVALID, PIPERX0ELECIDLE, PIPERX0EQDONE +, PIPERX0EQLPADAPTDONE, PIPERX0EQLPLFFSSEL, PIPERX0PHYSTATUS, PIPERX0STARTBLOCK, PIPERX0VALID, PIPERX1DATAVALID, PIPERX1ELECIDLE, PIPERX1EQDONE, PIPERX1EQLPADAPTDONE, PIPERX1EQLPLFFSSEL, PIPERX1PHYSTATUS, PIPERX1STARTBLOCK, PIPERX1VALID, PIPERX2DATAVALID, PIPERX2ELECIDLE, PIPERX2EQDONE, PIPERX2EQLPADAPTDONE, PIPERX2EQLPLFFSSEL, PIPERX2PHYSTATUS, PIPERX2STARTBLOCK, PIPERX2VALID +, PIPERX3DATAVALID, PIPERX3ELECIDLE, PIPERX3EQDONE, PIPERX3EQLPADAPTDONE, PIPERX3EQLPLFFSSEL, PIPERX3PHYSTATUS, PIPERX3STARTBLOCK, PIPERX3VALID, PIPERX4DATAVALID, PIPERX4ELECIDLE, PIPERX4EQDONE, PIPERX4EQLPADAPTDONE, PIPERX4EQLPLFFSSEL, PIPERX4PHYSTATUS, PIPERX4STARTBLOCK, PIPERX4VALID, PIPERX5DATAVALID, PIPERX5ELECIDLE, PIPERX5EQDONE, PIPERX5EQLPADAPTDONE, PIPERX5EQLPLFFSSEL +, PIPERX5PHYSTATUS, PIPERX5STARTBLOCK, PIPERX5VALID, PIPERX6DATAVALID, PIPERX6ELECIDLE, PIPERX6EQDONE, PIPERX6EQLPADAPTDONE, PIPERX6EQLPLFFSSEL, PIPERX6PHYSTATUS, PIPERX6STARTBLOCK, PIPERX6VALID, PIPERX7DATAVALID, PIPERX7ELECIDLE, PIPERX7EQDONE, PIPERX7EQLPADAPTDONE, PIPERX7EQLPLFFSSEL, PIPERX7PHYSTATUS, PIPERX7STARTBLOCK, PIPERX7VALID, PIPETX0EQDONE, PIPETX1EQDONE +, PIPETX2EQDONE, PIPETX3EQDONE, PIPETX4EQDONE, PIPETX5EQDONE, PIPETX6EQDONE, PIPETX7EQDONE, PLDISABLESCRAMBLER, PLEQRESETEIEOSCOUNT, PLGEN3PCSDISABLE, RECCLK, RESETN, SAXISCCTLAST, SAXISCCTVALID, SAXISRQTLAST, SAXISRQTVALID, USERCLK, DRPADDR, MICOMPLETIONRAMREADDATA, MIREPLAYRAMREADDATA, MIREQUESTRAMREADDATA, CFGDEVID +, CFGSUBSYSID, CFGSUBSYSVENDID, CFGVENDID, DRPDI, PIPERX0EQLPNEWTXCOEFFORPRESET, PIPERX1EQLPNEWTXCOEFFORPRESET, PIPERX2EQLPNEWTXCOEFFORPRESET, PIPERX3EQLPNEWTXCOEFFORPRESET, PIPERX4EQLPNEWTXCOEFFORPRESET, PIPERX5EQLPNEWTXCOEFFORPRESET, PIPERX6EQLPNEWTXCOEFFORPRESET, PIPERX7EQLPNEWTXCOEFFORPRESET, PIPETX0EQCOEFF, PIPETX1EQCOEFF, PIPETX2EQCOEFF, PIPETX3EQCOEFF, PIPETX4EQCOEFF, PIPETX5EQCOEFF, PIPETX6EQCOEFF, PIPETX7EQCOEFF, CFGMGMTADDR +, CFGFLRDONE, CFGINTERRUPTMSITPHTYPE, CFGINTERRUPTPENDING, PIPERX0CHARISK, PIPERX0SYNCHEADER, PIPERX1CHARISK, PIPERX1SYNCHEADER, PIPERX2CHARISK, PIPERX2SYNCHEADER, PIPERX3CHARISK, PIPERX3SYNCHEADER, PIPERX4CHARISK, PIPERX4SYNCHEADER, PIPERX5CHARISK, PIPERX5SYNCHEADER, PIPERX6CHARISK, PIPERX6SYNCHEADER, PIPERX7CHARISK, PIPERX7SYNCHEADER, MAXISCQTREADY, MAXISRCTREADY +, SAXISCCTDATA, SAXISRQTDATA, CFGDSFUNCTIONNUMBER, CFGFCSEL, CFGINTERRUPTMSIATTR, CFGINTERRUPTMSIFUNCTIONNUMBER, CFGMSGTRANSMITTYPE, CFGPERFUNCSTATUSCONTROL, CFGPERFUNCTIONNUMBER, PIPERX0STATUS, PIPERX1STATUS, PIPERX2STATUS, PIPERX3STATUS, PIPERX4STATUS, PIPERX5STATUS, PIPERX6STATUS, PIPERX7STATUS, CFGEXTREADDATA, CFGINTERRUPTMSIINT, CFGINTERRUPTMSIXDATA, CFGMGMTWRITEDATA +, CFGMSGTRANSMITDATA, CFGTPHSTTREADDATA, PIPERX0DATA, PIPERX1DATA, PIPERX2DATA, PIPERX3DATA, PIPERX4DATA, PIPERX5DATA, PIPERX6DATA, PIPERX7DATA, SAXISCCTUSER, CFGINTERRUPTINT, CFGINTERRUPTMSISELECT, CFGMGMTBYTEENABLE, CFGDSDEVICENUMBER, SAXISRQTUSER, CFGVFFLRDONE, PIPEEQFS, PIPEEQLF, CFGDSN, CFGINTERRUPTMSIPENDINGSTATUS +, CFGINTERRUPTMSIXADDRESS, CFGDSBUSNUMBER, CFGDSPORTNUMBER, CFGREVID, PLGEN3PCSRXSYNCDONE, SAXISCCTKEEP, SAXISRQTKEEP, CFGINTERRUPTMSITPHSTTAG); parameter ARI_CAP_ENABLE = "FALSE"; parameter AXISTEN_IF_CC_ALIGNMENT_MODE = "FALSE"; parameter AXISTEN_IF_CC_PARITY_CHK = "TRUE"; @@ -22736,7 +23049,33 @@ module PCIE_3_0 (...); input [8:0] CFGINTERRUPTMSITPHSTTAG; endmodule -module PCIE_3_1 (...); +module PCIE_3_1(CFGCURRENTSPEED, CFGDPASUBSTATECHANGE, CFGERRCOROUT, CFGERRFATALOUT, CFGERRNONFATALOUT, CFGEXTFUNCTIONNUMBER, CFGEXTREADRECEIVED, CFGEXTREGISTERNUMBER, CFGEXTWRITEBYTEENABLE, CFGEXTWRITEDATA, CFGEXTWRITERECEIVED, CFGFCCPLD, CFGFCCPLH, CFGFCNPD, CFGFCNPH, CFGFCPD, CFGFCPH, CFGFLRINPROCESS, CFGFUNCTIONPOWERSTATE, CFGFUNCTIONSTATUS, CFGHOTRESETOUT +, CFGINTERRUPTMSIDATA, CFGINTERRUPTMSIENABLE, CFGINTERRUPTMSIFAIL, CFGINTERRUPTMSIMASKUPDATE, CFGINTERRUPTMSIMMENABLE, CFGINTERRUPTMSISENT, CFGINTERRUPTMSIVFENABLE, CFGINTERRUPTMSIXENABLE, CFGINTERRUPTMSIXFAIL, CFGINTERRUPTMSIXMASK, CFGINTERRUPTMSIXSENT, CFGINTERRUPTMSIXVFENABLE, CFGINTERRUPTMSIXVFMASK, CFGINTERRUPTSENT, CFGLINKPOWERSTATE, CFGLOCALERROR, CFGLTRENABLE, CFGLTSSMSTATE, CFGMAXPAYLOAD, CFGMAXREADREQ, CFGMGMTREADDATA +, CFGMGMTREADWRITEDONE, CFGMSGRECEIVED, CFGMSGRECEIVEDDATA, CFGMSGRECEIVEDTYPE, CFGMSGTRANSMITDONE, CFGNEGOTIATEDWIDTH, CFGOBFFENABLE, CFGPERFUNCSTATUSDATA, CFGPERFUNCTIONUPDATEDONE, CFGPHYLINKDOWN, CFGPHYLINKSTATUS, CFGPLSTATUSCHANGE, CFGPOWERSTATECHANGEINTERRUPT, CFGRCBSTATUS, CFGTPHFUNCTIONNUM, CFGTPHREQUESTERENABLE, CFGTPHSTMODE, CFGTPHSTTADDRESS, CFGTPHSTTREADENABLE, CFGTPHSTTWRITEBYTEVALID, CFGTPHSTTWRITEDATA +, CFGTPHSTTWRITEENABLE, CFGVFFLRINPROCESS, CFGVFPOWERSTATE, CFGVFSTATUS, CFGVFTPHREQUESTERENABLE, CFGVFTPHSTMODE, CONFMCAPDESIGNSWITCH, CONFMCAPEOS, CONFMCAPINUSEBYPCIE, CONFREQREADY, CONFRESPRDATA, CONFRESPVALID, DBGDATAOUT, DBGMCAPCSB, DBGMCAPDATA, DBGMCAPEOS, DBGMCAPERROR, DBGMCAPMODE, DBGMCAPRDATAVALID, DBGMCAPRDWRB, DBGMCAPRESET +, DBGPLDATABLOCKRECEIVEDAFTEREDS, DBGPLGEN3FRAMINGERRORDETECTED, DBGPLGEN3SYNCHEADERERRORDETECTED, DBGPLINFERREDRXELECTRICALIDLE, DRPDO, DRPRDY, LL2LMMASTERTLPSENT0, LL2LMMASTERTLPSENT1, LL2LMMASTERTLPSENTTLPID0, LL2LMMASTERTLPSENTTLPID1, LL2LMMAXISRXTDATA, LL2LMMAXISRXTUSER, LL2LMMAXISRXTVALID, LL2LMSAXISTXTREADY, MAXISCQTDATA, MAXISCQTKEEP, MAXISCQTLAST, MAXISCQTUSER, MAXISCQTVALID, MAXISRCTDATA, MAXISRCTKEEP +, MAXISRCTLAST, MAXISRCTUSER, MAXISRCTVALID, MICOMPLETIONRAMREADADDRESSAL, MICOMPLETIONRAMREADADDRESSAU, MICOMPLETIONRAMREADADDRESSBL, MICOMPLETIONRAMREADADDRESSBU, MICOMPLETIONRAMREADENABLEL, MICOMPLETIONRAMREADENABLEU, MICOMPLETIONRAMWRITEADDRESSAL, MICOMPLETIONRAMWRITEADDRESSAU, MICOMPLETIONRAMWRITEADDRESSBL, MICOMPLETIONRAMWRITEADDRESSBU, MICOMPLETIONRAMWRITEDATAL, MICOMPLETIONRAMWRITEDATAU, MICOMPLETIONRAMWRITEENABLEL, MICOMPLETIONRAMWRITEENABLEU, MIREPLAYRAMADDRESS, MIREPLAYRAMREADENABLE, MIREPLAYRAMWRITEDATA, MIREPLAYRAMWRITEENABLE +, MIREQUESTRAMREADADDRESSA, MIREQUESTRAMREADADDRESSB, MIREQUESTRAMREADENABLE, MIREQUESTRAMWRITEADDRESSA, MIREQUESTRAMWRITEADDRESSB, MIREQUESTRAMWRITEDATA, MIREQUESTRAMWRITEENABLE, PCIECQNPREQCOUNT, PCIEPERST0B, PCIEPERST1B, PCIERQSEQNUM, PCIERQSEQNUMVLD, PCIERQTAG, PCIERQTAGAV, PCIERQTAGVLD, PCIETFCNPDAV, PCIETFCNPHAV, PIPERX0EQCONTROL, PIPERX0EQLPLFFS, PIPERX0EQLPTXPRESET, PIPERX0EQPRESET +, PIPERX0POLARITY, PIPERX1EQCONTROL, PIPERX1EQLPLFFS, PIPERX1EQLPTXPRESET, PIPERX1EQPRESET, PIPERX1POLARITY, PIPERX2EQCONTROL, PIPERX2EQLPLFFS, PIPERX2EQLPTXPRESET, PIPERX2EQPRESET, PIPERX2POLARITY, PIPERX3EQCONTROL, PIPERX3EQLPLFFS, PIPERX3EQLPTXPRESET, PIPERX3EQPRESET, PIPERX3POLARITY, PIPERX4EQCONTROL, PIPERX4EQLPLFFS, PIPERX4EQLPTXPRESET, PIPERX4EQPRESET, PIPERX4POLARITY +, PIPERX5EQCONTROL, PIPERX5EQLPLFFS, PIPERX5EQLPTXPRESET, PIPERX5EQPRESET, PIPERX5POLARITY, PIPERX6EQCONTROL, PIPERX6EQLPLFFS, PIPERX6EQLPTXPRESET, PIPERX6EQPRESET, PIPERX6POLARITY, PIPERX7EQCONTROL, PIPERX7EQLPLFFS, PIPERX7EQLPTXPRESET, PIPERX7EQPRESET, PIPERX7POLARITY, PIPETX0CHARISK, PIPETX0COMPLIANCE, PIPETX0DATA, PIPETX0DATAVALID, PIPETX0DEEMPH, PIPETX0ELECIDLE +, PIPETX0EQCONTROL, PIPETX0EQDEEMPH, PIPETX0EQPRESET, PIPETX0MARGIN, PIPETX0POWERDOWN, PIPETX0RATE, PIPETX0RCVRDET, PIPETX0RESET, PIPETX0STARTBLOCK, PIPETX0SWING, PIPETX0SYNCHEADER, PIPETX1CHARISK, PIPETX1COMPLIANCE, PIPETX1DATA, PIPETX1DATAVALID, PIPETX1DEEMPH, PIPETX1ELECIDLE, PIPETX1EQCONTROL, PIPETX1EQDEEMPH, PIPETX1EQPRESET, PIPETX1MARGIN +, PIPETX1POWERDOWN, PIPETX1RATE, PIPETX1RCVRDET, PIPETX1RESET, PIPETX1STARTBLOCK, PIPETX1SWING, PIPETX1SYNCHEADER, PIPETX2CHARISK, PIPETX2COMPLIANCE, PIPETX2DATA, PIPETX2DATAVALID, PIPETX2DEEMPH, PIPETX2ELECIDLE, PIPETX2EQCONTROL, PIPETX2EQDEEMPH, PIPETX2EQPRESET, PIPETX2MARGIN, PIPETX2POWERDOWN, PIPETX2RATE, PIPETX2RCVRDET, PIPETX2RESET +, PIPETX2STARTBLOCK, PIPETX2SWING, PIPETX2SYNCHEADER, PIPETX3CHARISK, PIPETX3COMPLIANCE, PIPETX3DATA, PIPETX3DATAVALID, PIPETX3DEEMPH, PIPETX3ELECIDLE, PIPETX3EQCONTROL, PIPETX3EQDEEMPH, PIPETX3EQPRESET, PIPETX3MARGIN, PIPETX3POWERDOWN, PIPETX3RATE, PIPETX3RCVRDET, PIPETX3RESET, PIPETX3STARTBLOCK, PIPETX3SWING, PIPETX3SYNCHEADER, PIPETX4CHARISK +, PIPETX4COMPLIANCE, PIPETX4DATA, PIPETX4DATAVALID, PIPETX4DEEMPH, PIPETX4ELECIDLE, PIPETX4EQCONTROL, PIPETX4EQDEEMPH, PIPETX4EQPRESET, PIPETX4MARGIN, PIPETX4POWERDOWN, PIPETX4RATE, PIPETX4RCVRDET, PIPETX4RESET, PIPETX4STARTBLOCK, PIPETX4SWING, PIPETX4SYNCHEADER, PIPETX5CHARISK, PIPETX5COMPLIANCE, PIPETX5DATA, PIPETX5DATAVALID, PIPETX5DEEMPH +, PIPETX5ELECIDLE, PIPETX5EQCONTROL, PIPETX5EQDEEMPH, PIPETX5EQPRESET, PIPETX5MARGIN, PIPETX5POWERDOWN, PIPETX5RATE, PIPETX5RCVRDET, PIPETX5RESET, PIPETX5STARTBLOCK, PIPETX5SWING, PIPETX5SYNCHEADER, PIPETX6CHARISK, PIPETX6COMPLIANCE, PIPETX6DATA, PIPETX6DATAVALID, PIPETX6DEEMPH, PIPETX6ELECIDLE, PIPETX6EQCONTROL, PIPETX6EQDEEMPH, PIPETX6EQPRESET +, PIPETX6MARGIN, PIPETX6POWERDOWN, PIPETX6RATE, PIPETX6RCVRDET, PIPETX6RESET, PIPETX6STARTBLOCK, PIPETX6SWING, PIPETX6SYNCHEADER, PIPETX7CHARISK, PIPETX7COMPLIANCE, PIPETX7DATA, PIPETX7DATAVALID, PIPETX7DEEMPH, PIPETX7ELECIDLE, PIPETX7EQCONTROL, PIPETX7EQDEEMPH, PIPETX7EQPRESET, PIPETX7MARGIN, PIPETX7POWERDOWN, PIPETX7RATE, PIPETX7RCVRDET +, PIPETX7RESET, PIPETX7STARTBLOCK, PIPETX7SWING, PIPETX7SYNCHEADER, PLEQINPROGRESS, PLEQPHASE, SAXISCCTREADY, SAXISRQTREADY, SPAREOUT, CFGCONFIGSPACEENABLE, CFGDEVID, CFGDSBUSNUMBER, CFGDSDEVICENUMBER, CFGDSFUNCTIONNUMBER, CFGDSN, CFGDSPORTNUMBER, CFGERRCORIN, CFGERRUNCORIN, CFGEXTREADDATA, CFGEXTREADDATAVALID, CFGFCSEL +, CFGFLRDONE, CFGHOTRESETIN, CFGINTERRUPTINT, CFGINTERRUPTMSIATTR, CFGINTERRUPTMSIFUNCTIONNUMBER, CFGINTERRUPTMSIINT, CFGINTERRUPTMSIPENDINGSTATUS, CFGINTERRUPTMSIPENDINGSTATUSDATAENABLE, CFGINTERRUPTMSIPENDINGSTATUSFUNCTIONNUM, CFGINTERRUPTMSISELECT, CFGINTERRUPTMSITPHPRESENT, CFGINTERRUPTMSITPHSTTAG, CFGINTERRUPTMSITPHTYPE, CFGINTERRUPTMSIXADDRESS, CFGINTERRUPTMSIXDATA, CFGINTERRUPTMSIXINT, CFGINTERRUPTPENDING, CFGLINKTRAININGENABLE, CFGMGMTADDR, CFGMGMTBYTEENABLE, CFGMGMTREAD +, CFGMGMTTYPE1CFGREGACCESS, CFGMGMTWRITE, CFGMGMTWRITEDATA, CFGMSGTRANSMIT, CFGMSGTRANSMITDATA, CFGMSGTRANSMITTYPE, CFGPERFUNCSTATUSCONTROL, CFGPERFUNCTIONNUMBER, CFGPERFUNCTIONOUTPUTREQUEST, CFGPOWERSTATECHANGEACK, CFGREQPMTRANSITIONL23READY, CFGREVID, CFGSUBSYSID, CFGSUBSYSVENDID, CFGTPHSTTREADDATA, CFGTPHSTTREADDATAVALID, CFGVENDID, CFGVFFLRDONE, CONFMCAPREQUESTBYCONF, CONFREQDATA, CONFREQREGNUM +, CONFREQTYPE, CONFREQVALID, CORECLK, CORECLKMICOMPLETIONRAML, CORECLKMICOMPLETIONRAMU, CORECLKMIREPLAYRAM, CORECLKMIREQUESTRAM, DBGCFGLOCALMGMTREGOVERRIDE, DBGDATASEL, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, LL2LMSAXISTXTUSER, LL2LMSAXISTXTVALID, LL2LMTXTLPID0, LL2LMTXTLPID1, MAXISCQTREADY, MAXISRCTREADY, MCAPCLK +, MCAPPERST0B, MCAPPERST1B, MGMTRESETN, MGMTSTICKYRESETN, MICOMPLETIONRAMREADDATA, MIREPLAYRAMREADDATA, MIREQUESTRAMREADDATA, PCIECQNPREQ, PIPECLK, PIPEEQFS, PIPEEQLF, PIPERESETN, PIPERX0CHARISK, PIPERX0DATA, PIPERX0DATAVALID, PIPERX0ELECIDLE, PIPERX0EQDONE, PIPERX0EQLPADAPTDONE, PIPERX0EQLPLFFSSEL, PIPERX0EQLPNEWTXCOEFFORPRESET, PIPERX0PHYSTATUS +, PIPERX0STARTBLOCK, PIPERX0STATUS, PIPERX0SYNCHEADER, PIPERX0VALID, PIPERX1CHARISK, PIPERX1DATA, PIPERX1DATAVALID, PIPERX1ELECIDLE, PIPERX1EQDONE, PIPERX1EQLPADAPTDONE, PIPERX1EQLPLFFSSEL, PIPERX1EQLPNEWTXCOEFFORPRESET, PIPERX1PHYSTATUS, PIPERX1STARTBLOCK, PIPERX1STATUS, PIPERX1SYNCHEADER, PIPERX1VALID, PIPERX2CHARISK, PIPERX2DATA, PIPERX2DATAVALID, PIPERX2ELECIDLE +, PIPERX2EQDONE, PIPERX2EQLPADAPTDONE, PIPERX2EQLPLFFSSEL, PIPERX2EQLPNEWTXCOEFFORPRESET, PIPERX2PHYSTATUS, PIPERX2STARTBLOCK, PIPERX2STATUS, PIPERX2SYNCHEADER, PIPERX2VALID, PIPERX3CHARISK, PIPERX3DATA, PIPERX3DATAVALID, PIPERX3ELECIDLE, PIPERX3EQDONE, PIPERX3EQLPADAPTDONE, PIPERX3EQLPLFFSSEL, PIPERX3EQLPNEWTXCOEFFORPRESET, PIPERX3PHYSTATUS, PIPERX3STARTBLOCK, PIPERX3STATUS, PIPERX3SYNCHEADER +, PIPERX3VALID, PIPERX4CHARISK, PIPERX4DATA, PIPERX4DATAVALID, PIPERX4ELECIDLE, PIPERX4EQDONE, PIPERX4EQLPADAPTDONE, PIPERX4EQLPLFFSSEL, PIPERX4EQLPNEWTXCOEFFORPRESET, PIPERX4PHYSTATUS, PIPERX4STARTBLOCK, PIPERX4STATUS, PIPERX4SYNCHEADER, PIPERX4VALID, PIPERX5CHARISK, PIPERX5DATA, PIPERX5DATAVALID, PIPERX5ELECIDLE, PIPERX5EQDONE, PIPERX5EQLPADAPTDONE, PIPERX5EQLPLFFSSEL +, PIPERX5EQLPNEWTXCOEFFORPRESET, PIPERX5PHYSTATUS, PIPERX5STARTBLOCK, PIPERX5STATUS, PIPERX5SYNCHEADER, PIPERX5VALID, PIPERX6CHARISK, PIPERX6DATA, PIPERX6DATAVALID, PIPERX6ELECIDLE, PIPERX6EQDONE, PIPERX6EQLPADAPTDONE, PIPERX6EQLPLFFSSEL, PIPERX6EQLPNEWTXCOEFFORPRESET, PIPERX6PHYSTATUS, PIPERX6STARTBLOCK, PIPERX6STATUS, PIPERX6SYNCHEADER, PIPERX6VALID, PIPERX7CHARISK, PIPERX7DATA +, PIPERX7DATAVALID, PIPERX7ELECIDLE, PIPERX7EQDONE, PIPERX7EQLPADAPTDONE, PIPERX7EQLPLFFSSEL, PIPERX7EQLPNEWTXCOEFFORPRESET, PIPERX7PHYSTATUS, PIPERX7STARTBLOCK, PIPERX7STATUS, PIPERX7SYNCHEADER, PIPERX7VALID, PIPETX0EQCOEFF, PIPETX0EQDONE, PIPETX1EQCOEFF, PIPETX1EQDONE, PIPETX2EQCOEFF, PIPETX2EQDONE, PIPETX3EQCOEFF, PIPETX3EQDONE, PIPETX4EQCOEFF, PIPETX4EQDONE +, PIPETX5EQCOEFF, PIPETX5EQDONE, PIPETX6EQCOEFF, PIPETX6EQDONE, PIPETX7EQCOEFF, PIPETX7EQDONE, PLEQRESETEIEOSCOUNT, PLGEN2UPSTREAMPREFERDEEMPH, RESETN, SAXISCCTDATA, SAXISCCTKEEP, SAXISCCTLAST, SAXISCCTUSER, SAXISCCTVALID, SAXISRQTDATA, SAXISRQTKEEP, SAXISRQTLAST, SAXISRQTUSER, SAXISRQTVALID, SPAREIN, USERCLK +); parameter ARI_CAP_ENABLE = "FALSE"; parameter AXISTEN_IF_CC_ALIGNMENT_MODE = "FALSE"; parameter AXISTEN_IF_CC_PARITY_CHK = "TRUE"; @@ -24004,7 +24343,40 @@ module PCIE_3_1 (...); input USERCLK; endmodule -module PCIE40E4 (...); +module PCIE40E4(AXIUSEROUT, CFGBUSNUMBER, CFGCURRENTSPEED, CFGERRCOROUT, CFGERRFATALOUT, CFGERRNONFATALOUT, CFGEXTFUNCTIONNUMBER, CFGEXTREADRECEIVED, CFGEXTREGISTERNUMBER, CFGEXTWRITEBYTEENABLE, CFGEXTWRITEDATA, CFGEXTWRITERECEIVED, CFGFCCPLD, CFGFCCPLH, CFGFCNPD, CFGFCNPH, CFGFCPD, CFGFCPH, CFGFLRINPROCESS, CFGFUNCTIONPOWERSTATE, CFGFUNCTIONSTATUS +, CFGHOTRESETOUT, CFGINTERRUPTMSIDATA, CFGINTERRUPTMSIENABLE, CFGINTERRUPTMSIFAIL, CFGINTERRUPTMSIMASKUPDATE, CFGINTERRUPTMSIMMENABLE, CFGINTERRUPTMSISENT, CFGINTERRUPTMSIXENABLE, CFGINTERRUPTMSIXMASK, CFGINTERRUPTMSIXVECPENDINGSTATUS, CFGINTERRUPTSENT, CFGLINKPOWERSTATE, CFGLOCALERROROUT, CFGLOCALERRORVALID, CFGLTRENABLE, CFGLTSSMSTATE, CFGMAXPAYLOAD, CFGMAXREADREQ, CFGMGMTREADDATA, CFGMGMTREADWRITEDONE, CFGMSGRECEIVED +, CFGMSGRECEIVEDDATA, CFGMSGRECEIVEDTYPE, CFGMSGTRANSMITDONE, CFGMSIXRAMADDRESS, CFGMSIXRAMREADENABLE, CFGMSIXRAMWRITEBYTEENABLE, CFGMSIXRAMWRITEDATA, CFGNEGOTIATEDWIDTH, CFGOBFFENABLE, CFGPHYLINKDOWN, CFGPHYLINKSTATUS, CFGPLSTATUSCHANGE, CFGPOWERSTATECHANGEINTERRUPT, CFGRCBSTATUS, CFGRXPMSTATE, CFGTPHRAMADDRESS, CFGTPHRAMREADENABLE, CFGTPHRAMWRITEBYTEENABLE, CFGTPHRAMWRITEDATA, CFGTPHREQUESTERENABLE, CFGTPHSTMODE +, CFGTXPMSTATE, CONFMCAPDESIGNSWITCH, CONFMCAPEOS, CONFMCAPINUSEBYPCIE, CONFREQREADY, CONFRESPRDATA, CONFRESPVALID, DBGCTRL0OUT, DBGCTRL1OUT, DBGDATA0OUT, DBGDATA1OUT, DRPDO, DRPRDY, MAXISCQTDATA, MAXISCQTKEEP, MAXISCQTLAST, MAXISCQTUSER, MAXISCQTVALID, MAXISRCTDATA, MAXISRCTKEEP, MAXISRCTLAST +, MAXISRCTUSER, MAXISRCTVALID, MIREPLAYRAMADDRESS0, MIREPLAYRAMADDRESS1, MIREPLAYRAMREADENABLE0, MIREPLAYRAMREADENABLE1, MIREPLAYRAMWRITEDATA0, MIREPLAYRAMWRITEDATA1, MIREPLAYRAMWRITEENABLE0, MIREPLAYRAMWRITEENABLE1, MIRXCOMPLETIONRAMREADADDRESS0, MIRXCOMPLETIONRAMREADADDRESS1, MIRXCOMPLETIONRAMREADENABLE0, MIRXCOMPLETIONRAMREADENABLE1, MIRXCOMPLETIONRAMWRITEADDRESS0, MIRXCOMPLETIONRAMWRITEADDRESS1, MIRXCOMPLETIONRAMWRITEDATA0, MIRXCOMPLETIONRAMWRITEDATA1, MIRXCOMPLETIONRAMWRITEENABLE0, MIRXCOMPLETIONRAMWRITEENABLE1, MIRXPOSTEDREQUESTRAMREADADDRESS0 +, MIRXPOSTEDREQUESTRAMREADADDRESS1, MIRXPOSTEDREQUESTRAMREADENABLE0, MIRXPOSTEDREQUESTRAMREADENABLE1, MIRXPOSTEDREQUESTRAMWRITEADDRESS0, MIRXPOSTEDREQUESTRAMWRITEADDRESS1, MIRXPOSTEDREQUESTRAMWRITEDATA0, MIRXPOSTEDREQUESTRAMWRITEDATA1, MIRXPOSTEDREQUESTRAMWRITEENABLE0, MIRXPOSTEDREQUESTRAMWRITEENABLE1, PCIECQNPREQCOUNT, PCIEPERST0B, PCIEPERST1B, PCIERQSEQNUM0, PCIERQSEQNUM1, PCIERQSEQNUMVLD0, PCIERQSEQNUMVLD1, PCIERQTAG0, PCIERQTAG1, PCIERQTAGAV, PCIERQTAGVLD0, PCIERQTAGVLD1 +, PCIETFCNPDAV, PCIETFCNPHAV, PIPERX00EQCONTROL, PIPERX00POLARITY, PIPERX01EQCONTROL, PIPERX01POLARITY, PIPERX02EQCONTROL, PIPERX02POLARITY, PIPERX03EQCONTROL, PIPERX03POLARITY, PIPERX04EQCONTROL, PIPERX04POLARITY, PIPERX05EQCONTROL, PIPERX05POLARITY, PIPERX06EQCONTROL, PIPERX06POLARITY, PIPERX07EQCONTROL, PIPERX07POLARITY, PIPERX08EQCONTROL, PIPERX08POLARITY, PIPERX09EQCONTROL +, PIPERX09POLARITY, PIPERX10EQCONTROL, PIPERX10POLARITY, PIPERX11EQCONTROL, PIPERX11POLARITY, PIPERX12EQCONTROL, PIPERX12POLARITY, PIPERX13EQCONTROL, PIPERX13POLARITY, PIPERX14EQCONTROL, PIPERX14POLARITY, PIPERX15EQCONTROL, PIPERX15POLARITY, PIPERXEQLPLFFS, PIPERXEQLPTXPRESET, PIPETX00CHARISK, PIPETX00COMPLIANCE, PIPETX00DATA, PIPETX00DATAVALID, PIPETX00ELECIDLE, PIPETX00EQCONTROL +, PIPETX00EQDEEMPH, PIPETX00POWERDOWN, PIPETX00STARTBLOCK, PIPETX00SYNCHEADER, PIPETX01CHARISK, PIPETX01COMPLIANCE, PIPETX01DATA, PIPETX01DATAVALID, PIPETX01ELECIDLE, PIPETX01EQCONTROL, PIPETX01EQDEEMPH, PIPETX01POWERDOWN, PIPETX01STARTBLOCK, PIPETX01SYNCHEADER, PIPETX02CHARISK, PIPETX02COMPLIANCE, PIPETX02DATA, PIPETX02DATAVALID, PIPETX02ELECIDLE, PIPETX02EQCONTROL, PIPETX02EQDEEMPH +, PIPETX02POWERDOWN, PIPETX02STARTBLOCK, PIPETX02SYNCHEADER, PIPETX03CHARISK, PIPETX03COMPLIANCE, PIPETX03DATA, PIPETX03DATAVALID, PIPETX03ELECIDLE, PIPETX03EQCONTROL, PIPETX03EQDEEMPH, PIPETX03POWERDOWN, PIPETX03STARTBLOCK, PIPETX03SYNCHEADER, PIPETX04CHARISK, PIPETX04COMPLIANCE, PIPETX04DATA, PIPETX04DATAVALID, PIPETX04ELECIDLE, PIPETX04EQCONTROL, PIPETX04EQDEEMPH, PIPETX04POWERDOWN +, PIPETX04STARTBLOCK, PIPETX04SYNCHEADER, PIPETX05CHARISK, PIPETX05COMPLIANCE, PIPETX05DATA, PIPETX05DATAVALID, PIPETX05ELECIDLE, PIPETX05EQCONTROL, PIPETX05EQDEEMPH, PIPETX05POWERDOWN, PIPETX05STARTBLOCK, PIPETX05SYNCHEADER, PIPETX06CHARISK, PIPETX06COMPLIANCE, PIPETX06DATA, PIPETX06DATAVALID, PIPETX06ELECIDLE, PIPETX06EQCONTROL, PIPETX06EQDEEMPH, PIPETX06POWERDOWN, PIPETX06STARTBLOCK +, PIPETX06SYNCHEADER, PIPETX07CHARISK, PIPETX07COMPLIANCE, PIPETX07DATA, PIPETX07DATAVALID, PIPETX07ELECIDLE, PIPETX07EQCONTROL, PIPETX07EQDEEMPH, PIPETX07POWERDOWN, PIPETX07STARTBLOCK, PIPETX07SYNCHEADER, PIPETX08CHARISK, PIPETX08COMPLIANCE, PIPETX08DATA, PIPETX08DATAVALID, PIPETX08ELECIDLE, PIPETX08EQCONTROL, PIPETX08EQDEEMPH, PIPETX08POWERDOWN, PIPETX08STARTBLOCK, PIPETX08SYNCHEADER +, PIPETX09CHARISK, PIPETX09COMPLIANCE, PIPETX09DATA, PIPETX09DATAVALID, PIPETX09ELECIDLE, PIPETX09EQCONTROL, PIPETX09EQDEEMPH, PIPETX09POWERDOWN, PIPETX09STARTBLOCK, PIPETX09SYNCHEADER, PIPETX10CHARISK, PIPETX10COMPLIANCE, PIPETX10DATA, PIPETX10DATAVALID, PIPETX10ELECIDLE, PIPETX10EQCONTROL, PIPETX10EQDEEMPH, PIPETX10POWERDOWN, PIPETX10STARTBLOCK, PIPETX10SYNCHEADER, PIPETX11CHARISK +, PIPETX11COMPLIANCE, PIPETX11DATA, PIPETX11DATAVALID, PIPETX11ELECIDLE, PIPETX11EQCONTROL, PIPETX11EQDEEMPH, PIPETX11POWERDOWN, PIPETX11STARTBLOCK, PIPETX11SYNCHEADER, PIPETX12CHARISK, PIPETX12COMPLIANCE, PIPETX12DATA, PIPETX12DATAVALID, PIPETX12ELECIDLE, PIPETX12EQCONTROL, PIPETX12EQDEEMPH, PIPETX12POWERDOWN, PIPETX12STARTBLOCK, PIPETX12SYNCHEADER, PIPETX13CHARISK, PIPETX13COMPLIANCE +, PIPETX13DATA, PIPETX13DATAVALID, PIPETX13ELECIDLE, PIPETX13EQCONTROL, PIPETX13EQDEEMPH, PIPETX13POWERDOWN, PIPETX13STARTBLOCK, PIPETX13SYNCHEADER, PIPETX14CHARISK, PIPETX14COMPLIANCE, PIPETX14DATA, PIPETX14DATAVALID, PIPETX14ELECIDLE, PIPETX14EQCONTROL, PIPETX14EQDEEMPH, PIPETX14POWERDOWN, PIPETX14STARTBLOCK, PIPETX14SYNCHEADER, PIPETX15CHARISK, PIPETX15COMPLIANCE, PIPETX15DATA +, PIPETX15DATAVALID, PIPETX15ELECIDLE, PIPETX15EQCONTROL, PIPETX15EQDEEMPH, PIPETX15POWERDOWN, PIPETX15STARTBLOCK, PIPETX15SYNCHEADER, PIPETXDEEMPH, PIPETXMARGIN, PIPETXRATE, PIPETXRCVRDET, PIPETXRESET, PIPETXSWING, PLEQINPROGRESS, PLEQPHASE, PLGEN34EQMISMATCH, SAXISCCTREADY, SAXISRQTREADY, USERSPAREOUT, AXIUSERIN, CFGCONFIGSPACEENABLE +, CFGDEVIDPF0, CFGDEVIDPF1, CFGDEVIDPF2, CFGDEVIDPF3, CFGDSBUSNUMBER, CFGDSDEVICENUMBER, CFGDSFUNCTIONNUMBER, CFGDSN, CFGDSPORTNUMBER, CFGERRCORIN, CFGERRUNCORIN, CFGEXTREADDATA, CFGEXTREADDATAVALID, CFGFCSEL, CFGFLRDONE, CFGHOTRESETIN, CFGINTERRUPTINT, CFGINTERRUPTMSIATTR, CFGINTERRUPTMSIFUNCTIONNUMBER, CFGINTERRUPTMSIINT, CFGINTERRUPTMSIPENDINGSTATUS +, CFGINTERRUPTMSIPENDINGSTATUSDATAENABLE, CFGINTERRUPTMSIPENDINGSTATUSFUNCTIONNUM, CFGINTERRUPTMSISELECT, CFGINTERRUPTMSITPHPRESENT, CFGINTERRUPTMSITPHSTTAG, CFGINTERRUPTMSITPHTYPE, CFGINTERRUPTMSIXADDRESS, CFGINTERRUPTMSIXDATA, CFGINTERRUPTMSIXINT, CFGINTERRUPTMSIXVECPENDING, CFGINTERRUPTPENDING, CFGLINKTRAININGENABLE, CFGMGMTADDR, CFGMGMTBYTEENABLE, CFGMGMTDEBUGACCESS, CFGMGMTFUNCTIONNUMBER, CFGMGMTREAD, CFGMGMTWRITE, CFGMGMTWRITEDATA, CFGMSGTRANSMIT, CFGMSGTRANSMITDATA +, CFGMSGTRANSMITTYPE, CFGMSIXRAMREADDATA, CFGPMASPML1ENTRYREJECT, CFGPMASPMTXL0SENTRYDISABLE, CFGPOWERSTATECHANGEACK, CFGREQPMTRANSITIONL23READY, CFGREVIDPF0, CFGREVIDPF1, CFGREVIDPF2, CFGREVIDPF3, CFGSUBSYSIDPF0, CFGSUBSYSIDPF1, CFGSUBSYSIDPF2, CFGSUBSYSIDPF3, CFGSUBSYSVENDID, CFGTPHRAMREADDATA, CFGVENDID, CFGVFFLRDONE, CFGVFFLRFUNCNUM, CONFMCAPREQUESTBYCONF, CONFREQDATA +, CONFREQREGNUM, CONFREQTYPE, CONFREQVALID, CORECLK, CORECLKMIREPLAYRAM0, CORECLKMIREPLAYRAM1, CORECLKMIRXCOMPLETIONRAM0, CORECLKMIRXCOMPLETIONRAM1, CORECLKMIRXPOSTEDREQUESTRAM0, CORECLKMIRXPOSTEDREQUESTRAM1, DBGSEL0, DBGSEL1, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, MAXISCQTREADY, MAXISRCTREADY, MCAPCLK, MCAPPERST0B +, MCAPPERST1B, MGMTRESETN, MGMTSTICKYRESETN, MIREPLAYRAMERRCOR, MIREPLAYRAMERRUNCOR, MIREPLAYRAMREADDATA0, MIREPLAYRAMREADDATA1, MIRXCOMPLETIONRAMERRCOR, MIRXCOMPLETIONRAMERRUNCOR, MIRXCOMPLETIONRAMREADDATA0, MIRXCOMPLETIONRAMREADDATA1, MIRXPOSTEDREQUESTRAMERRCOR, MIRXPOSTEDREQUESTRAMERRUNCOR, MIRXPOSTEDREQUESTRAMREADDATA0, MIRXPOSTEDREQUESTRAMREADDATA1, PCIECOMPLDELIVERED, PCIECOMPLDELIVEREDTAG0, PCIECOMPLDELIVEREDTAG1, PCIECQNPREQ, PCIECQNPUSERCREDITRCVD, PCIECQPIPELINEEMPTY +, PCIEPOSTEDREQDELIVERED, PIPECLK, PIPECLKEN, PIPEEQFS, PIPEEQLF, PIPERESETN, PIPERX00CHARISK, PIPERX00DATA, PIPERX00DATAVALID, PIPERX00ELECIDLE, PIPERX00EQDONE, PIPERX00EQLPADAPTDONE, PIPERX00EQLPLFFSSEL, PIPERX00EQLPNEWTXCOEFFORPRESET, PIPERX00PHYSTATUS, PIPERX00STARTBLOCK, PIPERX00STATUS, PIPERX00SYNCHEADER, PIPERX00VALID, PIPERX01CHARISK, PIPERX01DATA +, PIPERX01DATAVALID, PIPERX01ELECIDLE, PIPERX01EQDONE, PIPERX01EQLPADAPTDONE, PIPERX01EQLPLFFSSEL, PIPERX01EQLPNEWTXCOEFFORPRESET, PIPERX01PHYSTATUS, PIPERX01STARTBLOCK, PIPERX01STATUS, PIPERX01SYNCHEADER, PIPERX01VALID, PIPERX02CHARISK, PIPERX02DATA, PIPERX02DATAVALID, PIPERX02ELECIDLE, PIPERX02EQDONE, PIPERX02EQLPADAPTDONE, PIPERX02EQLPLFFSSEL, PIPERX02EQLPNEWTXCOEFFORPRESET, PIPERX02PHYSTATUS, PIPERX02STARTBLOCK +, PIPERX02STATUS, PIPERX02SYNCHEADER, PIPERX02VALID, PIPERX03CHARISK, PIPERX03DATA, PIPERX03DATAVALID, PIPERX03ELECIDLE, PIPERX03EQDONE, PIPERX03EQLPADAPTDONE, PIPERX03EQLPLFFSSEL, PIPERX03EQLPNEWTXCOEFFORPRESET, PIPERX03PHYSTATUS, PIPERX03STARTBLOCK, PIPERX03STATUS, PIPERX03SYNCHEADER, PIPERX03VALID, PIPERX04CHARISK, PIPERX04DATA, PIPERX04DATAVALID, PIPERX04ELECIDLE, PIPERX04EQDONE +, PIPERX04EQLPADAPTDONE, PIPERX04EQLPLFFSSEL, PIPERX04EQLPNEWTXCOEFFORPRESET, PIPERX04PHYSTATUS, PIPERX04STARTBLOCK, PIPERX04STATUS, PIPERX04SYNCHEADER, PIPERX04VALID, PIPERX05CHARISK, PIPERX05DATA, PIPERX05DATAVALID, PIPERX05ELECIDLE, PIPERX05EQDONE, PIPERX05EQLPADAPTDONE, PIPERX05EQLPLFFSSEL, PIPERX05EQLPNEWTXCOEFFORPRESET, PIPERX05PHYSTATUS, PIPERX05STARTBLOCK, PIPERX05STATUS, PIPERX05SYNCHEADER, PIPERX05VALID +, PIPERX06CHARISK, PIPERX06DATA, PIPERX06DATAVALID, PIPERX06ELECIDLE, PIPERX06EQDONE, PIPERX06EQLPADAPTDONE, PIPERX06EQLPLFFSSEL, PIPERX06EQLPNEWTXCOEFFORPRESET, PIPERX06PHYSTATUS, PIPERX06STARTBLOCK, PIPERX06STATUS, PIPERX06SYNCHEADER, PIPERX06VALID, PIPERX07CHARISK, PIPERX07DATA, PIPERX07DATAVALID, PIPERX07ELECIDLE, PIPERX07EQDONE, PIPERX07EQLPADAPTDONE, PIPERX07EQLPLFFSSEL, PIPERX07EQLPNEWTXCOEFFORPRESET +, PIPERX07PHYSTATUS, PIPERX07STARTBLOCK, PIPERX07STATUS, PIPERX07SYNCHEADER, PIPERX07VALID, PIPERX08CHARISK, PIPERX08DATA, PIPERX08DATAVALID, PIPERX08ELECIDLE, PIPERX08EQDONE, PIPERX08EQLPADAPTDONE, PIPERX08EQLPLFFSSEL, PIPERX08EQLPNEWTXCOEFFORPRESET, PIPERX08PHYSTATUS, PIPERX08STARTBLOCK, PIPERX08STATUS, PIPERX08SYNCHEADER, PIPERX08VALID, PIPERX09CHARISK, PIPERX09DATA, PIPERX09DATAVALID +, PIPERX09ELECIDLE, PIPERX09EQDONE, PIPERX09EQLPADAPTDONE, PIPERX09EQLPLFFSSEL, PIPERX09EQLPNEWTXCOEFFORPRESET, PIPERX09PHYSTATUS, PIPERX09STARTBLOCK, PIPERX09STATUS, PIPERX09SYNCHEADER, PIPERX09VALID, PIPERX10CHARISK, PIPERX10DATA, PIPERX10DATAVALID, PIPERX10ELECIDLE, PIPERX10EQDONE, PIPERX10EQLPADAPTDONE, PIPERX10EQLPLFFSSEL, PIPERX10EQLPNEWTXCOEFFORPRESET, PIPERX10PHYSTATUS, PIPERX10STARTBLOCK, PIPERX10STATUS +, PIPERX10SYNCHEADER, PIPERX10VALID, PIPERX11CHARISK, PIPERX11DATA, PIPERX11DATAVALID, PIPERX11ELECIDLE, PIPERX11EQDONE, PIPERX11EQLPADAPTDONE, PIPERX11EQLPLFFSSEL, PIPERX11EQLPNEWTXCOEFFORPRESET, PIPERX11PHYSTATUS, PIPERX11STARTBLOCK, PIPERX11STATUS, PIPERX11SYNCHEADER, PIPERX11VALID, PIPERX12CHARISK, PIPERX12DATA, PIPERX12DATAVALID, PIPERX12ELECIDLE, PIPERX12EQDONE, PIPERX12EQLPADAPTDONE +, PIPERX12EQLPLFFSSEL, PIPERX12EQLPNEWTXCOEFFORPRESET, PIPERX12PHYSTATUS, PIPERX12STARTBLOCK, PIPERX12STATUS, PIPERX12SYNCHEADER, PIPERX12VALID, PIPERX13CHARISK, PIPERX13DATA, PIPERX13DATAVALID, PIPERX13ELECIDLE, PIPERX13EQDONE, PIPERX13EQLPADAPTDONE, PIPERX13EQLPLFFSSEL, PIPERX13EQLPNEWTXCOEFFORPRESET, PIPERX13PHYSTATUS, PIPERX13STARTBLOCK, PIPERX13STATUS, PIPERX13SYNCHEADER, PIPERX13VALID, PIPERX14CHARISK +, PIPERX14DATA, PIPERX14DATAVALID, PIPERX14ELECIDLE, PIPERX14EQDONE, PIPERX14EQLPADAPTDONE, PIPERX14EQLPLFFSSEL, PIPERX14EQLPNEWTXCOEFFORPRESET, PIPERX14PHYSTATUS, PIPERX14STARTBLOCK, PIPERX14STATUS, PIPERX14SYNCHEADER, PIPERX14VALID, PIPERX15CHARISK, PIPERX15DATA, PIPERX15DATAVALID, PIPERX15ELECIDLE, PIPERX15EQDONE, PIPERX15EQLPADAPTDONE, PIPERX15EQLPLFFSSEL, PIPERX15EQLPNEWTXCOEFFORPRESET, PIPERX15PHYSTATUS +, PIPERX15STARTBLOCK, PIPERX15STATUS, PIPERX15SYNCHEADER, PIPERX15VALID, PIPETX00EQCOEFF, PIPETX00EQDONE, PIPETX01EQCOEFF, PIPETX01EQDONE, PIPETX02EQCOEFF, PIPETX02EQDONE, PIPETX03EQCOEFF, PIPETX03EQDONE, PIPETX04EQCOEFF, PIPETX04EQDONE, PIPETX05EQCOEFF, PIPETX05EQDONE, PIPETX06EQCOEFF, PIPETX06EQDONE, PIPETX07EQCOEFF, PIPETX07EQDONE, PIPETX08EQCOEFF +, PIPETX08EQDONE, PIPETX09EQCOEFF, PIPETX09EQDONE, PIPETX10EQCOEFF, PIPETX10EQDONE, PIPETX11EQCOEFF, PIPETX11EQDONE, PIPETX12EQCOEFF, PIPETX12EQDONE, PIPETX13EQCOEFF, PIPETX13EQDONE, PIPETX14EQCOEFF, PIPETX14EQDONE, PIPETX15EQCOEFF, PIPETX15EQDONE, PLEQRESETEIEOSCOUNT, PLGEN2UPSTREAMPREFERDEEMPH, PLGEN34REDOEQSPEED, PLGEN34REDOEQUALIZATION, RESETN, SAXISCCTDATA +, SAXISCCTKEEP, SAXISCCTLAST, SAXISCCTUSER, SAXISCCTVALID, SAXISRQTDATA, SAXISRQTKEEP, SAXISRQTLAST, SAXISRQTUSER, SAXISRQTVALID, USERCLK, USERCLK2, USERCLKEN, USERSPAREIN); parameter ARI_CAP_ENABLE = "FALSE"; parameter AUTO_FLR_RESPONSE = "FALSE"; parameter [1:0] AXISTEN_IF_CC_ALIGNMENT_MODE = 2'h0; @@ -25233,7 +25605,41 @@ module PCIE40E4 (...); input [31:0] USERSPAREIN; endmodule -module PCIE4CE4 (...); +module PCIE4CE4(AXIUSEROUT, CCIXTXCREDIT, CFGBUSNUMBER, CFGCURRENTSPEED, CFGERRCOROUT, CFGERRFATALOUT, CFGERRNONFATALOUT, CFGEXTFUNCTIONNUMBER, CFGEXTREADRECEIVED, CFGEXTREGISTERNUMBER, CFGEXTWRITEBYTEENABLE, CFGEXTWRITEDATA, CFGEXTWRITERECEIVED, CFGFCCPLD, CFGFCCPLH, CFGFCNPD, CFGFCNPH, CFGFCPD, CFGFCPH, CFGFLRINPROCESS, CFGFUNCTIONPOWERSTATE +, CFGFUNCTIONSTATUS, CFGHOTRESETOUT, CFGINTERRUPTMSIDATA, CFGINTERRUPTMSIENABLE, CFGINTERRUPTMSIFAIL, CFGINTERRUPTMSIMASKUPDATE, CFGINTERRUPTMSIMMENABLE, CFGINTERRUPTMSISENT, CFGINTERRUPTMSIXENABLE, CFGINTERRUPTMSIXMASK, CFGINTERRUPTMSIXVECPENDINGSTATUS, CFGINTERRUPTSENT, CFGLINKPOWERSTATE, CFGLOCALERROROUT, CFGLOCALERRORVALID, CFGLTRENABLE, CFGLTSSMSTATE, CFGMAXPAYLOAD, CFGMAXREADREQ, CFGMGMTREADDATA, CFGMGMTREADWRITEDONE +, CFGMSGRECEIVED, CFGMSGRECEIVEDDATA, CFGMSGRECEIVEDTYPE, CFGMSGTRANSMITDONE, CFGMSIXRAMADDRESS, CFGMSIXRAMREADENABLE, CFGMSIXRAMWRITEBYTEENABLE, CFGMSIXRAMWRITEDATA, CFGNEGOTIATEDWIDTH, CFGOBFFENABLE, CFGPHYLINKDOWN, CFGPHYLINKSTATUS, CFGPLSTATUSCHANGE, CFGPOWERSTATECHANGEINTERRUPT, CFGRCBSTATUS, CFGRXPMSTATE, CFGTPHRAMADDRESS, CFGTPHRAMREADENABLE, CFGTPHRAMWRITEBYTEENABLE, CFGTPHRAMWRITEDATA, CFGTPHREQUESTERENABLE +, CFGTPHSTMODE, CFGTXPMSTATE, CFGVC1ENABLE, CFGVC1NEGOTIATIONPENDING, CONFMCAPDESIGNSWITCH, CONFMCAPEOS, CONFMCAPINUSEBYPCIE, CONFREQREADY, CONFRESPRDATA, CONFRESPVALID, DBGCCIXOUT, DBGCTRL0OUT, DBGCTRL1OUT, DBGDATA0OUT, DBGDATA1OUT, DRPDO, DRPRDY, MAXISCCIXRXTUSER, MAXISCCIXRXTVALID, MAXISCQTDATA, MAXISCQTKEEP +, MAXISCQTLAST, MAXISCQTUSER, MAXISCQTVALID, MAXISRCTDATA, MAXISRCTKEEP, MAXISRCTLAST, MAXISRCTUSER, MAXISRCTVALID, MIREPLAYRAMADDRESS0, MIREPLAYRAMADDRESS1, MIREPLAYRAMREADENABLE0, MIREPLAYRAMREADENABLE1, MIREPLAYRAMWRITEDATA0, MIREPLAYRAMWRITEDATA1, MIREPLAYRAMWRITEENABLE0, MIREPLAYRAMWRITEENABLE1, MIRXCOMPLETIONRAMREADADDRESS0, MIRXCOMPLETIONRAMREADADDRESS1, MIRXCOMPLETIONRAMREADENABLE0, MIRXCOMPLETIONRAMREADENABLE1, MIRXCOMPLETIONRAMWRITEADDRESS0 +, MIRXCOMPLETIONRAMWRITEADDRESS1, MIRXCOMPLETIONRAMWRITEDATA0, MIRXCOMPLETIONRAMWRITEDATA1, MIRXCOMPLETIONRAMWRITEENABLE0, MIRXCOMPLETIONRAMWRITEENABLE1, MIRXPOSTEDREQUESTRAMREADADDRESS0, MIRXPOSTEDREQUESTRAMREADADDRESS1, MIRXPOSTEDREQUESTRAMREADENABLE0, MIRXPOSTEDREQUESTRAMREADENABLE1, MIRXPOSTEDREQUESTRAMWRITEADDRESS0, MIRXPOSTEDREQUESTRAMWRITEADDRESS1, MIRXPOSTEDREQUESTRAMWRITEDATA0, MIRXPOSTEDREQUESTRAMWRITEDATA1, MIRXPOSTEDREQUESTRAMWRITEENABLE0, MIRXPOSTEDREQUESTRAMWRITEENABLE1, PCIECQNPREQCOUNT, PCIEPERST0B, PCIEPERST1B, PCIERQSEQNUM0, PCIERQSEQNUM1, PCIERQSEQNUMVLD0 +, PCIERQSEQNUMVLD1, PCIERQTAG0, PCIERQTAG1, PCIERQTAGAV, PCIERQTAGVLD0, PCIERQTAGVLD1, PCIETFCNPDAV, PCIETFCNPHAV, PIPERX00EQCONTROL, PIPERX00POLARITY, PIPERX01EQCONTROL, PIPERX01POLARITY, PIPERX02EQCONTROL, PIPERX02POLARITY, PIPERX03EQCONTROL, PIPERX03POLARITY, PIPERX04EQCONTROL, PIPERX04POLARITY, PIPERX05EQCONTROL, PIPERX05POLARITY, PIPERX06EQCONTROL +, PIPERX06POLARITY, PIPERX07EQCONTROL, PIPERX07POLARITY, PIPERX08EQCONTROL, PIPERX08POLARITY, PIPERX09EQCONTROL, PIPERX09POLARITY, PIPERX10EQCONTROL, PIPERX10POLARITY, PIPERX11EQCONTROL, PIPERX11POLARITY, PIPERX12EQCONTROL, PIPERX12POLARITY, PIPERX13EQCONTROL, PIPERX13POLARITY, PIPERX14EQCONTROL, PIPERX14POLARITY, PIPERX15EQCONTROL, PIPERX15POLARITY, PIPERXEQLPLFFS, PIPERXEQLPTXPRESET +, PIPETX00CHARISK, PIPETX00COMPLIANCE, PIPETX00DATA, PIPETX00DATAVALID, PIPETX00ELECIDLE, PIPETX00EQCONTROL, PIPETX00EQDEEMPH, PIPETX00POWERDOWN, PIPETX00STARTBLOCK, PIPETX00SYNCHEADER, PIPETX01CHARISK, PIPETX01COMPLIANCE, PIPETX01DATA, PIPETX01DATAVALID, PIPETX01ELECIDLE, PIPETX01EQCONTROL, PIPETX01EQDEEMPH, PIPETX01POWERDOWN, PIPETX01STARTBLOCK, PIPETX01SYNCHEADER, PIPETX02CHARISK +, PIPETX02COMPLIANCE, PIPETX02DATA, PIPETX02DATAVALID, PIPETX02ELECIDLE, PIPETX02EQCONTROL, PIPETX02EQDEEMPH, PIPETX02POWERDOWN, PIPETX02STARTBLOCK, PIPETX02SYNCHEADER, PIPETX03CHARISK, PIPETX03COMPLIANCE, PIPETX03DATA, PIPETX03DATAVALID, PIPETX03ELECIDLE, PIPETX03EQCONTROL, PIPETX03EQDEEMPH, PIPETX03POWERDOWN, PIPETX03STARTBLOCK, PIPETX03SYNCHEADER, PIPETX04CHARISK, PIPETX04COMPLIANCE +, PIPETX04DATA, PIPETX04DATAVALID, PIPETX04ELECIDLE, PIPETX04EQCONTROL, PIPETX04EQDEEMPH, PIPETX04POWERDOWN, PIPETX04STARTBLOCK, PIPETX04SYNCHEADER, PIPETX05CHARISK, PIPETX05COMPLIANCE, PIPETX05DATA, PIPETX05DATAVALID, PIPETX05ELECIDLE, PIPETX05EQCONTROL, PIPETX05EQDEEMPH, PIPETX05POWERDOWN, PIPETX05STARTBLOCK, PIPETX05SYNCHEADER, PIPETX06CHARISK, PIPETX06COMPLIANCE, PIPETX06DATA +, PIPETX06DATAVALID, PIPETX06ELECIDLE, PIPETX06EQCONTROL, PIPETX06EQDEEMPH, PIPETX06POWERDOWN, PIPETX06STARTBLOCK, PIPETX06SYNCHEADER, PIPETX07CHARISK, PIPETX07COMPLIANCE, PIPETX07DATA, PIPETX07DATAVALID, PIPETX07ELECIDLE, PIPETX07EQCONTROL, PIPETX07EQDEEMPH, PIPETX07POWERDOWN, PIPETX07STARTBLOCK, PIPETX07SYNCHEADER, PIPETX08CHARISK, PIPETX08COMPLIANCE, PIPETX08DATA, PIPETX08DATAVALID +, PIPETX08ELECIDLE, PIPETX08EQCONTROL, PIPETX08EQDEEMPH, PIPETX08POWERDOWN, PIPETX08STARTBLOCK, PIPETX08SYNCHEADER, PIPETX09CHARISK, PIPETX09COMPLIANCE, PIPETX09DATA, PIPETX09DATAVALID, PIPETX09ELECIDLE, PIPETX09EQCONTROL, PIPETX09EQDEEMPH, PIPETX09POWERDOWN, PIPETX09STARTBLOCK, PIPETX09SYNCHEADER, PIPETX10CHARISK, PIPETX10COMPLIANCE, PIPETX10DATA, PIPETX10DATAVALID, PIPETX10ELECIDLE +, PIPETX10EQCONTROL, PIPETX10EQDEEMPH, PIPETX10POWERDOWN, PIPETX10STARTBLOCK, PIPETX10SYNCHEADER, PIPETX11CHARISK, PIPETX11COMPLIANCE, PIPETX11DATA, PIPETX11DATAVALID, PIPETX11ELECIDLE, PIPETX11EQCONTROL, PIPETX11EQDEEMPH, PIPETX11POWERDOWN, PIPETX11STARTBLOCK, PIPETX11SYNCHEADER, PIPETX12CHARISK, PIPETX12COMPLIANCE, PIPETX12DATA, PIPETX12DATAVALID, PIPETX12ELECIDLE, PIPETX12EQCONTROL +, PIPETX12EQDEEMPH, PIPETX12POWERDOWN, PIPETX12STARTBLOCK, PIPETX12SYNCHEADER, PIPETX13CHARISK, PIPETX13COMPLIANCE, PIPETX13DATA, PIPETX13DATAVALID, PIPETX13ELECIDLE, PIPETX13EQCONTROL, PIPETX13EQDEEMPH, PIPETX13POWERDOWN, PIPETX13STARTBLOCK, PIPETX13SYNCHEADER, PIPETX14CHARISK, PIPETX14COMPLIANCE, PIPETX14DATA, PIPETX14DATAVALID, PIPETX14ELECIDLE, PIPETX14EQCONTROL, PIPETX14EQDEEMPH +, PIPETX14POWERDOWN, PIPETX14STARTBLOCK, PIPETX14SYNCHEADER, PIPETX15CHARISK, PIPETX15COMPLIANCE, PIPETX15DATA, PIPETX15DATAVALID, PIPETX15ELECIDLE, PIPETX15EQCONTROL, PIPETX15EQDEEMPH, PIPETX15POWERDOWN, PIPETX15STARTBLOCK, PIPETX15SYNCHEADER, PIPETXDEEMPH, PIPETXMARGIN, PIPETXRATE, PIPETXRCVRDET, PIPETXRESET, PIPETXSWING, PLEQINPROGRESS, PLEQPHASE +, PLGEN34EQMISMATCH, SAXISCCTREADY, SAXISRQTREADY, USERSPAREOUT, AXIUSERIN, CCIXOPTIMIZEDTLPTXANDRXENABLE, CCIXRXCORRECTABLEERRORDETECTED, CCIXRXFIFOOVERFLOW, CCIXRXTLPFORWARDED0, CCIXRXTLPFORWARDED1, CCIXRXTLPFORWARDEDLENGTH0, CCIXRXTLPFORWARDEDLENGTH1, CCIXRXUNCORRECTABLEERRORDETECTED, CFGCONFIGSPACEENABLE, CFGDEVIDPF0, CFGDEVIDPF1, CFGDEVIDPF2, CFGDEVIDPF3, CFGDSBUSNUMBER, CFGDSDEVICENUMBER, CFGDSFUNCTIONNUMBER +, CFGDSN, CFGDSPORTNUMBER, CFGERRCORIN, CFGERRUNCORIN, CFGEXTREADDATA, CFGEXTREADDATAVALID, CFGFCSEL, CFGFCVCSEL, CFGFLRDONE, CFGHOTRESETIN, CFGINTERRUPTINT, CFGINTERRUPTMSIATTR, CFGINTERRUPTMSIFUNCTIONNUMBER, CFGINTERRUPTMSIINT, CFGINTERRUPTMSIPENDINGSTATUS, CFGINTERRUPTMSIPENDINGSTATUSDATAENABLE, CFGINTERRUPTMSIPENDINGSTATUSFUNCTIONNUM, CFGINTERRUPTMSISELECT, CFGINTERRUPTMSITPHPRESENT, CFGINTERRUPTMSITPHSTTAG, CFGINTERRUPTMSITPHTYPE +, CFGINTERRUPTMSIXADDRESS, CFGINTERRUPTMSIXDATA, CFGINTERRUPTMSIXINT, CFGINTERRUPTMSIXVECPENDING, CFGINTERRUPTPENDING, CFGLINKTRAININGENABLE, CFGMGMTADDR, CFGMGMTBYTEENABLE, CFGMGMTDEBUGACCESS, CFGMGMTFUNCTIONNUMBER, CFGMGMTREAD, CFGMGMTWRITE, CFGMGMTWRITEDATA, CFGMSGTRANSMIT, CFGMSGTRANSMITDATA, CFGMSGTRANSMITTYPE, CFGMSIXRAMREADDATA, CFGPMASPML1ENTRYREJECT, CFGPMASPMTXL0SENTRYDISABLE, CFGPOWERSTATECHANGEACK, CFGREQPMTRANSITIONL23READY +, CFGREVIDPF0, CFGREVIDPF1, CFGREVIDPF2, CFGREVIDPF3, CFGSUBSYSIDPF0, CFGSUBSYSIDPF1, CFGSUBSYSIDPF2, CFGSUBSYSIDPF3, CFGSUBSYSVENDID, CFGTPHRAMREADDATA, CFGVENDID, CFGVFFLRDONE, CFGVFFLRFUNCNUM, CONFMCAPREQUESTBYCONF, CONFREQDATA, CONFREQREGNUM, CONFREQTYPE, CONFREQVALID, CORECLK, CORECLKCCIX, CORECLKMIREPLAYRAM0 +, CORECLKMIREPLAYRAM1, CORECLKMIRXCOMPLETIONRAM0, CORECLKMIRXCOMPLETIONRAM1, CORECLKMIRXPOSTEDREQUESTRAM0, CORECLKMIRXPOSTEDREQUESTRAM1, DBGSEL0, DBGSEL1, DRPADDR, DRPCLK, DRPDI, DRPEN, DRPWE, MAXISCQTREADY, MAXISRCTREADY, MCAPCLK, MCAPPERST0B, MCAPPERST1B, MGMTRESETN, MGMTSTICKYRESETN, MIREPLAYRAMERRCOR, MIREPLAYRAMERRUNCOR +, MIREPLAYRAMREADDATA0, MIREPLAYRAMREADDATA1, MIRXCOMPLETIONRAMERRCOR, MIRXCOMPLETIONRAMERRUNCOR, MIRXCOMPLETIONRAMREADDATA0, MIRXCOMPLETIONRAMREADDATA1, MIRXPOSTEDREQUESTRAMERRCOR, MIRXPOSTEDREQUESTRAMERRUNCOR, MIRXPOSTEDREQUESTRAMREADDATA0, MIRXPOSTEDREQUESTRAMREADDATA1, PCIECOMPLDELIVERED, PCIECOMPLDELIVEREDTAG0, PCIECOMPLDELIVEREDTAG1, PCIECQNPREQ, PCIECQNPUSERCREDITRCVD, PCIECQPIPELINEEMPTY, PCIEPOSTEDREQDELIVERED, PIPECLK, PIPECLKEN, PIPEEQFS, PIPEEQLF +, PIPERESETN, PIPERX00CHARISK, PIPERX00DATA, PIPERX00DATAVALID, PIPERX00ELECIDLE, PIPERX00EQDONE, PIPERX00EQLPADAPTDONE, PIPERX00EQLPLFFSSEL, PIPERX00EQLPNEWTXCOEFFORPRESET, PIPERX00PHYSTATUS, PIPERX00STARTBLOCK, PIPERX00STATUS, PIPERX00SYNCHEADER, PIPERX00VALID, PIPERX01CHARISK, PIPERX01DATA, PIPERX01DATAVALID, PIPERX01ELECIDLE, PIPERX01EQDONE, PIPERX01EQLPADAPTDONE, PIPERX01EQLPLFFSSEL +, PIPERX01EQLPNEWTXCOEFFORPRESET, PIPERX01PHYSTATUS, PIPERX01STARTBLOCK, PIPERX01STATUS, PIPERX01SYNCHEADER, PIPERX01VALID, PIPERX02CHARISK, PIPERX02DATA, PIPERX02DATAVALID, PIPERX02ELECIDLE, PIPERX02EQDONE, PIPERX02EQLPADAPTDONE, PIPERX02EQLPLFFSSEL, PIPERX02EQLPNEWTXCOEFFORPRESET, PIPERX02PHYSTATUS, PIPERX02STARTBLOCK, PIPERX02STATUS, PIPERX02SYNCHEADER, PIPERX02VALID, PIPERX03CHARISK, PIPERX03DATA +, PIPERX03DATAVALID, PIPERX03ELECIDLE, PIPERX03EQDONE, PIPERX03EQLPADAPTDONE, PIPERX03EQLPLFFSSEL, PIPERX03EQLPNEWTXCOEFFORPRESET, PIPERX03PHYSTATUS, PIPERX03STARTBLOCK, PIPERX03STATUS, PIPERX03SYNCHEADER, PIPERX03VALID, PIPERX04CHARISK, PIPERX04DATA, PIPERX04DATAVALID, PIPERX04ELECIDLE, PIPERX04EQDONE, PIPERX04EQLPADAPTDONE, PIPERX04EQLPLFFSSEL, PIPERX04EQLPNEWTXCOEFFORPRESET, PIPERX04PHYSTATUS, PIPERX04STARTBLOCK +, PIPERX04STATUS, PIPERX04SYNCHEADER, PIPERX04VALID, PIPERX05CHARISK, PIPERX05DATA, PIPERX05DATAVALID, PIPERX05ELECIDLE, PIPERX05EQDONE, PIPERX05EQLPADAPTDONE, PIPERX05EQLPLFFSSEL, PIPERX05EQLPNEWTXCOEFFORPRESET, PIPERX05PHYSTATUS, PIPERX05STARTBLOCK, PIPERX05STATUS, PIPERX05SYNCHEADER, PIPERX05VALID, PIPERX06CHARISK, PIPERX06DATA, PIPERX06DATAVALID, PIPERX06ELECIDLE, PIPERX06EQDONE +, PIPERX06EQLPADAPTDONE, PIPERX06EQLPLFFSSEL, PIPERX06EQLPNEWTXCOEFFORPRESET, PIPERX06PHYSTATUS, PIPERX06STARTBLOCK, PIPERX06STATUS, PIPERX06SYNCHEADER, PIPERX06VALID, PIPERX07CHARISK, PIPERX07DATA, PIPERX07DATAVALID, PIPERX07ELECIDLE, PIPERX07EQDONE, PIPERX07EQLPADAPTDONE, PIPERX07EQLPLFFSSEL, PIPERX07EQLPNEWTXCOEFFORPRESET, PIPERX07PHYSTATUS, PIPERX07STARTBLOCK, PIPERX07STATUS, PIPERX07SYNCHEADER, PIPERX07VALID +, PIPERX08CHARISK, PIPERX08DATA, PIPERX08DATAVALID, PIPERX08ELECIDLE, PIPERX08EQDONE, PIPERX08EQLPADAPTDONE, PIPERX08EQLPLFFSSEL, PIPERX08EQLPNEWTXCOEFFORPRESET, PIPERX08PHYSTATUS, PIPERX08STARTBLOCK, PIPERX08STATUS, PIPERX08SYNCHEADER, PIPERX08VALID, PIPERX09CHARISK, PIPERX09DATA, PIPERX09DATAVALID, PIPERX09ELECIDLE, PIPERX09EQDONE, PIPERX09EQLPADAPTDONE, PIPERX09EQLPLFFSSEL, PIPERX09EQLPNEWTXCOEFFORPRESET +, PIPERX09PHYSTATUS, PIPERX09STARTBLOCK, PIPERX09STATUS, PIPERX09SYNCHEADER, PIPERX09VALID, PIPERX10CHARISK, PIPERX10DATA, PIPERX10DATAVALID, PIPERX10ELECIDLE, PIPERX10EQDONE, PIPERX10EQLPADAPTDONE, PIPERX10EQLPLFFSSEL, PIPERX10EQLPNEWTXCOEFFORPRESET, PIPERX10PHYSTATUS, PIPERX10STARTBLOCK, PIPERX10STATUS, PIPERX10SYNCHEADER, PIPERX10VALID, PIPERX11CHARISK, PIPERX11DATA, PIPERX11DATAVALID +, PIPERX11ELECIDLE, PIPERX11EQDONE, PIPERX11EQLPADAPTDONE, PIPERX11EQLPLFFSSEL, PIPERX11EQLPNEWTXCOEFFORPRESET, PIPERX11PHYSTATUS, PIPERX11STARTBLOCK, PIPERX11STATUS, PIPERX11SYNCHEADER, PIPERX11VALID, PIPERX12CHARISK, PIPERX12DATA, PIPERX12DATAVALID, PIPERX12ELECIDLE, PIPERX12EQDONE, PIPERX12EQLPADAPTDONE, PIPERX12EQLPLFFSSEL, PIPERX12EQLPNEWTXCOEFFORPRESET, PIPERX12PHYSTATUS, PIPERX12STARTBLOCK, PIPERX12STATUS +, PIPERX12SYNCHEADER, PIPERX12VALID, PIPERX13CHARISK, PIPERX13DATA, PIPERX13DATAVALID, PIPERX13ELECIDLE, PIPERX13EQDONE, PIPERX13EQLPADAPTDONE, PIPERX13EQLPLFFSSEL, PIPERX13EQLPNEWTXCOEFFORPRESET, PIPERX13PHYSTATUS, PIPERX13STARTBLOCK, PIPERX13STATUS, PIPERX13SYNCHEADER, PIPERX13VALID, PIPERX14CHARISK, PIPERX14DATA, PIPERX14DATAVALID, PIPERX14ELECIDLE, PIPERX14EQDONE, PIPERX14EQLPADAPTDONE +, PIPERX14EQLPLFFSSEL, PIPERX14EQLPNEWTXCOEFFORPRESET, PIPERX14PHYSTATUS, PIPERX14STARTBLOCK, PIPERX14STATUS, PIPERX14SYNCHEADER, PIPERX14VALID, PIPERX15CHARISK, PIPERX15DATA, PIPERX15DATAVALID, PIPERX15ELECIDLE, PIPERX15EQDONE, PIPERX15EQLPADAPTDONE, PIPERX15EQLPLFFSSEL, PIPERX15EQLPNEWTXCOEFFORPRESET, PIPERX15PHYSTATUS, PIPERX15STARTBLOCK, PIPERX15STATUS, PIPERX15SYNCHEADER, PIPERX15VALID, PIPETX00EQCOEFF +, PIPETX00EQDONE, PIPETX01EQCOEFF, PIPETX01EQDONE, PIPETX02EQCOEFF, PIPETX02EQDONE, PIPETX03EQCOEFF, PIPETX03EQDONE, PIPETX04EQCOEFF, PIPETX04EQDONE, PIPETX05EQCOEFF, PIPETX05EQDONE, PIPETX06EQCOEFF, PIPETX06EQDONE, PIPETX07EQCOEFF, PIPETX07EQDONE, PIPETX08EQCOEFF, PIPETX08EQDONE, PIPETX09EQCOEFF, PIPETX09EQDONE, PIPETX10EQCOEFF, PIPETX10EQDONE +, PIPETX11EQCOEFF, PIPETX11EQDONE, PIPETX12EQCOEFF, PIPETX12EQDONE, PIPETX13EQCOEFF, PIPETX13EQDONE, PIPETX14EQCOEFF, PIPETX14EQDONE, PIPETX15EQCOEFF, PIPETX15EQDONE, PLEQRESETEIEOSCOUNT, PLGEN2UPSTREAMPREFERDEEMPH, PLGEN34REDOEQSPEED, PLGEN34REDOEQUALIZATION, RESETN, SAXISCCIXTXTDATA, SAXISCCIXTXTUSER, SAXISCCIXTXTVALID, SAXISCCTDATA, SAXISCCTKEEP, SAXISCCTLAST +, SAXISCCTUSER, SAXISCCTVALID, SAXISRQTDATA, SAXISRQTKEEP, SAXISRQTLAST, SAXISRQTUSER, SAXISRQTVALID, USERCLK, USERCLK2, USERCLKEN, USERSPAREIN); parameter ARI_CAP_ENABLE = "FALSE"; parameter AUTO_FLR_RESPONSE = "FALSE"; parameter [7:0] AXISTEN_IF_CCIX_RX_CREDIT_LIMIT = 8'h08; @@ -26539,7 +26945,14 @@ module PCIE4CE4 (...); input [31:0] USERSPAREIN; endmodule -module EMAC (...); +module EMAC(DCRHOSTDONEIR, EMAC0CLIENTANINTERRUPT, EMAC0CLIENTRXBADFRAME, EMAC0CLIENTRXCLIENTCLKOUT, EMAC0CLIENTRXDVLD, EMAC0CLIENTRXDVLDMSW, EMAC0CLIENTRXDVREG6, EMAC0CLIENTRXFRAMEDROP, EMAC0CLIENTRXGOODFRAME, EMAC0CLIENTRXSTATSBYTEVLD, EMAC0CLIENTRXSTATSVLD, EMAC0CLIENTTXACK, EMAC0CLIENTTXCLIENTCLKOUT, EMAC0CLIENTTXCOLLISION, EMAC0CLIENTTXGMIIMIICLKOUT, EMAC0CLIENTTXRETRANSMIT, EMAC0CLIENTTXSTATS, EMAC0CLIENTTXSTATSBYTEVLD, EMAC0CLIENTTXSTATSVLD, EMAC0PHYENCOMMAALIGN, EMAC0PHYLOOPBACKMSB +, EMAC0PHYMCLKOUT, EMAC0PHYMDOUT, EMAC0PHYMDTRI, EMAC0PHYMGTRXRESET, EMAC0PHYMGTTXRESET, EMAC0PHYPOWERDOWN, EMAC0PHYSYNCACQSTATUS, EMAC0PHYTXCHARDISPMODE, EMAC0PHYTXCHARDISPVAL, EMAC0PHYTXCHARISK, EMAC0PHYTXCLK, EMAC0PHYTXEN, EMAC0PHYTXER, EMAC1CLIENTANINTERRUPT, EMAC1CLIENTRXBADFRAME, EMAC1CLIENTRXCLIENTCLKOUT, EMAC1CLIENTRXDVLD, EMAC1CLIENTRXDVLDMSW, EMAC1CLIENTRXDVREG6, EMAC1CLIENTRXFRAMEDROP, EMAC1CLIENTRXGOODFRAME +, EMAC1CLIENTRXSTATSBYTEVLD, EMAC1CLIENTRXSTATSVLD, EMAC1CLIENTTXACK, EMAC1CLIENTTXCLIENTCLKOUT, EMAC1CLIENTTXCOLLISION, EMAC1CLIENTTXGMIIMIICLKOUT, EMAC1CLIENTTXRETRANSMIT, EMAC1CLIENTTXSTATS, EMAC1CLIENTTXSTATSBYTEVLD, EMAC1CLIENTTXSTATSVLD, EMAC1PHYENCOMMAALIGN, EMAC1PHYLOOPBACKMSB, EMAC1PHYMCLKOUT, EMAC1PHYMDOUT, EMAC1PHYMDTRI, EMAC1PHYMGTRXRESET, EMAC1PHYMGTTXRESET, EMAC1PHYPOWERDOWN, EMAC1PHYSYNCACQSTATUS, EMAC1PHYTXCHARDISPMODE, EMAC1PHYTXCHARDISPVAL +, EMAC1PHYTXCHARISK, EMAC1PHYTXCLK, EMAC1PHYTXEN, EMAC1PHYTXER, EMACDCRACK, HOSTMIIMRDY, EMACDCRDBUS, EMAC0CLIENTRXD, EMAC1CLIENTRXD, HOSTRDDATA, EMAC0CLIENTRXSTATS, EMAC1CLIENTRXSTATS, EMAC0PHYTXD, EMAC1PHYTXD, CLIENTEMAC0DCMLOCKED, CLIENTEMAC0PAUSEREQ, CLIENTEMAC0RXCLIENTCLKIN, CLIENTEMAC0TXCLIENTCLKIN, CLIENTEMAC0TXDVLD, CLIENTEMAC0TXDVLDMSW, CLIENTEMAC0TXFIRSTBYTE +, CLIENTEMAC0TXGMIIMIICLKIN, CLIENTEMAC0TXUNDERRUN, CLIENTEMAC1DCMLOCKED, CLIENTEMAC1PAUSEREQ, CLIENTEMAC1RXCLIENTCLKIN, CLIENTEMAC1TXCLIENTCLKIN, CLIENTEMAC1TXDVLD, CLIENTEMAC1TXDVLDMSW, CLIENTEMAC1TXFIRSTBYTE, CLIENTEMAC1TXGMIIMIICLKIN, CLIENTEMAC1TXUNDERRUN, DCREMACCLK, DCREMACENABLE, DCREMACREAD, DCREMACWRITE, HOSTCLK, HOSTEMAC1SEL, HOSTMIIMSEL, HOSTREQ, PHYEMAC0COL, PHYEMAC0CRS +, PHYEMAC0GTXCLK, PHYEMAC0MCLKIN, PHYEMAC0MDIN, PHYEMAC0MIITXCLK, PHYEMAC0RXBUFERR, PHYEMAC0RXCHARISCOMMA, PHYEMAC0RXCHARISK, PHYEMAC0RXCHECKINGCRC, PHYEMAC0RXCLK, PHYEMAC0RXCOMMADET, PHYEMAC0RXDISPERR, PHYEMAC0RXDV, PHYEMAC0RXER, PHYEMAC0RXNOTINTABLE, PHYEMAC0RXRUNDISP, PHYEMAC0SIGNALDET, PHYEMAC0TXBUFERR, PHYEMAC1COL, PHYEMAC1CRS, PHYEMAC1GTXCLK, PHYEMAC1MCLKIN +, PHYEMAC1MDIN, PHYEMAC1MIITXCLK, PHYEMAC1RXBUFERR, PHYEMAC1RXCHARISCOMMA, PHYEMAC1RXCHARISK, PHYEMAC1RXCHECKINGCRC, PHYEMAC1RXCLK, PHYEMAC1RXCOMMADET, PHYEMAC1RXDISPERR, PHYEMAC1RXDV, PHYEMAC1RXER, PHYEMAC1RXNOTINTABLE, PHYEMAC1RXRUNDISP, PHYEMAC1SIGNALDET, PHYEMAC1TXBUFERR, RESET, DCREMACDBUS, CLIENTEMAC0PAUSEVAL, CLIENTEMAC0TXD, CLIENTEMAC1PAUSEVAL, CLIENTEMAC1TXD +, HOSTOPCODE, PHYEMAC0RXBUFSTATUS, PHYEMAC0RXLOSSOFSYNC, PHYEMAC1RXBUFSTATUS, PHYEMAC1RXLOSSOFSYNC, PHYEMAC0RXCLKCORCNT, PHYEMAC1RXCLKCORCNT, HOSTWRDATA, TIEEMAC0UNICASTADDR, TIEEMAC1UNICASTADDR, PHYEMAC0PHYAD, PHYEMAC1PHYAD, TIEEMAC0CONFIGVEC, TIEEMAC1CONFIGVEC, CLIENTEMAC0TXIFGDELAY, CLIENTEMAC1TXIFGDELAY, PHYEMAC0RXD, PHYEMAC1RXD, DCREMACABUS, HOSTADDR); parameter EMAC0_MODE = "RGMII"; parameter EMAC1_MODE = "RGMII"; output DCRHOSTDONEIR; @@ -26711,7 +27124,14 @@ module EMAC (...); input [9:0] HOSTADDR; endmodule -module TEMAC (...); +module TEMAC(DCRHOSTDONEIR, EMAC0CLIENTANINTERRUPT, EMAC0CLIENTRXBADFRAME, EMAC0CLIENTRXCLIENTCLKOUT, EMAC0CLIENTRXDVLD, EMAC0CLIENTRXDVLDMSW, EMAC0CLIENTRXFRAMEDROP, EMAC0CLIENTRXGOODFRAME, EMAC0CLIENTRXSTATSBYTEVLD, EMAC0CLIENTRXSTATSVLD, EMAC0CLIENTTXACK, EMAC0CLIENTTXCLIENTCLKOUT, EMAC0CLIENTTXCOLLISION, EMAC0CLIENTTXRETRANSMIT, EMAC0CLIENTTXSTATS, EMAC0CLIENTTXSTATSBYTEVLD, EMAC0CLIENTTXSTATSVLD, EMAC0PHYENCOMMAALIGN, EMAC0PHYLOOPBACKMSB, EMAC0PHYMCLKOUT, EMAC0PHYMDOUT +, EMAC0PHYMDTRI, EMAC0PHYMGTRXRESET, EMAC0PHYMGTTXRESET, EMAC0PHYPOWERDOWN, EMAC0PHYSYNCACQSTATUS, EMAC0PHYTXCHARDISPMODE, EMAC0PHYTXCHARDISPVAL, EMAC0PHYTXCHARISK, EMAC0PHYTXCLK, EMAC0PHYTXEN, EMAC0PHYTXER, EMAC0PHYTXGMIIMIICLKOUT, EMAC0SPEEDIS10100, EMAC1CLIENTANINTERRUPT, EMAC1CLIENTRXBADFRAME, EMAC1CLIENTRXCLIENTCLKOUT, EMAC1CLIENTRXDVLD, EMAC1CLIENTRXDVLDMSW, EMAC1CLIENTRXFRAMEDROP, EMAC1CLIENTRXGOODFRAME, EMAC1CLIENTRXSTATSBYTEVLD +, EMAC1CLIENTRXSTATSVLD, EMAC1CLIENTTXACK, EMAC1CLIENTTXCLIENTCLKOUT, EMAC1CLIENTTXCOLLISION, EMAC1CLIENTTXRETRANSMIT, EMAC1CLIENTTXSTATS, EMAC1CLIENTTXSTATSBYTEVLD, EMAC1CLIENTTXSTATSVLD, EMAC1PHYENCOMMAALIGN, EMAC1PHYLOOPBACKMSB, EMAC1PHYMCLKOUT, EMAC1PHYMDOUT, EMAC1PHYMDTRI, EMAC1PHYMGTRXRESET, EMAC1PHYMGTTXRESET, EMAC1PHYPOWERDOWN, EMAC1PHYSYNCACQSTATUS, EMAC1PHYTXCHARDISPMODE, EMAC1PHYTXCHARDISPVAL, EMAC1PHYTXCHARISK, EMAC1PHYTXCLK +, EMAC1PHYTXEN, EMAC1PHYTXER, EMAC1PHYTXGMIIMIICLKOUT, EMAC1SPEEDIS10100, EMACDCRACK, HOSTMIIMRDY, EMACDCRDBUS, EMAC0CLIENTRXD, EMAC1CLIENTRXD, HOSTRDDATA, EMAC0CLIENTRXSTATS, EMAC1CLIENTRXSTATS, EMAC0PHYTXD, EMAC1PHYTXD, CLIENTEMAC0DCMLOCKED, CLIENTEMAC0PAUSEREQ, CLIENTEMAC0RXCLIENTCLKIN, CLIENTEMAC0TXCLIENTCLKIN, CLIENTEMAC0TXDVLD, CLIENTEMAC0TXDVLDMSW, CLIENTEMAC0TXFIRSTBYTE +, CLIENTEMAC0TXUNDERRUN, CLIENTEMAC1DCMLOCKED, CLIENTEMAC1PAUSEREQ, CLIENTEMAC1RXCLIENTCLKIN, CLIENTEMAC1TXCLIENTCLKIN, CLIENTEMAC1TXDVLD, CLIENTEMAC1TXDVLDMSW, CLIENTEMAC1TXFIRSTBYTE, CLIENTEMAC1TXUNDERRUN, DCREMACCLK, DCREMACENABLE, DCREMACREAD, DCREMACWRITE, HOSTCLK, HOSTEMAC1SEL, HOSTMIIMSEL, HOSTREQ, PHYEMAC0COL, PHYEMAC0CRS, PHYEMAC0GTXCLK, PHYEMAC0MCLKIN +, PHYEMAC0MDIN, PHYEMAC0MIITXCLK, PHYEMAC0RXBUFERR, PHYEMAC0RXCHARISCOMMA, PHYEMAC0RXCHARISK, PHYEMAC0RXCHECKINGCRC, PHYEMAC0RXCLK, PHYEMAC0RXCOMMADET, PHYEMAC0RXDISPERR, PHYEMAC0RXDV, PHYEMAC0RXER, PHYEMAC0RXNOTINTABLE, PHYEMAC0RXRUNDISP, PHYEMAC0SIGNALDET, PHYEMAC0TXBUFERR, PHYEMAC0TXGMIIMIICLKIN, PHYEMAC1COL, PHYEMAC1CRS, PHYEMAC1GTXCLK, PHYEMAC1MCLKIN, PHYEMAC1MDIN +, PHYEMAC1MIITXCLK, PHYEMAC1RXBUFERR, PHYEMAC1RXCHARISCOMMA, PHYEMAC1RXCHARISK, PHYEMAC1RXCHECKINGCRC, PHYEMAC1RXCLK, PHYEMAC1RXCOMMADET, PHYEMAC1RXDISPERR, PHYEMAC1RXDV, PHYEMAC1RXER, PHYEMAC1RXNOTINTABLE, PHYEMAC1RXRUNDISP, PHYEMAC1SIGNALDET, PHYEMAC1TXBUFERR, PHYEMAC1TXGMIIMIICLKIN, RESET, DCREMACDBUS, DCREMACABUS, CLIENTEMAC0PAUSEVAL, CLIENTEMAC0TXD, CLIENTEMAC1PAUSEVAL +, CLIENTEMAC1TXD, HOSTOPCODE, PHYEMAC0RXBUFSTATUS, PHYEMAC0RXLOSSOFSYNC, PHYEMAC1RXBUFSTATUS, PHYEMAC1RXLOSSOFSYNC, PHYEMAC0RXCLKCORCNT, PHYEMAC1RXCLKCORCNT, HOSTWRDATA, PHYEMAC0PHYAD, PHYEMAC1PHYAD, CLIENTEMAC0TXIFGDELAY, CLIENTEMAC1TXIFGDELAY, PHYEMAC0RXD, PHYEMAC1RXD, HOSTADDR); parameter EMAC0_1000BASEX_ENABLE = "FALSE"; parameter EMAC0_ADDRFILTER_ENABLE = "FALSE"; parameter EMAC0_BYTEPHY = "FALSE"; @@ -26957,7 +27377,11 @@ module TEMAC (...); input [9:0] HOSTADDR; endmodule -module TEMAC_SINGLE (...); +module TEMAC_SINGLE(DCRHOSTDONEIR, EMACCLIENTANINTERRUPT, EMACCLIENTRXBADFRAME, EMACCLIENTRXCLIENTCLKOUT, EMACCLIENTRXDVLD, EMACCLIENTRXDVLDMSW, EMACCLIENTRXFRAMEDROP, EMACCLIENTRXGOODFRAME, EMACCLIENTRXSTATSBYTEVLD, EMACCLIENTRXSTATSVLD, EMACCLIENTTXACK, EMACCLIENTTXCLIENTCLKOUT, EMACCLIENTTXCOLLISION, EMACCLIENTTXRETRANSMIT, EMACCLIENTTXSTATS, EMACCLIENTTXSTATSBYTEVLD, EMACCLIENTTXSTATSVLD, EMACDCRACK, EMACPHYENCOMMAALIGN, EMACPHYLOOPBACKMSB, EMACPHYMCLKOUT +, EMACPHYMDOUT, EMACPHYMDTRI, EMACPHYMGTRXRESET, EMACPHYMGTTXRESET, EMACPHYPOWERDOWN, EMACPHYSYNCACQSTATUS, EMACPHYTXCHARDISPMODE, EMACPHYTXCHARDISPVAL, EMACPHYTXCHARISK, EMACPHYTXCLK, EMACPHYTXEN, EMACPHYTXER, EMACPHYTXGMIIMIICLKOUT, EMACSPEEDIS10100, HOSTMIIMRDY, EMACDCRDBUS, EMACCLIENTRXD, HOSTRDDATA, EMACCLIENTRXSTATS, EMACPHYTXD, CLIENTEMACDCMLOCKED +, CLIENTEMACPAUSEREQ, CLIENTEMACRXCLIENTCLKIN, CLIENTEMACTXCLIENTCLKIN, CLIENTEMACTXDVLD, CLIENTEMACTXDVLDMSW, CLIENTEMACTXFIRSTBYTE, CLIENTEMACTXUNDERRUN, DCREMACCLK, DCREMACENABLE, DCREMACREAD, DCREMACWRITE, HOSTCLK, HOSTMIIMSEL, HOSTREQ, PHYEMACCOL, PHYEMACCRS, PHYEMACGTXCLK, PHYEMACMCLKIN, PHYEMACMDIN, PHYEMACMIITXCLK, PHYEMACRXCHARISCOMMA +, PHYEMACRXCHARISK, PHYEMACRXCLK, PHYEMACRXDISPERR, PHYEMACRXDV, PHYEMACRXER, PHYEMACRXNOTINTABLE, PHYEMACRXRUNDISP, PHYEMACSIGNALDET, PHYEMACTXBUFERR, PHYEMACTXGMIIMIICLKIN, RESET, DCREMACDBUS, DCREMACABUS, CLIENTEMACPAUSEVAL, CLIENTEMACTXD, HOSTOPCODE, PHYEMACRXBUFSTATUS, PHYEMACRXCLKCORCNT, HOSTWRDATA, PHYEMACPHYAD, CLIENTEMACTXIFGDELAY +, PHYEMACRXD, HOSTADDR); parameter EMAC_1000BASEX_ENABLE = "FALSE"; parameter EMAC_ADDRFILTER_ENABLE = "FALSE"; parameter EMAC_BYTEPHY = "FALSE"; @@ -27088,7 +27512,24 @@ module TEMAC_SINGLE (...); input [9:0] HOSTADDR; endmodule -module CMAC (...); +module CMAC(DRP_DO, DRP_RDY, RX_DATAOUT0, RX_DATAOUT1, RX_DATAOUT2, RX_DATAOUT3, RX_ENAOUT0, RX_ENAOUT1, RX_ENAOUT2, RX_ENAOUT3, RX_EOPOUT0, RX_EOPOUT1, RX_EOPOUT2, RX_EOPOUT3, RX_ERROUT0, RX_ERROUT1, RX_ERROUT2, RX_ERROUT3, RX_LANE_ALIGNER_FILL_0, RX_LANE_ALIGNER_FILL_1, RX_LANE_ALIGNER_FILL_10 +, RX_LANE_ALIGNER_FILL_11, RX_LANE_ALIGNER_FILL_12, RX_LANE_ALIGNER_FILL_13, RX_LANE_ALIGNER_FILL_14, RX_LANE_ALIGNER_FILL_15, RX_LANE_ALIGNER_FILL_16, RX_LANE_ALIGNER_FILL_17, RX_LANE_ALIGNER_FILL_18, RX_LANE_ALIGNER_FILL_19, RX_LANE_ALIGNER_FILL_2, RX_LANE_ALIGNER_FILL_3, RX_LANE_ALIGNER_FILL_4, RX_LANE_ALIGNER_FILL_5, RX_LANE_ALIGNER_FILL_6, RX_LANE_ALIGNER_FILL_7, RX_LANE_ALIGNER_FILL_8, RX_LANE_ALIGNER_FILL_9, RX_MTYOUT0, RX_MTYOUT1, RX_MTYOUT2, RX_MTYOUT3 +, RX_PTP_PCSLANE_OUT, RX_PTP_TSTAMP_OUT, RX_SOPOUT0, RX_SOPOUT1, RX_SOPOUT2, RX_SOPOUT3, STAT_RX_ALIGNED, STAT_RX_ALIGNED_ERR, STAT_RX_BAD_CODE, STAT_RX_BAD_FCS, STAT_RX_BAD_PREAMBLE, STAT_RX_BAD_SFD, STAT_RX_BIP_ERR_0, STAT_RX_BIP_ERR_1, STAT_RX_BIP_ERR_10, STAT_RX_BIP_ERR_11, STAT_RX_BIP_ERR_12, STAT_RX_BIP_ERR_13, STAT_RX_BIP_ERR_14, STAT_RX_BIP_ERR_15, STAT_RX_BIP_ERR_16 +, STAT_RX_BIP_ERR_17, STAT_RX_BIP_ERR_18, STAT_RX_BIP_ERR_19, STAT_RX_BIP_ERR_2, STAT_RX_BIP_ERR_3, STAT_RX_BIP_ERR_4, STAT_RX_BIP_ERR_5, STAT_RX_BIP_ERR_6, STAT_RX_BIP_ERR_7, STAT_RX_BIP_ERR_8, STAT_RX_BIP_ERR_9, STAT_RX_BLOCK_LOCK, STAT_RX_BROADCAST, STAT_RX_FRAGMENT, STAT_RX_FRAMING_ERR_0, STAT_RX_FRAMING_ERR_1, STAT_RX_FRAMING_ERR_10, STAT_RX_FRAMING_ERR_11, STAT_RX_FRAMING_ERR_12, STAT_RX_FRAMING_ERR_13, STAT_RX_FRAMING_ERR_14 +, STAT_RX_FRAMING_ERR_15, STAT_RX_FRAMING_ERR_16, STAT_RX_FRAMING_ERR_17, STAT_RX_FRAMING_ERR_18, STAT_RX_FRAMING_ERR_19, STAT_RX_FRAMING_ERR_2, STAT_RX_FRAMING_ERR_3, STAT_RX_FRAMING_ERR_4, STAT_RX_FRAMING_ERR_5, STAT_RX_FRAMING_ERR_6, STAT_RX_FRAMING_ERR_7, STAT_RX_FRAMING_ERR_8, STAT_RX_FRAMING_ERR_9, STAT_RX_FRAMING_ERR_VALID_0, STAT_RX_FRAMING_ERR_VALID_1, STAT_RX_FRAMING_ERR_VALID_10, STAT_RX_FRAMING_ERR_VALID_11, STAT_RX_FRAMING_ERR_VALID_12, STAT_RX_FRAMING_ERR_VALID_13, STAT_RX_FRAMING_ERR_VALID_14, STAT_RX_FRAMING_ERR_VALID_15 +, STAT_RX_FRAMING_ERR_VALID_16, STAT_RX_FRAMING_ERR_VALID_17, STAT_RX_FRAMING_ERR_VALID_18, STAT_RX_FRAMING_ERR_VALID_19, STAT_RX_FRAMING_ERR_VALID_2, STAT_RX_FRAMING_ERR_VALID_3, STAT_RX_FRAMING_ERR_VALID_4, STAT_RX_FRAMING_ERR_VALID_5, STAT_RX_FRAMING_ERR_VALID_6, STAT_RX_FRAMING_ERR_VALID_7, STAT_RX_FRAMING_ERR_VALID_8, STAT_RX_FRAMING_ERR_VALID_9, STAT_RX_GOT_SIGNAL_OS, STAT_RX_HI_BER, STAT_RX_INRANGEERR, STAT_RX_INTERNAL_LOCAL_FAULT, STAT_RX_JABBER, STAT_RX_LANE0_VLM_BIP7, STAT_RX_LANE0_VLM_BIP7_VALID, STAT_RX_LOCAL_FAULT, STAT_RX_MF_ERR +, STAT_RX_MF_LEN_ERR, STAT_RX_MF_REPEAT_ERR, STAT_RX_MISALIGNED, STAT_RX_MULTICAST, STAT_RX_OVERSIZE, STAT_RX_PACKET_1024_1518_BYTES, STAT_RX_PACKET_128_255_BYTES, STAT_RX_PACKET_1519_1522_BYTES, STAT_RX_PACKET_1523_1548_BYTES, STAT_RX_PACKET_1549_2047_BYTES, STAT_RX_PACKET_2048_4095_BYTES, STAT_RX_PACKET_256_511_BYTES, STAT_RX_PACKET_4096_8191_BYTES, STAT_RX_PACKET_512_1023_BYTES, STAT_RX_PACKET_64_BYTES, STAT_RX_PACKET_65_127_BYTES, STAT_RX_PACKET_8192_9215_BYTES, STAT_RX_PACKET_BAD_FCS, STAT_RX_PACKET_LARGE, STAT_RX_PACKET_SMALL, STAT_RX_PAUSE +, STAT_RX_PAUSE_QUANTA0, STAT_RX_PAUSE_QUANTA1, STAT_RX_PAUSE_QUANTA2, STAT_RX_PAUSE_QUANTA3, STAT_RX_PAUSE_QUANTA4, STAT_RX_PAUSE_QUANTA5, STAT_RX_PAUSE_QUANTA6, STAT_RX_PAUSE_QUANTA7, STAT_RX_PAUSE_QUANTA8, STAT_RX_PAUSE_REQ, STAT_RX_PAUSE_VALID, STAT_RX_RECEIVED_LOCAL_FAULT, STAT_RX_REMOTE_FAULT, STAT_RX_STATUS, STAT_RX_STOMPED_FCS, STAT_RX_SYNCED, STAT_RX_SYNCED_ERR, STAT_RX_TEST_PATTERN_MISMATCH, STAT_RX_TOOLONG, STAT_RX_TOTAL_BYTES, STAT_RX_TOTAL_GOOD_BYTES +, STAT_RX_TOTAL_GOOD_PACKETS, STAT_RX_TOTAL_PACKETS, STAT_RX_TRUNCATED, STAT_RX_UNDERSIZE, STAT_RX_UNICAST, STAT_RX_USER_PAUSE, STAT_RX_VLAN, STAT_RX_VL_DEMUXED, STAT_RX_VL_NUMBER_0, STAT_RX_VL_NUMBER_1, STAT_RX_VL_NUMBER_10, STAT_RX_VL_NUMBER_11, STAT_RX_VL_NUMBER_12, STAT_RX_VL_NUMBER_13, STAT_RX_VL_NUMBER_14, STAT_RX_VL_NUMBER_15, STAT_RX_VL_NUMBER_16, STAT_RX_VL_NUMBER_17, STAT_RX_VL_NUMBER_18, STAT_RX_VL_NUMBER_19, STAT_RX_VL_NUMBER_2 +, STAT_RX_VL_NUMBER_3, STAT_RX_VL_NUMBER_4, STAT_RX_VL_NUMBER_5, STAT_RX_VL_NUMBER_6, STAT_RX_VL_NUMBER_7, STAT_RX_VL_NUMBER_8, STAT_RX_VL_NUMBER_9, STAT_TX_BAD_FCS, STAT_TX_BROADCAST, STAT_TX_FRAME_ERROR, STAT_TX_LOCAL_FAULT, STAT_TX_MULTICAST, STAT_TX_PACKET_1024_1518_BYTES, STAT_TX_PACKET_128_255_BYTES, STAT_TX_PACKET_1519_1522_BYTES, STAT_TX_PACKET_1523_1548_BYTES, STAT_TX_PACKET_1549_2047_BYTES, STAT_TX_PACKET_2048_4095_BYTES, STAT_TX_PACKET_256_511_BYTES, STAT_TX_PACKET_4096_8191_BYTES, STAT_TX_PACKET_512_1023_BYTES +, STAT_TX_PACKET_64_BYTES, STAT_TX_PACKET_65_127_BYTES, STAT_TX_PACKET_8192_9215_BYTES, STAT_TX_PACKET_LARGE, STAT_TX_PACKET_SMALL, STAT_TX_PAUSE, STAT_TX_PAUSE_VALID, STAT_TX_PTP_FIFO_READ_ERROR, STAT_TX_PTP_FIFO_WRITE_ERROR, STAT_TX_TOTAL_BYTES, STAT_TX_TOTAL_GOOD_BYTES, STAT_TX_TOTAL_GOOD_PACKETS, STAT_TX_TOTAL_PACKETS, STAT_TX_UNICAST, STAT_TX_USER_PAUSE, STAT_TX_VLAN, TX_OVFOUT, TX_PTP_PCSLANE_OUT, TX_PTP_TSTAMP_OUT, TX_PTP_TSTAMP_TAG_OUT, TX_PTP_TSTAMP_VALID_OUT +, TX_RDYOUT, TX_SERDES_ALT_DATA0, TX_SERDES_ALT_DATA1, TX_SERDES_ALT_DATA2, TX_SERDES_ALT_DATA3, TX_SERDES_DATA0, TX_SERDES_DATA1, TX_SERDES_DATA2, TX_SERDES_DATA3, TX_SERDES_DATA4, TX_SERDES_DATA5, TX_SERDES_DATA6, TX_SERDES_DATA7, TX_SERDES_DATA8, TX_SERDES_DATA9, TX_UNFOUT, CTL_CAUI4_MODE, CTL_RX_CHECK_ETYPE_GCP, CTL_RX_CHECK_ETYPE_GPP, CTL_RX_CHECK_ETYPE_PCP, CTL_RX_CHECK_ETYPE_PPP +, CTL_RX_CHECK_MCAST_GCP, CTL_RX_CHECK_MCAST_GPP, CTL_RX_CHECK_MCAST_PCP, CTL_RX_CHECK_MCAST_PPP, CTL_RX_CHECK_OPCODE_GCP, CTL_RX_CHECK_OPCODE_GPP, CTL_RX_CHECK_OPCODE_PCP, CTL_RX_CHECK_OPCODE_PPP, CTL_RX_CHECK_SA_GCP, CTL_RX_CHECK_SA_GPP, CTL_RX_CHECK_SA_PCP, CTL_RX_CHECK_SA_PPP, CTL_RX_CHECK_UCAST_GCP, CTL_RX_CHECK_UCAST_GPP, CTL_RX_CHECK_UCAST_PCP, CTL_RX_CHECK_UCAST_PPP, CTL_RX_ENABLE, CTL_RX_ENABLE_GCP, CTL_RX_ENABLE_GPP, CTL_RX_ENABLE_PCP, CTL_RX_ENABLE_PPP +, CTL_RX_FORCE_RESYNC, CTL_RX_PAUSE_ACK, CTL_RX_PAUSE_ENABLE, CTL_RX_SYSTEMTIMERIN, CTL_RX_TEST_PATTERN, CTL_TX_ENABLE, CTL_TX_LANE0_VLM_BIP7_OVERRIDE, CTL_TX_LANE0_VLM_BIP7_OVERRIDE_VALUE, CTL_TX_PAUSE_ENABLE, CTL_TX_PAUSE_QUANTA0, CTL_TX_PAUSE_QUANTA1, CTL_TX_PAUSE_QUANTA2, CTL_TX_PAUSE_QUANTA3, CTL_TX_PAUSE_QUANTA4, CTL_TX_PAUSE_QUANTA5, CTL_TX_PAUSE_QUANTA6, CTL_TX_PAUSE_QUANTA7, CTL_TX_PAUSE_QUANTA8, CTL_TX_PAUSE_REFRESH_TIMER0, CTL_TX_PAUSE_REFRESH_TIMER1, CTL_TX_PAUSE_REFRESH_TIMER2 +, CTL_TX_PAUSE_REFRESH_TIMER3, CTL_TX_PAUSE_REFRESH_TIMER4, CTL_TX_PAUSE_REFRESH_TIMER5, CTL_TX_PAUSE_REFRESH_TIMER6, CTL_TX_PAUSE_REFRESH_TIMER7, CTL_TX_PAUSE_REFRESH_TIMER8, CTL_TX_PAUSE_REQ, CTL_TX_PTP_VLANE_ADJUST_MODE, CTL_TX_RESEND_PAUSE, CTL_TX_SEND_IDLE, CTL_TX_SEND_RFI, CTL_TX_SYSTEMTIMERIN, CTL_TX_TEST_PATTERN, DRP_ADDR, DRP_CLK, DRP_DI, DRP_EN, DRP_WE, RX_CLK, RX_RESET, RX_SERDES_ALT_DATA0 +, RX_SERDES_ALT_DATA1, RX_SERDES_ALT_DATA2, RX_SERDES_ALT_DATA3, RX_SERDES_CLK, RX_SERDES_DATA0, RX_SERDES_DATA1, RX_SERDES_DATA2, RX_SERDES_DATA3, RX_SERDES_DATA4, RX_SERDES_DATA5, RX_SERDES_DATA6, RX_SERDES_DATA7, RX_SERDES_DATA8, RX_SERDES_DATA9, RX_SERDES_RESET, TX_CLK, TX_DATAIN0, TX_DATAIN1, TX_DATAIN2, TX_DATAIN3, TX_ENAIN0 +, TX_ENAIN1, TX_ENAIN2, TX_ENAIN3, TX_EOPIN0, TX_EOPIN1, TX_EOPIN2, TX_EOPIN3, TX_ERRIN0, TX_ERRIN1, TX_ERRIN2, TX_ERRIN3, TX_MTYIN0, TX_MTYIN1, TX_MTYIN2, TX_MTYIN3, TX_PTP_1588OP_IN, TX_PTP_CHKSUM_OFFSET_IN, TX_PTP_RXTSTAMP_IN, TX_PTP_TAG_FIELD_IN, TX_PTP_TSTAMP_OFFSET_IN, TX_PTP_UPD_CHKSUM_IN +, TX_RESET, TX_SOPIN0, TX_SOPIN1, TX_SOPIN2, TX_SOPIN3); parameter CTL_PTP_TRANSPCLK_MODE = "FALSE"; parameter CTL_RX_CHECK_ACK = "TRUE"; parameter CTL_RX_CHECK_PREAMBLE = "FALSE"; @@ -27533,7 +27974,26 @@ module CMAC (...); input TX_SOPIN3; endmodule -module CMACE4 (...); +module CMACE4(DRP_DO, DRP_RDY, RSFEC_BYPASS_RX_DOUT, RSFEC_BYPASS_RX_DOUT_CW_START, RSFEC_BYPASS_RX_DOUT_VALID, RSFEC_BYPASS_TX_DOUT, RSFEC_BYPASS_TX_DOUT_CW_START, RSFEC_BYPASS_TX_DOUT_VALID, RX_DATAOUT0, RX_DATAOUT1, RX_DATAOUT2, RX_DATAOUT3, RX_ENAOUT0, RX_ENAOUT1, RX_ENAOUT2, RX_ENAOUT3, RX_EOPOUT0, RX_EOPOUT1, RX_EOPOUT2, RX_EOPOUT3, RX_ERROUT0 +, RX_ERROUT1, RX_ERROUT2, RX_ERROUT3, RX_LANE_ALIGNER_FILL_0, RX_LANE_ALIGNER_FILL_1, RX_LANE_ALIGNER_FILL_10, RX_LANE_ALIGNER_FILL_11, RX_LANE_ALIGNER_FILL_12, RX_LANE_ALIGNER_FILL_13, RX_LANE_ALIGNER_FILL_14, RX_LANE_ALIGNER_FILL_15, RX_LANE_ALIGNER_FILL_16, RX_LANE_ALIGNER_FILL_17, RX_LANE_ALIGNER_FILL_18, RX_LANE_ALIGNER_FILL_19, RX_LANE_ALIGNER_FILL_2, RX_LANE_ALIGNER_FILL_3, RX_LANE_ALIGNER_FILL_4, RX_LANE_ALIGNER_FILL_5, RX_LANE_ALIGNER_FILL_6, RX_LANE_ALIGNER_FILL_7 +, RX_LANE_ALIGNER_FILL_8, RX_LANE_ALIGNER_FILL_9, RX_MTYOUT0, RX_MTYOUT1, RX_MTYOUT2, RX_MTYOUT3, RX_OTN_BIP8_0, RX_OTN_BIP8_1, RX_OTN_BIP8_2, RX_OTN_BIP8_3, RX_OTN_BIP8_4, RX_OTN_DATA_0, RX_OTN_DATA_1, RX_OTN_DATA_2, RX_OTN_DATA_3, RX_OTN_DATA_4, RX_OTN_ENA, RX_OTN_LANE0, RX_OTN_VLMARKER, RX_PREOUT, RX_PTP_PCSLANE_OUT +, RX_PTP_TSTAMP_OUT, RX_SOPOUT0, RX_SOPOUT1, RX_SOPOUT2, RX_SOPOUT3, STAT_RX_ALIGNED, STAT_RX_ALIGNED_ERR, STAT_RX_BAD_CODE, STAT_RX_BAD_FCS, STAT_RX_BAD_PREAMBLE, STAT_RX_BAD_SFD, STAT_RX_BIP_ERR_0, STAT_RX_BIP_ERR_1, STAT_RX_BIP_ERR_10, STAT_RX_BIP_ERR_11, STAT_RX_BIP_ERR_12, STAT_RX_BIP_ERR_13, STAT_RX_BIP_ERR_14, STAT_RX_BIP_ERR_15, STAT_RX_BIP_ERR_16, STAT_RX_BIP_ERR_17 +, STAT_RX_BIP_ERR_18, STAT_RX_BIP_ERR_19, STAT_RX_BIP_ERR_2, STAT_RX_BIP_ERR_3, STAT_RX_BIP_ERR_4, STAT_RX_BIP_ERR_5, STAT_RX_BIP_ERR_6, STAT_RX_BIP_ERR_7, STAT_RX_BIP_ERR_8, STAT_RX_BIP_ERR_9, STAT_RX_BLOCK_LOCK, STAT_RX_BROADCAST, STAT_RX_FRAGMENT, STAT_RX_FRAMING_ERR_0, STAT_RX_FRAMING_ERR_1, STAT_RX_FRAMING_ERR_10, STAT_RX_FRAMING_ERR_11, STAT_RX_FRAMING_ERR_12, STAT_RX_FRAMING_ERR_13, STAT_RX_FRAMING_ERR_14, STAT_RX_FRAMING_ERR_15 +, STAT_RX_FRAMING_ERR_16, STAT_RX_FRAMING_ERR_17, STAT_RX_FRAMING_ERR_18, STAT_RX_FRAMING_ERR_19, STAT_RX_FRAMING_ERR_2, STAT_RX_FRAMING_ERR_3, STAT_RX_FRAMING_ERR_4, STAT_RX_FRAMING_ERR_5, STAT_RX_FRAMING_ERR_6, STAT_RX_FRAMING_ERR_7, STAT_RX_FRAMING_ERR_8, STAT_RX_FRAMING_ERR_9, STAT_RX_FRAMING_ERR_VALID_0, STAT_RX_FRAMING_ERR_VALID_1, STAT_RX_FRAMING_ERR_VALID_10, STAT_RX_FRAMING_ERR_VALID_11, STAT_RX_FRAMING_ERR_VALID_12, STAT_RX_FRAMING_ERR_VALID_13, STAT_RX_FRAMING_ERR_VALID_14, STAT_RX_FRAMING_ERR_VALID_15, STAT_RX_FRAMING_ERR_VALID_16 +, STAT_RX_FRAMING_ERR_VALID_17, STAT_RX_FRAMING_ERR_VALID_18, STAT_RX_FRAMING_ERR_VALID_19, STAT_RX_FRAMING_ERR_VALID_2, STAT_RX_FRAMING_ERR_VALID_3, STAT_RX_FRAMING_ERR_VALID_4, STAT_RX_FRAMING_ERR_VALID_5, STAT_RX_FRAMING_ERR_VALID_6, STAT_RX_FRAMING_ERR_VALID_7, STAT_RX_FRAMING_ERR_VALID_8, STAT_RX_FRAMING_ERR_VALID_9, STAT_RX_GOT_SIGNAL_OS, STAT_RX_HI_BER, STAT_RX_INRANGEERR, STAT_RX_INTERNAL_LOCAL_FAULT, STAT_RX_JABBER, STAT_RX_LANE0_VLM_BIP7, STAT_RX_LANE0_VLM_BIP7_VALID, STAT_RX_LOCAL_FAULT, STAT_RX_MF_ERR, STAT_RX_MF_LEN_ERR +, STAT_RX_MF_REPEAT_ERR, STAT_RX_MISALIGNED, STAT_RX_MULTICAST, STAT_RX_OVERSIZE, STAT_RX_PACKET_1024_1518_BYTES, STAT_RX_PACKET_128_255_BYTES, STAT_RX_PACKET_1519_1522_BYTES, STAT_RX_PACKET_1523_1548_BYTES, STAT_RX_PACKET_1549_2047_BYTES, STAT_RX_PACKET_2048_4095_BYTES, STAT_RX_PACKET_256_511_BYTES, STAT_RX_PACKET_4096_8191_BYTES, STAT_RX_PACKET_512_1023_BYTES, STAT_RX_PACKET_64_BYTES, STAT_RX_PACKET_65_127_BYTES, STAT_RX_PACKET_8192_9215_BYTES, STAT_RX_PACKET_BAD_FCS, STAT_RX_PACKET_LARGE, STAT_RX_PACKET_SMALL, STAT_RX_PAUSE, STAT_RX_PAUSE_QUANTA0 +, STAT_RX_PAUSE_QUANTA1, STAT_RX_PAUSE_QUANTA2, STAT_RX_PAUSE_QUANTA3, STAT_RX_PAUSE_QUANTA4, STAT_RX_PAUSE_QUANTA5, STAT_RX_PAUSE_QUANTA6, STAT_RX_PAUSE_QUANTA7, STAT_RX_PAUSE_QUANTA8, STAT_RX_PAUSE_REQ, STAT_RX_PAUSE_VALID, STAT_RX_RECEIVED_LOCAL_FAULT, STAT_RX_REMOTE_FAULT, STAT_RX_RSFEC_AM_LOCK0, STAT_RX_RSFEC_AM_LOCK1, STAT_RX_RSFEC_AM_LOCK2, STAT_RX_RSFEC_AM_LOCK3, STAT_RX_RSFEC_CORRECTED_CW_INC, STAT_RX_RSFEC_CW_INC, STAT_RX_RSFEC_ERR_COUNT0_INC, STAT_RX_RSFEC_ERR_COUNT1_INC, STAT_RX_RSFEC_ERR_COUNT2_INC +, STAT_RX_RSFEC_ERR_COUNT3_INC, STAT_RX_RSFEC_HI_SER, STAT_RX_RSFEC_LANE_ALIGNMENT_STATUS, STAT_RX_RSFEC_LANE_FILL_0, STAT_RX_RSFEC_LANE_FILL_1, STAT_RX_RSFEC_LANE_FILL_2, STAT_RX_RSFEC_LANE_FILL_3, STAT_RX_RSFEC_LANE_MAPPING, STAT_RX_RSFEC_RSVD, STAT_RX_RSFEC_UNCORRECTED_CW_INC, STAT_RX_STATUS, STAT_RX_STOMPED_FCS, STAT_RX_SYNCED, STAT_RX_SYNCED_ERR, STAT_RX_TEST_PATTERN_MISMATCH, STAT_RX_TOOLONG, STAT_RX_TOTAL_BYTES, STAT_RX_TOTAL_GOOD_BYTES, STAT_RX_TOTAL_GOOD_PACKETS, STAT_RX_TOTAL_PACKETS, STAT_RX_TRUNCATED +, STAT_RX_UNDERSIZE, STAT_RX_UNICAST, STAT_RX_USER_PAUSE, STAT_RX_VLAN, STAT_RX_VL_DEMUXED, STAT_RX_VL_NUMBER_0, STAT_RX_VL_NUMBER_1, STAT_RX_VL_NUMBER_10, STAT_RX_VL_NUMBER_11, STAT_RX_VL_NUMBER_12, STAT_RX_VL_NUMBER_13, STAT_RX_VL_NUMBER_14, STAT_RX_VL_NUMBER_15, STAT_RX_VL_NUMBER_16, STAT_RX_VL_NUMBER_17, STAT_RX_VL_NUMBER_18, STAT_RX_VL_NUMBER_19, STAT_RX_VL_NUMBER_2, STAT_RX_VL_NUMBER_3, STAT_RX_VL_NUMBER_4, STAT_RX_VL_NUMBER_5 +, STAT_RX_VL_NUMBER_6, STAT_RX_VL_NUMBER_7, STAT_RX_VL_NUMBER_8, STAT_RX_VL_NUMBER_9, STAT_TX_BAD_FCS, STAT_TX_BROADCAST, STAT_TX_FRAME_ERROR, STAT_TX_LOCAL_FAULT, STAT_TX_MULTICAST, STAT_TX_PACKET_1024_1518_BYTES, STAT_TX_PACKET_128_255_BYTES, STAT_TX_PACKET_1519_1522_BYTES, STAT_TX_PACKET_1523_1548_BYTES, STAT_TX_PACKET_1549_2047_BYTES, STAT_TX_PACKET_2048_4095_BYTES, STAT_TX_PACKET_256_511_BYTES, STAT_TX_PACKET_4096_8191_BYTES, STAT_TX_PACKET_512_1023_BYTES, STAT_TX_PACKET_64_BYTES, STAT_TX_PACKET_65_127_BYTES, STAT_TX_PACKET_8192_9215_BYTES +, STAT_TX_PACKET_LARGE, STAT_TX_PACKET_SMALL, STAT_TX_PAUSE, STAT_TX_PAUSE_VALID, STAT_TX_PTP_FIFO_READ_ERROR, STAT_TX_PTP_FIFO_WRITE_ERROR, STAT_TX_TOTAL_BYTES, STAT_TX_TOTAL_GOOD_BYTES, STAT_TX_TOTAL_GOOD_PACKETS, STAT_TX_TOTAL_PACKETS, STAT_TX_UNICAST, STAT_TX_USER_PAUSE, STAT_TX_VLAN, TX_OVFOUT, TX_PTP_PCSLANE_OUT, TX_PTP_TSTAMP_OUT, TX_PTP_TSTAMP_TAG_OUT, TX_PTP_TSTAMP_VALID_OUT, TX_RDYOUT, TX_SERDES_ALT_DATA0, TX_SERDES_ALT_DATA1 +, TX_SERDES_ALT_DATA2, TX_SERDES_ALT_DATA3, TX_SERDES_DATA0, TX_SERDES_DATA1, TX_SERDES_DATA2, TX_SERDES_DATA3, TX_SERDES_DATA4, TX_SERDES_DATA5, TX_SERDES_DATA6, TX_SERDES_DATA7, TX_SERDES_DATA8, TX_SERDES_DATA9, TX_UNFOUT, CTL_CAUI4_MODE, CTL_RSFEC_ENABLE_TRANSCODER_BYPASS_MODE, CTL_RSFEC_IEEE_ERROR_INDICATION_MODE, CTL_RX_CHECK_ETYPE_GCP, CTL_RX_CHECK_ETYPE_GPP, CTL_RX_CHECK_ETYPE_PCP, CTL_RX_CHECK_ETYPE_PPP, CTL_RX_CHECK_MCAST_GCP +, CTL_RX_CHECK_MCAST_GPP, CTL_RX_CHECK_MCAST_PCP, CTL_RX_CHECK_MCAST_PPP, CTL_RX_CHECK_OPCODE_GCP, CTL_RX_CHECK_OPCODE_GPP, CTL_RX_CHECK_OPCODE_PCP, CTL_RX_CHECK_OPCODE_PPP, CTL_RX_CHECK_SA_GCP, CTL_RX_CHECK_SA_GPP, CTL_RX_CHECK_SA_PCP, CTL_RX_CHECK_SA_PPP, CTL_RX_CHECK_UCAST_GCP, CTL_RX_CHECK_UCAST_GPP, CTL_RX_CHECK_UCAST_PCP, CTL_RX_CHECK_UCAST_PPP, CTL_RX_ENABLE, CTL_RX_ENABLE_GCP, CTL_RX_ENABLE_GPP, CTL_RX_ENABLE_PCP, CTL_RX_ENABLE_PPP, CTL_RX_FORCE_RESYNC +, CTL_RX_PAUSE_ACK, CTL_RX_PAUSE_ENABLE, CTL_RX_RSFEC_ENABLE, CTL_RX_RSFEC_ENABLE_CORRECTION, CTL_RX_RSFEC_ENABLE_INDICATION, CTL_RX_SYSTEMTIMERIN, CTL_RX_TEST_PATTERN, CTL_TX_ENABLE, CTL_TX_LANE0_VLM_BIP7_OVERRIDE, CTL_TX_LANE0_VLM_BIP7_OVERRIDE_VALUE, CTL_TX_PAUSE_ENABLE, CTL_TX_PAUSE_QUANTA0, CTL_TX_PAUSE_QUANTA1, CTL_TX_PAUSE_QUANTA2, CTL_TX_PAUSE_QUANTA3, CTL_TX_PAUSE_QUANTA4, CTL_TX_PAUSE_QUANTA5, CTL_TX_PAUSE_QUANTA6, CTL_TX_PAUSE_QUANTA7, CTL_TX_PAUSE_QUANTA8, CTL_TX_PAUSE_REFRESH_TIMER0 +, CTL_TX_PAUSE_REFRESH_TIMER1, CTL_TX_PAUSE_REFRESH_TIMER2, CTL_TX_PAUSE_REFRESH_TIMER3, CTL_TX_PAUSE_REFRESH_TIMER4, CTL_TX_PAUSE_REFRESH_TIMER5, CTL_TX_PAUSE_REFRESH_TIMER6, CTL_TX_PAUSE_REFRESH_TIMER7, CTL_TX_PAUSE_REFRESH_TIMER8, CTL_TX_PAUSE_REQ, CTL_TX_PTP_VLANE_ADJUST_MODE, CTL_TX_RESEND_PAUSE, CTL_TX_RSFEC_ENABLE, CTL_TX_SEND_IDLE, CTL_TX_SEND_LFI, CTL_TX_SEND_RFI, CTL_TX_SYSTEMTIMERIN, CTL_TX_TEST_PATTERN, DRP_ADDR, DRP_CLK, DRP_DI, DRP_EN +, DRP_WE, RSFEC_BYPASS_RX_DIN, RSFEC_BYPASS_RX_DIN_CW_START, RSFEC_BYPASS_TX_DIN, RSFEC_BYPASS_TX_DIN_CW_START, RX_CLK, RX_RESET, RX_SERDES_ALT_DATA0, RX_SERDES_ALT_DATA1, RX_SERDES_ALT_DATA2, RX_SERDES_ALT_DATA3, RX_SERDES_CLK, RX_SERDES_DATA0, RX_SERDES_DATA1, RX_SERDES_DATA2, RX_SERDES_DATA3, RX_SERDES_DATA4, RX_SERDES_DATA5, RX_SERDES_DATA6, RX_SERDES_DATA7, RX_SERDES_DATA8 +, RX_SERDES_DATA9, RX_SERDES_RESET, TX_CLK, TX_DATAIN0, TX_DATAIN1, TX_DATAIN2, TX_DATAIN3, TX_ENAIN0, TX_ENAIN1, TX_ENAIN2, TX_ENAIN3, TX_EOPIN0, TX_EOPIN1, TX_EOPIN2, TX_EOPIN3, TX_ERRIN0, TX_ERRIN1, TX_ERRIN2, TX_ERRIN3, TX_MTYIN0, TX_MTYIN1 +, TX_MTYIN2, TX_MTYIN3, TX_PREIN, TX_PTP_1588OP_IN, TX_PTP_CHKSUM_OFFSET_IN, TX_PTP_RXTSTAMP_IN, TX_PTP_TAG_FIELD_IN, TX_PTP_TSTAMP_OFFSET_IN, TX_PTP_UPD_CHKSUM_IN, TX_RESET, TX_SOPIN0, TX_SOPIN1, TX_SOPIN2, TX_SOPIN3); parameter CTL_PTP_TRANSPCLK_MODE = "FALSE"; parameter CTL_RX_CHECK_ACK = "TRUE"; parameter CTL_RX_CHECK_PREAMBLE = "FALSE"; @@ -28033,7 +28493,16 @@ module CMACE4 (...); input TX_SOPIN3; endmodule -module MCB (...); +module MCB(CAS, CKE, DQIOWEN0, DQSIOWEN90N, DQSIOWEN90P, IOIDRPADD, IOIDRPBROADCAST, IOIDRPCLK, IOIDRPCS, IOIDRPSDO, IOIDRPTRAIN, IOIDRPUPDATE, LDMN, LDMP, ODT, P0CMDEMPTY, P0CMDFULL, P0RDEMPTY, P0RDERROR, P0RDFULL, P0RDOVERFLOW +, P0WREMPTY, P0WRERROR, P0WRFULL, P0WRUNDERRUN, P1CMDEMPTY, P1CMDFULL, P1RDEMPTY, P1RDERROR, P1RDFULL, P1RDOVERFLOW, P1WREMPTY, P1WRERROR, P1WRFULL, P1WRUNDERRUN, P2CMDEMPTY, P2CMDFULL, P2EMPTY, P2ERROR, P2FULL, P2RDOVERFLOW, P2WRUNDERRUN +, P3CMDEMPTY, P3CMDFULL, P3EMPTY, P3ERROR, P3FULL, P3RDOVERFLOW, P3WRUNDERRUN, P4CMDEMPTY, P4CMDFULL, P4EMPTY, P4ERROR, P4FULL, P4RDOVERFLOW, P4WRUNDERRUN, P5CMDEMPTY, P5CMDFULL, P5EMPTY, P5ERROR, P5FULL, P5RDOVERFLOW, P5WRUNDERRUN +, RAS, RST, SELFREFRESHMODE, UDMN, UDMP, UOCALSTART, UOCMDREADYIN, UODATAVALID, UODONECAL, UOREFRSHFLAG, UOSDO, WE, ADDR, DQON, DQOP, BA, P0RDDATA, P1RDDATA, P2RDDATA, P3RDDATA, P4RDDATA +, P5RDDATA, STATUS, IOIDRPADDR, P0RDCOUNT, P0WRCOUNT, P1RDCOUNT, P1WRCOUNT, P2COUNT, P3COUNT, P4COUNT, P5COUNT, UODATA, DQSIOIN, DQSIOIP, IOIDRPSDI, P0ARBEN, P0CMDCLK, P0CMDEN, P0RDCLK, P0RDEN, P0WRCLK +, P0WREN, P1ARBEN, P1CMDCLK, P1CMDEN, P1RDCLK, P1RDEN, P1WRCLK, P1WREN, P2ARBEN, P2CLK, P2CMDCLK, P2CMDEN, P2EN, P3ARBEN, P3CLK, P3CMDCLK, P3CMDEN, P3EN, P4ARBEN, P4CLK, P4CMDCLK +, P4CMDEN, P4EN, P5ARBEN, P5CLK, P5CMDCLK, P5CMDEN, P5EN, PLLLOCK, RECAL, SELFREFRESHENTER, SYSRST, UDQSIOIN, UDQSIOIP, UIADD, UIBROADCAST, UICLK, UICMD, UICMDEN, UICMDIN, UICS, UIDONECAL +, UIDQLOWERDEC, UIDQLOWERINC, UIDQUPPERDEC, UIDQUPPERINC, UIDRPUPDATE, UILDQSDEC, UILDQSINC, UIREAD, UISDI, UIUDQSDEC, UIUDQSINC, P0CMDCA, P1CMDCA, P2CMDCA, P3CMDCA, P4CMDCA, P5CMDCA, P0CMDRA, P1CMDRA, P2CMDRA, P3CMDRA +, P4CMDRA, P5CMDRA, DQI, PLLCE, PLLCLK, P0CMDBA, P0CMDINSTR, P1CMDBA, P1CMDINSTR, P2CMDBA, P2CMDINSTR, P3CMDBA, P3CMDINSTR, P4CMDBA, P4CMDINSTR, P5CMDBA, P5CMDINSTR, P0WRDATA, P1WRDATA, P2WRDATA, P3WRDATA +, P4WRDATA, P5WRDATA, P0RWRMASK, P1RWRMASK, P2WRMASK, P3WRMASK, P4WRMASK, P5WRMASK, UIDQCOUNT, UIADDR, P0CMDBL, P1CMDBL, P2CMDBL, P3CMDBL, P4CMDBL, P5CMDBL); parameter integer ARB_NUM_TIME_SLOTS = 12; parameter [17:0] ARB_TIME_SLOT_0 = 18'b111111111111111111; parameter [17:0] ARB_TIME_SLOT_1 = 18'b111111111111111111; @@ -28297,12 +28766,12 @@ module MCB (...); endmodule (* keep *) -module HBM_REF_CLK (...); +module HBM_REF_CLK(REF_CLK); input REF_CLK; endmodule (* keep *) -module HBM_SNGLBLI_INTF_APB (...); +module HBM_SNGLBLI_INTF_APB(CATTRIP_PIPE, PRDATA_PIPE, PREADY_PIPE, PSLVERR_PIPE, TEMP_PIPE, PADDR, PCLK, PENABLE, PRESET_N, PSEL, PWDATA, PWRITE); parameter CLK_SEL = "FALSE"; parameter [0:0] IS_PCLK_INVERTED = 1'b0; parameter [0:0] IS_PRESET_N_INVERTED = 1'b0; @@ -28327,7 +28796,9 @@ module HBM_SNGLBLI_INTF_APB (...); endmodule (* keep *) -module HBM_SNGLBLI_INTF_AXI (...); +module HBM_SNGLBLI_INTF_AXI(ARREADY_PIPE, AWREADY_PIPE, BID_PIPE, BRESP_PIPE, BVALID_PIPE, DFI_AW_AERR_N_PIPE, DFI_CLK_BUF, DFI_CTRLUPD_ACK_PIPE, DFI_DBI_BYTE_DISABLE_PIPE, DFI_DW_RDDATA_DBI_PIPE, DFI_DW_RDDATA_DERR_PIPE, DFI_DW_RDDATA_PAR_VALID_PIPE, DFI_DW_RDDATA_VALID_PIPE, DFI_INIT_COMPLETE_PIPE, DFI_PHYUPD_REQ_PIPE, DFI_PHYUPD_TYPE_PIPE, DFI_PHY_LP_STATE_PIPE, DFI_RST_N_BUF, MC_STATUS, PHY_STATUS, RDATA_PARITY_PIPE +, RDATA_PIPE, RID_PIPE, RLAST_PIPE, RRESP_PIPE, RVALID_PIPE, STATUS, WREADY_PIPE, ACLK, ARADDR, ARBURST, ARESET_N, ARID, ARLEN, ARSIZE, ARVALID, AWADDR, AWBURST, AWID, AWLEN, AWSIZE, AWVALID +, BREADY, BSCAN_CK, DFI_LP_PWR_X_REQ, MBIST_EN, RREADY, WDATA, WDATA_PARITY, WLAST, WSTRB, WVALID); parameter CLK_SEL = "FALSE"; parameter integer DATARATE = 1800; parameter [0:0] IS_ACLK_INVERTED = 1'b0; @@ -28395,7 +28866,42 @@ module HBM_SNGLBLI_INTF_AXI (...); endmodule (* keep *) -module HBM_ONE_STACK_INTF (...); +module HBM_ONE_STACK_INTF(APB_0_PRDATA, APB_0_PREADY, APB_0_PSLVERR, AXI_00_ARREADY, AXI_00_AWREADY, AXI_00_BID, AXI_00_BRESP, AXI_00_BVALID, AXI_00_DFI_AW_AERR_N, AXI_00_DFI_CLK_BUF, AXI_00_DFI_DBI_BYTE_DISABLE, AXI_00_DFI_DW_RDDATA_DBI, AXI_00_DFI_DW_RDDATA_DERR, AXI_00_DFI_DW_RDDATA_VALID, AXI_00_DFI_INIT_COMPLETE, AXI_00_DFI_PHYUPD_REQ, AXI_00_DFI_PHY_LP_STATE, AXI_00_DFI_RST_N_BUF, AXI_00_MC_STATUS, AXI_00_PHY_STATUS, AXI_00_RDATA +, AXI_00_RDATA_PARITY, AXI_00_RID, AXI_00_RLAST, AXI_00_RRESP, AXI_00_RVALID, AXI_00_WREADY, AXI_01_ARREADY, AXI_01_AWREADY, AXI_01_BID, AXI_01_BRESP, AXI_01_BVALID, AXI_01_DFI_AW_AERR_N, AXI_01_DFI_CLK_BUF, AXI_01_DFI_DBI_BYTE_DISABLE, AXI_01_DFI_DW_RDDATA_DBI, AXI_01_DFI_DW_RDDATA_DERR, AXI_01_DFI_DW_RDDATA_VALID, AXI_01_DFI_INIT_COMPLETE, AXI_01_DFI_PHYUPD_REQ, AXI_01_DFI_PHY_LP_STATE, AXI_01_DFI_RST_N_BUF +, AXI_01_RDATA, AXI_01_RDATA_PARITY, AXI_01_RID, AXI_01_RLAST, AXI_01_RRESP, AXI_01_RVALID, AXI_01_WREADY, AXI_02_ARREADY, AXI_02_AWREADY, AXI_02_BID, AXI_02_BRESP, AXI_02_BVALID, AXI_02_DFI_AW_AERR_N, AXI_02_DFI_CLK_BUF, AXI_02_DFI_DBI_BYTE_DISABLE, AXI_02_DFI_DW_RDDATA_DBI, AXI_02_DFI_DW_RDDATA_DERR, AXI_02_DFI_DW_RDDATA_VALID, AXI_02_DFI_INIT_COMPLETE, AXI_02_DFI_PHYUPD_REQ, AXI_02_DFI_PHY_LP_STATE +, AXI_02_DFI_RST_N_BUF, AXI_02_MC_STATUS, AXI_02_PHY_STATUS, AXI_02_RDATA, AXI_02_RDATA_PARITY, AXI_02_RID, AXI_02_RLAST, AXI_02_RRESP, AXI_02_RVALID, AXI_02_WREADY, AXI_03_ARREADY, AXI_03_AWREADY, AXI_03_BID, AXI_03_BRESP, AXI_03_BVALID, AXI_03_DFI_AW_AERR_N, AXI_03_DFI_CLK_BUF, AXI_03_DFI_DBI_BYTE_DISABLE, AXI_03_DFI_DW_RDDATA_DBI, AXI_03_DFI_DW_RDDATA_DERR, AXI_03_DFI_DW_RDDATA_VALID +, AXI_03_DFI_INIT_COMPLETE, AXI_03_DFI_PHYUPD_REQ, AXI_03_DFI_PHY_LP_STATE, AXI_03_DFI_RST_N_BUF, AXI_03_RDATA, AXI_03_RDATA_PARITY, AXI_03_RID, AXI_03_RLAST, AXI_03_RRESP, AXI_03_RVALID, AXI_03_WREADY, AXI_04_ARREADY, AXI_04_AWREADY, AXI_04_BID, AXI_04_BRESP, AXI_04_BVALID, AXI_04_DFI_AW_AERR_N, AXI_04_DFI_CLK_BUF, AXI_04_DFI_DBI_BYTE_DISABLE, AXI_04_DFI_DW_RDDATA_DBI, AXI_04_DFI_DW_RDDATA_DERR +, AXI_04_DFI_DW_RDDATA_VALID, AXI_04_DFI_INIT_COMPLETE, AXI_04_DFI_PHYUPD_REQ, AXI_04_DFI_PHY_LP_STATE, AXI_04_DFI_RST_N_BUF, AXI_04_MC_STATUS, AXI_04_PHY_STATUS, AXI_04_RDATA, AXI_04_RDATA_PARITY, AXI_04_RID, AXI_04_RLAST, AXI_04_RRESP, AXI_04_RVALID, AXI_04_WREADY, AXI_05_ARREADY, AXI_05_AWREADY, AXI_05_BID, AXI_05_BRESP, AXI_05_BVALID, AXI_05_DFI_AW_AERR_N, AXI_05_DFI_CLK_BUF +, AXI_05_DFI_DBI_BYTE_DISABLE, AXI_05_DFI_DW_RDDATA_DBI, AXI_05_DFI_DW_RDDATA_DERR, AXI_05_DFI_DW_RDDATA_VALID, AXI_05_DFI_INIT_COMPLETE, AXI_05_DFI_PHYUPD_REQ, AXI_05_DFI_PHY_LP_STATE, AXI_05_DFI_RST_N_BUF, AXI_05_RDATA, AXI_05_RDATA_PARITY, AXI_05_RID, AXI_05_RLAST, AXI_05_RRESP, AXI_05_RVALID, AXI_05_WREADY, AXI_06_ARREADY, AXI_06_AWREADY, AXI_06_BID, AXI_06_BRESP, AXI_06_BVALID, AXI_06_DFI_AW_AERR_N +, AXI_06_DFI_CLK_BUF, AXI_06_DFI_DBI_BYTE_DISABLE, AXI_06_DFI_DW_RDDATA_DBI, AXI_06_DFI_DW_RDDATA_DERR, AXI_06_DFI_DW_RDDATA_VALID, AXI_06_DFI_INIT_COMPLETE, AXI_06_DFI_PHYUPD_REQ, AXI_06_DFI_PHY_LP_STATE, AXI_06_DFI_RST_N_BUF, AXI_06_MC_STATUS, AXI_06_PHY_STATUS, AXI_06_RDATA, AXI_06_RDATA_PARITY, AXI_06_RID, AXI_06_RLAST, AXI_06_RRESP, AXI_06_RVALID, AXI_06_WREADY, AXI_07_ARREADY, AXI_07_AWREADY, AXI_07_BID +, AXI_07_BRESP, AXI_07_BVALID, AXI_07_DFI_AW_AERR_N, AXI_07_DFI_CLK_BUF, AXI_07_DFI_DBI_BYTE_DISABLE, AXI_07_DFI_DW_RDDATA_DBI, AXI_07_DFI_DW_RDDATA_DERR, AXI_07_DFI_DW_RDDATA_VALID, AXI_07_DFI_INIT_COMPLETE, AXI_07_DFI_PHYUPD_REQ, AXI_07_DFI_PHY_LP_STATE, AXI_07_DFI_RST_N_BUF, AXI_07_RDATA, AXI_07_RDATA_PARITY, AXI_07_RID, AXI_07_RLAST, AXI_07_RRESP, AXI_07_RVALID, AXI_07_WREADY, AXI_08_ARREADY, AXI_08_AWREADY +, AXI_08_BID, AXI_08_BRESP, AXI_08_BVALID, AXI_08_DFI_AW_AERR_N, AXI_08_DFI_CLK_BUF, AXI_08_DFI_DBI_BYTE_DISABLE, AXI_08_DFI_DW_RDDATA_DBI, AXI_08_DFI_DW_RDDATA_DERR, AXI_08_DFI_DW_RDDATA_VALID, AXI_08_DFI_INIT_COMPLETE, AXI_08_DFI_PHYUPD_REQ, AXI_08_DFI_PHY_LP_STATE, AXI_08_DFI_RST_N_BUF, AXI_08_MC_STATUS, AXI_08_PHY_STATUS, AXI_08_RDATA, AXI_08_RDATA_PARITY, AXI_08_RID, AXI_08_RLAST, AXI_08_RRESP, AXI_08_RVALID +, AXI_08_WREADY, AXI_09_ARREADY, AXI_09_AWREADY, AXI_09_BID, AXI_09_BRESP, AXI_09_BVALID, AXI_09_DFI_AW_AERR_N, AXI_09_DFI_CLK_BUF, AXI_09_DFI_DBI_BYTE_DISABLE, AXI_09_DFI_DW_RDDATA_DBI, AXI_09_DFI_DW_RDDATA_DERR, AXI_09_DFI_DW_RDDATA_VALID, AXI_09_DFI_INIT_COMPLETE, AXI_09_DFI_PHYUPD_REQ, AXI_09_DFI_PHY_LP_STATE, AXI_09_DFI_RST_N_BUF, AXI_09_RDATA, AXI_09_RDATA_PARITY, AXI_09_RID, AXI_09_RLAST, AXI_09_RRESP +, AXI_09_RVALID, AXI_09_WREADY, AXI_10_ARREADY, AXI_10_AWREADY, AXI_10_BID, AXI_10_BRESP, AXI_10_BVALID, AXI_10_DFI_AW_AERR_N, AXI_10_DFI_CLK_BUF, AXI_10_DFI_DBI_BYTE_DISABLE, AXI_10_DFI_DW_RDDATA_DBI, AXI_10_DFI_DW_RDDATA_DERR, AXI_10_DFI_DW_RDDATA_VALID, AXI_10_DFI_INIT_COMPLETE, AXI_10_DFI_PHYUPD_REQ, AXI_10_DFI_PHY_LP_STATE, AXI_10_DFI_RST_N_BUF, AXI_10_MC_STATUS, AXI_10_PHY_STATUS, AXI_10_RDATA, AXI_10_RDATA_PARITY +, AXI_10_RID, AXI_10_RLAST, AXI_10_RRESP, AXI_10_RVALID, AXI_10_WREADY, AXI_11_ARREADY, AXI_11_AWREADY, AXI_11_BID, AXI_11_BRESP, AXI_11_BVALID, AXI_11_DFI_AW_AERR_N, AXI_11_DFI_CLK_BUF, AXI_11_DFI_DBI_BYTE_DISABLE, AXI_11_DFI_DW_RDDATA_DBI, AXI_11_DFI_DW_RDDATA_DERR, AXI_11_DFI_DW_RDDATA_VALID, AXI_11_DFI_INIT_COMPLETE, AXI_11_DFI_PHYUPD_REQ, AXI_11_DFI_PHY_LP_STATE, AXI_11_DFI_RST_N_BUF, AXI_11_RDATA +, AXI_11_RDATA_PARITY, AXI_11_RID, AXI_11_RLAST, AXI_11_RRESP, AXI_11_RVALID, AXI_11_WREADY, AXI_12_ARREADY, AXI_12_AWREADY, AXI_12_BID, AXI_12_BRESP, AXI_12_BVALID, AXI_12_DFI_AW_AERR_N, AXI_12_DFI_CLK_BUF, AXI_12_DFI_DBI_BYTE_DISABLE, AXI_12_DFI_DW_RDDATA_DBI, AXI_12_DFI_DW_RDDATA_DERR, AXI_12_DFI_DW_RDDATA_VALID, AXI_12_DFI_INIT_COMPLETE, AXI_12_DFI_PHYUPD_REQ, AXI_12_DFI_PHY_LP_STATE, AXI_12_DFI_RST_N_BUF +, AXI_12_MC_STATUS, AXI_12_PHY_STATUS, AXI_12_RDATA, AXI_12_RDATA_PARITY, AXI_12_RID, AXI_12_RLAST, AXI_12_RRESP, AXI_12_RVALID, AXI_12_WREADY, AXI_13_ARREADY, AXI_13_AWREADY, AXI_13_BID, AXI_13_BRESP, AXI_13_BVALID, AXI_13_DFI_AW_AERR_N, AXI_13_DFI_CLK_BUF, AXI_13_DFI_DBI_BYTE_DISABLE, AXI_13_DFI_DW_RDDATA_DBI, AXI_13_DFI_DW_RDDATA_DERR, AXI_13_DFI_DW_RDDATA_VALID, AXI_13_DFI_INIT_COMPLETE +, AXI_13_DFI_PHYUPD_REQ, AXI_13_DFI_PHY_LP_STATE, AXI_13_DFI_RST_N_BUF, AXI_13_RDATA, AXI_13_RDATA_PARITY, AXI_13_RID, AXI_13_RLAST, AXI_13_RRESP, AXI_13_RVALID, AXI_13_WREADY, AXI_14_ARREADY, AXI_14_AWREADY, AXI_14_BID, AXI_14_BRESP, AXI_14_BVALID, AXI_14_DFI_AW_AERR_N, AXI_14_DFI_CLK_BUF, AXI_14_DFI_DBI_BYTE_DISABLE, AXI_14_DFI_DW_RDDATA_DBI, AXI_14_DFI_DW_RDDATA_DERR, AXI_14_DFI_DW_RDDATA_VALID +, AXI_14_DFI_INIT_COMPLETE, AXI_14_DFI_PHYUPD_REQ, AXI_14_DFI_PHY_LP_STATE, AXI_14_DFI_RST_N_BUF, AXI_14_MC_STATUS, AXI_14_PHY_STATUS, AXI_14_RDATA, AXI_14_RDATA_PARITY, AXI_14_RID, AXI_14_RLAST, AXI_14_RRESP, AXI_14_RVALID, AXI_14_WREADY, AXI_15_ARREADY, AXI_15_AWREADY, AXI_15_BID, AXI_15_BRESP, AXI_15_BVALID, AXI_15_DFI_AW_AERR_N, AXI_15_DFI_CLK_BUF, AXI_15_DFI_DBI_BYTE_DISABLE +, AXI_15_DFI_DW_RDDATA_DBI, AXI_15_DFI_DW_RDDATA_DERR, AXI_15_DFI_DW_RDDATA_VALID, AXI_15_DFI_INIT_COMPLETE, AXI_15_DFI_PHYUPD_REQ, AXI_15_DFI_PHY_LP_STATE, AXI_15_DFI_RST_N_BUF, AXI_15_RDATA, AXI_15_RDATA_PARITY, AXI_15_RID, AXI_15_RLAST, AXI_15_RRESP, AXI_15_RVALID, AXI_15_WREADY, DRAM_0_STAT_CATTRIP, DRAM_0_STAT_TEMP, APB_0_PADDR, APB_0_PCLK, APB_0_PENABLE, APB_0_PRESET_N, APB_0_PSEL +, APB_0_PWDATA, APB_0_PWRITE, AXI_00_ACLK, AXI_00_ARADDR, AXI_00_ARBURST, AXI_00_ARESET_N, AXI_00_ARID, AXI_00_ARLEN, AXI_00_ARSIZE, AXI_00_ARVALID, AXI_00_AWADDR, AXI_00_AWBURST, AXI_00_AWID, AXI_00_AWLEN, AXI_00_AWSIZE, AXI_00_AWVALID, AXI_00_BREADY, AXI_00_DFI_LP_PWR_X_REQ, AXI_00_RREADY, AXI_00_WDATA, AXI_00_WDATA_PARITY +, AXI_00_WLAST, AXI_00_WSTRB, AXI_00_WVALID, AXI_01_ACLK, AXI_01_ARADDR, AXI_01_ARBURST, AXI_01_ARESET_N, AXI_01_ARID, AXI_01_ARLEN, AXI_01_ARSIZE, AXI_01_ARVALID, AXI_01_AWADDR, AXI_01_AWBURST, AXI_01_AWID, AXI_01_AWLEN, AXI_01_AWSIZE, AXI_01_AWVALID, AXI_01_BREADY, AXI_01_DFI_LP_PWR_X_REQ, AXI_01_RREADY, AXI_01_WDATA +, AXI_01_WDATA_PARITY, AXI_01_WLAST, AXI_01_WSTRB, AXI_01_WVALID, AXI_02_ACLK, AXI_02_ARADDR, AXI_02_ARBURST, AXI_02_ARESET_N, AXI_02_ARID, AXI_02_ARLEN, AXI_02_ARSIZE, AXI_02_ARVALID, AXI_02_AWADDR, AXI_02_AWBURST, AXI_02_AWID, AXI_02_AWLEN, AXI_02_AWSIZE, AXI_02_AWVALID, AXI_02_BREADY, AXI_02_DFI_LP_PWR_X_REQ, AXI_02_RREADY +, AXI_02_WDATA, AXI_02_WDATA_PARITY, AXI_02_WLAST, AXI_02_WSTRB, AXI_02_WVALID, AXI_03_ACLK, AXI_03_ARADDR, AXI_03_ARBURST, AXI_03_ARESET_N, AXI_03_ARID, AXI_03_ARLEN, AXI_03_ARSIZE, AXI_03_ARVALID, AXI_03_AWADDR, AXI_03_AWBURST, AXI_03_AWID, AXI_03_AWLEN, AXI_03_AWSIZE, AXI_03_AWVALID, AXI_03_BREADY, AXI_03_DFI_LP_PWR_X_REQ +, AXI_03_RREADY, AXI_03_WDATA, AXI_03_WDATA_PARITY, AXI_03_WLAST, AXI_03_WSTRB, AXI_03_WVALID, AXI_04_ACLK, AXI_04_ARADDR, AXI_04_ARBURST, AXI_04_ARESET_N, AXI_04_ARID, AXI_04_ARLEN, AXI_04_ARSIZE, AXI_04_ARVALID, AXI_04_AWADDR, AXI_04_AWBURST, AXI_04_AWID, AXI_04_AWLEN, AXI_04_AWSIZE, AXI_04_AWVALID, AXI_04_BREADY +, AXI_04_DFI_LP_PWR_X_REQ, AXI_04_RREADY, AXI_04_WDATA, AXI_04_WDATA_PARITY, AXI_04_WLAST, AXI_04_WSTRB, AXI_04_WVALID, AXI_05_ACLK, AXI_05_ARADDR, AXI_05_ARBURST, AXI_05_ARESET_N, AXI_05_ARID, AXI_05_ARLEN, AXI_05_ARSIZE, AXI_05_ARVALID, AXI_05_AWADDR, AXI_05_AWBURST, AXI_05_AWID, AXI_05_AWLEN, AXI_05_AWSIZE, AXI_05_AWVALID +, AXI_05_BREADY, AXI_05_DFI_LP_PWR_X_REQ, AXI_05_RREADY, AXI_05_WDATA, AXI_05_WDATA_PARITY, AXI_05_WLAST, AXI_05_WSTRB, AXI_05_WVALID, AXI_06_ACLK, AXI_06_ARADDR, AXI_06_ARBURST, AXI_06_ARESET_N, AXI_06_ARID, AXI_06_ARLEN, AXI_06_ARSIZE, AXI_06_ARVALID, AXI_06_AWADDR, AXI_06_AWBURST, AXI_06_AWID, AXI_06_AWLEN, AXI_06_AWSIZE +, AXI_06_AWVALID, AXI_06_BREADY, AXI_06_DFI_LP_PWR_X_REQ, AXI_06_RREADY, AXI_06_WDATA, AXI_06_WDATA_PARITY, AXI_06_WLAST, AXI_06_WSTRB, AXI_06_WVALID, AXI_07_ACLK, AXI_07_ARADDR, AXI_07_ARBURST, AXI_07_ARESET_N, AXI_07_ARID, AXI_07_ARLEN, AXI_07_ARSIZE, AXI_07_ARVALID, AXI_07_AWADDR, AXI_07_AWBURST, AXI_07_AWID, AXI_07_AWLEN +, AXI_07_AWSIZE, AXI_07_AWVALID, AXI_07_BREADY, AXI_07_DFI_LP_PWR_X_REQ, AXI_07_RREADY, AXI_07_WDATA, AXI_07_WDATA_PARITY, AXI_07_WLAST, AXI_07_WSTRB, AXI_07_WVALID, AXI_08_ACLK, AXI_08_ARADDR, AXI_08_ARBURST, AXI_08_ARESET_N, AXI_08_ARID, AXI_08_ARLEN, AXI_08_ARSIZE, AXI_08_ARVALID, AXI_08_AWADDR, AXI_08_AWBURST, AXI_08_AWID +, AXI_08_AWLEN, AXI_08_AWSIZE, AXI_08_AWVALID, AXI_08_BREADY, AXI_08_DFI_LP_PWR_X_REQ, AXI_08_RREADY, AXI_08_WDATA, AXI_08_WDATA_PARITY, AXI_08_WLAST, AXI_08_WSTRB, AXI_08_WVALID, AXI_09_ACLK, AXI_09_ARADDR, AXI_09_ARBURST, AXI_09_ARESET_N, AXI_09_ARID, AXI_09_ARLEN, AXI_09_ARSIZE, AXI_09_ARVALID, AXI_09_AWADDR, AXI_09_AWBURST +, AXI_09_AWID, AXI_09_AWLEN, AXI_09_AWSIZE, AXI_09_AWVALID, AXI_09_BREADY, AXI_09_DFI_LP_PWR_X_REQ, AXI_09_RREADY, AXI_09_WDATA, AXI_09_WDATA_PARITY, AXI_09_WLAST, AXI_09_WSTRB, AXI_09_WVALID, AXI_10_ACLK, AXI_10_ARADDR, AXI_10_ARBURST, AXI_10_ARESET_N, AXI_10_ARID, AXI_10_ARLEN, AXI_10_ARSIZE, AXI_10_ARVALID, AXI_10_AWADDR +, AXI_10_AWBURST, AXI_10_AWID, AXI_10_AWLEN, AXI_10_AWSIZE, AXI_10_AWVALID, AXI_10_BREADY, AXI_10_DFI_LP_PWR_X_REQ, AXI_10_RREADY, AXI_10_WDATA, AXI_10_WDATA_PARITY, AXI_10_WLAST, AXI_10_WSTRB, AXI_10_WVALID, AXI_11_ACLK, AXI_11_ARADDR, AXI_11_ARBURST, AXI_11_ARESET_N, AXI_11_ARID, AXI_11_ARLEN, AXI_11_ARSIZE, AXI_11_ARVALID +, AXI_11_AWADDR, AXI_11_AWBURST, AXI_11_AWID, AXI_11_AWLEN, AXI_11_AWSIZE, AXI_11_AWVALID, AXI_11_BREADY, AXI_11_DFI_LP_PWR_X_REQ, AXI_11_RREADY, AXI_11_WDATA, AXI_11_WDATA_PARITY, AXI_11_WLAST, AXI_11_WSTRB, AXI_11_WVALID, AXI_12_ACLK, AXI_12_ARADDR, AXI_12_ARBURST, AXI_12_ARESET_N, AXI_12_ARID, AXI_12_ARLEN, AXI_12_ARSIZE +, AXI_12_ARVALID, AXI_12_AWADDR, AXI_12_AWBURST, AXI_12_AWID, AXI_12_AWLEN, AXI_12_AWSIZE, AXI_12_AWVALID, AXI_12_BREADY, AXI_12_DFI_LP_PWR_X_REQ, AXI_12_RREADY, AXI_12_WDATA, AXI_12_WDATA_PARITY, AXI_12_WLAST, AXI_12_WSTRB, AXI_12_WVALID, AXI_13_ACLK, AXI_13_ARADDR, AXI_13_ARBURST, AXI_13_ARESET_N, AXI_13_ARID, AXI_13_ARLEN +, AXI_13_ARSIZE, AXI_13_ARVALID, AXI_13_AWADDR, AXI_13_AWBURST, AXI_13_AWID, AXI_13_AWLEN, AXI_13_AWSIZE, AXI_13_AWVALID, AXI_13_BREADY, AXI_13_DFI_LP_PWR_X_REQ, AXI_13_RREADY, AXI_13_WDATA, AXI_13_WDATA_PARITY, AXI_13_WLAST, AXI_13_WSTRB, AXI_13_WVALID, AXI_14_ACLK, AXI_14_ARADDR, AXI_14_ARBURST, AXI_14_ARESET_N, AXI_14_ARID +, AXI_14_ARLEN, AXI_14_ARSIZE, AXI_14_ARVALID, AXI_14_AWADDR, AXI_14_AWBURST, AXI_14_AWID, AXI_14_AWLEN, AXI_14_AWSIZE, AXI_14_AWVALID, AXI_14_BREADY, AXI_14_DFI_LP_PWR_X_REQ, AXI_14_RREADY, AXI_14_WDATA, AXI_14_WDATA_PARITY, AXI_14_WLAST, AXI_14_WSTRB, AXI_14_WVALID, AXI_15_ACLK, AXI_15_ARADDR, AXI_15_ARBURST, AXI_15_ARESET_N +, AXI_15_ARID, AXI_15_ARLEN, AXI_15_ARSIZE, AXI_15_ARVALID, AXI_15_AWADDR, AXI_15_AWBURST, AXI_15_AWID, AXI_15_AWLEN, AXI_15_AWSIZE, AXI_15_AWVALID, AXI_15_BREADY, AXI_15_DFI_LP_PWR_X_REQ, AXI_15_RREADY, AXI_15_WDATA, AXI_15_WDATA_PARITY, AXI_15_WLAST, AXI_15_WSTRB, AXI_15_WVALID, BSCAN_DRCK, BSCAN_TCK, HBM_REF_CLK +, MBIST_EN_00, MBIST_EN_01, MBIST_EN_02, MBIST_EN_03, MBIST_EN_04, MBIST_EN_05, MBIST_EN_06, MBIST_EN_07); parameter CLK_SEL_00 = "FALSE"; parameter CLK_SEL_01 = "FALSE"; parameter CLK_SEL_02 = "FALSE"; @@ -29298,7 +29804,77 @@ module HBM_ONE_STACK_INTF (...); endmodule (* keep *) -module HBM_TWO_STACK_INTF (...); +module HBM_TWO_STACK_INTF(APB_0_PRDATA, APB_0_PREADY, APB_0_PSLVERR, APB_1_PRDATA, APB_1_PREADY, APB_1_PSLVERR, AXI_00_ARREADY, AXI_00_AWREADY, AXI_00_BID, AXI_00_BRESP, AXI_00_BVALID, AXI_00_DFI_AW_AERR_N, AXI_00_DFI_CLK_BUF, AXI_00_DFI_DBI_BYTE_DISABLE, AXI_00_DFI_DW_RDDATA_DBI, AXI_00_DFI_DW_RDDATA_DERR, AXI_00_DFI_DW_RDDATA_VALID, AXI_00_DFI_INIT_COMPLETE, AXI_00_DFI_PHYUPD_REQ, AXI_00_DFI_PHY_LP_STATE, AXI_00_DFI_RST_N_BUF +, AXI_00_MC_STATUS, AXI_00_PHY_STATUS, AXI_00_RDATA, AXI_00_RDATA_PARITY, AXI_00_RID, AXI_00_RLAST, AXI_00_RRESP, AXI_00_RVALID, AXI_00_WREADY, AXI_01_ARREADY, AXI_01_AWREADY, AXI_01_BID, AXI_01_BRESP, AXI_01_BVALID, AXI_01_DFI_AW_AERR_N, AXI_01_DFI_CLK_BUF, AXI_01_DFI_DBI_BYTE_DISABLE, AXI_01_DFI_DW_RDDATA_DBI, AXI_01_DFI_DW_RDDATA_DERR, AXI_01_DFI_DW_RDDATA_VALID, AXI_01_DFI_INIT_COMPLETE +, AXI_01_DFI_PHYUPD_REQ, AXI_01_DFI_PHY_LP_STATE, AXI_01_DFI_RST_N_BUF, AXI_01_RDATA, AXI_01_RDATA_PARITY, AXI_01_RID, AXI_01_RLAST, AXI_01_RRESP, AXI_01_RVALID, AXI_01_WREADY, AXI_02_ARREADY, AXI_02_AWREADY, AXI_02_BID, AXI_02_BRESP, AXI_02_BVALID, AXI_02_DFI_AW_AERR_N, AXI_02_DFI_CLK_BUF, AXI_02_DFI_DBI_BYTE_DISABLE, AXI_02_DFI_DW_RDDATA_DBI, AXI_02_DFI_DW_RDDATA_DERR, AXI_02_DFI_DW_RDDATA_VALID +, AXI_02_DFI_INIT_COMPLETE, AXI_02_DFI_PHYUPD_REQ, AXI_02_DFI_PHY_LP_STATE, AXI_02_DFI_RST_N_BUF, AXI_02_MC_STATUS, AXI_02_PHY_STATUS, AXI_02_RDATA, AXI_02_RDATA_PARITY, AXI_02_RID, AXI_02_RLAST, AXI_02_RRESP, AXI_02_RVALID, AXI_02_WREADY, AXI_03_ARREADY, AXI_03_AWREADY, AXI_03_BID, AXI_03_BRESP, AXI_03_BVALID, AXI_03_DFI_AW_AERR_N, AXI_03_DFI_CLK_BUF, AXI_03_DFI_DBI_BYTE_DISABLE +, AXI_03_DFI_DW_RDDATA_DBI, AXI_03_DFI_DW_RDDATA_DERR, AXI_03_DFI_DW_RDDATA_VALID, AXI_03_DFI_INIT_COMPLETE, AXI_03_DFI_PHYUPD_REQ, AXI_03_DFI_PHY_LP_STATE, AXI_03_DFI_RST_N_BUF, AXI_03_RDATA, AXI_03_RDATA_PARITY, AXI_03_RID, AXI_03_RLAST, AXI_03_RRESP, AXI_03_RVALID, AXI_03_WREADY, AXI_04_ARREADY, AXI_04_AWREADY, AXI_04_BID, AXI_04_BRESP, AXI_04_BVALID, AXI_04_DFI_AW_AERR_N, AXI_04_DFI_CLK_BUF +, AXI_04_DFI_DBI_BYTE_DISABLE, AXI_04_DFI_DW_RDDATA_DBI, AXI_04_DFI_DW_RDDATA_DERR, AXI_04_DFI_DW_RDDATA_VALID, AXI_04_DFI_INIT_COMPLETE, AXI_04_DFI_PHYUPD_REQ, AXI_04_DFI_PHY_LP_STATE, AXI_04_DFI_RST_N_BUF, AXI_04_MC_STATUS, AXI_04_PHY_STATUS, AXI_04_RDATA, AXI_04_RDATA_PARITY, AXI_04_RID, AXI_04_RLAST, AXI_04_RRESP, AXI_04_RVALID, AXI_04_WREADY, AXI_05_ARREADY, AXI_05_AWREADY, AXI_05_BID, AXI_05_BRESP +, AXI_05_BVALID, AXI_05_DFI_AW_AERR_N, AXI_05_DFI_CLK_BUF, AXI_05_DFI_DBI_BYTE_DISABLE, AXI_05_DFI_DW_RDDATA_DBI, AXI_05_DFI_DW_RDDATA_DERR, AXI_05_DFI_DW_RDDATA_VALID, AXI_05_DFI_INIT_COMPLETE, AXI_05_DFI_PHYUPD_REQ, AXI_05_DFI_PHY_LP_STATE, AXI_05_DFI_RST_N_BUF, AXI_05_RDATA, AXI_05_RDATA_PARITY, AXI_05_RID, AXI_05_RLAST, AXI_05_RRESP, AXI_05_RVALID, AXI_05_WREADY, AXI_06_ARREADY, AXI_06_AWREADY, AXI_06_BID +, AXI_06_BRESP, AXI_06_BVALID, AXI_06_DFI_AW_AERR_N, AXI_06_DFI_CLK_BUF, AXI_06_DFI_DBI_BYTE_DISABLE, AXI_06_DFI_DW_RDDATA_DBI, AXI_06_DFI_DW_RDDATA_DERR, AXI_06_DFI_DW_RDDATA_VALID, AXI_06_DFI_INIT_COMPLETE, AXI_06_DFI_PHYUPD_REQ, AXI_06_DFI_PHY_LP_STATE, AXI_06_DFI_RST_N_BUF, AXI_06_MC_STATUS, AXI_06_PHY_STATUS, AXI_06_RDATA, AXI_06_RDATA_PARITY, AXI_06_RID, AXI_06_RLAST, AXI_06_RRESP, AXI_06_RVALID, AXI_06_WREADY +, AXI_07_ARREADY, AXI_07_AWREADY, AXI_07_BID, AXI_07_BRESP, AXI_07_BVALID, AXI_07_DFI_AW_AERR_N, AXI_07_DFI_CLK_BUF, AXI_07_DFI_DBI_BYTE_DISABLE, AXI_07_DFI_DW_RDDATA_DBI, AXI_07_DFI_DW_RDDATA_DERR, AXI_07_DFI_DW_RDDATA_VALID, AXI_07_DFI_INIT_COMPLETE, AXI_07_DFI_PHYUPD_REQ, AXI_07_DFI_PHY_LP_STATE, AXI_07_DFI_RST_N_BUF, AXI_07_RDATA, AXI_07_RDATA_PARITY, AXI_07_RID, AXI_07_RLAST, AXI_07_RRESP, AXI_07_RVALID +, AXI_07_WREADY, AXI_08_ARREADY, AXI_08_AWREADY, AXI_08_BID, AXI_08_BRESP, AXI_08_BVALID, AXI_08_DFI_AW_AERR_N, AXI_08_DFI_CLK_BUF, AXI_08_DFI_DBI_BYTE_DISABLE, AXI_08_DFI_DW_RDDATA_DBI, AXI_08_DFI_DW_RDDATA_DERR, AXI_08_DFI_DW_RDDATA_VALID, AXI_08_DFI_INIT_COMPLETE, AXI_08_DFI_PHYUPD_REQ, AXI_08_DFI_PHY_LP_STATE, AXI_08_DFI_RST_N_BUF, AXI_08_MC_STATUS, AXI_08_PHY_STATUS, AXI_08_RDATA, AXI_08_RDATA_PARITY, AXI_08_RID +, AXI_08_RLAST, AXI_08_RRESP, AXI_08_RVALID, AXI_08_WREADY, AXI_09_ARREADY, AXI_09_AWREADY, AXI_09_BID, AXI_09_BRESP, AXI_09_BVALID, AXI_09_DFI_AW_AERR_N, AXI_09_DFI_CLK_BUF, AXI_09_DFI_DBI_BYTE_DISABLE, AXI_09_DFI_DW_RDDATA_DBI, AXI_09_DFI_DW_RDDATA_DERR, AXI_09_DFI_DW_RDDATA_VALID, AXI_09_DFI_INIT_COMPLETE, AXI_09_DFI_PHYUPD_REQ, AXI_09_DFI_PHY_LP_STATE, AXI_09_DFI_RST_N_BUF, AXI_09_RDATA, AXI_09_RDATA_PARITY +, AXI_09_RID, AXI_09_RLAST, AXI_09_RRESP, AXI_09_RVALID, AXI_09_WREADY, AXI_10_ARREADY, AXI_10_AWREADY, AXI_10_BID, AXI_10_BRESP, AXI_10_BVALID, AXI_10_DFI_AW_AERR_N, AXI_10_DFI_CLK_BUF, AXI_10_DFI_DBI_BYTE_DISABLE, AXI_10_DFI_DW_RDDATA_DBI, AXI_10_DFI_DW_RDDATA_DERR, AXI_10_DFI_DW_RDDATA_VALID, AXI_10_DFI_INIT_COMPLETE, AXI_10_DFI_PHYUPD_REQ, AXI_10_DFI_PHY_LP_STATE, AXI_10_DFI_RST_N_BUF, AXI_10_MC_STATUS +, AXI_10_PHY_STATUS, AXI_10_RDATA, AXI_10_RDATA_PARITY, AXI_10_RID, AXI_10_RLAST, AXI_10_RRESP, AXI_10_RVALID, AXI_10_WREADY, AXI_11_ARREADY, AXI_11_AWREADY, AXI_11_BID, AXI_11_BRESP, AXI_11_BVALID, AXI_11_DFI_AW_AERR_N, AXI_11_DFI_CLK_BUF, AXI_11_DFI_DBI_BYTE_DISABLE, AXI_11_DFI_DW_RDDATA_DBI, AXI_11_DFI_DW_RDDATA_DERR, AXI_11_DFI_DW_RDDATA_VALID, AXI_11_DFI_INIT_COMPLETE, AXI_11_DFI_PHYUPD_REQ +, AXI_11_DFI_PHY_LP_STATE, AXI_11_DFI_RST_N_BUF, AXI_11_RDATA, AXI_11_RDATA_PARITY, AXI_11_RID, AXI_11_RLAST, AXI_11_RRESP, AXI_11_RVALID, AXI_11_WREADY, AXI_12_ARREADY, AXI_12_AWREADY, AXI_12_BID, AXI_12_BRESP, AXI_12_BVALID, AXI_12_DFI_AW_AERR_N, AXI_12_DFI_CLK_BUF, AXI_12_DFI_DBI_BYTE_DISABLE, AXI_12_DFI_DW_RDDATA_DBI, AXI_12_DFI_DW_RDDATA_DERR, AXI_12_DFI_DW_RDDATA_VALID, AXI_12_DFI_INIT_COMPLETE +, AXI_12_DFI_PHYUPD_REQ, AXI_12_DFI_PHY_LP_STATE, AXI_12_DFI_RST_N_BUF, AXI_12_MC_STATUS, AXI_12_PHY_STATUS, AXI_12_RDATA, AXI_12_RDATA_PARITY, AXI_12_RID, AXI_12_RLAST, AXI_12_RRESP, AXI_12_RVALID, AXI_12_WREADY, AXI_13_ARREADY, AXI_13_AWREADY, AXI_13_BID, AXI_13_BRESP, AXI_13_BVALID, AXI_13_DFI_AW_AERR_N, AXI_13_DFI_CLK_BUF, AXI_13_DFI_DBI_BYTE_DISABLE, AXI_13_DFI_DW_RDDATA_DBI +, AXI_13_DFI_DW_RDDATA_DERR, AXI_13_DFI_DW_RDDATA_VALID, AXI_13_DFI_INIT_COMPLETE, AXI_13_DFI_PHYUPD_REQ, AXI_13_DFI_PHY_LP_STATE, AXI_13_DFI_RST_N_BUF, AXI_13_RDATA, AXI_13_RDATA_PARITY, AXI_13_RID, AXI_13_RLAST, AXI_13_RRESP, AXI_13_RVALID, AXI_13_WREADY, AXI_14_ARREADY, AXI_14_AWREADY, AXI_14_BID, AXI_14_BRESP, AXI_14_BVALID, AXI_14_DFI_AW_AERR_N, AXI_14_DFI_CLK_BUF, AXI_14_DFI_DBI_BYTE_DISABLE +, AXI_14_DFI_DW_RDDATA_DBI, AXI_14_DFI_DW_RDDATA_DERR, AXI_14_DFI_DW_RDDATA_VALID, AXI_14_DFI_INIT_COMPLETE, AXI_14_DFI_PHYUPD_REQ, AXI_14_DFI_PHY_LP_STATE, AXI_14_DFI_RST_N_BUF, AXI_14_MC_STATUS, AXI_14_PHY_STATUS, AXI_14_RDATA, AXI_14_RDATA_PARITY, AXI_14_RID, AXI_14_RLAST, AXI_14_RRESP, AXI_14_RVALID, AXI_14_WREADY, AXI_15_ARREADY, AXI_15_AWREADY, AXI_15_BID, AXI_15_BRESP, AXI_15_BVALID +, AXI_15_DFI_AW_AERR_N, AXI_15_DFI_CLK_BUF, AXI_15_DFI_DBI_BYTE_DISABLE, AXI_15_DFI_DW_RDDATA_DBI, AXI_15_DFI_DW_RDDATA_DERR, AXI_15_DFI_DW_RDDATA_VALID, AXI_15_DFI_INIT_COMPLETE, AXI_15_DFI_PHYUPD_REQ, AXI_15_DFI_PHY_LP_STATE, AXI_15_DFI_RST_N_BUF, AXI_15_RDATA, AXI_15_RDATA_PARITY, AXI_15_RID, AXI_15_RLAST, AXI_15_RRESP, AXI_15_RVALID, AXI_15_WREADY, AXI_16_ARREADY, AXI_16_AWREADY, AXI_16_BID, AXI_16_BRESP +, AXI_16_BVALID, AXI_16_DFI_AW_AERR_N, AXI_16_DFI_CLK_BUF, AXI_16_DFI_DBI_BYTE_DISABLE, AXI_16_DFI_DW_RDDATA_DBI, AXI_16_DFI_DW_RDDATA_DERR, AXI_16_DFI_DW_RDDATA_VALID, AXI_16_DFI_INIT_COMPLETE, AXI_16_DFI_PHYUPD_REQ, AXI_16_DFI_PHY_LP_STATE, AXI_16_DFI_RST_N_BUF, AXI_16_MC_STATUS, AXI_16_PHY_STATUS, AXI_16_RDATA, AXI_16_RDATA_PARITY, AXI_16_RID, AXI_16_RLAST, AXI_16_RRESP, AXI_16_RVALID, AXI_16_WREADY, AXI_17_ARREADY +, AXI_17_AWREADY, AXI_17_BID, AXI_17_BRESP, AXI_17_BVALID, AXI_17_DFI_AW_AERR_N, AXI_17_DFI_CLK_BUF, AXI_17_DFI_DBI_BYTE_DISABLE, AXI_17_DFI_DW_RDDATA_DBI, AXI_17_DFI_DW_RDDATA_DERR, AXI_17_DFI_DW_RDDATA_VALID, AXI_17_DFI_INIT_COMPLETE, AXI_17_DFI_PHYUPD_REQ, AXI_17_DFI_PHY_LP_STATE, AXI_17_DFI_RST_N_BUF, AXI_17_RDATA, AXI_17_RDATA_PARITY, AXI_17_RID, AXI_17_RLAST, AXI_17_RRESP, AXI_17_RVALID, AXI_17_WREADY +, AXI_18_ARREADY, AXI_18_AWREADY, AXI_18_BID, AXI_18_BRESP, AXI_18_BVALID, AXI_18_DFI_AW_AERR_N, AXI_18_DFI_CLK_BUF, AXI_18_DFI_DBI_BYTE_DISABLE, AXI_18_DFI_DW_RDDATA_DBI, AXI_18_DFI_DW_RDDATA_DERR, AXI_18_DFI_DW_RDDATA_VALID, AXI_18_DFI_INIT_COMPLETE, AXI_18_DFI_PHYUPD_REQ, AXI_18_DFI_PHY_LP_STATE, AXI_18_DFI_RST_N_BUF, AXI_18_MC_STATUS, AXI_18_PHY_STATUS, AXI_18_RDATA, AXI_18_RDATA_PARITY, AXI_18_RID, AXI_18_RLAST +, AXI_18_RRESP, AXI_18_RVALID, AXI_18_WREADY, AXI_19_ARREADY, AXI_19_AWREADY, AXI_19_BID, AXI_19_BRESP, AXI_19_BVALID, AXI_19_DFI_AW_AERR_N, AXI_19_DFI_CLK_BUF, AXI_19_DFI_DBI_BYTE_DISABLE, AXI_19_DFI_DW_RDDATA_DBI, AXI_19_DFI_DW_RDDATA_DERR, AXI_19_DFI_DW_RDDATA_VALID, AXI_19_DFI_INIT_COMPLETE, AXI_19_DFI_PHYUPD_REQ, AXI_19_DFI_PHY_LP_STATE, AXI_19_DFI_RST_N_BUF, AXI_19_RDATA, AXI_19_RDATA_PARITY, AXI_19_RID +, AXI_19_RLAST, AXI_19_RRESP, AXI_19_RVALID, AXI_19_WREADY, AXI_20_ARREADY, AXI_20_AWREADY, AXI_20_BID, AXI_20_BRESP, AXI_20_BVALID, AXI_20_DFI_AW_AERR_N, AXI_20_DFI_CLK_BUF, AXI_20_DFI_DBI_BYTE_DISABLE, AXI_20_DFI_DW_RDDATA_DBI, AXI_20_DFI_DW_RDDATA_DERR, AXI_20_DFI_DW_RDDATA_VALID, AXI_20_DFI_INIT_COMPLETE, AXI_20_DFI_PHYUPD_REQ, AXI_20_DFI_PHY_LP_STATE, AXI_20_DFI_RST_N_BUF, AXI_20_MC_STATUS, AXI_20_PHY_STATUS +, AXI_20_RDATA, AXI_20_RDATA_PARITY, AXI_20_RID, AXI_20_RLAST, AXI_20_RRESP, AXI_20_RVALID, AXI_20_WREADY, AXI_21_ARREADY, AXI_21_AWREADY, AXI_21_BID, AXI_21_BRESP, AXI_21_BVALID, AXI_21_DFI_AW_AERR_N, AXI_21_DFI_CLK_BUF, AXI_21_DFI_DBI_BYTE_DISABLE, AXI_21_DFI_DW_RDDATA_DBI, AXI_21_DFI_DW_RDDATA_DERR, AXI_21_DFI_DW_RDDATA_VALID, AXI_21_DFI_INIT_COMPLETE, AXI_21_DFI_PHYUPD_REQ, AXI_21_DFI_PHY_LP_STATE +, AXI_21_DFI_RST_N_BUF, AXI_21_RDATA, AXI_21_RDATA_PARITY, AXI_21_RID, AXI_21_RLAST, AXI_21_RRESP, AXI_21_RVALID, AXI_21_WREADY, AXI_22_ARREADY, AXI_22_AWREADY, AXI_22_BID, AXI_22_BRESP, AXI_22_BVALID, AXI_22_DFI_AW_AERR_N, AXI_22_DFI_CLK_BUF, AXI_22_DFI_DBI_BYTE_DISABLE, AXI_22_DFI_DW_RDDATA_DBI, AXI_22_DFI_DW_RDDATA_DERR, AXI_22_DFI_DW_RDDATA_VALID, AXI_22_DFI_INIT_COMPLETE, AXI_22_DFI_PHYUPD_REQ +, AXI_22_DFI_PHY_LP_STATE, AXI_22_DFI_RST_N_BUF, AXI_22_MC_STATUS, AXI_22_PHY_STATUS, AXI_22_RDATA, AXI_22_RDATA_PARITY, AXI_22_RID, AXI_22_RLAST, AXI_22_RRESP, AXI_22_RVALID, AXI_22_WREADY, AXI_23_ARREADY, AXI_23_AWREADY, AXI_23_BID, AXI_23_BRESP, AXI_23_BVALID, AXI_23_DFI_AW_AERR_N, AXI_23_DFI_CLK_BUF, AXI_23_DFI_DBI_BYTE_DISABLE, AXI_23_DFI_DW_RDDATA_DBI, AXI_23_DFI_DW_RDDATA_DERR +, AXI_23_DFI_DW_RDDATA_VALID, AXI_23_DFI_INIT_COMPLETE, AXI_23_DFI_PHYUPD_REQ, AXI_23_DFI_PHY_LP_STATE, AXI_23_DFI_RST_N_BUF, AXI_23_RDATA, AXI_23_RDATA_PARITY, AXI_23_RID, AXI_23_RLAST, AXI_23_RRESP, AXI_23_RVALID, AXI_23_WREADY, AXI_24_ARREADY, AXI_24_AWREADY, AXI_24_BID, AXI_24_BRESP, AXI_24_BVALID, AXI_24_DFI_AW_AERR_N, AXI_24_DFI_CLK_BUF, AXI_24_DFI_DBI_BYTE_DISABLE, AXI_24_DFI_DW_RDDATA_DBI +, AXI_24_DFI_DW_RDDATA_DERR, AXI_24_DFI_DW_RDDATA_VALID, AXI_24_DFI_INIT_COMPLETE, AXI_24_DFI_PHYUPD_REQ, AXI_24_DFI_PHY_LP_STATE, AXI_24_DFI_RST_N_BUF, AXI_24_MC_STATUS, AXI_24_PHY_STATUS, AXI_24_RDATA, AXI_24_RDATA_PARITY, AXI_24_RID, AXI_24_RLAST, AXI_24_RRESP, AXI_24_RVALID, AXI_24_WREADY, AXI_25_ARREADY, AXI_25_AWREADY, AXI_25_BID, AXI_25_BRESP, AXI_25_BVALID, AXI_25_DFI_AW_AERR_N +, AXI_25_DFI_CLK_BUF, AXI_25_DFI_DBI_BYTE_DISABLE, AXI_25_DFI_DW_RDDATA_DBI, AXI_25_DFI_DW_RDDATA_DERR, AXI_25_DFI_DW_RDDATA_VALID, AXI_25_DFI_INIT_COMPLETE, AXI_25_DFI_PHYUPD_REQ, AXI_25_DFI_PHY_LP_STATE, AXI_25_DFI_RST_N_BUF, AXI_25_RDATA, AXI_25_RDATA_PARITY, AXI_25_RID, AXI_25_RLAST, AXI_25_RRESP, AXI_25_RVALID, AXI_25_WREADY, AXI_26_ARREADY, AXI_26_AWREADY, AXI_26_BID, AXI_26_BRESP, AXI_26_BVALID +, AXI_26_DFI_AW_AERR_N, AXI_26_DFI_CLK_BUF, AXI_26_DFI_DBI_BYTE_DISABLE, AXI_26_DFI_DW_RDDATA_DBI, AXI_26_DFI_DW_RDDATA_DERR, AXI_26_DFI_DW_RDDATA_VALID, AXI_26_DFI_INIT_COMPLETE, AXI_26_DFI_PHYUPD_REQ, AXI_26_DFI_PHY_LP_STATE, AXI_26_DFI_RST_N_BUF, AXI_26_MC_STATUS, AXI_26_PHY_STATUS, AXI_26_RDATA, AXI_26_RDATA_PARITY, AXI_26_RID, AXI_26_RLAST, AXI_26_RRESP, AXI_26_RVALID, AXI_26_WREADY, AXI_27_ARREADY, AXI_27_AWREADY +, AXI_27_BID, AXI_27_BRESP, AXI_27_BVALID, AXI_27_DFI_AW_AERR_N, AXI_27_DFI_CLK_BUF, AXI_27_DFI_DBI_BYTE_DISABLE, AXI_27_DFI_DW_RDDATA_DBI, AXI_27_DFI_DW_RDDATA_DERR, AXI_27_DFI_DW_RDDATA_VALID, AXI_27_DFI_INIT_COMPLETE, AXI_27_DFI_PHYUPD_REQ, AXI_27_DFI_PHY_LP_STATE, AXI_27_DFI_RST_N_BUF, AXI_27_RDATA, AXI_27_RDATA_PARITY, AXI_27_RID, AXI_27_RLAST, AXI_27_RRESP, AXI_27_RVALID, AXI_27_WREADY, AXI_28_ARREADY +, AXI_28_AWREADY, AXI_28_BID, AXI_28_BRESP, AXI_28_BVALID, AXI_28_DFI_AW_AERR_N, AXI_28_DFI_CLK_BUF, AXI_28_DFI_DBI_BYTE_DISABLE, AXI_28_DFI_DW_RDDATA_DBI, AXI_28_DFI_DW_RDDATA_DERR, AXI_28_DFI_DW_RDDATA_VALID, AXI_28_DFI_INIT_COMPLETE, AXI_28_DFI_PHYUPD_REQ, AXI_28_DFI_PHY_LP_STATE, AXI_28_DFI_RST_N_BUF, AXI_28_MC_STATUS, AXI_28_PHY_STATUS, AXI_28_RDATA, AXI_28_RDATA_PARITY, AXI_28_RID, AXI_28_RLAST, AXI_28_RRESP +, AXI_28_RVALID, AXI_28_WREADY, AXI_29_ARREADY, AXI_29_AWREADY, AXI_29_BID, AXI_29_BRESP, AXI_29_BVALID, AXI_29_DFI_AW_AERR_N, AXI_29_DFI_CLK_BUF, AXI_29_DFI_DBI_BYTE_DISABLE, AXI_29_DFI_DW_RDDATA_DBI, AXI_29_DFI_DW_RDDATA_DERR, AXI_29_DFI_DW_RDDATA_VALID, AXI_29_DFI_INIT_COMPLETE, AXI_29_DFI_PHYUPD_REQ, AXI_29_DFI_PHY_LP_STATE, AXI_29_DFI_RST_N_BUF, AXI_29_RDATA, AXI_29_RDATA_PARITY, AXI_29_RID, AXI_29_RLAST +, AXI_29_RRESP, AXI_29_RVALID, AXI_29_WREADY, AXI_30_ARREADY, AXI_30_AWREADY, AXI_30_BID, AXI_30_BRESP, AXI_30_BVALID, AXI_30_DFI_AW_AERR_N, AXI_30_DFI_CLK_BUF, AXI_30_DFI_DBI_BYTE_DISABLE, AXI_30_DFI_DW_RDDATA_DBI, AXI_30_DFI_DW_RDDATA_DERR, AXI_30_DFI_DW_RDDATA_VALID, AXI_30_DFI_INIT_COMPLETE, AXI_30_DFI_PHYUPD_REQ, AXI_30_DFI_PHY_LP_STATE, AXI_30_DFI_RST_N_BUF, AXI_30_MC_STATUS, AXI_30_PHY_STATUS, AXI_30_RDATA +, AXI_30_RDATA_PARITY, AXI_30_RID, AXI_30_RLAST, AXI_30_RRESP, AXI_30_RVALID, AXI_30_WREADY, AXI_31_ARREADY, AXI_31_AWREADY, AXI_31_BID, AXI_31_BRESP, AXI_31_BVALID, AXI_31_DFI_AW_AERR_N, AXI_31_DFI_CLK_BUF, AXI_31_DFI_DBI_BYTE_DISABLE, AXI_31_DFI_DW_RDDATA_DBI, AXI_31_DFI_DW_RDDATA_DERR, AXI_31_DFI_DW_RDDATA_VALID, AXI_31_DFI_INIT_COMPLETE, AXI_31_DFI_PHYUPD_REQ, AXI_31_DFI_PHY_LP_STATE, AXI_31_DFI_RST_N_BUF +, AXI_31_RDATA, AXI_31_RDATA_PARITY, AXI_31_RID, AXI_31_RLAST, AXI_31_RRESP, AXI_31_RVALID, AXI_31_WREADY, DRAM_0_STAT_CATTRIP, DRAM_0_STAT_TEMP, DRAM_1_STAT_CATTRIP, DRAM_1_STAT_TEMP, APB_0_PADDR, APB_0_PCLK, APB_0_PENABLE, APB_0_PRESET_N, APB_0_PSEL, APB_0_PWDATA, APB_0_PWRITE, APB_1_PADDR, APB_1_PCLK, APB_1_PENABLE +, APB_1_PRESET_N, APB_1_PSEL, APB_1_PWDATA, APB_1_PWRITE, AXI_00_ACLK, AXI_00_ARADDR, AXI_00_ARBURST, AXI_00_ARESET_N, AXI_00_ARID, AXI_00_ARLEN, AXI_00_ARSIZE, AXI_00_ARVALID, AXI_00_AWADDR, AXI_00_AWBURST, AXI_00_AWID, AXI_00_AWLEN, AXI_00_AWSIZE, AXI_00_AWVALID, AXI_00_BREADY, AXI_00_DFI_LP_PWR_X_REQ, AXI_00_RREADY +, AXI_00_WDATA, AXI_00_WDATA_PARITY, AXI_00_WLAST, AXI_00_WSTRB, AXI_00_WVALID, AXI_01_ACLK, AXI_01_ARADDR, AXI_01_ARBURST, AXI_01_ARESET_N, AXI_01_ARID, AXI_01_ARLEN, AXI_01_ARSIZE, AXI_01_ARVALID, AXI_01_AWADDR, AXI_01_AWBURST, AXI_01_AWID, AXI_01_AWLEN, AXI_01_AWSIZE, AXI_01_AWVALID, AXI_01_BREADY, AXI_01_DFI_LP_PWR_X_REQ +, AXI_01_RREADY, AXI_01_WDATA, AXI_01_WDATA_PARITY, AXI_01_WLAST, AXI_01_WSTRB, AXI_01_WVALID, AXI_02_ACLK, AXI_02_ARADDR, AXI_02_ARBURST, AXI_02_ARESET_N, AXI_02_ARID, AXI_02_ARLEN, AXI_02_ARSIZE, AXI_02_ARVALID, AXI_02_AWADDR, AXI_02_AWBURST, AXI_02_AWID, AXI_02_AWLEN, AXI_02_AWSIZE, AXI_02_AWVALID, AXI_02_BREADY +, AXI_02_DFI_LP_PWR_X_REQ, AXI_02_RREADY, AXI_02_WDATA, AXI_02_WDATA_PARITY, AXI_02_WLAST, AXI_02_WSTRB, AXI_02_WVALID, AXI_03_ACLK, AXI_03_ARADDR, AXI_03_ARBURST, AXI_03_ARESET_N, AXI_03_ARID, AXI_03_ARLEN, AXI_03_ARSIZE, AXI_03_ARVALID, AXI_03_AWADDR, AXI_03_AWBURST, AXI_03_AWID, AXI_03_AWLEN, AXI_03_AWSIZE, AXI_03_AWVALID +, AXI_03_BREADY, AXI_03_DFI_LP_PWR_X_REQ, AXI_03_RREADY, AXI_03_WDATA, AXI_03_WDATA_PARITY, AXI_03_WLAST, AXI_03_WSTRB, AXI_03_WVALID, AXI_04_ACLK, AXI_04_ARADDR, AXI_04_ARBURST, AXI_04_ARESET_N, AXI_04_ARID, AXI_04_ARLEN, AXI_04_ARSIZE, AXI_04_ARVALID, AXI_04_AWADDR, AXI_04_AWBURST, AXI_04_AWID, AXI_04_AWLEN, AXI_04_AWSIZE +, AXI_04_AWVALID, AXI_04_BREADY, AXI_04_DFI_LP_PWR_X_REQ, AXI_04_RREADY, AXI_04_WDATA, AXI_04_WDATA_PARITY, AXI_04_WLAST, AXI_04_WSTRB, AXI_04_WVALID, AXI_05_ACLK, AXI_05_ARADDR, AXI_05_ARBURST, AXI_05_ARESET_N, AXI_05_ARID, AXI_05_ARLEN, AXI_05_ARSIZE, AXI_05_ARVALID, AXI_05_AWADDR, AXI_05_AWBURST, AXI_05_AWID, AXI_05_AWLEN +, AXI_05_AWSIZE, AXI_05_AWVALID, AXI_05_BREADY, AXI_05_DFI_LP_PWR_X_REQ, AXI_05_RREADY, AXI_05_WDATA, AXI_05_WDATA_PARITY, AXI_05_WLAST, AXI_05_WSTRB, AXI_05_WVALID, AXI_06_ACLK, AXI_06_ARADDR, AXI_06_ARBURST, AXI_06_ARESET_N, AXI_06_ARID, AXI_06_ARLEN, AXI_06_ARSIZE, AXI_06_ARVALID, AXI_06_AWADDR, AXI_06_AWBURST, AXI_06_AWID +, AXI_06_AWLEN, AXI_06_AWSIZE, AXI_06_AWVALID, AXI_06_BREADY, AXI_06_DFI_LP_PWR_X_REQ, AXI_06_RREADY, AXI_06_WDATA, AXI_06_WDATA_PARITY, AXI_06_WLAST, AXI_06_WSTRB, AXI_06_WVALID, AXI_07_ACLK, AXI_07_ARADDR, AXI_07_ARBURST, AXI_07_ARESET_N, AXI_07_ARID, AXI_07_ARLEN, AXI_07_ARSIZE, AXI_07_ARVALID, AXI_07_AWADDR, AXI_07_AWBURST +, AXI_07_AWID, AXI_07_AWLEN, AXI_07_AWSIZE, AXI_07_AWVALID, AXI_07_BREADY, AXI_07_DFI_LP_PWR_X_REQ, AXI_07_RREADY, AXI_07_WDATA, AXI_07_WDATA_PARITY, AXI_07_WLAST, AXI_07_WSTRB, AXI_07_WVALID, AXI_08_ACLK, AXI_08_ARADDR, AXI_08_ARBURST, AXI_08_ARESET_N, AXI_08_ARID, AXI_08_ARLEN, AXI_08_ARSIZE, AXI_08_ARVALID, AXI_08_AWADDR +, AXI_08_AWBURST, AXI_08_AWID, AXI_08_AWLEN, AXI_08_AWSIZE, AXI_08_AWVALID, AXI_08_BREADY, AXI_08_DFI_LP_PWR_X_REQ, AXI_08_RREADY, AXI_08_WDATA, AXI_08_WDATA_PARITY, AXI_08_WLAST, AXI_08_WSTRB, AXI_08_WVALID, AXI_09_ACLK, AXI_09_ARADDR, AXI_09_ARBURST, AXI_09_ARESET_N, AXI_09_ARID, AXI_09_ARLEN, AXI_09_ARSIZE, AXI_09_ARVALID +, AXI_09_AWADDR, AXI_09_AWBURST, AXI_09_AWID, AXI_09_AWLEN, AXI_09_AWSIZE, AXI_09_AWVALID, AXI_09_BREADY, AXI_09_DFI_LP_PWR_X_REQ, AXI_09_RREADY, AXI_09_WDATA, AXI_09_WDATA_PARITY, AXI_09_WLAST, AXI_09_WSTRB, AXI_09_WVALID, AXI_10_ACLK, AXI_10_ARADDR, AXI_10_ARBURST, AXI_10_ARESET_N, AXI_10_ARID, AXI_10_ARLEN, AXI_10_ARSIZE +, AXI_10_ARVALID, AXI_10_AWADDR, AXI_10_AWBURST, AXI_10_AWID, AXI_10_AWLEN, AXI_10_AWSIZE, AXI_10_AWVALID, AXI_10_BREADY, AXI_10_DFI_LP_PWR_X_REQ, AXI_10_RREADY, AXI_10_WDATA, AXI_10_WDATA_PARITY, AXI_10_WLAST, AXI_10_WSTRB, AXI_10_WVALID, AXI_11_ACLK, AXI_11_ARADDR, AXI_11_ARBURST, AXI_11_ARESET_N, AXI_11_ARID, AXI_11_ARLEN +, AXI_11_ARSIZE, AXI_11_ARVALID, AXI_11_AWADDR, AXI_11_AWBURST, AXI_11_AWID, AXI_11_AWLEN, AXI_11_AWSIZE, AXI_11_AWVALID, AXI_11_BREADY, AXI_11_DFI_LP_PWR_X_REQ, AXI_11_RREADY, AXI_11_WDATA, AXI_11_WDATA_PARITY, AXI_11_WLAST, AXI_11_WSTRB, AXI_11_WVALID, AXI_12_ACLK, AXI_12_ARADDR, AXI_12_ARBURST, AXI_12_ARESET_N, AXI_12_ARID +, AXI_12_ARLEN, AXI_12_ARSIZE, AXI_12_ARVALID, AXI_12_AWADDR, AXI_12_AWBURST, AXI_12_AWID, AXI_12_AWLEN, AXI_12_AWSIZE, AXI_12_AWVALID, AXI_12_BREADY, AXI_12_DFI_LP_PWR_X_REQ, AXI_12_RREADY, AXI_12_WDATA, AXI_12_WDATA_PARITY, AXI_12_WLAST, AXI_12_WSTRB, AXI_12_WVALID, AXI_13_ACLK, AXI_13_ARADDR, AXI_13_ARBURST, AXI_13_ARESET_N +, AXI_13_ARID, AXI_13_ARLEN, AXI_13_ARSIZE, AXI_13_ARVALID, AXI_13_AWADDR, AXI_13_AWBURST, AXI_13_AWID, AXI_13_AWLEN, AXI_13_AWSIZE, AXI_13_AWVALID, AXI_13_BREADY, AXI_13_DFI_LP_PWR_X_REQ, AXI_13_RREADY, AXI_13_WDATA, AXI_13_WDATA_PARITY, AXI_13_WLAST, AXI_13_WSTRB, AXI_13_WVALID, AXI_14_ACLK, AXI_14_ARADDR, AXI_14_ARBURST +, AXI_14_ARESET_N, AXI_14_ARID, AXI_14_ARLEN, AXI_14_ARSIZE, AXI_14_ARVALID, AXI_14_AWADDR, AXI_14_AWBURST, AXI_14_AWID, AXI_14_AWLEN, AXI_14_AWSIZE, AXI_14_AWVALID, AXI_14_BREADY, AXI_14_DFI_LP_PWR_X_REQ, AXI_14_RREADY, AXI_14_WDATA, AXI_14_WDATA_PARITY, AXI_14_WLAST, AXI_14_WSTRB, AXI_14_WVALID, AXI_15_ACLK, AXI_15_ARADDR +, AXI_15_ARBURST, AXI_15_ARESET_N, AXI_15_ARID, AXI_15_ARLEN, AXI_15_ARSIZE, AXI_15_ARVALID, AXI_15_AWADDR, AXI_15_AWBURST, AXI_15_AWID, AXI_15_AWLEN, AXI_15_AWSIZE, AXI_15_AWVALID, AXI_15_BREADY, AXI_15_DFI_LP_PWR_X_REQ, AXI_15_RREADY, AXI_15_WDATA, AXI_15_WDATA_PARITY, AXI_15_WLAST, AXI_15_WSTRB, AXI_15_WVALID, AXI_16_ACLK +, AXI_16_ARADDR, AXI_16_ARBURST, AXI_16_ARESET_N, AXI_16_ARID, AXI_16_ARLEN, AXI_16_ARSIZE, AXI_16_ARVALID, AXI_16_AWADDR, AXI_16_AWBURST, AXI_16_AWID, AXI_16_AWLEN, AXI_16_AWSIZE, AXI_16_AWVALID, AXI_16_BREADY, AXI_16_DFI_LP_PWR_X_REQ, AXI_16_RREADY, AXI_16_WDATA, AXI_16_WDATA_PARITY, AXI_16_WLAST, AXI_16_WSTRB, AXI_16_WVALID +, AXI_17_ACLK, AXI_17_ARADDR, AXI_17_ARBURST, AXI_17_ARESET_N, AXI_17_ARID, AXI_17_ARLEN, AXI_17_ARSIZE, AXI_17_ARVALID, AXI_17_AWADDR, AXI_17_AWBURST, AXI_17_AWID, AXI_17_AWLEN, AXI_17_AWSIZE, AXI_17_AWVALID, AXI_17_BREADY, AXI_17_DFI_LP_PWR_X_REQ, AXI_17_RREADY, AXI_17_WDATA, AXI_17_WDATA_PARITY, AXI_17_WLAST, AXI_17_WSTRB +, AXI_17_WVALID, AXI_18_ACLK, AXI_18_ARADDR, AXI_18_ARBURST, AXI_18_ARESET_N, AXI_18_ARID, AXI_18_ARLEN, AXI_18_ARSIZE, AXI_18_ARVALID, AXI_18_AWADDR, AXI_18_AWBURST, AXI_18_AWID, AXI_18_AWLEN, AXI_18_AWSIZE, AXI_18_AWVALID, AXI_18_BREADY, AXI_18_DFI_LP_PWR_X_REQ, AXI_18_RREADY, AXI_18_WDATA, AXI_18_WDATA_PARITY, AXI_18_WLAST +, AXI_18_WSTRB, AXI_18_WVALID, AXI_19_ACLK, AXI_19_ARADDR, AXI_19_ARBURST, AXI_19_ARESET_N, AXI_19_ARID, AXI_19_ARLEN, AXI_19_ARSIZE, AXI_19_ARVALID, AXI_19_AWADDR, AXI_19_AWBURST, AXI_19_AWID, AXI_19_AWLEN, AXI_19_AWSIZE, AXI_19_AWVALID, AXI_19_BREADY, AXI_19_DFI_LP_PWR_X_REQ, AXI_19_RREADY, AXI_19_WDATA, AXI_19_WDATA_PARITY +, AXI_19_WLAST, AXI_19_WSTRB, AXI_19_WVALID, AXI_20_ACLK, AXI_20_ARADDR, AXI_20_ARBURST, AXI_20_ARESET_N, AXI_20_ARID, AXI_20_ARLEN, AXI_20_ARSIZE, AXI_20_ARVALID, AXI_20_AWADDR, AXI_20_AWBURST, AXI_20_AWID, AXI_20_AWLEN, AXI_20_AWSIZE, AXI_20_AWVALID, AXI_20_BREADY, AXI_20_DFI_LP_PWR_X_REQ, AXI_20_RREADY, AXI_20_WDATA +, AXI_20_WDATA_PARITY, AXI_20_WLAST, AXI_20_WSTRB, AXI_20_WVALID, AXI_21_ACLK, AXI_21_ARADDR, AXI_21_ARBURST, AXI_21_ARESET_N, AXI_21_ARID, AXI_21_ARLEN, AXI_21_ARSIZE, AXI_21_ARVALID, AXI_21_AWADDR, AXI_21_AWBURST, AXI_21_AWID, AXI_21_AWLEN, AXI_21_AWSIZE, AXI_21_AWVALID, AXI_21_BREADY, AXI_21_DFI_LP_PWR_X_REQ, AXI_21_RREADY +, AXI_21_WDATA, AXI_21_WDATA_PARITY, AXI_21_WLAST, AXI_21_WSTRB, AXI_21_WVALID, AXI_22_ACLK, AXI_22_ARADDR, AXI_22_ARBURST, AXI_22_ARESET_N, AXI_22_ARID, AXI_22_ARLEN, AXI_22_ARSIZE, AXI_22_ARVALID, AXI_22_AWADDR, AXI_22_AWBURST, AXI_22_AWID, AXI_22_AWLEN, AXI_22_AWSIZE, AXI_22_AWVALID, AXI_22_BREADY, AXI_22_DFI_LP_PWR_X_REQ +, AXI_22_RREADY, AXI_22_WDATA, AXI_22_WDATA_PARITY, AXI_22_WLAST, AXI_22_WSTRB, AXI_22_WVALID, AXI_23_ACLK, AXI_23_ARADDR, AXI_23_ARBURST, AXI_23_ARESET_N, AXI_23_ARID, AXI_23_ARLEN, AXI_23_ARSIZE, AXI_23_ARVALID, AXI_23_AWADDR, AXI_23_AWBURST, AXI_23_AWID, AXI_23_AWLEN, AXI_23_AWSIZE, AXI_23_AWVALID, AXI_23_BREADY +, AXI_23_DFI_LP_PWR_X_REQ, AXI_23_RREADY, AXI_23_WDATA, AXI_23_WDATA_PARITY, AXI_23_WLAST, AXI_23_WSTRB, AXI_23_WVALID, AXI_24_ACLK, AXI_24_ARADDR, AXI_24_ARBURST, AXI_24_ARESET_N, AXI_24_ARID, AXI_24_ARLEN, AXI_24_ARSIZE, AXI_24_ARVALID, AXI_24_AWADDR, AXI_24_AWBURST, AXI_24_AWID, AXI_24_AWLEN, AXI_24_AWSIZE, AXI_24_AWVALID +, AXI_24_BREADY, AXI_24_DFI_LP_PWR_X_REQ, AXI_24_RREADY, AXI_24_WDATA, AXI_24_WDATA_PARITY, AXI_24_WLAST, AXI_24_WSTRB, AXI_24_WVALID, AXI_25_ACLK, AXI_25_ARADDR, AXI_25_ARBURST, AXI_25_ARESET_N, AXI_25_ARID, AXI_25_ARLEN, AXI_25_ARSIZE, AXI_25_ARVALID, AXI_25_AWADDR, AXI_25_AWBURST, AXI_25_AWID, AXI_25_AWLEN, AXI_25_AWSIZE +, AXI_25_AWVALID, AXI_25_BREADY, AXI_25_DFI_LP_PWR_X_REQ, AXI_25_RREADY, AXI_25_WDATA, AXI_25_WDATA_PARITY, AXI_25_WLAST, AXI_25_WSTRB, AXI_25_WVALID, AXI_26_ACLK, AXI_26_ARADDR, AXI_26_ARBURST, AXI_26_ARESET_N, AXI_26_ARID, AXI_26_ARLEN, AXI_26_ARSIZE, AXI_26_ARVALID, AXI_26_AWADDR, AXI_26_AWBURST, AXI_26_AWID, AXI_26_AWLEN +, AXI_26_AWSIZE, AXI_26_AWVALID, AXI_26_BREADY, AXI_26_DFI_LP_PWR_X_REQ, AXI_26_RREADY, AXI_26_WDATA, AXI_26_WDATA_PARITY, AXI_26_WLAST, AXI_26_WSTRB, AXI_26_WVALID, AXI_27_ACLK, AXI_27_ARADDR, AXI_27_ARBURST, AXI_27_ARESET_N, AXI_27_ARID, AXI_27_ARLEN, AXI_27_ARSIZE, AXI_27_ARVALID, AXI_27_AWADDR, AXI_27_AWBURST, AXI_27_AWID +, AXI_27_AWLEN, AXI_27_AWSIZE, AXI_27_AWVALID, AXI_27_BREADY, AXI_27_DFI_LP_PWR_X_REQ, AXI_27_RREADY, AXI_27_WDATA, AXI_27_WDATA_PARITY, AXI_27_WLAST, AXI_27_WSTRB, AXI_27_WVALID, AXI_28_ACLK, AXI_28_ARADDR, AXI_28_ARBURST, AXI_28_ARESET_N, AXI_28_ARID, AXI_28_ARLEN, AXI_28_ARSIZE, AXI_28_ARVALID, AXI_28_AWADDR, AXI_28_AWBURST +, AXI_28_AWID, AXI_28_AWLEN, AXI_28_AWSIZE, AXI_28_AWVALID, AXI_28_BREADY, AXI_28_DFI_LP_PWR_X_REQ, AXI_28_RREADY, AXI_28_WDATA, AXI_28_WDATA_PARITY, AXI_28_WLAST, AXI_28_WSTRB, AXI_28_WVALID, AXI_29_ACLK, AXI_29_ARADDR, AXI_29_ARBURST, AXI_29_ARESET_N, AXI_29_ARID, AXI_29_ARLEN, AXI_29_ARSIZE, AXI_29_ARVALID, AXI_29_AWADDR +, AXI_29_AWBURST, AXI_29_AWID, AXI_29_AWLEN, AXI_29_AWSIZE, AXI_29_AWVALID, AXI_29_BREADY, AXI_29_DFI_LP_PWR_X_REQ, AXI_29_RREADY, AXI_29_WDATA, AXI_29_WDATA_PARITY, AXI_29_WLAST, AXI_29_WSTRB, AXI_29_WVALID, AXI_30_ACLK, AXI_30_ARADDR, AXI_30_ARBURST, AXI_30_ARESET_N, AXI_30_ARID, AXI_30_ARLEN, AXI_30_ARSIZE, AXI_30_ARVALID +, AXI_30_AWADDR, AXI_30_AWBURST, AXI_30_AWID, AXI_30_AWLEN, AXI_30_AWSIZE, AXI_30_AWVALID, AXI_30_BREADY, AXI_30_DFI_LP_PWR_X_REQ, AXI_30_RREADY, AXI_30_WDATA, AXI_30_WDATA_PARITY, AXI_30_WLAST, AXI_30_WSTRB, AXI_30_WVALID, AXI_31_ACLK, AXI_31_ARADDR, AXI_31_ARBURST, AXI_31_ARESET_N, AXI_31_ARID, AXI_31_ARLEN, AXI_31_ARSIZE +, AXI_31_ARVALID, AXI_31_AWADDR, AXI_31_AWBURST, AXI_31_AWID, AXI_31_AWLEN, AXI_31_AWSIZE, AXI_31_AWVALID, AXI_31_BREADY, AXI_31_DFI_LP_PWR_X_REQ, AXI_31_RREADY, AXI_31_WDATA, AXI_31_WDATA_PARITY, AXI_31_WLAST, AXI_31_WSTRB, AXI_31_WVALID, BSCAN_DRCK_0, BSCAN_DRCK_1, BSCAN_TCK_0, BSCAN_TCK_1, HBM_REF_CLK_0, HBM_REF_CLK_1 +, MBIST_EN_00, MBIST_EN_01, MBIST_EN_02, MBIST_EN_03, MBIST_EN_04, MBIST_EN_05, MBIST_EN_06, MBIST_EN_07, MBIST_EN_08, MBIST_EN_09, MBIST_EN_10, MBIST_EN_11, MBIST_EN_12, MBIST_EN_13, MBIST_EN_14, MBIST_EN_15); parameter CLK_SEL_00 = "FALSE"; parameter CLK_SEL_01 = "FALSE"; parameter CLK_SEL_02 = "FALSE"; @@ -31096,7 +31672,16 @@ module HBM_TWO_STACK_INTF (...); input MBIST_EN_15; endmodule -module PPC405_ADV (...); +module PPC405_ADV(APUFCMDECODED, APUFCMDECUDIVALID, APUFCMENDIAN, APUFCMFLUSH, APUFCMINSTRVALID, APUFCMLOADDVALID, APUFCMOPERANDVALID, APUFCMWRITEBACKOK, APUFCMXERCA, C405CPMCORESLEEPREQ, C405CPMMSRCE, C405CPMMSREE, C405CPMTIMERIRQ, C405CPMTIMERRESETREQ, C405DBGLOADDATAONAPUDBUS, C405DBGMSRWE, C405DBGSTOPACK, C405DBGWBCOMPLETE, C405DBGWBFULL, C405JTGCAPTUREDR, C405JTGEXTEST +, C405JTGPGMOUT, C405JTGSHIFTDR, C405JTGTDO, C405JTGTDOEN, C405JTGUPDATEDR, C405PLBDCUABORT, C405PLBDCUCACHEABLE, C405PLBDCUGUARDED, C405PLBDCUREQUEST, C405PLBDCURNW, C405PLBDCUSIZE2, C405PLBDCUU0ATTR, C405PLBDCUWRITETHRU, C405PLBICUABORT, C405PLBICUCACHEABLE, C405PLBICUREQUEST, C405PLBICUU0ATTR, C405RSTCHIPRESETREQ, C405RSTCORERESETREQ, C405RSTSYSRESETREQ, C405TRCCYCLE +, C405TRCTRIGGEREVENTOUT, C405XXXMACHINECHECK, DCREMACCLK, DCREMACENABLER, DCREMACREAD, DCREMACWRITE, DSOCMBRAMEN, DSOCMBUSY, DSOCMRDADDRVALID, DSOCMWRADDRVALID, EXTDCRREAD, EXTDCRWRITE, ISOCMBRAMEN, ISOCMBRAMEVENWRITEEN, ISOCMBRAMODDWRITEEN, ISOCMDCRBRAMEVENEN, ISOCMDCRBRAMODDEN, ISOCMDCRBRAMRDSELECT, C405TRCTRIGGEREVENTTYPE, C405PLBDCUPRIORITY, C405PLBICUPRIORITY +, C405TRCEVENEXECUTIONSTATUS, C405TRCODDEXECUTIONSTATUS, C405DBGWBIAR, C405PLBICUABUS, APUFCMDECUDI, APUFCMINSTRUCTION, APUFCMLOADDATA, APUFCMRADATA, APUFCMRBDATA, C405PLBDCUABUS, DCREMACDBUS, DSOCMBRAMWRDBUS, EXTDCRDBUSOUT, ISOCMBRAMWRDBUS, APUFCMLOADBYTEEN, C405TRCTRACESTATUS, DSOCMBRAMBYTEWRITE, C405PLBDCUWRDBUS, C405PLBDCUBE, EXTDCRABUS, C405PLBICUSIZE +, ISOCMBRAMRDABUS, ISOCMBRAMWRABUS, DSOCMBRAMABUS, DCREMACABUS, BRAMDSOCMCLK, BRAMISOCMCLK, CPMC405CLOCK, CPMC405CORECLKINACTIVE, CPMC405CPUCLKEN, CPMC405JTAGCLKEN, CPMC405SYNCBYPASS, CPMC405TIMERCLKEN, CPMC405TIMERTICK, CPMDCRCLK, CPMFCMCLK, DBGC405DEBUGHALT, DBGC405EXTBUSHOLDACK, DBGC405UNCONDDEBUGEVENT, DSOCMRWCOMPLETE, EICC405CRITINPUTIRQ, EICC405EXTINPUTIRQ +, EMACDCRACK, EXTDCRACK, FCMAPUDCDCREN, FCMAPUDCDFORCEALIGN, FCMAPUDCDFORCEBESTEERING, FCMAPUDCDFPUOP, FCMAPUDCDGPRWRITE, FCMAPUDCDLDSTBYTE, FCMAPUDCDLDSTDW, FCMAPUDCDLDSTHW, FCMAPUDCDLDSTQW, FCMAPUDCDLDSTWD, FCMAPUDCDLOAD, FCMAPUDCDPRIVOP, FCMAPUDCDRAEN, FCMAPUDCDRBEN, FCMAPUDCDSTORE, FCMAPUDCDTRAPBE, FCMAPUDCDTRAPLE, FCMAPUDCDUPDATE, FCMAPUDCDXERCAEN +, FCMAPUDCDXEROVEN, FCMAPUDECODEBUSY, FCMAPUDONE, FCMAPUEXCEPTION, FCMAPUEXEBLOCKINGMCO, FCMAPUEXENONBLOCKINGMCO, FCMAPUINSTRACK, FCMAPULOADWAIT, FCMAPURESULTVALID, FCMAPUSLEEPNOTREADY, FCMAPUXERCA, FCMAPUXEROV, JTGC405BNDSCANTDO, JTGC405TCK, JTGC405TDI, JTGC405TMS, JTGC405TRSTNEG, MCBCPUCLKEN, MCBJTAGEN, MCBTIMEREN, MCPPCRST +, PLBC405DCUADDRACK, PLBC405DCUBUSY, PLBC405DCUERR, PLBC405DCURDDACK, PLBC405DCUSSIZE1, PLBC405DCUWRDACK, PLBC405ICUADDRACK, PLBC405ICUBUSY, PLBC405ICUERR, PLBC405ICURDDACK, PLBC405ICUSSIZE1, PLBCLK, RSTC405RESETCHIP, RSTC405RESETCORE, RSTC405RESETSYS, TIEC405DETERMINISTICMULT, TIEC405DISOPERANDFWD, TIEC405MMUEN, TIEPVRBIT10, TIEPVRBIT11, TIEPVRBIT28 +, TIEPVRBIT29, TIEPVRBIT30, TIEPVRBIT31, TIEPVRBIT8, TIEPVRBIT9, TRCC405TRACEDISABLE, TRCC405TRIGGEREVENTIN, TIEAPUCONTROL, TIEAPUUDI1, TIEAPUUDI2, TIEAPUUDI3, TIEAPUUDI4, TIEAPUUDI5, TIEAPUUDI6, TIEAPUUDI7, TIEAPUUDI8, FCMAPUEXECRFIELD, BRAMDSOCMRDDBUS, BRAMISOCMDCRRDDBUS, EMACDCRDBUS, EXTDCRDBUSIN +, FCMAPURESULT, FCMAPUCR, TIEDCRADDR, BRAMISOCMRDDBUS, PLBC405DCURDDBUS, PLBC405ICURDDBUS, DSARCVALUE, DSCNTLVALUE, ISARCVALUE, ISCNTLVALUE, PLBC405DCURDWDADDR, PLBC405ICURDWDADDR); parameter in_delay=100; parameter out_delay=100; output APUFCMDECODED; @@ -31302,7 +31887,22 @@ module PPC405_ADV (...); input [1:3] PLBC405ICURDWDADDR; endmodule -module PPC440 (...); +module PPC440(APUFCMDECFPUOP, APUFCMDECLOAD, APUFCMDECNONAUTON, APUFCMDECSTORE, APUFCMDECUDIVALID, APUFCMENDIAN, APUFCMFLUSH, APUFCMINSTRVALID, APUFCMLOADDVALID, APUFCMMSRFE0, APUFCMMSRFE1, APUFCMNEXTINSTRREADY, APUFCMOPERANDVALID, APUFCMWRITEBACKOK, C440CPMCORESLEEPREQ, C440CPMDECIRPTREQ, C440CPMFITIRPTREQ, C440CPMMSRCE, C440CPMMSREE, C440CPMTIMERRESETREQ, C440CPMWDIRPTREQ +, C440JTGTDO, C440JTGTDOEN, C440MACHINECHECK, C440RSTCHIPRESETREQ, C440RSTCORERESETREQ, C440RSTSYSTEMRESETREQ, C440TRCCYCLE, C440TRCTRIGGEREVENTOUT, DMA0LLRSTENGINEACK, DMA0LLRXDSTRDYN, DMA0LLTXEOFN, DMA0LLTXEOPN, DMA0LLTXSOFN, DMA0LLTXSOPN, DMA0LLTXSRCRDYN, DMA0RXIRQ, DMA0TXIRQ, DMA1LLRSTENGINEACK, DMA1LLRXDSTRDYN, DMA1LLTXEOFN, DMA1LLTXEOPN +, DMA1LLTXSOFN, DMA1LLTXSOPN, DMA1LLTXSRCRDYN, DMA1RXIRQ, DMA1TXIRQ, DMA2LLRSTENGINEACK, DMA2LLRXDSTRDYN, DMA2LLTXEOFN, DMA2LLTXEOPN, DMA2LLTXSOFN, DMA2LLTXSOPN, DMA2LLTXSRCRDYN, DMA2RXIRQ, DMA2TXIRQ, DMA3LLRSTENGINEACK, DMA3LLRXDSTRDYN, DMA3LLTXEOFN, DMA3LLTXEOPN, DMA3LLTXSOFN, DMA3LLTXSOPN, DMA3LLTXSRCRDYN +, DMA3RXIRQ, DMA3TXIRQ, MIMCADDRESSVALID, MIMCBANKCONFLICT, MIMCREADNOTWRITE, MIMCROWCONFLICT, MIMCWRITEDATAVALID, PPCCPMINTERCONNECTBUSY, PPCDMDCRREAD, PPCDMDCRWRITE, PPCDSDCRACK, PPCDSDCRTIMEOUTWAIT, PPCEICINTERCONNECTIRQ, PPCMPLBABORT, PPCMPLBBUSLOCK, PPCMPLBLOCKERR, PPCMPLBRDBURST, PPCMPLBREQUEST, PPCMPLBRNW, PPCMPLBWRBURST, PPCS0PLBADDRACK +, PPCS0PLBRDBTERM, PPCS0PLBRDCOMP, PPCS0PLBRDDACK, PPCS0PLBREARBITRATE, PPCS0PLBWAIT, PPCS0PLBWRBTERM, PPCS0PLBWRCOMP, PPCS0PLBWRDACK, PPCS1PLBADDRACK, PPCS1PLBRDBTERM, PPCS1PLBRDCOMP, PPCS1PLBRDDACK, PPCS1PLBREARBITRATE, PPCS1PLBWAIT, PPCS1PLBWRBTERM, PPCS1PLBWRCOMP, PPCS1PLBWRDACK, APUFCMLOADDATA, MIMCWRITEDATA, PPCMPLBWRDBUS, PPCS0PLBRDDBUS +, PPCS1PLBRDDBUS, C440TRCTRIGGEREVENTTYPE, MIMCBYTEENABLE, PPCMPLBBE, PPCMPLBTATTRIBUTE, PPCMPLBPRIORITY, PPCS0PLBSSIZE, PPCS1PLBSSIZE, APUFCMDECLDSTXFERSIZE, C440TRCBRANCHSTATUS, PPCMPLBTYPE, APUFCMINSTRUCTION, APUFCMRADATA, APUFCMRBDATA, DMA0LLTXD, DMA1LLTXD, DMA2LLTXD, DMA3LLTXD, PPCDMDCRDBUSOUT, PPCDSDCRDBUSIN, PPCMPLBABUS +, MIMCADDRESS, APUFCMDECUDI, APUFCMLOADBYTEADDR, DMA0LLTXREM, DMA1LLTXREM, DMA2LLTXREM, DMA3LLTXREM, PPCMPLBSIZE, PPCS0PLBMBUSY, PPCS0PLBMIRQ, PPCS0PLBMRDERR, PPCS0PLBMWRERR, PPCS0PLBRDWDADDR, PPCS1PLBMBUSY, PPCS1PLBMIRQ, PPCS1PLBMRDERR, PPCS1PLBMWRERR, PPCS1PLBRDWDADDR, C440TRCEXECUTIONSTATUS, C440TRCTRACESTATUS, C440DBGSYSTEMCONTROL +, PPCDMDCRABUS, PPCDMDCRUABUS, PPCMPLBUABUS, CPMC440CLK, CPMC440CLKEN, CPMC440CORECLOCKINACTIVE, CPMC440TIMERCLOCK, CPMDCRCLK, CPMDMA0LLCLK, CPMDMA1LLCLK, CPMDMA2LLCLK, CPMDMA3LLCLK, CPMFCMCLK, CPMINTERCONNECTCLK, CPMINTERCONNECTCLKEN, CPMINTERCONNECTCLKNTO1, CPMMCCLK, CPMPPCMPLBCLK, CPMPPCS0PLBCLK, CPMPPCS1PLBCLK, DBGC440DEBUGHALT +, DBGC440UNCONDDEBUGEVENT, DCRPPCDMACK, DCRPPCDMTIMEOUTWAIT, DCRPPCDSREAD, DCRPPCDSWRITE, EICC440CRITIRQ, EICC440EXTIRQ, FCMAPUCONFIRMINSTR, FCMAPUDONE, FCMAPUEXCEPTION, FCMAPUFPSCRFEX, FCMAPURESULTVALID, FCMAPUSLEEPNOTREADY, JTGC440TCK, JTGC440TDI, JTGC440TMS, JTGC440TRSTNEG, LLDMA0RSTENGINEREQ, LLDMA0RXEOFN, LLDMA0RXEOPN, LLDMA0RXSOFN +, LLDMA0RXSOPN, LLDMA0RXSRCRDYN, LLDMA0TXDSTRDYN, LLDMA1RSTENGINEREQ, LLDMA1RXEOFN, LLDMA1RXEOPN, LLDMA1RXSOFN, LLDMA1RXSOPN, LLDMA1RXSRCRDYN, LLDMA1TXDSTRDYN, LLDMA2RSTENGINEREQ, LLDMA2RXEOFN, LLDMA2RXEOPN, LLDMA2RXSOFN, LLDMA2RXSOPN, LLDMA2RXSRCRDYN, LLDMA2TXDSTRDYN, LLDMA3RSTENGINEREQ, LLDMA3RXEOFN, LLDMA3RXEOPN, LLDMA3RXSOFN +, LLDMA3RXSOPN, LLDMA3RXSRCRDYN, LLDMA3TXDSTRDYN, MCMIADDRREADYTOACCEPT, MCMIREADDATAERR, MCMIREADDATAVALID, PLBPPCMADDRACK, PLBPPCMMBUSY, PLBPPCMMIRQ, PLBPPCMMRDERR, PLBPPCMMWRERR, PLBPPCMRDBTERM, PLBPPCMRDDACK, PLBPPCMRDPENDREQ, PLBPPCMREARBITRATE, PLBPPCMTIMEOUT, PLBPPCMWRBTERM, PLBPPCMWRDACK, PLBPPCMWRPENDREQ, PLBPPCS0ABORT, PLBPPCS0BUSLOCK +, PLBPPCS0LOCKERR, PLBPPCS0PAVALID, PLBPPCS0RDBURST, PLBPPCS0RDPENDREQ, PLBPPCS0RDPRIM, PLBPPCS0RNW, PLBPPCS0SAVALID, PLBPPCS0WRBURST, PLBPPCS0WRPENDREQ, PLBPPCS0WRPRIM, PLBPPCS1ABORT, PLBPPCS1BUSLOCK, PLBPPCS1LOCKERR, PLBPPCS1PAVALID, PLBPPCS1RDBURST, PLBPPCS1RDPENDREQ, PLBPPCS1RDPRIM, PLBPPCS1RNW, PLBPPCS1SAVALID, PLBPPCS1WRBURST, PLBPPCS1WRPENDREQ +, PLBPPCS1WRPRIM, RSTC440RESETCHIP, RSTC440RESETCORE, RSTC440RESETSYSTEM, TIEC440ENDIANRESET, TRCC440TRACEDISABLE, TRCC440TRIGGEREVENTIN, FCMAPUSTOREDATA, MCMIREADDATA, PLBPPCMRDDBUS, PLBPPCS0WRDBUS, PLBPPCS1WRDBUS, PLBPPCS0BE, PLBPPCS0TATTRIBUTE, PLBPPCS1BE, PLBPPCS1TATTRIBUTE, PLBPPCMRDPENDPRI, PLBPPCMREQPRI, PLBPPCMSSIZE, PLBPPCMWRPENDPRI, PLBPPCS0MASTERID +, PLBPPCS0MSIZE, PLBPPCS0RDPENDPRI, PLBPPCS0REQPRI, PLBPPCS0WRPENDPRI, PLBPPCS1MASTERID, PLBPPCS1MSIZE, PLBPPCS1RDPENDPRI, PLBPPCS1REQPRI, PLBPPCS1WRPENDPRI, TIEC440DCURDLDCACHEPLBPRIO, TIEC440DCURDNONCACHEPLBPRIO, TIEC440DCURDTOUCHPLBPRIO, TIEC440DCURDURGENTPLBPRIO, TIEC440DCUWRFLUSHPLBPRIO, TIEC440DCUWRSTOREPLBPRIO, TIEC440DCUWRURGENTPLBPRIO, TIEC440ICURDFETCHPLBPRIO, TIEC440ICURDSPECPLBPRIO, TIEC440ICURDTOUCHPLBPRIO, TIEDCRBASEADDR, PLBPPCS0TYPE +, PLBPPCS1TYPE, DCRPPCDMDBUSIN, DCRPPCDSDBUSOUT, FCMAPURESULT, LLDMA0RXD, LLDMA1RXD, LLDMA2RXD, LLDMA3RXD, PLBPPCS0ABUS, PLBPPCS1ABUS, FCMAPUCR, LLDMA0RXREM, LLDMA1RXREM, LLDMA2RXREM, LLDMA3RXREM, PLBPPCMRDWDADDR, PLBPPCS0SIZE, PLBPPCS1SIZE, TIEC440ERPNRESET, TIEC440USERRESET, DBGC440SYSTEMSTATUS +, DCRPPCDSABUS, PLBPPCS0UABUS, PLBPPCS1UABUS, TIEC440PIR, TIEC440PVR); parameter CLOCK_DELAY = "FALSE"; parameter DCR_AUTOLOCK_ENABLE = "TRUE"; parameter PPCDM_ASYNCMODE = "FALSE"; @@ -31692,7 +32292,36 @@ module PPC440 (...); endmodule (* keep *) -module PS7 (...); +module PS7(DMA0DAVALID, DMA0DRREADY, DMA0RSTN, DMA1DAVALID, DMA1DRREADY, DMA1RSTN, DMA2DAVALID, DMA2DRREADY, DMA2RSTN, DMA3DAVALID, DMA3DRREADY, DMA3RSTN, EMIOCAN0PHYTX, EMIOCAN1PHYTX, EMIOENET0GMIITXEN, EMIOENET0GMIITXER, EMIOENET0MDIOMDC, EMIOENET0MDIOO, EMIOENET0MDIOTN, EMIOENET0PTPDELAYREQRX, EMIOENET0PTPDELAYREQTX +, EMIOENET0PTPPDELAYREQRX, EMIOENET0PTPPDELAYREQTX, EMIOENET0PTPPDELAYRESPRX, EMIOENET0PTPPDELAYRESPTX, EMIOENET0PTPSYNCFRAMERX, EMIOENET0PTPSYNCFRAMETX, EMIOENET0SOFRX, EMIOENET0SOFTX, EMIOENET1GMIITXEN, EMIOENET1GMIITXER, EMIOENET1MDIOMDC, EMIOENET1MDIOO, EMIOENET1MDIOTN, EMIOENET1PTPDELAYREQRX, EMIOENET1PTPDELAYREQTX, EMIOENET1PTPPDELAYREQRX, EMIOENET1PTPPDELAYREQTX, EMIOENET1PTPPDELAYRESPRX, EMIOENET1PTPPDELAYRESPTX, EMIOENET1PTPSYNCFRAMERX, EMIOENET1PTPSYNCFRAMETX +, EMIOENET1SOFRX, EMIOENET1SOFTX, EMIOI2C0SCLO, EMIOI2C0SCLTN, EMIOI2C0SDAO, EMIOI2C0SDATN, EMIOI2C1SCLO, EMIOI2C1SCLTN, EMIOI2C1SDAO, EMIOI2C1SDATN, EMIOPJTAGTDO, EMIOPJTAGTDTN, EMIOSDIO0BUSPOW, EMIOSDIO0CLK, EMIOSDIO0CMDO, EMIOSDIO0CMDTN, EMIOSDIO0LED, EMIOSDIO1BUSPOW, EMIOSDIO1CLK, EMIOSDIO1CMDO, EMIOSDIO1CMDTN +, EMIOSDIO1LED, EMIOSPI0MO, EMIOSPI0MOTN, EMIOSPI0SCLKO, EMIOSPI0SCLKTN, EMIOSPI0SO, EMIOSPI0SSNTN, EMIOSPI0STN, EMIOSPI1MO, EMIOSPI1MOTN, EMIOSPI1SCLKO, EMIOSPI1SCLKTN, EMIOSPI1SO, EMIOSPI1SSNTN, EMIOSPI1STN, EMIOTRACECTL, EMIOUART0DTRN, EMIOUART0RTSN, EMIOUART0TX, EMIOUART1DTRN, EMIOUART1RTSN +, EMIOUART1TX, EMIOUSB0VBUSPWRSELECT, EMIOUSB1VBUSPWRSELECT, EMIOWDTRSTO, EVENTEVENTO, MAXIGP0ARESETN, MAXIGP0ARVALID, MAXIGP0AWVALID, MAXIGP0BREADY, MAXIGP0RREADY, MAXIGP0WLAST, MAXIGP0WVALID, MAXIGP1ARESETN, MAXIGP1ARVALID, MAXIGP1AWVALID, MAXIGP1BREADY, MAXIGP1RREADY, MAXIGP1WLAST, MAXIGP1WVALID, SAXIACPARESETN, SAXIACPARREADY +, SAXIACPAWREADY, SAXIACPBVALID, SAXIACPRLAST, SAXIACPRVALID, SAXIACPWREADY, SAXIGP0ARESETN, SAXIGP0ARREADY, SAXIGP0AWREADY, SAXIGP0BVALID, SAXIGP0RLAST, SAXIGP0RVALID, SAXIGP0WREADY, SAXIGP1ARESETN, SAXIGP1ARREADY, SAXIGP1AWREADY, SAXIGP1BVALID, SAXIGP1RLAST, SAXIGP1RVALID, SAXIGP1WREADY, SAXIHP0ARESETN, SAXIHP0ARREADY +, SAXIHP0AWREADY, SAXIHP0BVALID, SAXIHP0RLAST, SAXIHP0RVALID, SAXIHP0WREADY, SAXIHP1ARESETN, SAXIHP1ARREADY, SAXIHP1AWREADY, SAXIHP1BVALID, SAXIHP1RLAST, SAXIHP1RVALID, SAXIHP1WREADY, SAXIHP2ARESETN, SAXIHP2ARREADY, SAXIHP2AWREADY, SAXIHP2BVALID, SAXIHP2RLAST, SAXIHP2RVALID, SAXIHP2WREADY, SAXIHP3ARESETN, SAXIHP3ARREADY +, SAXIHP3AWREADY, SAXIHP3BVALID, SAXIHP3RLAST, SAXIHP3RVALID, SAXIHP3WREADY, MAXIGP0ARID, MAXIGP0AWID, MAXIGP0WID, MAXIGP1ARID, MAXIGP1AWID, MAXIGP1WID, DMA0DATYPE, DMA1DATYPE, DMA2DATYPE, DMA3DATYPE, EMIOUSB0PORTINDCTL, EMIOUSB1PORTINDCTL, EVENTSTANDBYWFE, EVENTSTANDBYWFI, MAXIGP0ARBURST, MAXIGP0ARLOCK +, MAXIGP0ARSIZE, MAXIGP0AWBURST, MAXIGP0AWLOCK, MAXIGP0AWSIZE, MAXIGP1ARBURST, MAXIGP1ARLOCK, MAXIGP1ARSIZE, MAXIGP1AWBURST, MAXIGP1AWLOCK, MAXIGP1AWSIZE, SAXIACPBRESP, SAXIACPRRESP, SAXIGP0BRESP, SAXIGP0RRESP, SAXIGP1BRESP, SAXIGP1RRESP, SAXIHP0BRESP, SAXIHP0RRESP, SAXIHP1BRESP, SAXIHP1RRESP, SAXIHP2BRESP +, SAXIHP2RRESP, SAXIHP3BRESP, SAXIHP3RRESP, IRQP2F, EMIOSDIO0BUSVOLT, EMIOSDIO1BUSVOLT, EMIOSPI0SSON, EMIOSPI1SSON, EMIOTTC0WAVEO, EMIOTTC1WAVEO, MAXIGP0ARPROT, MAXIGP0AWPROT, MAXIGP1ARPROT, MAXIGP1AWPROT, SAXIACPBID, SAXIACPRID, SAXIHP0RACOUNT, SAXIHP1RACOUNT, SAXIHP2RACOUNT, SAXIHP3RACOUNT, EMIOTRACEDATA +, FTMTP2FDEBUG, MAXIGP0ARADDR, MAXIGP0AWADDR, MAXIGP0WDATA, MAXIGP1ARADDR, MAXIGP1AWADDR, MAXIGP1WDATA, SAXIGP0RDATA, SAXIGP1RDATA, EMIOSDIO0DATAO, EMIOSDIO0DATATN, EMIOSDIO1DATAO, EMIOSDIO1DATATN, FCLKCLK, FCLKRESETN, FTMTF2PTRIGACK, FTMTP2FTRIG, MAXIGP0ARCACHE, MAXIGP0ARLEN, MAXIGP0ARQOS, MAXIGP0AWCACHE +, MAXIGP0AWLEN, MAXIGP0AWQOS, MAXIGP0WSTRB, MAXIGP1ARCACHE, MAXIGP1ARLEN, MAXIGP1ARQOS, MAXIGP1AWCACHE, MAXIGP1AWLEN, MAXIGP1AWQOS, MAXIGP1WSTRB, SAXIGP0BID, SAXIGP0RID, SAXIGP1BID, SAXIGP1RID, SAXIHP0BID, SAXIHP0RID, SAXIHP0WACOUNT, SAXIHP1BID, SAXIHP1RID, SAXIHP1WACOUNT, SAXIHP2BID +, SAXIHP2RID, SAXIHP2WACOUNT, SAXIHP3BID, SAXIHP3RID, SAXIHP3WACOUNT, EMIOGPIOO, EMIOGPIOTN, SAXIACPRDATA, SAXIHP0RDATA, SAXIHP1RDATA, SAXIHP2RDATA, SAXIHP3RDATA, EMIOENET0GMIITXD, EMIOENET1GMIITXD, SAXIHP0RCOUNT, SAXIHP0WCOUNT, SAXIHP1RCOUNT, SAXIHP1WCOUNT, SAXIHP2RCOUNT, SAXIHP2WCOUNT, SAXIHP3RCOUNT +, SAXIHP3WCOUNT, DDRCASB, DDRCKE, DDRCKN, DDRCKP, DDRCSB, DDRDRSTB, DDRODT, DDRRASB, DDRVRN, DDRVRP, DDRWEB, PSCLK, PSPORB, PSSRSTB, DDRA, DDRBA, DDRDQ, DDRDM, DDRDQSN, DDRDQSP +, MIO, DMA0ACLK, DMA0DAREADY, DMA0DRLAST, DMA0DRVALID, DMA1ACLK, DMA1DAREADY, DMA1DRLAST, DMA1DRVALID, DMA2ACLK, DMA2DAREADY, DMA2DRLAST, DMA2DRVALID, DMA3ACLK, DMA3DAREADY, DMA3DRLAST, DMA3DRVALID, EMIOCAN0PHYRX, EMIOCAN1PHYRX, EMIOENET0EXTINTIN, EMIOENET0GMIICOL +, EMIOENET0GMIICRS, EMIOENET0GMIIRXCLK, EMIOENET0GMIIRXDV, EMIOENET0GMIIRXER, EMIOENET0GMIITXCLK, EMIOENET0MDIOI, EMIOENET1EXTINTIN, EMIOENET1GMIICOL, EMIOENET1GMIICRS, EMIOENET1GMIIRXCLK, EMIOENET1GMIIRXDV, EMIOENET1GMIIRXER, EMIOENET1GMIITXCLK, EMIOENET1MDIOI, EMIOI2C0SCLI, EMIOI2C0SDAI, EMIOI2C1SCLI, EMIOI2C1SDAI, EMIOPJTAGTCK, EMIOPJTAGTDI, EMIOPJTAGTMS +, EMIOSDIO0CDN, EMIOSDIO0CLKFB, EMIOSDIO0CMDI, EMIOSDIO0WP, EMIOSDIO1CDN, EMIOSDIO1CLKFB, EMIOSDIO1CMDI, EMIOSDIO1WP, EMIOSPI0MI, EMIOSPI0SCLKI, EMIOSPI0SI, EMIOSPI0SSIN, EMIOSPI1MI, EMIOSPI1SCLKI, EMIOSPI1SI, EMIOSPI1SSIN, EMIOSRAMINTIN, EMIOTRACECLK, EMIOUART0CTSN, EMIOUART0DCDN, EMIOUART0DSRN +, EMIOUART0RIN, EMIOUART0RX, EMIOUART1CTSN, EMIOUART1DCDN, EMIOUART1DSRN, EMIOUART1RIN, EMIOUART1RX, EMIOUSB0VBUSPWRFAULT, EMIOUSB1VBUSPWRFAULT, EMIOWDTCLKI, EVENTEVENTI, FPGAIDLEN, FTMDTRACEINCLOCK, FTMDTRACEINVALID, MAXIGP0ACLK, MAXIGP0ARREADY, MAXIGP0AWREADY, MAXIGP0BVALID, MAXIGP0RLAST, MAXIGP0RVALID, MAXIGP0WREADY +, MAXIGP1ACLK, MAXIGP1ARREADY, MAXIGP1AWREADY, MAXIGP1BVALID, MAXIGP1RLAST, MAXIGP1RVALID, MAXIGP1WREADY, SAXIACPACLK, SAXIACPARVALID, SAXIACPAWVALID, SAXIACPBREADY, SAXIACPRREADY, SAXIACPWLAST, SAXIACPWVALID, SAXIGP0ACLK, SAXIGP0ARVALID, SAXIGP0AWVALID, SAXIGP0BREADY, SAXIGP0RREADY, SAXIGP0WLAST, SAXIGP0WVALID +, SAXIGP1ACLK, SAXIGP1ARVALID, SAXIGP1AWVALID, SAXIGP1BREADY, SAXIGP1RREADY, SAXIGP1WLAST, SAXIGP1WVALID, SAXIHP0ACLK, SAXIHP0ARVALID, SAXIHP0AWVALID, SAXIHP0BREADY, SAXIHP0RDISSUECAP1EN, SAXIHP0RREADY, SAXIHP0WLAST, SAXIHP0WRISSUECAP1EN, SAXIHP0WVALID, SAXIHP1ACLK, SAXIHP1ARVALID, SAXIHP1AWVALID, SAXIHP1BREADY, SAXIHP1RDISSUECAP1EN +, SAXIHP1RREADY, SAXIHP1WLAST, SAXIHP1WRISSUECAP1EN, SAXIHP1WVALID, SAXIHP2ACLK, SAXIHP2ARVALID, SAXIHP2AWVALID, SAXIHP2BREADY, SAXIHP2RDISSUECAP1EN, SAXIHP2RREADY, SAXIHP2WLAST, SAXIHP2WRISSUECAP1EN, SAXIHP2WVALID, SAXIHP3ACLK, SAXIHP3ARVALID, SAXIHP3AWVALID, SAXIHP3BREADY, SAXIHP3RDISSUECAP1EN, SAXIHP3RREADY, SAXIHP3WLAST, SAXIHP3WRISSUECAP1EN +, SAXIHP3WVALID, MAXIGP0BID, MAXIGP0RID, MAXIGP1BID, MAXIGP1RID, IRQF2P, DMA0DRTYPE, DMA1DRTYPE, DMA2DRTYPE, DMA3DRTYPE, MAXIGP0BRESP, MAXIGP0RRESP, MAXIGP1BRESP, MAXIGP1RRESP, SAXIACPARBURST, SAXIACPARLOCK, SAXIACPARSIZE, SAXIACPAWBURST, SAXIACPAWLOCK, SAXIACPAWSIZE, SAXIGP0ARBURST +, SAXIGP0ARLOCK, SAXIGP0ARSIZE, SAXIGP0AWBURST, SAXIGP0AWLOCK, SAXIGP0AWSIZE, SAXIGP1ARBURST, SAXIGP1ARLOCK, SAXIGP1ARSIZE, SAXIGP1AWBURST, SAXIGP1AWLOCK, SAXIGP1AWSIZE, SAXIHP0ARBURST, SAXIHP0ARLOCK, SAXIHP0ARSIZE, SAXIHP0AWBURST, SAXIHP0AWLOCK, SAXIHP0AWSIZE, SAXIHP1ARBURST, SAXIHP1ARLOCK, SAXIHP1ARSIZE, SAXIHP1AWBURST +, SAXIHP1AWLOCK, SAXIHP1AWSIZE, SAXIHP2ARBURST, SAXIHP2ARLOCK, SAXIHP2ARSIZE, SAXIHP2AWBURST, SAXIHP2AWLOCK, SAXIHP2AWSIZE, SAXIHP3ARBURST, SAXIHP3ARLOCK, SAXIHP3ARSIZE, SAXIHP3AWBURST, SAXIHP3AWLOCK, SAXIHP3AWSIZE, EMIOTTC0CLKI, EMIOTTC1CLKI, SAXIACPARID, SAXIACPARPROT, SAXIACPAWID, SAXIACPAWPROT, SAXIACPWID +, SAXIGP0ARPROT, SAXIGP0AWPROT, SAXIGP1ARPROT, SAXIGP1AWPROT, SAXIHP0ARPROT, SAXIHP0AWPROT, SAXIHP1ARPROT, SAXIHP1AWPROT, SAXIHP2ARPROT, SAXIHP2AWPROT, SAXIHP3ARPROT, SAXIHP3AWPROT, FTMDTRACEINDATA, FTMTF2PDEBUG, MAXIGP0RDATA, MAXIGP1RDATA, SAXIACPARADDR, SAXIACPAWADDR, SAXIGP0ARADDR, SAXIGP0AWADDR, SAXIGP0WDATA +, SAXIGP1ARADDR, SAXIGP1AWADDR, SAXIGP1WDATA, SAXIHP0ARADDR, SAXIHP0AWADDR, SAXIHP1ARADDR, SAXIHP1AWADDR, SAXIHP2ARADDR, SAXIHP2AWADDR, SAXIHP3ARADDR, SAXIHP3AWADDR, DDRARB, EMIOSDIO0DATAI, EMIOSDIO1DATAI, FCLKCLKTRIGN, FTMDTRACEINATID, FTMTF2PTRIG, FTMTP2FTRIGACK, SAXIACPARCACHE, SAXIACPARLEN, SAXIACPARQOS +, SAXIACPAWCACHE, SAXIACPAWLEN, SAXIACPAWQOS, SAXIGP0ARCACHE, SAXIGP0ARLEN, SAXIGP0ARQOS, SAXIGP0AWCACHE, SAXIGP0AWLEN, SAXIGP0AWQOS, SAXIGP0WSTRB, SAXIGP1ARCACHE, SAXIGP1ARLEN, SAXIGP1ARQOS, SAXIGP1AWCACHE, SAXIGP1AWLEN, SAXIGP1AWQOS, SAXIGP1WSTRB, SAXIHP0ARCACHE, SAXIHP0ARLEN, SAXIHP0ARQOS, SAXIHP0AWCACHE +, SAXIHP0AWLEN, SAXIHP0AWQOS, SAXIHP1ARCACHE, SAXIHP1ARLEN, SAXIHP1ARQOS, SAXIHP1AWCACHE, SAXIHP1AWLEN, SAXIHP1AWQOS, SAXIHP2ARCACHE, SAXIHP2ARLEN, SAXIHP2ARQOS, SAXIHP2AWCACHE, SAXIHP2AWLEN, SAXIHP2AWQOS, SAXIHP3ARCACHE, SAXIHP3ARLEN, SAXIHP3ARQOS, SAXIHP3AWCACHE, SAXIHP3AWLEN, SAXIHP3AWQOS, SAXIACPARUSER +, SAXIACPAWUSER, SAXIGP0ARID, SAXIGP0AWID, SAXIGP0WID, SAXIGP1ARID, SAXIGP1AWID, SAXIGP1WID, SAXIHP0ARID, SAXIHP0AWID, SAXIHP0WID, SAXIHP1ARID, SAXIHP1AWID, SAXIHP1WID, SAXIHP2ARID, SAXIHP2AWID, SAXIHP2WID, SAXIHP3ARID, SAXIHP3AWID, SAXIHP3WID, EMIOGPIOI, SAXIACPWDATA +, SAXIHP0WDATA, SAXIHP1WDATA, SAXIHP2WDATA, SAXIHP3WDATA, EMIOENET0GMIIRXD, EMIOENET1GMIIRXD, SAXIACPWSTRB, SAXIHP0WSTRB, SAXIHP1WSTRB, SAXIHP2WSTRB, SAXIHP3WSTRB); output DMA0DAVALID; output DMA0DRREADY; output DMA0RSTN; @@ -32316,7 +32945,55 @@ module PS7 (...); endmodule (* keep *) -module PS8 (...); +module PS8(ADMA2PLCACK, ADMA2PLTVLD, DPAUDIOREFCLK, DPAUXDATAOEN, DPAUXDATAOUT, DPLIVEVIDEODEOUT, DPMAXISMIXEDAUDIOTDATA, DPMAXISMIXEDAUDIOTID, DPMAXISMIXEDAUDIOTVALID, DPSAXISAUDIOTREADY, DPVIDEOOUTHSYNC, DPVIDEOOUTPIXEL1, DPVIDEOOUTVSYNC, DPVIDEOREFCLK, EMIOCAN0PHYTX, EMIOCAN1PHYTX, EMIOENET0DMABUSWIDTH, EMIOENET0DMATXENDTOG, EMIOENET0GEMTSUTIMERCNT, EMIOENET0GMIITXD, EMIOENET0GMIITXEN +, EMIOENET0GMIITXER, EMIOENET0MDIOMDC, EMIOENET0MDIOO, EMIOENET0MDIOTN, EMIOENET0RXWDATA, EMIOENET0RXWEOP, EMIOENET0RXWERR, EMIOENET0RXWFLUSH, EMIOENET0RXWSOP, EMIOENET0RXWSTATUS, EMIOENET0RXWWR, EMIOENET0SPEEDMODE, EMIOENET0TXRRD, EMIOENET0TXRSTATUS, EMIOENET1DMABUSWIDTH, EMIOENET1DMATXENDTOG, EMIOENET1GMIITXD, EMIOENET1GMIITXEN, EMIOENET1GMIITXER, EMIOENET1MDIOMDC, EMIOENET1MDIOO +, EMIOENET1MDIOTN, EMIOENET1RXWDATA, EMIOENET1RXWEOP, EMIOENET1RXWERR, EMIOENET1RXWFLUSH, EMIOENET1RXWSOP, EMIOENET1RXWSTATUS, EMIOENET1RXWWR, EMIOENET1SPEEDMODE, EMIOENET1TXRRD, EMIOENET1TXRSTATUS, EMIOENET2DMABUSWIDTH, EMIOENET2DMATXENDTOG, EMIOENET2GMIITXD, EMIOENET2GMIITXEN, EMIOENET2GMIITXER, EMIOENET2MDIOMDC, EMIOENET2MDIOO, EMIOENET2MDIOTN, EMIOENET2RXWDATA, EMIOENET2RXWEOP +, EMIOENET2RXWERR, EMIOENET2RXWFLUSH, EMIOENET2RXWSOP, EMIOENET2RXWSTATUS, EMIOENET2RXWWR, EMIOENET2SPEEDMODE, EMIOENET2TXRRD, EMIOENET2TXRSTATUS, EMIOENET3DMABUSWIDTH, EMIOENET3DMATXENDTOG, EMIOENET3GMIITXD, EMIOENET3GMIITXEN, EMIOENET3GMIITXER, EMIOENET3MDIOMDC, EMIOENET3MDIOO, EMIOENET3MDIOTN, EMIOENET3RXWDATA, EMIOENET3RXWEOP, EMIOENET3RXWERR, EMIOENET3RXWFLUSH, EMIOENET3RXWSOP +, EMIOENET3RXWSTATUS, EMIOENET3RXWWR, EMIOENET3SPEEDMODE, EMIOENET3TXRRD, EMIOENET3TXRSTATUS, EMIOGEM0DELAYREQRX, EMIOGEM0DELAYREQTX, EMIOGEM0PDELAYREQRX, EMIOGEM0PDELAYREQTX, EMIOGEM0PDELAYRESPRX, EMIOGEM0PDELAYRESPTX, EMIOGEM0RXSOF, EMIOGEM0SYNCFRAMERX, EMIOGEM0SYNCFRAMETX, EMIOGEM0TSUTIMERCMPVAL, EMIOGEM0TXRFIXEDLAT, EMIOGEM0TXSOF, EMIOGEM1DELAYREQRX, EMIOGEM1DELAYREQTX, EMIOGEM1PDELAYREQRX, EMIOGEM1PDELAYREQTX +, EMIOGEM1PDELAYRESPRX, EMIOGEM1PDELAYRESPTX, EMIOGEM1RXSOF, EMIOGEM1SYNCFRAMERX, EMIOGEM1SYNCFRAMETX, EMIOGEM1TSUTIMERCMPVAL, EMIOGEM1TXRFIXEDLAT, EMIOGEM1TXSOF, EMIOGEM2DELAYREQRX, EMIOGEM2DELAYREQTX, EMIOGEM2PDELAYREQRX, EMIOGEM2PDELAYREQTX, EMIOGEM2PDELAYRESPRX, EMIOGEM2PDELAYRESPTX, EMIOGEM2RXSOF, EMIOGEM2SYNCFRAMERX, EMIOGEM2SYNCFRAMETX, EMIOGEM2TSUTIMERCMPVAL, EMIOGEM2TXRFIXEDLAT, EMIOGEM2TXSOF, EMIOGEM3DELAYREQRX +, EMIOGEM3DELAYREQTX, EMIOGEM3PDELAYREQRX, EMIOGEM3PDELAYREQTX, EMIOGEM3PDELAYRESPRX, EMIOGEM3PDELAYRESPTX, EMIOGEM3RXSOF, EMIOGEM3SYNCFRAMERX, EMIOGEM3SYNCFRAMETX, EMIOGEM3TSUTIMERCMPVAL, EMIOGEM3TXRFIXEDLAT, EMIOGEM3TXSOF, EMIOGPIOO, EMIOGPIOTN, EMIOI2C0SCLO, EMIOI2C0SCLTN, EMIOI2C0SDAO, EMIOI2C0SDATN, EMIOI2C1SCLO, EMIOI2C1SCLTN, EMIOI2C1SDAO, EMIOI2C1SDATN +, EMIOSDIO0BUSPOWER, EMIOSDIO0BUSVOLT, EMIOSDIO0CLKOUT, EMIOSDIO0CMDENA, EMIOSDIO0CMDOUT, EMIOSDIO0DATAENA, EMIOSDIO0DATAOUT, EMIOSDIO0LEDCONTROL, EMIOSDIO1BUSPOWER, EMIOSDIO1BUSVOLT, EMIOSDIO1CLKOUT, EMIOSDIO1CMDENA, EMIOSDIO1CMDOUT, EMIOSDIO1DATAENA, EMIOSDIO1DATAOUT, EMIOSDIO1LEDCONTROL, EMIOSPI0MO, EMIOSPI0MOTN, EMIOSPI0SCLKO, EMIOSPI0SCLKTN, EMIOSPI0SO +, EMIOSPI0SSNTN, EMIOSPI0SSON, EMIOSPI0STN, EMIOSPI1MO, EMIOSPI1MOTN, EMIOSPI1SCLKO, EMIOSPI1SCLKTN, EMIOSPI1SO, EMIOSPI1SSNTN, EMIOSPI1SSON, EMIOSPI1STN, EMIOTTC0WAVEO, EMIOTTC1WAVEO, EMIOTTC2WAVEO, EMIOTTC3WAVEO, EMIOU2DSPORTVBUSCTRLUSB30, EMIOU2DSPORTVBUSCTRLUSB31, EMIOU3DSPORTVBUSCTRLUSB30, EMIOU3DSPORTVBUSCTRLUSB31, EMIOUART0DTRN, EMIOUART0RTSN +, EMIOUART0TX, EMIOUART1DTRN, EMIOUART1RTSN, EMIOUART1TX, EMIOWDT0RSTO, EMIOWDT1RSTO, FMIOGEM0FIFORXCLKTOPLBUFG, FMIOGEM0FIFOTXCLKTOPLBUFG, FMIOGEM1FIFORXCLKTOPLBUFG, FMIOGEM1FIFOTXCLKTOPLBUFG, FMIOGEM2FIFORXCLKTOPLBUFG, FMIOGEM2FIFOTXCLKTOPLBUFG, FMIOGEM3FIFORXCLKTOPLBUFG, FMIOGEM3FIFOTXCLKTOPLBUFG, FMIOGEMTSUCLKTOPLBUFG, FTMGPO, GDMA2PLCACK, GDMA2PLTVLD, MAXIGP0ARADDR, MAXIGP0ARBURST, MAXIGP0ARCACHE +, MAXIGP0ARID, MAXIGP0ARLEN, MAXIGP0ARLOCK, MAXIGP0ARPROT, MAXIGP0ARQOS, MAXIGP0ARSIZE, MAXIGP0ARUSER, MAXIGP0ARVALID, MAXIGP0AWADDR, MAXIGP0AWBURST, MAXIGP0AWCACHE, MAXIGP0AWID, MAXIGP0AWLEN, MAXIGP0AWLOCK, MAXIGP0AWPROT, MAXIGP0AWQOS, MAXIGP0AWSIZE, MAXIGP0AWUSER, MAXIGP0AWVALID, MAXIGP0BREADY, MAXIGP0RREADY +, MAXIGP0WDATA, MAXIGP0WLAST, MAXIGP0WSTRB, MAXIGP0WVALID, MAXIGP1ARADDR, MAXIGP1ARBURST, MAXIGP1ARCACHE, MAXIGP1ARID, MAXIGP1ARLEN, MAXIGP1ARLOCK, MAXIGP1ARPROT, MAXIGP1ARQOS, MAXIGP1ARSIZE, MAXIGP1ARUSER, MAXIGP1ARVALID, MAXIGP1AWADDR, MAXIGP1AWBURST, MAXIGP1AWCACHE, MAXIGP1AWID, MAXIGP1AWLEN, MAXIGP1AWLOCK +, MAXIGP1AWPROT, MAXIGP1AWQOS, MAXIGP1AWSIZE, MAXIGP1AWUSER, MAXIGP1AWVALID, MAXIGP1BREADY, MAXIGP1RREADY, MAXIGP1WDATA, MAXIGP1WLAST, MAXIGP1WSTRB, MAXIGP1WVALID, MAXIGP2ARADDR, MAXIGP2ARBURST, MAXIGP2ARCACHE, MAXIGP2ARID, MAXIGP2ARLEN, MAXIGP2ARLOCK, MAXIGP2ARPROT, MAXIGP2ARQOS, MAXIGP2ARSIZE, MAXIGP2ARUSER +, MAXIGP2ARVALID, MAXIGP2AWADDR, MAXIGP2AWBURST, MAXIGP2AWCACHE, MAXIGP2AWID, MAXIGP2AWLEN, MAXIGP2AWLOCK, MAXIGP2AWPROT, MAXIGP2AWQOS, MAXIGP2AWSIZE, MAXIGP2AWUSER, MAXIGP2AWVALID, MAXIGP2BREADY, MAXIGP2RREADY, MAXIGP2WDATA, MAXIGP2WLAST, MAXIGP2WSTRB, MAXIGP2WVALID, OSCRTCCLK, PLCLK, PMUAIBAFIFMFPDREQ +, PMUAIBAFIFMLPDREQ, PMUERRORTOPL, PMUPLGPO, PSPLEVENTO, PSPLIRQFPD, PSPLIRQLPD, PSPLSTANDBYWFE, PSPLSTANDBYWFI, PSPLTRACECTL, PSPLTRACEDATA, PSPLTRIGACK, PSPLTRIGGER, PSS_ALTO_CORE_PAD_MGTTXN0OUT, PSS_ALTO_CORE_PAD_MGTTXN1OUT, PSS_ALTO_CORE_PAD_MGTTXN2OUT, PSS_ALTO_CORE_PAD_MGTTXN3OUT, PSS_ALTO_CORE_PAD_MGTTXP0OUT, PSS_ALTO_CORE_PAD_MGTTXP1OUT, PSS_ALTO_CORE_PAD_MGTTXP2OUT, PSS_ALTO_CORE_PAD_MGTTXP3OUT, PSS_ALTO_CORE_PAD_PADO +, RPUEVENTO0, RPUEVENTO1, SACEFPDACADDR, SACEFPDACPROT, SACEFPDACSNOOP, SACEFPDACVALID, SACEFPDARREADY, SACEFPDAWREADY, SACEFPDBID, SACEFPDBRESP, SACEFPDBUSER, SACEFPDBVALID, SACEFPDCDREADY, SACEFPDCRREADY, SACEFPDRDATA, SACEFPDRID, SACEFPDRLAST, SACEFPDRRESP, SACEFPDRUSER, SACEFPDRVALID, SACEFPDWREADY +, SAXIACPARREADY, SAXIACPAWREADY, SAXIACPBID, SAXIACPBRESP, SAXIACPBVALID, SAXIACPRDATA, SAXIACPRID, SAXIACPRLAST, SAXIACPRRESP, SAXIACPRVALID, SAXIACPWREADY, SAXIGP0ARREADY, SAXIGP0AWREADY, SAXIGP0BID, SAXIGP0BRESP, SAXIGP0BVALID, SAXIGP0RACOUNT, SAXIGP0RCOUNT, SAXIGP0RDATA, SAXIGP0RID, SAXIGP0RLAST +, SAXIGP0RRESP, SAXIGP0RVALID, SAXIGP0WACOUNT, SAXIGP0WCOUNT, SAXIGP0WREADY, SAXIGP1ARREADY, SAXIGP1AWREADY, SAXIGP1BID, SAXIGP1BRESP, SAXIGP1BVALID, SAXIGP1RACOUNT, SAXIGP1RCOUNT, SAXIGP1RDATA, SAXIGP1RID, SAXIGP1RLAST, SAXIGP1RRESP, SAXIGP1RVALID, SAXIGP1WACOUNT, SAXIGP1WCOUNT, SAXIGP1WREADY, SAXIGP2ARREADY +, SAXIGP2AWREADY, SAXIGP2BID, SAXIGP2BRESP, SAXIGP2BVALID, SAXIGP2RACOUNT, SAXIGP2RCOUNT, SAXIGP2RDATA, SAXIGP2RID, SAXIGP2RLAST, SAXIGP2RRESP, SAXIGP2RVALID, SAXIGP2WACOUNT, SAXIGP2WCOUNT, SAXIGP2WREADY, SAXIGP3ARREADY, SAXIGP3AWREADY, SAXIGP3BID, SAXIGP3BRESP, SAXIGP3BVALID, SAXIGP3RACOUNT, SAXIGP3RCOUNT +, SAXIGP3RDATA, SAXIGP3RID, SAXIGP3RLAST, SAXIGP3RRESP, SAXIGP3RVALID, SAXIGP3WACOUNT, SAXIGP3WCOUNT, SAXIGP3WREADY, SAXIGP4ARREADY, SAXIGP4AWREADY, SAXIGP4BID, SAXIGP4BRESP, SAXIGP4BVALID, SAXIGP4RACOUNT, SAXIGP4RCOUNT, SAXIGP4RDATA, SAXIGP4RID, SAXIGP4RLAST, SAXIGP4RRESP, SAXIGP4RVALID, SAXIGP4WACOUNT +, SAXIGP4WCOUNT, SAXIGP4WREADY, SAXIGP5ARREADY, SAXIGP5AWREADY, SAXIGP5BID, SAXIGP5BRESP, SAXIGP5BVALID, SAXIGP5RACOUNT, SAXIGP5RCOUNT, SAXIGP5RDATA, SAXIGP5RID, SAXIGP5RLAST, SAXIGP5RRESP, SAXIGP5RVALID, SAXIGP5WACOUNT, SAXIGP5WCOUNT, SAXIGP5WREADY, SAXIGP6ARREADY, SAXIGP6AWREADY, SAXIGP6BID, SAXIGP6BRESP +, SAXIGP6BVALID, SAXIGP6RACOUNT, SAXIGP6RCOUNT, SAXIGP6RDATA, SAXIGP6RID, SAXIGP6RLAST, SAXIGP6RRESP, SAXIGP6RVALID, SAXIGP6WACOUNT, SAXIGP6WCOUNT, SAXIGP6WREADY, PSS_ALTO_CORE_PAD_BOOTMODE, PSS_ALTO_CORE_PAD_CLK, PSS_ALTO_CORE_PAD_DONEB, PSS_ALTO_CORE_PAD_DRAMA, PSS_ALTO_CORE_PAD_DRAMACTN, PSS_ALTO_CORE_PAD_DRAMALERTN, PSS_ALTO_CORE_PAD_DRAMBA, PSS_ALTO_CORE_PAD_DRAMBG, PSS_ALTO_CORE_PAD_DRAMCK, PSS_ALTO_CORE_PAD_DRAMCKE +, PSS_ALTO_CORE_PAD_DRAMCKN, PSS_ALTO_CORE_PAD_DRAMCSN, PSS_ALTO_CORE_PAD_DRAMDM, PSS_ALTO_CORE_PAD_DRAMDQ, PSS_ALTO_CORE_PAD_DRAMDQS, PSS_ALTO_CORE_PAD_DRAMDQSN, PSS_ALTO_CORE_PAD_DRAMODT, PSS_ALTO_CORE_PAD_DRAMPARITY, PSS_ALTO_CORE_PAD_DRAMRAMRSTN, PSS_ALTO_CORE_PAD_ERROROUT, PSS_ALTO_CORE_PAD_ERRORSTATUS, PSS_ALTO_CORE_PAD_INITB, PSS_ALTO_CORE_PAD_JTAGTCK, PSS_ALTO_CORE_PAD_JTAGTDI, PSS_ALTO_CORE_PAD_JTAGTDO, PSS_ALTO_CORE_PAD_JTAGTMS, PSS_ALTO_CORE_PAD_MIO, PSS_ALTO_CORE_PAD_PORB, PSS_ALTO_CORE_PAD_PROGB, PSS_ALTO_CORE_PAD_RCALIBINOUT, PSS_ALTO_CORE_PAD_SRSTB +, PSS_ALTO_CORE_PAD_ZQ, ADMAFCICLK, AIBPMUAFIFMFPDACK, AIBPMUAFIFMLPDACK, DDRCEXTREFRESHRANK0REQ, DDRCEXTREFRESHRANK1REQ, DDRCREFRESHPLCLK, DPAUXDATAIN, DPEXTERNALCUSTOMEVENT1, DPEXTERNALCUSTOMEVENT2, DPEXTERNALVSYNCEVENT, DPHOTPLUGDETECT, DPLIVEGFXALPHAIN, DPLIVEGFXPIXEL1IN, DPLIVEVIDEOINDE, DPLIVEVIDEOINHSYNC, DPLIVEVIDEOINPIXEL1, DPLIVEVIDEOINVSYNC, DPMAXISMIXEDAUDIOTREADY, DPSAXISAUDIOCLK, DPSAXISAUDIOTDATA +, DPSAXISAUDIOTID, DPSAXISAUDIOTVALID, DPVIDEOINCLK, EMIOCAN0PHYRX, EMIOCAN1PHYRX, EMIOENET0DMATXSTATUSTOG, EMIOENET0EXTINTIN, EMIOENET0GMIICOL, EMIOENET0GMIICRS, EMIOENET0GMIIRXCLK, EMIOENET0GMIIRXD, EMIOENET0GMIIRXDV, EMIOENET0GMIIRXER, EMIOENET0GMIITXCLK, EMIOENET0MDIOI, EMIOENET0RXWOVERFLOW, EMIOENET0TXRCONTROL, EMIOENET0TXRDATA, EMIOENET0TXRDATARDY, EMIOENET0TXREOP, EMIOENET0TXRERR +, EMIOENET0TXRFLUSHED, EMIOENET0TXRSOP, EMIOENET0TXRUNDERFLOW, EMIOENET0TXRVALID, EMIOENET1DMATXSTATUSTOG, EMIOENET1EXTINTIN, EMIOENET1GMIICOL, EMIOENET1GMIICRS, EMIOENET1GMIIRXCLK, EMIOENET1GMIIRXD, EMIOENET1GMIIRXDV, EMIOENET1GMIIRXER, EMIOENET1GMIITXCLK, EMIOENET1MDIOI, EMIOENET1RXWOVERFLOW, EMIOENET1TXRCONTROL, EMIOENET1TXRDATA, EMIOENET1TXRDATARDY, EMIOENET1TXREOP, EMIOENET1TXRERR, EMIOENET1TXRFLUSHED +, EMIOENET1TXRSOP, EMIOENET1TXRUNDERFLOW, EMIOENET1TXRVALID, EMIOENET2DMATXSTATUSTOG, EMIOENET2EXTINTIN, EMIOENET2GMIICOL, EMIOENET2GMIICRS, EMIOENET2GMIIRXCLK, EMIOENET2GMIIRXD, EMIOENET2GMIIRXDV, EMIOENET2GMIIRXER, EMIOENET2GMIITXCLK, EMIOENET2MDIOI, EMIOENET2RXWOVERFLOW, EMIOENET2TXRCONTROL, EMIOENET2TXRDATA, EMIOENET2TXRDATARDY, EMIOENET2TXREOP, EMIOENET2TXRERR, EMIOENET2TXRFLUSHED, EMIOENET2TXRSOP +, EMIOENET2TXRUNDERFLOW, EMIOENET2TXRVALID, EMIOENET3DMATXSTATUSTOG, EMIOENET3EXTINTIN, EMIOENET3GMIICOL, EMIOENET3GMIICRS, EMIOENET3GMIIRXCLK, EMIOENET3GMIIRXD, EMIOENET3GMIIRXDV, EMIOENET3GMIIRXER, EMIOENET3GMIITXCLK, EMIOENET3MDIOI, EMIOENET3RXWOVERFLOW, EMIOENET3TXRCONTROL, EMIOENET3TXRDATA, EMIOENET3TXRDATARDY, EMIOENET3TXREOP, EMIOENET3TXRERR, EMIOENET3TXRFLUSHED, EMIOENET3TXRSOP, EMIOENET3TXRUNDERFLOW +, EMIOENET3TXRVALID, EMIOENETTSUCLK, EMIOGEM0TSUINCCTRL, EMIOGEM1TSUINCCTRL, EMIOGEM2TSUINCCTRL, EMIOGEM3TSUINCCTRL, EMIOGPIOI, EMIOHUBPORTOVERCRNTUSB20, EMIOHUBPORTOVERCRNTUSB21, EMIOHUBPORTOVERCRNTUSB30, EMIOHUBPORTOVERCRNTUSB31, EMIOI2C0SCLI, EMIOI2C0SDAI, EMIOI2C1SCLI, EMIOI2C1SDAI, EMIOSDIO0CDN, EMIOSDIO0CMDIN, EMIOSDIO0DATAIN, EMIOSDIO0FBCLKIN, EMIOSDIO0WP, EMIOSDIO1CDN +, EMIOSDIO1CMDIN, EMIOSDIO1DATAIN, EMIOSDIO1FBCLKIN, EMIOSDIO1WP, EMIOSPI0MI, EMIOSPI0SCLKI, EMIOSPI0SI, EMIOSPI0SSIN, EMIOSPI1MI, EMIOSPI1SCLKI, EMIOSPI1SI, EMIOSPI1SSIN, EMIOTTC0CLKI, EMIOTTC1CLKI, EMIOTTC2CLKI, EMIOTTC3CLKI, EMIOUART0CTSN, EMIOUART0DCDN, EMIOUART0DSRN, EMIOUART0RIN, EMIOUART0RX +, EMIOUART1CTSN, EMIOUART1DCDN, EMIOUART1DSRN, EMIOUART1RIN, EMIOUART1RX, EMIOWDT0CLKI, EMIOWDT1CLKI, FMIOGEM0FIFORXCLKFROMPL, FMIOGEM0FIFOTXCLKFROMPL, FMIOGEM0SIGNALDETECT, FMIOGEM1FIFORXCLKFROMPL, FMIOGEM1FIFOTXCLKFROMPL, FMIOGEM1SIGNALDETECT, FMIOGEM2FIFORXCLKFROMPL, FMIOGEM2FIFOTXCLKFROMPL, FMIOGEM2SIGNALDETECT, FMIOGEM3FIFORXCLKFROMPL, FMIOGEM3FIFOTXCLKFROMPL, FMIOGEM3SIGNALDETECT, FMIOGEMTSUCLKFROMPL, FTMGPI +, GDMAFCICLK, MAXIGP0ACLK, MAXIGP0ARREADY, MAXIGP0AWREADY, MAXIGP0BID, MAXIGP0BRESP, MAXIGP0BVALID, MAXIGP0RDATA, MAXIGP0RID, MAXIGP0RLAST, MAXIGP0RRESP, MAXIGP0RVALID, MAXIGP0WREADY, MAXIGP1ACLK, MAXIGP1ARREADY, MAXIGP1AWREADY, MAXIGP1BID, MAXIGP1BRESP, MAXIGP1BVALID, MAXIGP1RDATA, MAXIGP1RID +, MAXIGP1RLAST, MAXIGP1RRESP, MAXIGP1RVALID, MAXIGP1WREADY, MAXIGP2ACLK, MAXIGP2ARREADY, MAXIGP2AWREADY, MAXIGP2BID, MAXIGP2BRESP, MAXIGP2BVALID, MAXIGP2RDATA, MAXIGP2RID, MAXIGP2RLAST, MAXIGP2RRESP, MAXIGP2RVALID, MAXIGP2WREADY, NFIQ0LPDRPU, NFIQ1LPDRPU, NIRQ0LPDRPU, NIRQ1LPDRPU, PL2ADMACVLD +, PL2ADMATACK, PL2GDMACVLD, PL2GDMATACK, PLACECLK, PLACPINACT, PLFPGASTOP, PLLAUXREFCLKFPD, PLLAUXREFCLKLPD, PLPMUGPI, PLPSAPUGICFIQ, PLPSAPUGICIRQ, PLPSEVENTI, PLPSIRQ0, PLPSIRQ1, PLPSTRACECLK, PLPSTRIGACK, PLPSTRIGGER, PMUERRORFROMPL, PSS_ALTO_CORE_PAD_MGTRXN0IN, PSS_ALTO_CORE_PAD_MGTRXN1IN, PSS_ALTO_CORE_PAD_MGTRXN2IN +, PSS_ALTO_CORE_PAD_MGTRXN3IN, PSS_ALTO_CORE_PAD_MGTRXP0IN, PSS_ALTO_CORE_PAD_MGTRXP1IN, PSS_ALTO_CORE_PAD_MGTRXP2IN, PSS_ALTO_CORE_PAD_MGTRXP3IN, PSS_ALTO_CORE_PAD_PADI, PSS_ALTO_CORE_PAD_REFN0IN, PSS_ALTO_CORE_PAD_REFN1IN, PSS_ALTO_CORE_PAD_REFN2IN, PSS_ALTO_CORE_PAD_REFN3IN, PSS_ALTO_CORE_PAD_REFP0IN, PSS_ALTO_CORE_PAD_REFP1IN, PSS_ALTO_CORE_PAD_REFP2IN, PSS_ALTO_CORE_PAD_REFP3IN, RPUEVENTI0, RPUEVENTI1, SACEFPDACREADY, SACEFPDARADDR, SACEFPDARBAR, SACEFPDARBURST, SACEFPDARCACHE +, SACEFPDARDOMAIN, SACEFPDARID, SACEFPDARLEN, SACEFPDARLOCK, SACEFPDARPROT, SACEFPDARQOS, SACEFPDARREGION, SACEFPDARSIZE, SACEFPDARSNOOP, SACEFPDARUSER, SACEFPDARVALID, SACEFPDAWADDR, SACEFPDAWBAR, SACEFPDAWBURST, SACEFPDAWCACHE, SACEFPDAWDOMAIN, SACEFPDAWID, SACEFPDAWLEN, SACEFPDAWLOCK, SACEFPDAWPROT, SACEFPDAWQOS +, SACEFPDAWREGION, SACEFPDAWSIZE, SACEFPDAWSNOOP, SACEFPDAWUSER, SACEFPDAWVALID, SACEFPDBREADY, SACEFPDCDDATA, SACEFPDCDLAST, SACEFPDCDVALID, SACEFPDCRRESP, SACEFPDCRVALID, SACEFPDRACK, SACEFPDRREADY, SACEFPDWACK, SACEFPDWDATA, SACEFPDWLAST, SACEFPDWSTRB, SACEFPDWUSER, SACEFPDWVALID, SAXIACPACLK, SAXIACPARADDR +, SAXIACPARBURST, SAXIACPARCACHE, SAXIACPARID, SAXIACPARLEN, SAXIACPARLOCK, SAXIACPARPROT, SAXIACPARQOS, SAXIACPARSIZE, SAXIACPARUSER, SAXIACPARVALID, SAXIACPAWADDR, SAXIACPAWBURST, SAXIACPAWCACHE, SAXIACPAWID, SAXIACPAWLEN, SAXIACPAWLOCK, SAXIACPAWPROT, SAXIACPAWQOS, SAXIACPAWSIZE, SAXIACPAWUSER, SAXIACPAWVALID +, SAXIACPBREADY, SAXIACPRREADY, SAXIACPWDATA, SAXIACPWLAST, SAXIACPWSTRB, SAXIACPWVALID, SAXIGP0ARADDR, SAXIGP0ARBURST, SAXIGP0ARCACHE, SAXIGP0ARID, SAXIGP0ARLEN, SAXIGP0ARLOCK, SAXIGP0ARPROT, SAXIGP0ARQOS, SAXIGP0ARSIZE, SAXIGP0ARUSER, SAXIGP0ARVALID, SAXIGP0AWADDR, SAXIGP0AWBURST, SAXIGP0AWCACHE, SAXIGP0AWID +, SAXIGP0AWLEN, SAXIGP0AWLOCK, SAXIGP0AWPROT, SAXIGP0AWQOS, SAXIGP0AWSIZE, SAXIGP0AWUSER, SAXIGP0AWVALID, SAXIGP0BREADY, SAXIGP0RCLK, SAXIGP0RREADY, SAXIGP0WCLK, SAXIGP0WDATA, SAXIGP0WLAST, SAXIGP0WSTRB, SAXIGP0WVALID, SAXIGP1ARADDR, SAXIGP1ARBURST, SAXIGP1ARCACHE, SAXIGP1ARID, SAXIGP1ARLEN, SAXIGP1ARLOCK +, SAXIGP1ARPROT, SAXIGP1ARQOS, SAXIGP1ARSIZE, SAXIGP1ARUSER, SAXIGP1ARVALID, SAXIGP1AWADDR, SAXIGP1AWBURST, SAXIGP1AWCACHE, SAXIGP1AWID, SAXIGP1AWLEN, SAXIGP1AWLOCK, SAXIGP1AWPROT, SAXIGP1AWQOS, SAXIGP1AWSIZE, SAXIGP1AWUSER, SAXIGP1AWVALID, SAXIGP1BREADY, SAXIGP1RCLK, SAXIGP1RREADY, SAXIGP1WCLK, SAXIGP1WDATA +, SAXIGP1WLAST, SAXIGP1WSTRB, SAXIGP1WVALID, SAXIGP2ARADDR, SAXIGP2ARBURST, SAXIGP2ARCACHE, SAXIGP2ARID, SAXIGP2ARLEN, SAXIGP2ARLOCK, SAXIGP2ARPROT, SAXIGP2ARQOS, SAXIGP2ARSIZE, SAXIGP2ARUSER, SAXIGP2ARVALID, SAXIGP2AWADDR, SAXIGP2AWBURST, SAXIGP2AWCACHE, SAXIGP2AWID, SAXIGP2AWLEN, SAXIGP2AWLOCK, SAXIGP2AWPROT +, SAXIGP2AWQOS, SAXIGP2AWSIZE, SAXIGP2AWUSER, SAXIGP2AWVALID, SAXIGP2BREADY, SAXIGP2RCLK, SAXIGP2RREADY, SAXIGP2WCLK, SAXIGP2WDATA, SAXIGP2WLAST, SAXIGP2WSTRB, SAXIGP2WVALID, SAXIGP3ARADDR, SAXIGP3ARBURST, SAXIGP3ARCACHE, SAXIGP3ARID, SAXIGP3ARLEN, SAXIGP3ARLOCK, SAXIGP3ARPROT, SAXIGP3ARQOS, SAXIGP3ARSIZE +, SAXIGP3ARUSER, SAXIGP3ARVALID, SAXIGP3AWADDR, SAXIGP3AWBURST, SAXIGP3AWCACHE, SAXIGP3AWID, SAXIGP3AWLEN, SAXIGP3AWLOCK, SAXIGP3AWPROT, SAXIGP3AWQOS, SAXIGP3AWSIZE, SAXIGP3AWUSER, SAXIGP3AWVALID, SAXIGP3BREADY, SAXIGP3RCLK, SAXIGP3RREADY, SAXIGP3WCLK, SAXIGP3WDATA, SAXIGP3WLAST, SAXIGP3WSTRB, SAXIGP3WVALID +, SAXIGP4ARADDR, SAXIGP4ARBURST, SAXIGP4ARCACHE, SAXIGP4ARID, SAXIGP4ARLEN, SAXIGP4ARLOCK, SAXIGP4ARPROT, SAXIGP4ARQOS, SAXIGP4ARSIZE, SAXIGP4ARUSER, SAXIGP4ARVALID, SAXIGP4AWADDR, SAXIGP4AWBURST, SAXIGP4AWCACHE, SAXIGP4AWID, SAXIGP4AWLEN, SAXIGP4AWLOCK, SAXIGP4AWPROT, SAXIGP4AWQOS, SAXIGP4AWSIZE, SAXIGP4AWUSER +, SAXIGP4AWVALID, SAXIGP4BREADY, SAXIGP4RCLK, SAXIGP4RREADY, SAXIGP4WCLK, SAXIGP4WDATA, SAXIGP4WLAST, SAXIGP4WSTRB, SAXIGP4WVALID, SAXIGP5ARADDR, SAXIGP5ARBURST, SAXIGP5ARCACHE, SAXIGP5ARID, SAXIGP5ARLEN, SAXIGP5ARLOCK, SAXIGP5ARPROT, SAXIGP5ARQOS, SAXIGP5ARSIZE, SAXIGP5ARUSER, SAXIGP5ARVALID, SAXIGP5AWADDR +, SAXIGP5AWBURST, SAXIGP5AWCACHE, SAXIGP5AWID, SAXIGP5AWLEN, SAXIGP5AWLOCK, SAXIGP5AWPROT, SAXIGP5AWQOS, SAXIGP5AWSIZE, SAXIGP5AWUSER, SAXIGP5AWVALID, SAXIGP5BREADY, SAXIGP5RCLK, SAXIGP5RREADY, SAXIGP5WCLK, SAXIGP5WDATA, SAXIGP5WLAST, SAXIGP5WSTRB, SAXIGP5WVALID, SAXIGP6ARADDR, SAXIGP6ARBURST, SAXIGP6ARCACHE +, SAXIGP6ARID, SAXIGP6ARLEN, SAXIGP6ARLOCK, SAXIGP6ARPROT, SAXIGP6ARQOS, SAXIGP6ARSIZE, SAXIGP6ARUSER, SAXIGP6ARVALID, SAXIGP6AWADDR, SAXIGP6AWBURST, SAXIGP6AWCACHE, SAXIGP6AWID, SAXIGP6AWLEN, SAXIGP6AWLOCK, SAXIGP6AWPROT, SAXIGP6AWQOS, SAXIGP6AWSIZE, SAXIGP6AWUSER, SAXIGP6AWVALID, SAXIGP6BREADY, SAXIGP6RCLK +, SAXIGP6RREADY, SAXIGP6WCLK, SAXIGP6WDATA, SAXIGP6WLAST, SAXIGP6WSTRB, SAXIGP6WVALID, STMEVENT); output [7:0] ADMA2PLCACK; output [7:0] ADMA2PLTVLD; output DPAUDIOREFCLK; @@ -33334,7 +34011,17 @@ module PS8 (...); input [59:0] STMEVENT; endmodule -module ILKN (...); +module ILKN(DRP_DO, DRP_RDY, RX_BYPASS_DATAOUT00, RX_BYPASS_DATAOUT01, RX_BYPASS_DATAOUT02, RX_BYPASS_DATAOUT03, RX_BYPASS_DATAOUT04, RX_BYPASS_DATAOUT05, RX_BYPASS_DATAOUT06, RX_BYPASS_DATAOUT07, RX_BYPASS_DATAOUT08, RX_BYPASS_DATAOUT09, RX_BYPASS_DATAOUT10, RX_BYPASS_DATAOUT11, RX_BYPASS_ENAOUT, RX_BYPASS_IS_AVAILOUT, RX_BYPASS_IS_BADLYFRAMEDOUT, RX_BYPASS_IS_OVERFLOWOUT, RX_BYPASS_IS_SYNCEDOUT, RX_BYPASS_IS_SYNCWORDOUT, RX_CHANOUT0 +, RX_CHANOUT1, RX_CHANOUT2, RX_CHANOUT3, RX_DATAOUT0, RX_DATAOUT1, RX_DATAOUT2, RX_DATAOUT3, RX_ENAOUT0, RX_ENAOUT1, RX_ENAOUT2, RX_ENAOUT3, RX_EOPOUT0, RX_EOPOUT1, RX_EOPOUT2, RX_EOPOUT3, RX_ERROUT0, RX_ERROUT1, RX_ERROUT2, RX_ERROUT3, RX_MTYOUT0, RX_MTYOUT1 +, RX_MTYOUT2, RX_MTYOUT3, RX_OVFOUT, RX_SOPOUT0, RX_SOPOUT1, RX_SOPOUT2, RX_SOPOUT3, STAT_RX_ALIGNED, STAT_RX_ALIGNED_ERR, STAT_RX_BAD_TYPE_ERR, STAT_RX_BURSTMAX_ERR, STAT_RX_BURST_ERR, STAT_RX_CRC24_ERR, STAT_RX_CRC32_ERR, STAT_RX_CRC32_VALID, STAT_RX_DESCRAM_ERR, STAT_RX_DIAGWORD_INTFSTAT, STAT_RX_DIAGWORD_LANESTAT, STAT_RX_FC_STAT, STAT_RX_FRAMING_ERR, STAT_RX_MEOP_ERR +, STAT_RX_MF_ERR, STAT_RX_MF_LEN_ERR, STAT_RX_MF_REPEAT_ERR, STAT_RX_MISALIGNED, STAT_RX_MSOP_ERR, STAT_RX_MUBITS, STAT_RX_MUBITS_UPDATED, STAT_RX_OVERFLOW_ERR, STAT_RX_RETRANS_CRC24_ERR, STAT_RX_RETRANS_DISC, STAT_RX_RETRANS_LATENCY, STAT_RX_RETRANS_REQ, STAT_RX_RETRANS_RETRY_ERR, STAT_RX_RETRANS_SEQ, STAT_RX_RETRANS_SEQ_UPDATED, STAT_RX_RETRANS_STATE, STAT_RX_RETRANS_SUBSEQ, STAT_RX_RETRANS_WDOG_ERR, STAT_RX_RETRANS_WRAP_ERR, STAT_RX_SYNCED, STAT_RX_SYNCED_ERR +, STAT_RX_WORD_SYNC, STAT_TX_BURST_ERR, STAT_TX_ERRINJ_BITERR_DONE, STAT_TX_OVERFLOW_ERR, STAT_TX_RETRANS_BURST_ERR, STAT_TX_RETRANS_BUSY, STAT_TX_RETRANS_RAM_PERROUT, STAT_TX_RETRANS_RAM_RADDR, STAT_TX_RETRANS_RAM_RD_B0, STAT_TX_RETRANS_RAM_RD_B1, STAT_TX_RETRANS_RAM_RD_B2, STAT_TX_RETRANS_RAM_RD_B3, STAT_TX_RETRANS_RAM_RSEL, STAT_TX_RETRANS_RAM_WADDR, STAT_TX_RETRANS_RAM_WDATA, STAT_TX_RETRANS_RAM_WE_B0, STAT_TX_RETRANS_RAM_WE_B1, STAT_TX_RETRANS_RAM_WE_B2, STAT_TX_RETRANS_RAM_WE_B3, STAT_TX_UNDERFLOW_ERR, TX_OVFOUT +, TX_RDYOUT, TX_SERDES_DATA00, TX_SERDES_DATA01, TX_SERDES_DATA02, TX_SERDES_DATA03, TX_SERDES_DATA04, TX_SERDES_DATA05, TX_SERDES_DATA06, TX_SERDES_DATA07, TX_SERDES_DATA08, TX_SERDES_DATA09, TX_SERDES_DATA10, TX_SERDES_DATA11, CORE_CLK, CTL_RX_FORCE_RESYNC, CTL_RX_RETRANS_ACK, CTL_RX_RETRANS_ENABLE, CTL_RX_RETRANS_ERRIN, CTL_RX_RETRANS_FORCE_REQ, CTL_RX_RETRANS_RESET, CTL_RX_RETRANS_RESET_MODE +, CTL_TX_DIAGWORD_INTFSTAT, CTL_TX_DIAGWORD_LANESTAT, CTL_TX_ENABLE, CTL_TX_ERRINJ_BITERR_GO, CTL_TX_ERRINJ_BITERR_LANE, CTL_TX_FC_STAT, CTL_TX_MUBITS, CTL_TX_RETRANS_ENABLE, CTL_TX_RETRANS_RAM_PERRIN, CTL_TX_RETRANS_RAM_RDATA, CTL_TX_RETRANS_REQ, CTL_TX_RETRANS_REQ_VALID, CTL_TX_RLIM_DELTA, CTL_TX_RLIM_ENABLE, CTL_TX_RLIM_INTV, CTL_TX_RLIM_MAX, DRP_ADDR, DRP_CLK, DRP_DI, DRP_EN, DRP_WE +, LBUS_CLK, RX_BYPASS_FORCE_REALIGNIN, RX_BYPASS_RDIN, RX_RESET, RX_SERDES_CLK, RX_SERDES_DATA00, RX_SERDES_DATA01, RX_SERDES_DATA02, RX_SERDES_DATA03, RX_SERDES_DATA04, RX_SERDES_DATA05, RX_SERDES_DATA06, RX_SERDES_DATA07, RX_SERDES_DATA08, RX_SERDES_DATA09, RX_SERDES_DATA10, RX_SERDES_DATA11, RX_SERDES_RESET, TX_BCTLIN0, TX_BCTLIN1, TX_BCTLIN2 +, TX_BCTLIN3, TX_BYPASS_CTRLIN, TX_BYPASS_DATAIN00, TX_BYPASS_DATAIN01, TX_BYPASS_DATAIN02, TX_BYPASS_DATAIN03, TX_BYPASS_DATAIN04, TX_BYPASS_DATAIN05, TX_BYPASS_DATAIN06, TX_BYPASS_DATAIN07, TX_BYPASS_DATAIN08, TX_BYPASS_DATAIN09, TX_BYPASS_DATAIN10, TX_BYPASS_DATAIN11, TX_BYPASS_ENAIN, TX_BYPASS_GEARBOX_SEQIN, TX_BYPASS_MFRAMER_STATEIN, TX_CHANIN0, TX_CHANIN1, TX_CHANIN2, TX_CHANIN3 +, TX_DATAIN0, TX_DATAIN1, TX_DATAIN2, TX_DATAIN3, TX_ENAIN0, TX_ENAIN1, TX_ENAIN2, TX_ENAIN3, TX_EOPIN0, TX_EOPIN1, TX_EOPIN2, TX_EOPIN3, TX_ERRIN0, TX_ERRIN1, TX_ERRIN2, TX_ERRIN3, TX_MTYIN0, TX_MTYIN1, TX_MTYIN2, TX_MTYIN3, TX_RESET +, TX_SERDES_REFCLK, TX_SERDES_REFCLK_RESET, TX_SOPIN0, TX_SOPIN1, TX_SOPIN2, TX_SOPIN3); parameter BYPASS = "FALSE"; parameter [1:0] CTL_RX_BURSTMAX = 2'h3; parameter [1:0] CTL_RX_CHAN_EXT = 2'h0; @@ -33579,7 +34266,17 @@ module ILKN (...); input TX_SOPIN3; endmodule -module ILKNE4 (...); +module ILKNE4(DRP_DO, DRP_RDY, RX_BYPASS_DATAOUT00, RX_BYPASS_DATAOUT01, RX_BYPASS_DATAOUT02, RX_BYPASS_DATAOUT03, RX_BYPASS_DATAOUT04, RX_BYPASS_DATAOUT05, RX_BYPASS_DATAOUT06, RX_BYPASS_DATAOUT07, RX_BYPASS_DATAOUT08, RX_BYPASS_DATAOUT09, RX_BYPASS_DATAOUT10, RX_BYPASS_DATAOUT11, RX_BYPASS_ENAOUT, RX_BYPASS_IS_AVAILOUT, RX_BYPASS_IS_BADLYFRAMEDOUT, RX_BYPASS_IS_OVERFLOWOUT, RX_BYPASS_IS_SYNCEDOUT, RX_BYPASS_IS_SYNCWORDOUT, RX_CHANOUT0 +, RX_CHANOUT1, RX_CHANOUT2, RX_CHANOUT3, RX_DATAOUT0, RX_DATAOUT1, RX_DATAOUT2, RX_DATAOUT3, RX_ENAOUT0, RX_ENAOUT1, RX_ENAOUT2, RX_ENAOUT3, RX_EOPOUT0, RX_EOPOUT1, RX_EOPOUT2, RX_EOPOUT3, RX_ERROUT0, RX_ERROUT1, RX_ERROUT2, RX_ERROUT3, RX_MTYOUT0, RX_MTYOUT1 +, RX_MTYOUT2, RX_MTYOUT3, RX_OVFOUT, RX_SOPOUT0, RX_SOPOUT1, RX_SOPOUT2, RX_SOPOUT3, STAT_RX_ALIGNED, STAT_RX_ALIGNED_ERR, STAT_RX_BAD_TYPE_ERR, STAT_RX_BURSTMAX_ERR, STAT_RX_BURST_ERR, STAT_RX_CRC24_ERR, STAT_RX_CRC32_ERR, STAT_RX_CRC32_VALID, STAT_RX_DESCRAM_ERR, STAT_RX_DIAGWORD_INTFSTAT, STAT_RX_DIAGWORD_LANESTAT, STAT_RX_FC_STAT, STAT_RX_FRAMING_ERR, STAT_RX_MEOP_ERR +, STAT_RX_MF_ERR, STAT_RX_MF_LEN_ERR, STAT_RX_MF_REPEAT_ERR, STAT_RX_MISALIGNED, STAT_RX_MSOP_ERR, STAT_RX_MUBITS, STAT_RX_MUBITS_UPDATED, STAT_RX_OVERFLOW_ERR, STAT_RX_RETRANS_CRC24_ERR, STAT_RX_RETRANS_DISC, STAT_RX_RETRANS_LATENCY, STAT_RX_RETRANS_REQ, STAT_RX_RETRANS_RETRY_ERR, STAT_RX_RETRANS_SEQ, STAT_RX_RETRANS_SEQ_UPDATED, STAT_RX_RETRANS_STATE, STAT_RX_RETRANS_SUBSEQ, STAT_RX_RETRANS_WDOG_ERR, STAT_RX_RETRANS_WRAP_ERR, STAT_RX_SYNCED, STAT_RX_SYNCED_ERR +, STAT_RX_WORD_SYNC, STAT_TX_BURST_ERR, STAT_TX_ERRINJ_BITERR_DONE, STAT_TX_OVERFLOW_ERR, STAT_TX_RETRANS_BURST_ERR, STAT_TX_RETRANS_BUSY, STAT_TX_RETRANS_RAM_PERROUT, STAT_TX_RETRANS_RAM_RADDR, STAT_TX_RETRANS_RAM_RD_B0, STAT_TX_RETRANS_RAM_RD_B1, STAT_TX_RETRANS_RAM_RD_B2, STAT_TX_RETRANS_RAM_RD_B3, STAT_TX_RETRANS_RAM_RSEL, STAT_TX_RETRANS_RAM_WADDR, STAT_TX_RETRANS_RAM_WDATA, STAT_TX_RETRANS_RAM_WE_B0, STAT_TX_RETRANS_RAM_WE_B1, STAT_TX_RETRANS_RAM_WE_B2, STAT_TX_RETRANS_RAM_WE_B3, STAT_TX_UNDERFLOW_ERR, TX_OVFOUT +, TX_RDYOUT, TX_SERDES_DATA00, TX_SERDES_DATA01, TX_SERDES_DATA02, TX_SERDES_DATA03, TX_SERDES_DATA04, TX_SERDES_DATA05, TX_SERDES_DATA06, TX_SERDES_DATA07, TX_SERDES_DATA08, TX_SERDES_DATA09, TX_SERDES_DATA10, TX_SERDES_DATA11, CORE_CLK, CTL_RX_FORCE_RESYNC, CTL_RX_RETRANS_ACK, CTL_RX_RETRANS_ENABLE, CTL_RX_RETRANS_ERRIN, CTL_RX_RETRANS_FORCE_REQ, CTL_RX_RETRANS_RESET, CTL_RX_RETRANS_RESET_MODE +, CTL_TX_DIAGWORD_INTFSTAT, CTL_TX_DIAGWORD_LANESTAT, CTL_TX_ENABLE, CTL_TX_ERRINJ_BITERR_GO, CTL_TX_ERRINJ_BITERR_LANE, CTL_TX_FC_STAT, CTL_TX_MUBITS, CTL_TX_RETRANS_ENABLE, CTL_TX_RETRANS_RAM_PERRIN, CTL_TX_RETRANS_RAM_RDATA, CTL_TX_RETRANS_REQ, CTL_TX_RETRANS_REQ_VALID, CTL_TX_RLIM_DELTA, CTL_TX_RLIM_ENABLE, CTL_TX_RLIM_INTV, CTL_TX_RLIM_MAX, DRP_ADDR, DRP_CLK, DRP_DI, DRP_EN, DRP_WE +, LBUS_CLK, RX_BYPASS_FORCE_REALIGNIN, RX_BYPASS_RDIN, RX_RESET, RX_SERDES_CLK, RX_SERDES_DATA00, RX_SERDES_DATA01, RX_SERDES_DATA02, RX_SERDES_DATA03, RX_SERDES_DATA04, RX_SERDES_DATA05, RX_SERDES_DATA06, RX_SERDES_DATA07, RX_SERDES_DATA08, RX_SERDES_DATA09, RX_SERDES_DATA10, RX_SERDES_DATA11, RX_SERDES_RESET, TX_BCTLIN0, TX_BCTLIN1, TX_BCTLIN2 +, TX_BCTLIN3, TX_BYPASS_CTRLIN, TX_BYPASS_DATAIN00, TX_BYPASS_DATAIN01, TX_BYPASS_DATAIN02, TX_BYPASS_DATAIN03, TX_BYPASS_DATAIN04, TX_BYPASS_DATAIN05, TX_BYPASS_DATAIN06, TX_BYPASS_DATAIN07, TX_BYPASS_DATAIN08, TX_BYPASS_DATAIN09, TX_BYPASS_DATAIN10, TX_BYPASS_DATAIN11, TX_BYPASS_ENAIN, TX_BYPASS_GEARBOX_SEQIN, TX_BYPASS_MFRAMER_STATEIN, TX_CHANIN0, TX_CHANIN1, TX_CHANIN2, TX_CHANIN3 +, TX_DATAIN0, TX_DATAIN1, TX_DATAIN2, TX_DATAIN3, TX_ENAIN0, TX_ENAIN1, TX_ENAIN2, TX_ENAIN3, TX_EOPIN0, TX_EOPIN1, TX_EOPIN2, TX_EOPIN3, TX_ERRIN0, TX_ERRIN1, TX_ERRIN2, TX_ERRIN3, TX_MTYIN0, TX_MTYIN1, TX_MTYIN2, TX_MTYIN3, TX_RESET +, TX_SERDES_REFCLK, TX_SERDES_REFCLK_RESET, TX_SOPIN0, TX_SOPIN1, TX_SOPIN2, TX_SOPIN3); parameter BYPASS = "FALSE"; parameter [1:0] CTL_RX_BURSTMAX = 2'h3; parameter [1:0] CTL_RX_CHAN_EXT = 2'h0; @@ -33825,7 +34522,17 @@ module ILKNE4 (...); endmodule (* keep *) -module VCU (...); +module VCU(VCUPLARREADYAXILITEAPB, VCUPLAWREADYAXILITEAPB, VCUPLBRESPAXILITEAPB, VCUPLBVALIDAXILITEAPB, VCUPLCORESTATUSCLKPLL, VCUPLDECARADDR0, VCUPLDECARADDR1, VCUPLDECARBURST0, VCUPLDECARBURST1, VCUPLDECARCACHE0, VCUPLDECARCACHE1, VCUPLDECARID0, VCUPLDECARID1, VCUPLDECARLEN0, VCUPLDECARLEN1, VCUPLDECARPROT0, VCUPLDECARPROT1, VCUPLDECARQOS0, VCUPLDECARQOS1, VCUPLDECARSIZE0, VCUPLDECARSIZE1 +, VCUPLDECARVALID0, VCUPLDECARVALID1, VCUPLDECAWADDR0, VCUPLDECAWADDR1, VCUPLDECAWBURST0, VCUPLDECAWBURST1, VCUPLDECAWCACHE0, VCUPLDECAWCACHE1, VCUPLDECAWID0, VCUPLDECAWID1, VCUPLDECAWLEN0, VCUPLDECAWLEN1, VCUPLDECAWPROT0, VCUPLDECAWPROT1, VCUPLDECAWQOS0, VCUPLDECAWQOS1, VCUPLDECAWSIZE0, VCUPLDECAWSIZE1, VCUPLDECAWVALID0, VCUPLDECAWVALID1, VCUPLDECBREADY0 +, VCUPLDECBREADY1, VCUPLDECRREADY0, VCUPLDECRREADY1, VCUPLDECWDATA0, VCUPLDECWDATA1, VCUPLDECWLAST0, VCUPLDECWLAST1, VCUPLDECWVALID0, VCUPLDECWVALID1, VCUPLENCALL2CADDR, VCUPLENCALL2CRVALID, VCUPLENCALL2CWDATA, VCUPLENCALL2CWVALID, VCUPLENCARADDR0, VCUPLENCARADDR1, VCUPLENCARBURST0, VCUPLENCARBURST1, VCUPLENCARCACHE0, VCUPLENCARCACHE1, VCUPLENCARID0, VCUPLENCARID1 +, VCUPLENCARLEN0, VCUPLENCARLEN1, VCUPLENCARPROT0, VCUPLENCARPROT1, VCUPLENCARQOS0, VCUPLENCARQOS1, VCUPLENCARSIZE0, VCUPLENCARSIZE1, VCUPLENCARVALID0, VCUPLENCARVALID1, VCUPLENCAWADDR0, VCUPLENCAWADDR1, VCUPLENCAWBURST0, VCUPLENCAWBURST1, VCUPLENCAWCACHE0, VCUPLENCAWCACHE1, VCUPLENCAWID0, VCUPLENCAWID1, VCUPLENCAWLEN0, VCUPLENCAWLEN1, VCUPLENCAWPROT0 +, VCUPLENCAWPROT1, VCUPLENCAWQOS0, VCUPLENCAWQOS1, VCUPLENCAWSIZE0, VCUPLENCAWSIZE1, VCUPLENCAWVALID0, VCUPLENCAWVALID1, VCUPLENCBREADY0, VCUPLENCBREADY1, VCUPLENCRREADY0, VCUPLENCRREADY1, VCUPLENCWDATA0, VCUPLENCWDATA1, VCUPLENCWLAST0, VCUPLENCWLAST1, VCUPLENCWVALID0, VCUPLENCWVALID1, VCUPLMCUMAXIICDCARADDR, VCUPLMCUMAXIICDCARBURST, VCUPLMCUMAXIICDCARCACHE, VCUPLMCUMAXIICDCARID +, VCUPLMCUMAXIICDCARLEN, VCUPLMCUMAXIICDCARLOCK, VCUPLMCUMAXIICDCARPROT, VCUPLMCUMAXIICDCARQOS, VCUPLMCUMAXIICDCARSIZE, VCUPLMCUMAXIICDCARVALID, VCUPLMCUMAXIICDCAWADDR, VCUPLMCUMAXIICDCAWBURST, VCUPLMCUMAXIICDCAWCACHE, VCUPLMCUMAXIICDCAWID, VCUPLMCUMAXIICDCAWLEN, VCUPLMCUMAXIICDCAWLOCK, VCUPLMCUMAXIICDCAWPROT, VCUPLMCUMAXIICDCAWQOS, VCUPLMCUMAXIICDCAWSIZE, VCUPLMCUMAXIICDCAWVALID, VCUPLMCUMAXIICDCBREADY, VCUPLMCUMAXIICDCRREADY, VCUPLMCUMAXIICDCWDATA, VCUPLMCUMAXIICDCWLAST, VCUPLMCUMAXIICDCWSTRB +, VCUPLMCUMAXIICDCWVALID, VCUPLMCUSTATUSCLKPLL, VCUPLPINTREQ, VCUPLPLLSTATUSPLLLOCK, VCUPLPWRSUPPLYSTATUSVCCAUX, VCUPLPWRSUPPLYSTATUSVCUINT, VCUPLRDATAAXILITEAPB, VCUPLRRESPAXILITEAPB, VCUPLRVALIDAXILITEAPB, VCUPLWREADYAXILITEAPB, INITPLVCUGASKETCLAMPCONTROLLVLSHVCCINTD, PLVCUARADDRAXILITEAPB, PLVCUARPROTAXILITEAPB, PLVCUARVALIDAXILITEAPB, PLVCUAWADDRAXILITEAPB, PLVCUAWPROTAXILITEAPB, PLVCUAWVALIDAXILITEAPB, PLVCUAXIDECCLK, PLVCUAXIENCCLK, PLVCUAXILITECLK, PLVCUAXIMCUCLK +, PLVCUBREADYAXILITEAPB, PLVCUCORECLK, PLVCUDECARREADY0, PLVCUDECARREADY1, PLVCUDECAWREADY0, PLVCUDECAWREADY1, PLVCUDECBID0, PLVCUDECBID1, PLVCUDECBRESP0, PLVCUDECBRESP1, PLVCUDECBVALID0, PLVCUDECBVALID1, PLVCUDECRDATA0, PLVCUDECRDATA1, PLVCUDECRID0, PLVCUDECRID1, PLVCUDECRLAST0, PLVCUDECRLAST1, PLVCUDECRRESP0, PLVCUDECRRESP1, PLVCUDECRVALID0 +, PLVCUDECRVALID1, PLVCUDECWREADY0, PLVCUDECWREADY1, PLVCUENCALL2CRDATA, PLVCUENCALL2CRREADY, PLVCUENCARREADY0, PLVCUENCARREADY1, PLVCUENCAWREADY0, PLVCUENCAWREADY1, PLVCUENCBID0, PLVCUENCBID1, PLVCUENCBRESP0, PLVCUENCBRESP1, PLVCUENCBVALID0, PLVCUENCBVALID1, PLVCUENCL2CCLK, PLVCUENCRDATA0, PLVCUENCRDATA1, PLVCUENCRID0, PLVCUENCRID1, PLVCUENCRLAST0 +, PLVCUENCRLAST1, PLVCUENCRRESP0, PLVCUENCRRESP1, PLVCUENCRVALID0, PLVCUENCRVALID1, PLVCUENCWREADY0, PLVCUENCWREADY1, PLVCUMCUCLK, PLVCUMCUMAXIICDCARREADY, PLVCUMCUMAXIICDCAWREADY, PLVCUMCUMAXIICDCBID, PLVCUMCUMAXIICDCBRESP, PLVCUMCUMAXIICDCBVALID, PLVCUMCUMAXIICDCRDATA, PLVCUMCUMAXIICDCRID, PLVCUMCUMAXIICDCRLAST, PLVCUMCUMAXIICDCRRESP, PLVCUMCUMAXIICDCRVALID, PLVCUMCUMAXIICDCWREADY, PLVCUPLLREFCLKPL, PLVCURAWRSTN +, PLVCURREADYAXILITEAPB, PLVCUWDATAAXILITEAPB, PLVCUWSTRBAXILITEAPB, PLVCUWVALIDAXILITEAPB); parameter integer CORECLKREQ = 667; parameter integer DECHORRESOLUTION = 3840; parameter DECODERCHROMAFORMAT = "4_2_2"; @@ -34057,7 +34764,9 @@ module VCU (...); input PLVCUWVALIDAXILITEAPB; endmodule -module FE (...); +module FE(DEBUG_DOUT, DEBUG_PHASE, INTERRUPT, M_AXIS_DOUT_TDATA, M_AXIS_DOUT_TLAST, M_AXIS_DOUT_TVALID, M_AXIS_STATUS_TDATA, M_AXIS_STATUS_TVALID, SPARE_OUT, S_AXIS_CTRL_TREADY, S_AXIS_DIN_TREADY, S_AXIS_DIN_WORDS_TREADY, S_AXIS_DOUT_WORDS_TREADY, S_AXI_ARREADY, S_AXI_AWREADY, S_AXI_BVALID, S_AXI_RDATA, S_AXI_RVALID, S_AXI_WREADY, CORE_CLK, DEBUG_CLK_EN +, DEBUG_EN, DEBUG_SEL_IN, M_AXIS_DOUT_ACLK, M_AXIS_DOUT_TREADY, M_AXIS_STATUS_ACLK, M_AXIS_STATUS_TREADY, RESET_N, SPARE_IN, S_AXIS_CTRL_ACLK, S_AXIS_CTRL_TDATA, S_AXIS_CTRL_TVALID, S_AXIS_DIN_ACLK, S_AXIS_DIN_TDATA, S_AXIS_DIN_TLAST, S_AXIS_DIN_TVALID, S_AXIS_DIN_WORDS_ACLK, S_AXIS_DIN_WORDS_TDATA, S_AXIS_DIN_WORDS_TLAST, S_AXIS_DIN_WORDS_TVALID, S_AXIS_DOUT_WORDS_ACLK, S_AXIS_DOUT_WORDS_TDATA +, S_AXIS_DOUT_WORDS_TLAST, S_AXIS_DOUT_WORDS_TVALID, S_AXI_ACLK, S_AXI_ARADDR, S_AXI_ARVALID, S_AXI_AWADDR, S_AXI_AWVALID, S_AXI_BREADY, S_AXI_RREADY, S_AXI_WDATA, S_AXI_WVALID); parameter MODE = "TURBO_DECODE"; parameter real PHYSICAL_UTILIZATION = 100.00; parameter SIM_DEVICE = "ULTRASCALE_PLUS"; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 46b30573c..b08fbe499 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -355,8 +355,10 @@ struct SynthXilinxPass : public ScriptPass if (check_label("prepare")) { run("proc"); - if (flatten || help_mode) + if (flatten || help_mode) { + run("check"); run("flatten", "(with '-flatten')"); + } if (active_design) active_design->scratchpad_unset("tribuf.added_something"); run("tribuf -logic"); @@ -386,6 +388,8 @@ struct SynthXilinxPass : public ScriptPass run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')"); run("clean", " (skip if '-nosrl' and '-widemux=0')"); } + + run("sort"); } if (check_label("map_dsp", "(skip if '-nodsp')")) { @@ -635,8 +639,10 @@ struct SynthXilinxPass : public ScriptPass if (check_label("map_luts")) { run("opt_expr -mux_undef -noclkinv"); - if (flatten_before_abc) + if (flatten_before_abc) { + run("check"); run("flatten"); + } if (help_mode) run("abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1]", "(option for '-nowidelut', '-dff', '-retime')"); else if (abc9) { diff --git a/techlibs/xilinx/xilinx_dsp.cc b/techlibs/xilinx/xilinx_dsp.cc index 22e6bce5b..194b9ac10 100644 --- a/techlibs/xilinx/xilinx_dsp.cc +++ b/techlibs/xilinx/xilinx_dsp.cc @@ -263,6 +263,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp)); log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); + log_debug("preSub: %s\n", log_id(st.preSub, "--")); log_debug("ffAD: %s\n", log_id(st.ffAD, "--")); log_debug("ffA2: %s\n", log_id(st.ffA2, "--")); log_debug("ffA1: %s\n", log_id(st.ffA1, "--")); @@ -278,17 +279,22 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) Cell *cell = st.dsp; - if (st.preAdd) { - log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type)); - bool A_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool(); - bool D_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool(); - if (st.sigA == st.preAdd->getPort(ID::B)) + if (st.preAdd || st.preSub) { + Cell* preAdder = st.preAdd ? st.preAdd : st.preSub; + + log(" preadder %s (%s)\n", log_id(preAdder), log_id(preAdder->type)); + bool A_SIGNED = preAdder->getParam(ID::A_SIGNED).as_bool(); + bool D_SIGNED = preAdder->getParam(ID::B_SIGNED).as_bool(); + if (st.sigA == preAdder->getPort(ID::B)) std::swap(A_SIGNED, D_SIGNED); st.sigA.extend_u0(30, A_SIGNED); st.sigD.extend_u0(25, D_SIGNED); cell->setPort(ID::A, st.sigA); cell->setPort(ID::D, st.sigD); - cell->setPort(ID(INMODE), Const::from_string("00100")); + if (preAdder->type == ID($add)) + cell->setPort(ID(INMODE), Const::from_string("00100")); + else + cell->setPort(ID(INMODE), Const::from_string("01100")); if (st.ffAD) { if (st.ffAD->type.in(ID($dffe), ID($sdffe))) { @@ -303,7 +309,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) cell->setParam(ID(USE_DPORT), Const("TRUE")); - pm.autoremove(st.preAdd); + pm.autoremove(preAdder); } if (st.postAdd) { log(" postadder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type)); diff --git a/techlibs/xilinx/xilinx_dsp.pmg b/techlibs/xilinx/xilinx_dsp.pmg index ef0157621..6ec891290 100644 --- a/techlibs/xilinx/xilinx_dsp.pmg +++ b/techlibs/xilinx/xilinx_dsp.pmg @@ -6,6 +6,8 @@ // If ADREG matched, treat 'A' input as input of ADREG // ( 3) Match the driver of the 'A' and 'D' inputs for a possible $add cell // (pre-adder) +// (3.1) Match the driver of the 'A' and 'D' inputs for a possible $sub cell +// (pre-adder) // ( 4) If pre-adder was present, find match 'A' input for A2REG // If pre-adder was not present, move ADREG to A2REG // If A2REG, then match 'A' input for A1REG @@ -152,13 +154,41 @@ code sigA sigD } endcode +// (3.1) Match the driver of the 'A' and 'D' inputs for a possible $sub cell +// (pre-adder) +match preSub + if sigD.empty() || sigD.is_fully_zero() + // Ensure that preAdder not already used + if param(dsp, \USE_DPORT).decode_string() == "FALSE" + if port(dsp, \INMODE, Const(0, 5)).is_fully_zero() + + select preSub->type.in($sub) + // Output has to be 25 bits or less + select GetSize(port(preSub, \Y)) <= 25 + select nusers(port(preSub, \Y)) == 2 + // D port has to be 25 bits or less + select GetSize(port(preSub, \A)) <= 25 + // A port has to be 30 bits or less + select GetSize(port(preSub, \B)) <= 30 + index port(preSub, \Y) === sigA + + optional +endmatch + +code sigA sigD + if (preSub) { + sigD = port(preSub, \A); + sigA = port(preSub, \B); + } +endcode + // (4) If pre-adder was present, find match 'A' input for A2REG // If pre-adder was not present, move ADREG to A2REG // Then match 'A' input for A1REG code argQ ffAD sigA clock ffA2 ffA1 // Only search for ffA2 if there was a pre-adder // (otherwise ffA2 would have been matched as ffAD) - if (preAdd) { + if (preAdd || preSub) { if (param(dsp, \AREG).as_int() == 0) { argQ = sigA; subpattern(in_dffe); diff --git a/tests/.gitignore b/tests/.gitignore index d8e01e026..8fa73e3d6 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -2,3 +2,5 @@ *.out *.err run-test.mk +**/Makefile +*.result diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 000000000..794e99c46 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,127 @@ +ifneq ($(wildcard ../Makefile.conf),) +include ../Makefile.conf +endif + +OVERRIDE_MAIN=1 +include ./common.mk + +# Directories with tests not run: +# errors +# lut +# pyosys +# smv +# sva +# tools +# unit +# vloghtb + +# Tests that generate Makefile with gen_tests_makefile.py +MK_TEST_DIRS = +MK_TEST_DIRS += ./arch/analogdevices +MK_TEST_DIRS += ./arch/anlogic +MK_TEST_DIRS += ./arch/ecp5 +MK_TEST_DIRS += ./arch/efinix +MK_TEST_DIRS += ./arch/fabulous +MK_TEST_DIRS += ./arch/gatemate +MK_TEST_DIRS += ./arch/gowin +MK_TEST_DIRS += ./arch/ice40 +MK_TEST_DIRS += ./arch/intel_alm +MK_TEST_DIRS += ./arch/machxo2 +MK_TEST_DIRS += ./arch/microchip +MK_TEST_DIRS += ./arch/nanoxplore +MK_TEST_DIRS += ./arch/nexus +MK_TEST_DIRS += ./arch/quicklogic/pp3 +MK_TEST_DIRS += ./arch/quicklogic/qlf_k6n10f +MK_TEST_DIRS += ./arch/xilinx +MK_TEST_DIRS += ./bind +MK_TEST_DIRS += ./bugpoint +MK_TEST_DIRS += ./opt +MK_TEST_DIRS += ./sat +MK_TEST_DIRS += ./sdc +MK_TEST_DIRS += ./sim +MK_TEST_DIRS += ./svtypes +MK_TEST_DIRS += ./techmap +MK_TEST_DIRS += ./various +MK_TEST_DIRS += ./rtlil +ifeq ($(ENABLE_VERIFIC),1) +ifneq ($(YOSYS_NOVERIFIC),1) +MK_TEST_DIRS += ./verific +endif +endif +MK_TEST_DIRS += ./verilog +MK_TEST_DIRS += ./arith_tree +MK_TEST_DIRS += ./simple +MK_TEST_DIRS += ./simple_abc9 +MK_TEST_DIRS += ./hana +MK_TEST_DIRS += ./asicworld +MK_TEST_DIRS += ./realmath +MK_TEST_DIRS += ./share +MK_TEST_DIRS += ./opt_share +MK_TEST_DIRS += ./fsm +MK_TEST_DIRS += ./memlib +MK_TEST_DIRS += ./bram +MK_TEST_DIRS += ./svinterfaces +MK_TEST_DIRS += ./xprop +MK_TEST_DIRS += ./select +MK_TEST_DIRS += ./peepopt +MK_TEST_DIRS += ./proc +MK_TEST_DIRS += ./blif +MK_TEST_DIRS += ./arch +MK_TEST_DIRS += ./rpc +MK_TEST_DIRS += ./memfile +MK_TEST_DIRS += ./fmt +MK_TEST_DIRS += ./cxxrtl +MK_TEST_DIRS += ./liberty +#ifeq ($(ENABLE_FUNCTIONAL_TESTS),1) +#MK_TEST_DIRS += ./functional +#endif +MK_TEST_DIRS += ./memories +MK_TEST_DIRS += ./aiger +MK_TEST_DIRS += ./alumacc + +all: vanilla-test + +# makefile-./ is a dummy string, not a directory +.PHONY: makefile-tests +.SILENT: $(MK_TEST_DIRS:%=%/Makefile) +makefile-tests: $(MK_TEST_DIRS:%=makefile-./%) +prep: $(MK_TEST_DIRS:%=%/Makefile) + @echo "All Makefiles generated." + +.PHONY: force-create +# this target actually emits Makefile files +%/Makefile: force-create + +@cd $* && python3 generate_mk.py + +makefile-./%: %/Makefile + @$(MAKE) -C $* + @echo "...passed tests in $*" + +.PHONY: functional +functional: +ifeq ($(ENABLE_FUNCTIONAL_TESTS),1) + @cd functional && ./run-test.sh +endif + +vanilla-test: prep makefile-tests functional + @echo "" + @echo " Passed \"make vanilla-test\"." +ifeq ($(ENABLE_VERIFIC),1) +ifeq ($(YOSYS_NOVERIFIC),1) + @echo " Ran tests without verific support due to YOSYS_NOVERIFIC=1." +endif +endif + @echo "" + @$(MAKE) --no-print-directory summary + +clean: + @rm -rf ./asicworld/*.out ./asicworld/*.log + @rm -rf ./hana/*.out ./hana/*.log + @rm -rf ./simple/*.out ./simple/*.log + @rm -rf ./memories/*.out ./memories/*.log ./memories/*.dmp + @rm -rf ./sat/*.log ./techmap/*.log ./various/*.log + @rm -rf ./bram/temp ./fsm/temp ./realmath/temp ./share/temp ./smv/temp ./various/temp + @rm -f ./svinterfaces/*.log_stdout ./svinterfaces/*.log_stderr ./svinterfaces/dut_result.txt ./svinterfaces/reference_result.txt ./svinterfaces/a.out ./svinterfaces/*_syn.v ./svinterfaces/*.diff + @rm -f ./tools/cmp_tbdata + @rm -f $(addsuffix /Makefile,$(MK_TEST_DIRS)) + @find . -name '*.result' -type f -exec rm -f {} + diff --git a/tests/aiger/generate_mk.py b/tests/aiger/generate_mk.py new file mode 100644 index 000000000..a90a63527 --- /dev/null +++ b/tests/aiger/generate_mk.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +import glob +import os + +def base(fn): + return os.path.splitext(fn)[0] + +def cmd(lines): + return " \\\n".join(lines) + +# NB: *.aag and *.aig must contain a symbol table naming the primary +# inputs and outputs, otherwise ABC and Yosys will name them +# arbitrarily (and inconsistently with each other). + +# Since ABC cannot read *.aag, read the *.aig instead +# (which would have been created by the reference aig2aig utility, +# available from http://fmv.jku.at/aiger/) +def create_tests(): + aags = sorted(glob.glob("*.aag")) + yss = sorted(glob.glob("*.ys")) + for aag in aags: + b = base(aag) + + gen_tests_makefile.generate_target(aag, cmd([ + f"$(ABC) -q \"read -c {b}.aig; write {b}_ref.v\";", + "$(YOSYS) -qp \"", + f"read_verilog {b}_ref.v;", + "prep;", + "design -stash gold;", + f"read_aiger -clk_name clock {aag};", + "prep;", + "design -stash gate;", + "design -import gold -as gold;", + "design -import gate -as gate;", + "miter -equiv -flatten -make_assert -make_outputs gold gate miter;", + "sat -verify -prove-asserts -show-ports -seq 16 miter;", + f"\" -l {aag}.log" + ])) + + # ---- Yosys script tests ---- + for ys in yss: + gen_tests_makefile.generate_ys_test(ys) + + gen_tests_makefile.generate_target("aigmap", cmd([ + "rm -rf gate; mkdir gate;", + "$(YOSYS) --no-version -p \"test_cell -aigmap -w gate/ -n 1 -s 1 all\";", + "set -o pipefail; diff --brief gold gate | tee aigmap.err;", + "rm -f aigmap.err" + ])) + +extra = [ f"ABC ?= {gen_tests_makefile.yosys_basedir}/yosys-abc", "SHELL := /usr/bin/env bash" ] + +gen_tests_makefile.generate_custom(create_tests, extra) diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh deleted file mode 100755 index 94d83ede4..000000000 --- a/tests/aiger/run-test.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -set -e - -OPTIND=1 -abcprog="../../yosys-abc" # default to built-in version of abc -while getopts "A:" opt -do - case "$opt" in - A) abcprog="$OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -# NB: *.aag and *.aig must contain a symbol table naming the primary -# inputs and outputs, otherwise ABC and Yosys will name them -# arbitrarily (and inconsistently with each other). - -for aag in *.aag; do - # Since ABC cannot read *.aag, read the *.aig instead - # (which would have been created by the reference aig2aig utility, - # available from http://fmv.jku.at/aiger/) - echo "Checking $aag." - $abcprog -q "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v" - ../../yosys -qp " -read_verilog ${aag%.*}_ref.v -prep -design -stash gold -read_aiger -clk_name clock $aag -prep -design -stash gate -design -import gold -as gold -design -import gate -as gate -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -show-ports -seq 16 miter -" -l ${aag}.log -done - -for aig in *.aig; do - echo "Checking $aig." - $abcprog -q "read -c $aig; write ${aig%.*}_ref.v" - ../../yosys -qp " -read_verilog ${aig%.*}_ref.v -prep -design -stash gold -read_aiger -clk_name clock $aig -prep -design -stash gate -design -import gold -as gold -design -import gate -as gate -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -show-ports -seq 16 miter -" -l ${aig}.log -done - -for y in *.ys; do - echo "Running $y." - ../../yosys -ql ${y%.*}.log $y -done - -# compare aigmap with reference -# make gold with: rm gold/*; yosys --no-version -p "test_cell -aigmap -w gold/ -n 1 -s 1 all" -rm -rf gate; mkdir gate -../../yosys --no-version -p "test_cell -aigmap -w gate/ -n 1 -s 1 all" -( - set -o pipefail - diff --brief gold gate | tee aigmap.err -) -rm aigmap.err diff --git a/tests/alumacc/generate_mk.py b/tests/alumacc/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/alumacc/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/alumacc/run-test.sh b/tests/alumacc/run-test.sh deleted file mode 100644 index 2e3f5235c..000000000 --- a/tests/alumacc/run-test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done diff --git a/tests/arch/analogdevices/.gitignore b/tests/arch/analogdevices/.gitignore new file mode 100644 index 000000000..fb232f235 --- /dev/null +++ b/tests/arch/analogdevices/.gitignore @@ -0,0 +1 @@ +t_*.ys diff --git a/tests/arch/analogdevices/add_sub.ys b/tests/arch/analogdevices/add_sub.ys new file mode 100644 index 000000000..2a297851c --- /dev/null +++ b/tests/arch/analogdevices/add_sub.ys @@ -0,0 +1,13 @@ +read_verilog ../common/add_sub.v +hierarchy -top top +proc +design -save orig + +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +stat +select -assert-count 8 t:LUT2 +select -assert-count 2 t:CRY4 +select -assert-count 2 t:CRY4INIT +select -assert-none t:LUT2 t:CRY4 t:CRY4INIT %% t:* %D diff --git a/tests/arch/analogdevices/adffs.ys b/tests/arch/analogdevices/adffs.ys new file mode 100644 index 000000000..9affcd52f --- /dev/null +++ b/tests/arch/analogdevices/adffs.ys @@ -0,0 +1,47 @@ +read_verilog ../common/adffs.v +design -save read + +hierarchy -top adff +proc +equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adff # Constrain all select calls below inside the top module +select -assert-count 1 t:FFCE + +select -assert-none t:FFCE %% t:* %D + + +design -load read +hierarchy -top adffn +proc +equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adffn # Constrain all select calls below inside the top module +select -assert-count 1 t:FFCE +select -assert-count 1 t:LUT1 + +select -assert-none t:FFCE t:LUT1 %% t:* %D + + +design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +select -assert-count 1 t:FFRE +select -assert-count 1 t:LUT2 +stat +select -assert-none t:FFRE t:LUT2 %% t:* %D + + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +select -assert-count 1 t:FFRE_N +select -assert-count 1 t:LUT1 + +select -assert-none t:FFRE_N t:LUT1 %% t:* %D diff --git a/tests/arch/analogdevices/asym_ram_sdp.ys b/tests/arch/analogdevices/asym_ram_sdp.ys new file mode 100644 index 000000000..22ed5e010 --- /dev/null +++ b/tests/arch/analogdevices/asym_ram_sdp.ys @@ -0,0 +1,50 @@ +# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RBRAM2 + +# w4b | r16b +design -reset +read_verilog asym_ram_sdp_read_wider.v +synth_analogdevices -top asym_ram_sdp_read_wider -noiopad +select -assert-count 1 t:RBRAM2 + +# w8b | r16b +design -reset +read_verilog asym_ram_sdp_read_wider.v +chparam -set WIDTHA 8 -set SIZEA 512 -set ADDRWIDTHA 9 asym_ram_sdp_read_wider +synth_analogdevices -top asym_ram_sdp_read_wider -noiopad +select -assert-count 1 t:RBRAM2 + +# w4b | r32b +design -reset +read_verilog asym_ram_sdp_read_wider.v +chparam -set WIDTHB 32 -set SIZEB 128 -set ADDRWIDTHB 7 asym_ram_sdp_read_wider +synth_analogdevices -top asym_ram_sdp_read_wider -noiopad +select -assert-count 2 t:RBRAM2 + +# w16b | r4b +design -reset +read_verilog asym_ram_sdp_write_wider.v +synth_analogdevices -top asym_ram_sdp_write_wider -noiopad +select -assert-count 1 t:RBRAM2 + +# w16b | r8b +design -reset +read_verilog asym_ram_sdp_write_wider.v +chparam -set WIDTHB 8 -set SIZEB 512 -set ADDRWIDTHB 9 asym_ram_sdp_read_wider +synth_analogdevices -top asym_ram_sdp_write_wider -noiopad +select -assert-count 1 t:RBRAM2 + +# w32b | r4b +design -reset +read_verilog asym_ram_sdp_write_wider.v +chparam -set WIDTHA 32 -set SIZEA 128 -set ADDRWIDTHA 7 asym_ram_sdp_read_wider +synth_analogdevices -top asym_ram_sdp_write_wider -noiopad +select -assert-count 1 t:RBRAM2 + +# w4b | r24b +design -reset +read_verilog asym_ram_sdp_read_wider.v +chparam -set SIZEA 768 +chparam -set WIDTHB 24 -set SIZEB 128 -set ADDRWIDTHB 7 asym_ram_sdp_read_wider +synth_analogdevices -top asym_ram_sdp_read_wider -noiopad +select -assert-count 2 t:RBRAM2 + diff --git a/tests/arch/analogdevices/asym_ram_sdp_read_wider.v b/tests/arch/analogdevices/asym_ram_sdp_read_wider.v new file mode 100644 index 000000000..853ba6254 --- /dev/null +++ b/tests/arch/analogdevices/asym_ram_sdp_read_wider.v @@ -0,0 +1,73 @@ +// Asymmetric port RAM +// Read Wider than Write. Read Statement in loop +//asym_ram_sdp_read_wider.v +module asym_ram_sdp_read_wider (clkA, clkB, enaA, weA, enaB, addrA, addrB, diA, doB); + parameter WIDTHA = 4; + parameter SIZEA = 1024; + parameter ADDRWIDTHA = 10; + + parameter WIDTHB = 16; + parameter SIZEB = 256; + parameter ADDRWIDTHB = 8; + + input clkA; + input clkB; + input weA; + input enaA, enaB; + input [ADDRWIDTHA-1:0] addrA; + input [ADDRWIDTHB-1:0] addrB; + input [WIDTHA-1:0] diA; + output [WIDTHB-1:0] doB; + + `define max(a,b) {(a) > (b) ? (a) : (b)} + `define min(a,b) {(a) < (b) ? (a) : (b)} + + function integer log2; + input integer value; + reg [31:0] shifted; + integer res; + begin + if (value < 2) + log2 = value; + else + begin + shifted = value-1; + for (res=0; shifted>0; res=res+1) + shifted = shifted>>1; + log2 = res; + end + end + endfunction + + localparam maxSIZE = `max(SIZEA, SIZEB); + localparam maxWIDTH = `max(WIDTHA, WIDTHB); + localparam minWIDTH = `min(WIDTHA, WIDTHB); + + localparam RATIO = maxWIDTH / minWIDTH; + localparam log2RATIO = log2(RATIO); + + (* ram_style="block" *) + reg [minWIDTH-1:0] RAM [0:maxSIZE-1]; + reg [WIDTHB-1:0] readB; + + always @(posedge clkA) + begin + if (enaA) begin + if (weA) + RAM[addrA] <= diA; + end + end + + always @(posedge clkB) + begin : ramread + integer i; + reg [log2RATIO-1:0] lsbaddr; + if (enaB) begin + for (i = 0; i < RATIO; i = i+1) begin + lsbaddr = i; + readB[(i+1)*minWIDTH-1 -: minWIDTH] <= RAM[{addrB, lsbaddr}]; + end + end + end + assign doB = readB; +endmodule diff --git a/tests/arch/analogdevices/asym_ram_sdp_write_wider.v b/tests/arch/analogdevices/asym_ram_sdp_write_wider.v new file mode 100644 index 000000000..abffa9fc4 --- /dev/null +++ b/tests/arch/analogdevices/asym_ram_sdp_write_wider.v @@ -0,0 +1,72 @@ +// Asymmetric port RAM +// Write wider than Read. Write Statement in a loop. +// asym_ram_sdp_write_wider.v +module asym_ram_sdp_write_wider (clkA, clkB, weA, enaA, enaB, addrA, addrB, diA, doB); + parameter WIDTHB = 4; + parameter SIZEB = 1024; + parameter ADDRWIDTHB = 10; + + parameter WIDTHA = 16; + parameter SIZEA = 256; + parameter ADDRWIDTHA = 8; + + input clkA; + input clkB; + input weA; + input enaA, enaB; + input [ADDRWIDTHA-1:0] addrA; + input [ADDRWIDTHB-1:0] addrB; + input [WIDTHA-1:0] diA; + output [WIDTHB-1:0] doB; + + `define max(a,b) {(a) > (b) ? (a) : (b)} + `define min(a,b) {(a) < (b) ? (a) : (b)} + + function integer log2; + input integer value; + reg [31:0] shifted; + integer res; + begin + if (value < 2) + log2 = value; + else + begin + shifted = value-1; + for (res=0; shifted>0; res=res+1) + shifted = shifted>>1; + log2 = res; + end + end + endfunction + + localparam maxSIZE = `max(SIZEA, SIZEB); + localparam maxWIDTH = `max(WIDTHA, WIDTHB); + localparam minWIDTH = `min(WIDTHA, WIDTHB); + + localparam RATIO = maxWIDTH / minWIDTH; + localparam log2RATIO = log2(RATIO); + + (* ram_style="block" *) + reg [minWIDTH-1:0] RAM [0:maxSIZE-1]; + reg [WIDTHB-1:0] readB; + + always @(posedge clkB) begin + if (enaB) begin + readB <= RAM[addrB]; + end + end + assign doB = readB; + + always @(posedge clkA) + begin : ramwrite + integer i; + reg [log2RATIO-1:0] lsbaddr; + for (i=0; i< RATIO; i= i+ 1) begin : write1 + lsbaddr = i; + if (enaA) begin + if (weA) + RAM[{addrA, lsbaddr}] <= diA[(i+1)*minWIDTH-1 -: minWIDTH]; + end + end + end +endmodule diff --git a/tests/arch/analogdevices/attributes_test.ys b/tests/arch/analogdevices/attributes_test.ys new file mode 100644 index 000000000..03d6decff --- /dev/null +++ b/tests/arch/analogdevices/attributes_test.ys @@ -0,0 +1,39 @@ +# Check that blockram memory without parameters is not modified +read_verilog ../common/memory_attributes/attributes_test.v +hierarchy -top block_ram +synth_analogdevices -top block_ram -noiopad +cd block_ram # Constrain all select calls below inside the top module +# select -assert-count 1 t:RBRAM2 # This currently infers LUTRAM because BRAM is expensive. + +# Check that distributed memory without parameters is not modified +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +hierarchy -top distributed_ram +synth_analogdevices -top distributed_ram -noiopad +cd distributed_ram # Constrain all select calls below inside the top module +select -assert-count 8 t:RAMS64X1 +select -assert-count 8 t:FFRE + +# Set ram_style distributed to blockram memory; will be implemented as distributed +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +setattr -set ram_style "distributed" block_ram/m:* +synth_analogdevices -top block_ram -noiopad +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 64 t:RAMS64X1 +select -assert-count 4 t:FFRE + +# Set synthesis, logic_block to blockram memory; will be implemented as distributed +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +setattr -set logic_block 1 block_ram/m:* +synth_analogdevices -top block_ram -noiopad +cd block_ram # Constrain all select calls below inside the top module +select -assert-count 0 t:RBRAM2 + +# Set ram_style block to a distributed memory; will be implemented as blockram +design -reset +read_verilog ../common/memory_attributes/attributes_test.v +synth_analogdevices -top distributed_ram_manual -noiopad +cd distributed_ram_manual # Constrain all select calls below inside the top module +# select -assert-count 1 t:RBRAM2 # This gets implemented in logic instead diff --git a/tests/arch/analogdevices/blockram.ys b/tests/arch/analogdevices/blockram.ys new file mode 100644 index 000000000..f6efa5ba8 --- /dev/null +++ b/tests/arch/analogdevices/blockram.ys @@ -0,0 +1,77 @@ +### TODO: Not running equivalence checking because BRAM models does not exists +### currently. Checking instance counts instead. +# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RBRAM2 +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 12 -set DATA_WIDTH 1 sync_ram_sdp +setattr -set ram_style "block" sync_ram_sdp +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 + +design -reset +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp +setattr -set ram_style "block" sync_ram_sdp +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 + +design -reset +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp +setattr -set ram_style "block" sync_ram_sdp +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 + +design -reset +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 + +# Anything memory bits < 1024 -> LUTRAM +design -reset +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 0 t:RBRAM2 +select -assert-count 8 t:RAMD64X1 +select -assert-count 2 t:FFRE + +# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1 +design -reset +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 + + +### With parameters + +design -reset +read_verilog ../common/blockram.v +hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1 +setattr -set ram_style "block" m:memory +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 + +design -reset +read_verilog ../common/blockram.v +hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1 +setattr -set logic_block 1 m:memory +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 0 t:RBRAM2 + +design -reset +read_verilog ../common/blockram.v +hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 8 -chparam DATA_WIDTH 1 +setattr -set ram_style "block" m:memory +synth_analogdevices -top sync_ram_sdp -noiopad +cd sync_ram_sdp +select -assert-count 1 t:RBRAM2 diff --git a/tests/arch/analogdevices/bug1460.ys b/tests/arch/analogdevices/bug1460.ys new file mode 100644 index 000000000..66fb96a5b --- /dev/null +++ b/tests/arch/analogdevices/bug1460.ys @@ -0,0 +1,34 @@ +read_verilog < 1: + top_list.pop(0) + + # iterate over string substitutions + for top in top_list: + # limit number of tests per file to allow parallel make + if not f: + fn = f"t_mem{i}.ys" + f = open(fn, mode="w") + j = 0 + + # output yosys script test file + print( + blockram_template.format(param_str=param_str, top=top, tech=sim_test.tech, opts=" ".join(sim_test.opts)), + file=f + ) + for assertion in sim_test.assertions: + print(f"log ** CHECKING CELL COUNTS FOR TEST {top} WITH PARAMS{param_str} ON TECH {sim_test.tech}", file=f) + print(f"select {assertion}", file=f) + print("", file=f) + + # increment test counter + j += 1 + if j >= max_j: + f = f.close() + i += 1 + +if f: + f.close() diff --git a/tests/arch/analogdevices/mul.ys b/tests/arch/analogdevices/mul.ys new file mode 100644 index 000000000..460bfeb68 --- /dev/null +++ b/tests/arch/analogdevices/mul.ys @@ -0,0 +1,9 @@ +read_verilog ../common/mul.v +hierarchy -top top +proc +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:RBBDSP +select -assert-none t:RBBDSP %% t:* %D diff --git a/tests/arch/analogdevices/mul_unsigned.v b/tests/arch/analogdevices/mul_unsigned.v new file mode 100644 index 000000000..e3713a642 --- /dev/null +++ b/tests/arch/analogdevices/mul_unsigned.v @@ -0,0 +1,30 @@ +/* +Example from: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_1/ug901-vivado-synthesis.pdf [p. 89]. +*/ + +// Unsigned 16x24-bit Multiplier +// 1 latency stage on operands +// 3 latency stage after the multiplication +// File: multipliers2.v +// +module mul_unsigned (clk, A, B, RES); +parameter WIDTHA = /*16*/ 6; +parameter WIDTHB = /*24*/ 9; +input clk; +input [WIDTHA-1:0] A; +input [WIDTHB-1:0] B; +output [WIDTHA+WIDTHB-1:0] RES; +reg [WIDTHA-1:0] rA; +reg [WIDTHB-1:0] rB; +reg [WIDTHA+WIDTHB-1:0] M [3:0]; +integer i; +always @(posedge clk) + begin + rA <= A; + rB <= B; + M[0] <= rA * rB; + for (i = 0; i < 3; i = i+1) + M[i+1] <= M[i]; + end +assign RES = M[3]; +endmodule diff --git a/tests/arch/analogdevices/mul_unsigned.ys b/tests/arch/analogdevices/mul_unsigned.ys new file mode 100644 index 000000000..5bdbdaac4 --- /dev/null +++ b/tests/arch/analogdevices/mul_unsigned.ys @@ -0,0 +1,10 @@ +read_verilog mul_unsigned.v +hierarchy -top mul_unsigned +proc + +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mul_unsigned # Constrain all select calls below inside the top module +select -assert-count 1 t:RBBDSP +select -assert-count 75 t:FFRE +select -assert-none t:RBBDSP t:FFRE %% t:* %D diff --git a/tests/arch/analogdevices/mux.ys b/tests/arch/analogdevices/mux.ys new file mode 100644 index 000000000..375ce90f2 --- /dev/null +++ b/tests/arch/analogdevices/mux.ys @@ -0,0 +1,50 @@ +read_verilog ../common/mux.v +design -save read + +hierarchy -top mux2 +proc +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux2 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT3 + +select -assert-none t:LUT3 %% t:* %D + + +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT6 + +select -assert-none t:LUT6 %% t:* %D + + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT3 +select -assert-count 2 t:LUT6 + +select -assert-none t:LUT3 t:LUT6 %% t:* %D + + +design -load read +hierarchy -top mux16 +proc +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux16 # Constrain all select calls below inside the top module +select -assert-max 2 t:LUT3 +select -assert-max 2 t:LUT4 +select -assert-min 4 t:LUT6 +select -assert-max 7 t:LUT6 +select -assert-max 2 t:LUTMUX7 +dump + +select -assert-none t:LUT6 t:LUT4 t:LUT3 t:LUTMUX7 %% t:* %D diff --git a/tests/arch/analogdevices/opt_lut_ins.ys b/tests/arch/analogdevices/opt_lut_ins.ys new file mode 100644 index 000000000..9723ee651 --- /dev/null +++ b/tests/arch/analogdevices/opt_lut_ins.ys @@ -0,0 +1,26 @@ +read_rtlil << EOF + +module \top + + wire width 4 input 1 \A + + wire output 2 \O + + cell \LUT4 $0 + parameter \INIT 16'1111110011000000 + connect \I0 \A [0] + connect \I1 \A [1] + connect \I2 \A [2] + connect \I3 \A [3] + connect \O \O + end +end + +EOF + +read_verilog -lib +/analogdevices/cells_sim.v +equiv_opt -assert -map +/analogdevices/cells_sim.v opt_lut_ins -tech analogdevices + +design -load postopt + +select -assert-count 1 t:LUT3 diff --git a/tests/arch/analogdevices/shifter.ys b/tests/arch/analogdevices/shifter.ys new file mode 100644 index 000000000..3cd67cb93 --- /dev/null +++ b/tests/arch/analogdevices/shifter.ys @@ -0,0 +1,10 @@ +read_verilog ../common/shifter.v +hierarchy -top top +proc +flatten +equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 8 t:FFRE +select -assert-none t:FFRE %% t:* %D diff --git a/tests/arch/anlogic/generate_mk.py b/tests/arch/anlogic/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/anlogic/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/anlogic/run-test.sh b/tests/arch/anlogic/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/anlogic/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/common/blockram.v b/tests/arch/common/blockram.v index 4a9d45a6b..4358a4655 100644 --- a/tests/arch/common/blockram.v +++ b/tests/arch/common/blockram.v @@ -22,6 +22,30 @@ module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) endmodule // sync_ram_sp +module sync_ram_sp_nochange #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire write_enable, clk, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clk) begin + if (write_enable) + memory[address_in] <= data_in; + else + data_out_r <= memory[address_in]; + end + + assign data_out = data_out_r; + +endmodule // sync_ram_sp_nochange + + module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) (input wire clk, write_enable, input wire [DATA_WIDTH-1:0] data_in, @@ -112,6 +136,62 @@ module sync_ram_sdp_wrr #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10, SHIFT_VAL=1) endmodule // sync_ram_sdp_wrr +module double_sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10, USE_TDP=0) +( + input wire write_enable_a, clk_a, + input wire [DATA_WIDTH-1:0] data_in_a, + input wire [ADDRESS_WIDTH-1:0] address_in_a, + output wire [DATA_WIDTH-1:0] data_out_a, + + input wire write_enable_b, clk_b, + input wire [DATA_WIDTH-1:0] data_in_b, + input wire [ADDRESS_WIDTH-1:0] address_in_b, + output wire [DATA_WIDTH-1:0] data_out_b +); + + generate + if (USE_TDP) begin + + sync_ram_tdp #( + .DATA_WIDTH(DATA_WIDTH), + .ADDRESS_WIDTH(ADDRESS_WIDTH+1) + ) ram ( + .clk_a(clk_a), .clk_b(clk_b), + .write_enable_a(write_enable_a), .write_enable_b(write_enable_b), + .write_data_a(data_in_a), .write_data_b(data_in_b), + .addr_a({1'b0, address_in_a}), .addr_b({1'b1, address_in_b}), + .read_data_a(data_out_a), .read_data_b(data_out_b) + ); + + end else begin + + sync_ram_sp #( + .DATA_WIDTH(DATA_WIDTH), + .ADDRESS_WIDTH(ADDRESS_WIDTH) + ) a_ram ( + .write_enable(write_enable_a), + .clk(clk_a), + .data_in(data_in_a), + .address_in(address_in_a), + .data_out(data_out_a) + ); + + sync_ram_sp #( + .DATA_WIDTH(DATA_WIDTH), + .ADDRESS_WIDTH(ADDRESS_WIDTH) + ) b_ram ( + .write_enable(write_enable_b), + .clk(clk_b), + .data_in(data_in_b), + .address_in(address_in_b), + .data_out(data_out_b) + ); + end + endgenerate + +endmodule // double_sync_ram_sp + + module double_sync_ram_sdp #(parameter DATA_WIDTH_A=8, ADDRESS_WIDTH_A=10, DATA_WIDTH_B=8, ADDRESS_WIDTH_B=10) ( input wire write_enable_a, clk_a, diff --git a/tests/arch/ecp5/generate_mk.py b/tests/arch/ecp5/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/ecp5/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/ecp5/opt_lut_ins.ys b/tests/arch/ecp5/opt_lut_ins.ys index 622b5406c..7f9970c69 100644 --- a/tests/arch/ecp5/opt_lut_ins.ys +++ b/tests/arch/ecp5/opt_lut_ins.ys @@ -23,7 +23,7 @@ EOF read_verilog -lib +/ecp5/cells_sim.v -equiv_opt -assert -map +/ecp5/cells_sim.v opt_lut_ins -tech ecp5 +equiv_opt -assert -map +/ecp5/cells_sim.v opt_lut_ins -tech lattice design -load postopt diff --git a/tests/arch/ecp5/run-test.sh b/tests/arch/ecp5/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/ecp5/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/efinix/generate_mk.py b/tests/arch/efinix/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/efinix/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/efinix/run-test.sh b/tests/arch/efinix/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/efinix/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/fabulous/fsm.ys b/tests/arch/fabulous/fsm.ys index 9c3831682..5f7ae28dd 100644 --- a/tests/arch/fabulous/fsm.ys +++ b/tests/arch/fabulous/fsm.ys @@ -13,7 +13,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd fsm # Constrain all select calls below inside the top module select -assert-count 6 t:LUTFF -select -assert-max 4 t:LUT2 -select -assert-max 2 t:LUT3 -select -assert-max 9 t:LUT4 +select -assert-max 5 t:LUT2 +select -assert-max 4 t:LUT3 +select -assert-max 8 t:LUT4 select -assert-none t:LUT2 t:LUT3 t:LUT4 t:LUTFF %% t:* %D diff --git a/tests/arch/fabulous/generate_mk.py b/tests/arch/fabulous/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/fabulous/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/gatemate/add_sub.ys b/tests/arch/gatemate/add_sub.ys index bf261ba5a..6720e08a0 100644 --- a/tests/arch/gatemate/add_sub.ys +++ b/tests/arch/gatemate/add_sub.ys @@ -1,9 +1,29 @@ read_verilog ../common/add_sub.v hierarchy -top top proc +design -save orig + equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 8 t:CC_ADDF select -assert-max 4 t:CC_LUT1 select -assert-none t:CC_ADDF t:CC_LUT1 %% t:* %D + +design -load orig + +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 8 t:CC_ADDF +select -assert-max 4 t:CC_LUT1 +select -assert-none t:CC_ADDF t:CC_LUT1 %% t:* %D + +design -load orig + +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 8 t:CC_ADDF +select -assert-max 4 t:CC_LUT1 +select -assert-none t:CC_ADDF t:CC_LUT1 %% t:* %D diff --git a/tests/arch/gatemate/adffs.ys b/tests/arch/gatemate/adffs.ys index b2ded6e9d..0a80a4b48 100644 --- a/tests/arch/gatemate/adffs.ys +++ b/tests/arch/gatemate/adffs.ys @@ -31,6 +31,28 @@ select -assert-count 1 t:CC_DFF select -assert-max 1 t:CC_LUT2 select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 %% t:* %D +design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_BUFG +select -assert-count 1 t:CC_DFF +select -assert-max 1 t:CC_LUT2 +select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 %% t:* %D + +design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_BUFG +select -assert-count 1 t:CC_DFF +select -assert-max 1 t:CC_LUT2 +select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 %% t:* %D + design -load read hierarchy -top ndffnr proc @@ -41,3 +63,25 @@ select -assert-count 1 t:CC_BUFG select -assert-count 1 t:CC_DFF select -assert-max 1 t:CC_LUT2 select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 %% t:* %D + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_BUFG +select -assert-count 1 t:CC_DFF +select -assert-max 1 t:CC_LUT2 +select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 %% t:* %D + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_BUFG +select -assert-count 1 t:CC_DFF +select -assert-max 1 t:CC_LUT2 +select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 %% t:* %D diff --git a/tests/arch/gatemate/counter.ys b/tests/arch/gatemate/counter.ys index 77ed858b3..8aa04e5cb 100644 --- a/tests/arch/gatemate/counter.ys +++ b/tests/arch/gatemate/counter.ys @@ -2,6 +2,9 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten + +design -save orig + equiv_opt -assert -async2sync -map +/gatemate/cells_sim.v synth_gatemate -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -10,3 +13,25 @@ select -assert-count 8 t:CC_ADDF select -assert-count 1 t:CC_BUFG select -assert-count 8 t:CC_DFF select -assert-none t:CC_ADDF t:CC_BUFG t:CC_DFF %% t:* %D + +design -load orig + +equiv_opt -assert -async2sync -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 8 t:CC_ADDF +select -assert-count 1 t:CC_BUFG +select -assert-count 8 t:CC_DFF +select -assert-none t:CC_ADDF t:CC_BUFG t:CC_DFF %% t:* %D + +design -load orig + +equiv_opt -assert -async2sync -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 8 t:CC_ADDF +select -assert-count 1 t:CC_BUFG +select -assert-count 8 t:CC_DFF +select -assert-none t:CC_ADDF t:CC_BUFG t:CC_DFF %% t:* %D diff --git a/tests/arch/gatemate/fsm.ys b/tests/arch/gatemate/fsm.ys index 506862c90..8af1a0a47 100644 --- a/tests/arch/gatemate/fsm.ys +++ b/tests/arch/gatemate/fsm.ys @@ -3,6 +3,8 @@ hierarchy -top fsm proc flatten +design -save orig + equiv_opt -run :prove -map +/gatemate/cells_sim.v synth_gatemate -noiopad async2sync miter -equiv -make_assert -flatten gold gate miter @@ -18,3 +20,42 @@ select -assert-max 5 t:CC_LUT2 select -assert-max 6 t:CC_LUT3 select -assert-max 9 t:CC_LUT4 select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 t:CC_LUT3 t:CC_LUT4 %% t:* %D + +design -load orig + +equiv_opt -run :prove -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree +async2sync +miter -equiv -make_assert -flatten gold gate miter +stat +sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter + +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd fsm # Constrain all select calls below inside the top module + +select -assert-count 1 t:CC_BUFG +select -assert-count 6 t:CC_DFF +select -assert-max 2 t:CC_LUT1 +select -assert-count 1 t:CC_LUT2 +select -assert-max 14 t:CC_L2T4 +select -assert-max 5 t:CC_L2T5 +select -assert-max 1 t:CC_MX2 +select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT1 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 t:CC_MX2 %% t:* %D + +design -load orig + +equiv_opt -run :prove -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new +async2sync +miter -equiv -make_assert -flatten gold gate miter +stat +sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter + +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd fsm # Constrain all select calls below inside the top module + +select -assert-count 1 t:CC_BUFG +select -assert-count 6 t:CC_DFF +select -assert-count 2 t:CC_LUT2 +select -assert-count 9 t:CC_L2T4 +select -assert-count 6 t:CC_L2T5 +select -assert-count 1 t:CC_MX2 +select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 t:CC_MX2 %% t:* %D diff --git a/tests/arch/gatemate/generate_mk.py b/tests/arch/gatemate/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/gatemate/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/gatemate/latches.ys b/tests/arch/gatemate/latches.ys index 5f64c6db5..a044bf5d6 100644 --- a/tests/arch/gatemate/latches.ys +++ b/tests/arch/gatemate/latches.ys @@ -27,3 +27,23 @@ cd latchsr # Constrain all select calls below inside the top module select -assert-count 1 t:CC_DLT select -assert-max 2 t:CC_LUT3 select -assert-none t:CC_DLT t:CC_LUT3 %% t:* %D + +design -load read +hierarchy -top latchsr +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd latchsr # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_DLT +select -assert-max 2 t:CC_L2T4 +select -assert-none t:CC_DLT t:CC_L2T4 %% t:* %D + +design -load read +hierarchy -top latchsr +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd latchsr # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_DLT +select -assert-max 2 t:CC_L2T4 +select -assert-none t:CC_DLT t:CC_L2T4 %% t:* %D diff --git a/tests/arch/gatemate/logic.ys b/tests/arch/gatemate/logic.ys index 026406bc8..e6204cdca 100644 --- a/tests/arch/gatemate/logic.ys +++ b/tests/arch/gatemate/logic.ys @@ -1,6 +1,9 @@ read_verilog ../common/logic.v hierarchy -top top proc + +design -save orig + equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module @@ -8,3 +11,23 @@ select -assert-max 1 t:CC_LUT1 select -assert-max 6 t:CC_LUT2 select -assert-max 2 t:CC_LUT4 select -assert-none t:CC_LUT1 t:CC_LUT2 t:CC_LUT4 %% t:* %D + +design -load orig + +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_LUT1 +select -assert-count 6 t:CC_LUT2 +select -assert-count 2 t:CC_L2T4 +select -assert-none t:CC_LUT1 t:CC_LUT2 t:CC_L2T4 %% t:* %D + +design -load orig + +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_LUT1 +select -assert-count 6 t:CC_LUT2 +select -assert-count 2 t:CC_L2T4 +select -assert-none t:CC_LUT1 t:CC_LUT2 t:CC_L2T4 %% t:* %D diff --git a/tests/arch/gatemate/luttrees.ys b/tests/arch/gatemate/luttrees.ys index 545643226..f3a61ee60 100644 --- a/tests/arch/gatemate/luttrees.ys +++ b/tests/arch/gatemate/luttrees.ys @@ -11,3 +11,24 @@ cd luttrees # Constrain all select calls below inside the top module select -assert-count 750 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D +design -load read + +hierarchy -top luttrees +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -nomx4 -nomx8 -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd luttrees # Constrain all select calls below inside the top module + +select -assert-count 750 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% +select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D + +design -load read + +hierarchy -top luttrees +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -nomx4 -nomx8 -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd luttrees # Constrain all select calls below inside the top module + +select -assert-count 750 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% +select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D diff --git a/tests/arch/gatemate/mul.ys b/tests/arch/gatemate/mul.ys index ded5fe729..ef2255a76 100644 --- a/tests/arch/gatemate/mul.ys +++ b/tests/arch/gatemate/mul.ys @@ -31,3 +31,29 @@ select -assert-count 1 t:CC_BUFG select -assert-max 18 t:CC_LUT4 select -assert-count 18 t:CC_DFF select -assert-none t:CC_MULT t:CC_BUFG t:CC_LUT4 t:CC_DFF %% t:* %D + +design -load read +hierarchy -top mul_unsigned_sync +proc +equiv_opt -assert -async2sync -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mul_unsigned_sync # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_MULT +select -assert-count 1 t:CC_BUFG +select -assert-count 18 t:CC_LUT2 +select -assert-count 18 t:CC_MX2 +select -assert-count 18 t:CC_DFF +select -assert-none t:CC_MULT t:CC_BUFG t:CC_LUT2 t:CC_MX2 t:CC_DFF %% t:* %D + +design -load read +hierarchy -top mul_unsigned_sync +proc +# equiv_opt -assert -async2sync -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check (fails) +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mul_unsigned_sync # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_MULT +select -assert-count 1 t:CC_BUFG +select -assert-count 18 t:CC_LUT2 +select -assert-count 18 t:CC_MX2 +select -assert-count 18 t:CC_DFF +select -assert-none t:CC_MULT t:CC_BUFG t:CC_LUT2 t:CC_MX2 t:CC_DFF %% t:* %D diff --git a/tests/arch/gatemate/mux.ys b/tests/arch/gatemate/mux.ys index 320ff33d7..51c3b5daf 100644 --- a/tests/arch/gatemate/mux.ys +++ b/tests/arch/gatemate/mux.ys @@ -12,6 +12,25 @@ select -assert-max 2 t:CC_LUT4 select -assert-max 1 t:CC_MX2 select -assert-none t:CC_LUT2 t:CC_LUT4 t:CC_MX2 %% t:* %D +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 3 t:CC_MX2 +select -assert-none t:CC_MX2 %% t:* %D + +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 1 t:CC_LUT1 +select -assert-count 3 t:CC_MX2 +select -assert-none t:CC_LUT1 t:CC_MX2 %% t:* %D + design -load read hierarchy -top mux8 proc @@ -22,3 +41,21 @@ select -assert-max 1 t:CC_LUT3 select -assert-max 5 t:CC_LUT4 select -assert-max 1 t:CC_MX2 select -assert-none t:CC_LUT3 t:CC_LUT4 t:CC_MX2 %% t:* %D + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 7 t:CC_MX2 +select -assert-none t:CC_MX2 %% t:* %D + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -abc_new # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 7 t:CC_MX2 +select -assert-none t:CC_MX2 %% t:* %D diff --git a/tests/arch/gatemate/run-test.sh b/tests/arch/gatemate/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/gatemate/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/generate_mk.py b/tests/arch/generate_mk.py new file mode 100644 index 000000000..4c12a497c --- /dev/null +++ b/tests/arch/generate_mk.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +from pathlib import Path +import sys +sys.path.append("..") + +import gen_tests_makefile + +techlibs_dir = Path("../../techlibs") + +# Architecture-specific defines +defines = { + "ice40": ["ICE40_HX", "ICE40_LP", "ICE40_U"] +} + +def archs(): + # Loop over architectures + for arch in techlibs_dir.iterdir(): + if not arch.is_dir(): + continue + arch_name = arch.name + + for path in arch.rglob("cells_sim.v"): + rel_parts = path.relative_to(techlibs_dir).parts + target_base = "_".join(rel_parts[-len(rel_parts):]).replace(".v", "") + path_str = str(path) + if arch_name in defines: + for defn in defines[arch_name]: + target_name = f"{target_base}_{defn}" + cmd = f"iverilog -t null -I{arch} -D{defn} -DNO_ICE40_DEFAULT_ASSIGNMENTS {path_str}" + gen_tests_makefile.generate_target(target_name, cmd) + else: + target_name = f"{target_base}" + cmd = f"iverilog -t null -I{arch} -g2005-sv {path_str}" + gen_tests_makefile.generate_target(target_name, cmd) + +def common(): + for path in ["../../techlibs/common/simcells.v", "../../techlibs/common/simlib.v"]: + path_obj = Path(path) + target_name = path_obj.stem + cmd = f"iverilog -t null {path}" + gen_tests_makefile.generate_target(target_name, cmd) + +def main(): + def callback(): + archs() + common() + + gen_tests_makefile.generate_custom(callback) + +if __name__ == "__main__": + main() diff --git a/tests/arch/gowin/bug5688.ys b/tests/arch/gowin/bug5688.ys new file mode 100644 index 000000000..39019c4d6 --- /dev/null +++ b/tests/arch/gowin/bug5688.ys @@ -0,0 +1,31 @@ +read_verilog << EOT +`default_nettype none + +module top ( + input wire clk, + input wire [9:0] rd_addr, + output reg [15:0] rd_data, + input wire [9:0] wr_addr, + input wire [15:0] wr_data, + input wire wr_en +); + + (* ram_style = "block" *) reg [15:0] mem [0:1023]; + + // Read port — separate always block + always @(posedge clk) begin + rd_data <= mem[rd_addr]; + end + + // Write port — separate always block + always @(posedge clk) begin + if (wr_en) + mem[wr_addr] <= wr_data; + end + +endmodule + +EOT +synth_gowin -top top +splitnets +select -assert-any top/mem.0.0 %ci*:+DPX9B[ADA]:+DFF:+IBUF i:wr_en %i diff --git a/tests/arch/gowin/generate_mk.py b/tests/arch/gowin/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/gowin/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/gowin/latches.ys b/tests/arch/gowin/latches.ys new file mode 100644 index 000000000..6a05d2357 --- /dev/null +++ b/tests/arch/gowin/latches.ys @@ -0,0 +1,25 @@ +read_verilog ../common/latches.v +design -save read + +hierarchy -top latchp +proc +equiv_opt -async2sync -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd latchp # Constrain all select calls below inside the top module +select -assert-count 1 t:DL +select -assert-count 3 t:IBUF +select -assert-count 1 t:OBUF + +select -assert-none t:DL t:IBUF t:OBUF %% t:* %D + +design -load read +hierarchy -top latchn +proc +equiv_opt -async2sync -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd latchn # Constrain all select calls below inside the top module +select -assert-count 1 t:DLN +select -assert-count 3 t:IBUF +select -assert-count 1 t:OBUF + +select -assert-none t:DLN t:IBUF t:OBUF %% t:* %D diff --git a/tests/arch/gowin/mul_gw1n.ys b/tests/arch/gowin/mul_gw1n.ys new file mode 100644 index 000000000..9b1748255 --- /dev/null +++ b/tests/arch/gowin/mul_gw1n.ys @@ -0,0 +1,53 @@ +read_verilog ../common/mul.v +chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 +hierarchy -top top +proc +# equivalence checking is somewhat slow (and missing simulation models) +synth_gowin -family gw1n +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT9X9 + + +# Make sure that DSPs are not inferred with -nodsp option +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 +hierarchy -top top +proc +synth_gowin -family gw1n -nodsp +cd top # Constrain all select calls below inside the top module +select -assert-none t:MULT9X9 + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 16 -set Y_WIDTH 16 -set A_WIDTH 32 +hierarchy -top top +proc +synth_gowin -family gw1n +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT18X18 + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 32 -set Y_WIDTH 32 -set A_WIDTH 64 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_gowin +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT36X36 + + +# We end up with two 18x18 multipliers +# 36x36 min width is 22 +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 32 -set Y_WIDTH 16 -set A_WIDTH 48 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_gowin +cd top # Constrain all select calls below inside the top module +select -assert-count 2 t:MULT18X18 diff --git a/tests/arch/gowin/mul_gw2a.ys b/tests/arch/gowin/mul_gw2a.ys new file mode 100644 index 000000000..895c580b7 --- /dev/null +++ b/tests/arch/gowin/mul_gw2a.ys @@ -0,0 +1,53 @@ +read_verilog ../common/mul.v +chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 +hierarchy -top top +proc +# equivalence checking is somewhat slow (and missing simulation models) +synth_gowin -family gw2a +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT9X9 + + +# Make sure that DSPs are not inferred with -nodsp option +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 +hierarchy -top top +proc +synth_gowin -family gw2a -nodsp +cd top # Constrain all select calls below inside the top module +select -assert-none t:MULT9X9 + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 16 -set Y_WIDTH 16 -set A_WIDTH 32 +hierarchy -top top +proc +synth_gowin -family gw2a +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT18X18 + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 32 -set Y_WIDTH 32 -set A_WIDTH 64 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_gowin -family gw2a +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT36X36 + + +# We end up with two 18x18 multipliers +# 36x36 min width is 22 +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 32 -set Y_WIDTH 16 -set A_WIDTH 48 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_gowin -family gw2a +cd top # Constrain all select calls below inside the top module +select -assert-count 2 t:MULT18X18 diff --git a/tests/arch/gowin/run-test.sh b/tests/arch/gowin/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/gowin/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/ice40/fsm.ys b/tests/arch/ice40/fsm.ys index e3b746202..b01d34bba 100644 --- a/tests/arch/ice40/fsm.ys +++ b/tests/arch/ice40/fsm.ys @@ -12,5 +12,5 @@ cd fsm # Constrain all select calls below inside the top module select -assert-count 4 t:SB_DFF select -assert-count 2 t:SB_DFFESR -select -assert-max 15 t:SB_LUT4 +select -assert-max 16 t:SB_LUT4 select -assert-none t:SB_DFFESR t:SB_DFF t:SB_LUT4 %% t:* %D diff --git a/tests/arch/ice40/generate_mk.py b/tests/arch/ice40/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/ice40/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/ice40/ice40_dsp_const.ys b/tests/arch/ice40/ice40_dsp_const.ys index c9c76a1ac..735f945a1 100644 --- a/tests/arch/ice40/ice40_dsp_const.ys +++ b/tests/arch/ice40/ice40_dsp_const.ys @@ -74,6 +74,7 @@ EOT techmap -wb -D EQUIV -autoproc -map +/ice40/cells_sim.v +async2sync equiv_make top ref equiv select -assert-any -module equiv t:$equiv equiv_induct diff --git a/tests/arch/ice40/run-test.sh b/tests/arch/ice40/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/ice40/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/intel_alm/generate_mk.py b/tests/arch/intel_alm/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/intel_alm/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/intel_alm/run-test.sh b/tests/arch/intel_alm/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/intel_alm/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/machxo2/generate_mk.py b/tests/arch/machxo2/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/machxo2/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/machxo2/run-test.sh b/tests/arch/machxo2/run-test.sh deleted file mode 100644 index 691b70966..000000000 --- a/tests/arch/machxo2/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/microchip/generate_mk.py b/tests/arch/microchip/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/microchip/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/microchip/run-test.sh b/tests/arch/microchip/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/microchip/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/nanoxplore/generate_mk.py b/tests/arch/nanoxplore/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/nanoxplore/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/nanoxplore/run-test.sh b/tests/arch/nanoxplore/run-test.sh deleted file mode 100755 index 691b70966..000000000 --- a/tests/arch/nanoxplore/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/nexus/generate_mk.py b/tests/arch/nexus/generate_mk.py new file mode 100644 index 000000000..06a6040ad --- /dev/null +++ b/tests/arch/nexus/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/nexus/run-test.sh b/tests/arch/nexus/run-test.sh deleted file mode 100644 index 691b70966..000000000 --- a/tests/arch/nexus/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/quicklogic/pp3/generate_mk.py b/tests/arch/quicklogic/pp3/generate_mk.py new file mode 100644 index 000000000..e001d7e4a --- /dev/null +++ b/tests/arch/quicklogic/pp3/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../../..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/quicklogic/pp3/run-test.sh b/tests/arch/quicklogic/pp3/run-test.sh deleted file mode 100755 index 43a7874b2..000000000 --- a/tests/arch/quicklogic/pp3/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/quicklogic/qlf_k6n10f/generate_mk.py b/tests/arch/quicklogic/qlf_k6n10f/generate_mk.py new file mode 100644 index 000000000..e9abad21a --- /dev/null +++ b/tests/arch/quicklogic/qlf_k6n10f/generate_mk.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("../../..") + +import gen_tests_makefile +import mem_gen + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/arch/quicklogic/qlf_k6n10f/run-test.sh b/tests/arch/quicklogic/qlf_k6n10f/run-test.sh deleted file mode 100755 index c7daba12d..000000000 --- a/tests/arch/quicklogic/qlf_k6n10f/run-test.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -set -eu -python3 mem_gen.py -source ../../../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash diff --git a/tests/arch/run-test.sh b/tests/arch/run-test.sh deleted file mode 100755 index 7602717d2..000000000 --- a/tests/arch/run-test.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -set -e - -declare -A defines=( ["ice40"]="ICE40_HX ICE40_LP ICE40_U" ) - -echo "Running syntax check on arch sim models" -for arch in ../../techlibs/*; do - find $arch -name cells_sim.v | while read path; do - arch_name=$(basename -- $arch) - if [ "${defines[$arch_name]}" ]; then - for def in ${defines[$arch_name]}; do - echo -n "Test $path -D$def ->" - iverilog -t null -I$arch -D$def -DNO_ICE40_DEFAULT_ASSIGNMENTS $path - echo " ok" - done - else - echo -n "Test $path ->" - iverilog -t null -I$arch -g2005-sv $path - echo " ok" - fi - done -done - -for path in "../../techlibs/common/simcells.v" "../../techlibs/common/simlib.v"; do - echo -n "Test $path ->" - iverilog -t null $path - echo " ok" -done diff --git a/tests/arch/xilinx/dsp_preadder_sub.ys b/tests/arch/xilinx/dsp_preadder_sub.ys new file mode 100644 index 000000000..0e23ac373 --- /dev/null +++ b/tests/arch/xilinx/dsp_preadder_sub.ys @@ -0,0 +1,29 @@ +read_verilog < run-test.mk -exec ${MAKE:-make} -f run-test.mk diff --git a/tests/blif/.gitignore b/tests/blif/.gitignore new file mode 100644 index 000000000..e87afd97c --- /dev/null +++ b/tests/blif/.gitignore @@ -0,0 +1 @@ +/*.out diff --git a/tests/blif/gatesi.blif b/tests/blif/gatesi.blif new file mode 100644 index 000000000..d6fa4d5c9 --- /dev/null +++ b/tests/blif/gatesi.blif @@ -0,0 +1,480 @@ +# Generated by Yosys 0.60+88 (git sha1 69b604104, g++ 15.2.1 -fPIC -O3) + +.model test +.inputs clk in_a_var[0] in_a_var[1] in_a_var[2] in_a_var[3] in_a_var[4] in_a_var[5] in_a_var[6] in_a_var[7] in_b_var[0] in_b_var[1] in_b_var[2] in_b_var[3] in_b_var[4] in_b_var[5] in_b_var[6] in_b_var[7] +.outputs out_var[0] out_var[1] out_var[2] out_var[3] out_var[4] out_var[5] out_var[6] out_var[7] +.gate ORNOT A=:1.test_1[0] B=in_a_var[0] Y=$abc$2385$new_n57 +.gate ORNOT A=in_a_var[0] B=:1.test_1[0] Y=$abc$2385$new_n58 +.gate XNOR A=:1.test_1[0] B=in_a_var[0] Y=$abc$2385$new_n59 +.gate NAND A=in_b_var[0] B=$abc$2385$new_n59 Y=$abc$2385$new_n60 +.gate XOR A=in_b_var[0] B=$abc$2385$new_n59 Y=$abc$2385$auto$maccmap.cc:114:fulladd$252.Y[0] +.gate NAND A=$abc$2385$new_n57 B=$abc$2385$new_n60 Y=$abc$2385$new_n62 +.gate NOR A=:1.test_1[0] B=:1.test_1[1] Y=$abc$2385$new_n63 +.gate AND A=:1.test_1[0] B=:1.test_1[1] Y=$abc$2385$new_n64 +.gate XOR A=:1.test_1[0] B=:1.test_1[1] Y=$abc$2385$new_n65 +.gate NOT A=$abc$2385$new_n65 Y=$abc$2385$new_n66 +.gate AND A=:1.test_1[2] B=$abc$2385$new_n64 Y=$abc$2385$new_n67 +.gate AND A=:1.test_1[3] B=$abc$2385$new_n67 Y=$abc$2385$new_n68 +.gate AND A=:1.test_1[4] B=$abc$2385$new_n68 Y=$abc$2385$new_n69 +.gate AND A=:1.test_1[5] B=$abc$2385$new_n69 Y=$abc$2385$new_n70 +.gate AND A=:1.test_1[6] B=$abc$2385$new_n70 Y=$abc$2385$new_n71 +.gate XNOR A=:1.test_1[6] B=$abc$2385$new_n70 Y=$abc$2385$new_n72 +.gate NOT A=$abc$2385$new_n72 Y=$abc$2385$new_n73 +.gate AND A=:1.test_1[7] B=$abc$2385$new_n71 Y=$abc$2385$new_n74 +.gate XNOR A=:1.test_1[7] B=$abc$2385$new_n71 Y=$abc$2385$new_n75 +.gate ANDNOT A=:1.test_1[5] B=$abc$2385$new_n69 Y=$abc$2385$new_n76 +.gate XNOR A=:1.test_1[5] B=$abc$2385$new_n69 Y=$abc$2385$new_n77 +.gate NOR A=:1.test_1[3] B=:1.test_1[4] Y=$abc$2385$new_n78 +.gate AND A=$abc$2385$new_n63 B=$abc$2385$new_n78 Y=$abc$2385$new_n79 +.gate ANDNOT A=$abc$2385$new_n79 B=:1.test_1[2] Y=$abc$2385$new_n80 +.gate AND A=$abc$2385$new_n77 B=$abc$2385$new_n80 Y=$abc$2385$new_n81 +.gate NAND A=$abc$2385$new_n75 B=$abc$2385$new_n81 Y=$abc$2385$new_n82 +.gate OR A=$abc$2385$new_n73 B=$abc$2385$new_n82 Y=$abc$2385$new_n83 +.gate AND A=$abc$2385$new_n66 B=$abc$2385$new_n83 Y=$abc$2385$new_n84 +.gate ORNOT A=$abc$2385$new_n84 B=in_a_var[1] Y=$abc$2385$new_n85 +.gate XNOR A=in_a_var[1] B=$abc$2385$new_n84 Y=$abc$2385$new_n86 +.gate NAND A=in_b_var[1] B=$abc$2385$new_n86 Y=$abc$2385$new_n87 +.gate XNOR A=in_b_var[1] B=$abc$2385$new_n86 Y=$abc$2385$new_n88 +.gate ANDNOT A=$abc$2385$new_n62 B=$abc$2385$new_n88 Y=$abc$2385$new_n89 +.gate AND A=$abc$2385$new_n85 B=$abc$2385$new_n87 Y=$abc$2385$new_n90 +.gate XNOR A=:1.test_1[2] B=$abc$2385$new_n64 Y=$abc$2385$new_n91 +.gate AND A=$abc$2385$new_n83 B=$abc$2385$new_n91 Y=$abc$2385$new_n92 +.gate ORNOT A=$abc$2385$new_n92 B=in_a_var[2] Y=$abc$2385$new_n93 +.gate XNOR A=in_a_var[2] B=$abc$2385$new_n92 Y=$abc$2385$new_n94 +.gate NAND A=in_b_var[2] B=$abc$2385$new_n94 Y=$abc$2385$new_n95 +.gate XNOR A=in_b_var[2] B=$abc$2385$new_n94 Y=$abc$2385$new_n96 +.gate OR A=$abc$2385$new_n90 B=$abc$2385$new_n96 Y=$abc$2385$new_n97 +.gate XOR A=$abc$2385$new_n90 B=$abc$2385$new_n96 Y=$abc$2385$new_n98 +.gate NAND A=$abc$2385$new_n89 B=$abc$2385$new_n98 Y=$abc$2385$new_n99 +.gate XOR A=$abc$2385$new_n89 B=$abc$2385$new_n98 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[2] +.gate NAND A=$abc$2385$new_n97 B=$abc$2385$new_n99 Y=$abc$2385$new_n101 +.gate AND A=$abc$2385$new_n93 B=$abc$2385$new_n95 Y=$abc$2385$new_n102 +.gate XNOR A=:1.test_1[3] B=$abc$2385$new_n67 Y=$abc$2385$new_n103 +.gate AND A=$abc$2385$new_n83 B=$abc$2385$new_n103 Y=$abc$2385$new_n104 +.gate ORNOT A=$abc$2385$new_n104 B=in_a_var[3] Y=$abc$2385$new_n105 +.gate XNOR A=in_a_var[3] B=$abc$2385$new_n104 Y=$abc$2385$new_n106 +.gate NAND A=in_b_var[3] B=$abc$2385$new_n106 Y=$abc$2385$new_n107 +.gate XNOR A=in_b_var[3] B=$abc$2385$new_n106 Y=$abc$2385$new_n108 +.gate OR A=$abc$2385$new_n102 B=$abc$2385$new_n108 Y=$abc$2385$new_n109 +.gate XOR A=$abc$2385$new_n102 B=$abc$2385$new_n108 Y=$abc$2385$new_n110 +.gate NAND A=$abc$2385$new_n101 B=$abc$2385$new_n110 Y=$abc$2385$new_n111 +.gate XOR A=$abc$2385$new_n101 B=$abc$2385$new_n110 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[3] +.gate NAND A=$abc$2385$new_n109 B=$abc$2385$new_n111 Y=$abc$2385$new_n113 +.gate AND A=$abc$2385$new_n105 B=$abc$2385$new_n107 Y=$abc$2385$new_n114 +.gate XNOR A=:1.test_1[4] B=$abc$2385$new_n68 Y=$abc$2385$new_n115 +.gate AND A=$abc$2385$new_n83 B=$abc$2385$new_n115 Y=$abc$2385$new_n116 +.gate ORNOT A=$abc$2385$new_n116 B=in_a_var[4] Y=$abc$2385$new_n117 +.gate XNOR A=in_a_var[4] B=$abc$2385$new_n116 Y=$abc$2385$new_n118 +.gate NAND A=in_b_var[4] B=$abc$2385$new_n118 Y=$abc$2385$new_n119 +.gate XNOR A=in_b_var[4] B=$abc$2385$new_n118 Y=$abc$2385$new_n120 +.gate OR A=$abc$2385$new_n114 B=$abc$2385$new_n120 Y=$abc$2385$new_n121 +.gate XOR A=$abc$2385$new_n114 B=$abc$2385$new_n120 Y=$abc$2385$new_n122 +.gate NAND A=$abc$2385$new_n113 B=$abc$2385$new_n122 Y=$abc$2385$new_n123 +.gate XOR A=$abc$2385$new_n113 B=$abc$2385$new_n122 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[4] +.gate AND A=$abc$2385$new_n121 B=$abc$2385$new_n123 Y=$abc$2385$new_n125 +.gate AND A=$abc$2385$new_n117 B=$abc$2385$new_n119 Y=$abc$2385$new_n126 +.gate AND A=$abc$2385$new_n77 B=$abc$2385$new_n83 Y=$abc$2385$new_n127 +.gate ORNOT A=$abc$2385$new_n127 B=in_a_var[5] Y=$abc$2385$new_n128 +.gate XNOR A=in_a_var[5] B=$abc$2385$new_n127 Y=$abc$2385$new_n129 +.gate NAND A=in_b_var[5] B=$abc$2385$new_n129 Y=$abc$2385$new_n130 +.gate XNOR A=in_b_var[5] B=$abc$2385$new_n129 Y=$abc$2385$new_n131 +.gate OR A=$abc$2385$new_n126 B=$abc$2385$new_n131 Y=$abc$2385$new_n132 +.gate NAND A=$abc$2385$new_n126 B=$abc$2385$new_n131 Y=$abc$2385$new_n133 +.gate XOR A=$abc$2385$new_n126 B=$abc$2385$new_n131 Y=$abc$2385$new_n134 +.gate XNOR A=$abc$2385$new_n125 B=$abc$2385$new_n134 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[5] +.gate AND A=$abc$2385$new_n128 B=$abc$2385$new_n130 Y=$abc$2385$new_n136 +.gate AND A=$abc$2385$new_n72 B=$abc$2385$new_n82 Y=$abc$2385$new_n137 +.gate ORNOT A=$abc$2385$new_n137 B=in_a_var[6] Y=$abc$2385$new_n138 +.gate XNOR A=in_a_var[6] B=$abc$2385$new_n137 Y=$abc$2385$new_n139 +.gate NAND A=in_b_var[6] B=$abc$2385$new_n139 Y=$abc$2385$new_n140 +.gate XNOR A=in_b_var[6] B=$abc$2385$new_n139 Y=$abc$2385$new_n141 +.gate OR A=$abc$2385$new_n136 B=$abc$2385$new_n141 Y=$abc$2385$new_n142 +.gate XOR A=$abc$2385$new_n136 B=$abc$2385$new_n141 Y=$abc$2385$new_n143 +.gate NAND A=$abc$2385$new_n125 B=$abc$2385$new_n132 Y=$abc$2385$new_n144 +.gate AND A=$abc$2385$new_n133 B=$abc$2385$new_n144 Y=$abc$2385$new_n145 +.gate NAND A=$abc$2385$new_n143 B=$abc$2385$new_n145 Y=$abc$2385$new_n146 +.gate XOR A=$abc$2385$new_n143 B=$abc$2385$new_n145 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[6] +.gate AND A=$abc$2385$new_n142 B=$abc$2385$new_n146 Y=$abc$2385$new_n148 +.gate AND A=$abc$2385$new_n138 B=$abc$2385$new_n140 Y=$abc$2385$new_n149 +.gate AND A=$abc$2385$new_n75 B=$abc$2385$new_n83 Y=$abc$2385$new_n150 +.gate NOR A=in_b_var[7] B=in_a_var[7] Y=$abc$2385$new_n151 +.gate XOR A=in_b_var[7] B=in_a_var[7] Y=$abc$2385$new_n152 +.gate XNOR A=$abc$2385$new_n150 B=$abc$2385$new_n152 Y=$abc$2385$new_n153 +.gate XNOR A=$abc$2385$new_n149 B=$abc$2385$new_n153 Y=$abc$2385$new_n154 +.gate XNOR A=$abc$2385$new_n148 B=$abc$2385$new_n154 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[7] +.gate XNOR A=$abc$2385$new_n62 B=$abc$2385$new_n88 Y=$abc$2385$auto$maccmap.cc:240:synth$253.P[1] +.gate NAND A=:1.test_1[0] B=:1.test_2[0] Y=$abc$2385$new_n157 +.gate ANDNOT A=:1.test_2[0] B=$abc$2385$new_n91 Y=$abc$2385$new_n158 +.gate ANDNOT A=:1.test_2[1] B=$abc$2385$new_n64 Y=$abc$2385$new_n159 +.gate AND A=:1.test_2[1] B=$abc$2385$new_n65 Y=$abc$2385$new_n160 +.gate ORNOT A=$abc$2385$new_n160 B=:1.test_1[0] Y=$abc$2385$new_n161 +.gate AND A=:1.test_2[2] B=$abc$2385$new_n161 Y=$abc$2385$new_n162 +.gate ANDNOT A=:1.test_1[1] B=:1.test_1[0] Y=$abc$2385$new_n163 +.gate ANDNOT A=:1.test_2[2] B=:1.test_1[0] Y=$abc$2385$new_n164 +.gate XNOR A=$abc$2385$new_n160 B=$abc$2385$new_n164 Y=$abc$2385$new_n165 +.gate MUX A=$abc$2385$new_n160 B=$abc$2385$new_n165 S=:1.test_2[2] Y=$abc$2385$new_n166 +.gate ORNOT A=:1.test_2[0] B=:1.test_1[0] Y=$abc$2385$new_n167 +.gate AND A=$abc$2385$new_n159 B=$abc$2385$new_n167 Y=$abc$2385$new_n168 +.gate AND A=$abc$2385$new_n166 B=$abc$2385$new_n168 Y=$abc$2385$new_n169 +.gate XOR A=$abc$2385$new_n166 B=$abc$2385$new_n168 Y=$abc$2385$new_n170 +.gate AND A=$abc$2385$new_n158 B=$abc$2385$new_n170 Y=$abc$2385$new_n171 +.gate ANDNOT A=:1.test_2[0] B=$abc$2385$new_n103 Y=$abc$2385$new_n172 +.gate ANDNOT A=:1.test_2[1] B=$abc$2385$new_n91 Y=$abc$2385$new_n173 +.gate ANDNOT A=:1.test_2[1] B=$abc$2385$new_n103 Y=$abc$2385$new_n174 +.gate AND A=$abc$2385$new_n158 B=$abc$2385$new_n174 Y=$abc$2385$new_n175 +.gate XOR A=$abc$2385$new_n172 B=$abc$2385$new_n173 Y=$abc$2385$new_n176 +.gate NAND A=:1.test_2[2] B=$abc$2385$new_n65 Y=$abc$2385$new_n177 +.gate AND A=:1.test_1[0] B=:1.test_2[3] Y=$abc$2385$new_n178 +.gate NAND A=:1.test_1[0] B=$abc$2385$new_n177 Y=$abc$2385$new_n179 +.gate XNOR A=$abc$2385$new_n177 B=$abc$2385$new_n178 Y=$abc$2385$new_n180 +.gate NAND A=$abc$2385$new_n162 B=$abc$2385$new_n180 Y=$abc$2385$new_n181 +.gate XOR A=$abc$2385$new_n162 B=$abc$2385$new_n180 Y=$abc$2385$new_n182 +.gate NAND A=$abc$2385$new_n176 B=$abc$2385$new_n182 Y=$abc$2385$new_n183 +.gate XOR A=$abc$2385$new_n176 B=$abc$2385$new_n182 Y=$abc$2385$new_n184 +.gate NAND A=$abc$2385$new_n171 B=$abc$2385$new_n184 Y=$abc$2385$new_n185 +.gate XOR A=$abc$2385$new_n171 B=$abc$2385$new_n184 Y=$abc$2385$new_n186 +.gate NAND A=$abc$2385$new_n169 B=$abc$2385$new_n186 Y=$abc$2385$new_n187 +.gate NAND A=$abc$2385$new_n185 B=$abc$2385$new_n187 Y=$abc$2385$new_n188 +.gate ANDNOT A=:1.test_2[0] B=$abc$2385$new_n115 Y=$abc$2385$new_n189 +.gate ANDNOT A=:1.test_2[1] B=$abc$2385$new_n115 Y=$abc$2385$new_n190 +.gate NAND A=$abc$2385$new_n172 B=$abc$2385$new_n190 Y=$abc$2385$new_n191 +.gate XOR A=$abc$2385$new_n174 B=$abc$2385$new_n189 Y=$abc$2385$new_n192 +.gate ANDNOT A=:1.test_2[2] B=$abc$2385$new_n91 Y=$abc$2385$new_n193 +.gate NAND A=$abc$2385$new_n192 B=$abc$2385$new_n193 Y=$abc$2385$new_n194 +.gate XOR A=$abc$2385$new_n192 B=$abc$2385$new_n193 Y=$abc$2385$new_n195 +.gate AND A=:1.test_2[3] B=$abc$2385$new_n179 Y=$abc$2385$new_n196 +.gate NAND A=:1.test_2[3] B=$abc$2385$new_n65 Y=$abc$2385$new_n197 +.gate NAND A=:1.test_1[0] B=$abc$2385$new_n197 Y=$abc$2385$new_n198 +.gate AND A=:1.test_2[4] B=$abc$2385$new_n198 Y=$abc$2385$new_n199 +.gate NAND A=:1.test_2[3] B=$abc$2385$new_n163 Y=$abc$2385$new_n200 +.gate NAND A=$abc$2385$new_n199 B=$abc$2385$new_n200 Y=$abc$2385$new_n201 +.gate ORNOT A=:1.test_2[4] B=$abc$2385$new_n197 Y=$abc$2385$new_n202 +.gate AND A=$abc$2385$new_n201 B=$abc$2385$new_n202 Y=$abc$2385$new_n203 +.gate NAND A=$abc$2385$new_n175 B=$abc$2385$new_n203 Y=$abc$2385$new_n204 +.gate XOR A=$abc$2385$new_n175 B=$abc$2385$new_n203 Y=$abc$2385$new_n205 +.gate NAND A=$abc$2385$new_n196 B=$abc$2385$new_n205 Y=$abc$2385$new_n206 +.gate XOR A=$abc$2385$new_n196 B=$abc$2385$new_n205 Y=$abc$2385$new_n207 +.gate AND A=$abc$2385$new_n195 B=$abc$2385$new_n207 Y=$abc$2385$new_n208 +.gate XOR A=$abc$2385$new_n195 B=$abc$2385$new_n207 Y=$abc$2385$new_n209 +.gate NAND A=$abc$2385$new_n181 B=$abc$2385$new_n183 Y=$abc$2385$new_n210 +.gate AND A=$abc$2385$new_n209 B=$abc$2385$new_n210 Y=$abc$2385$new_n211 +.gate XOR A=$abc$2385$new_n209 B=$abc$2385$new_n210 Y=$abc$2385$new_n212 +.gate AND A=$abc$2385$new_n188 B=$abc$2385$new_n212 Y=$abc$2385$new_n213 +.gate ANDNOT A=:1.test_2[0] B=$abc$2385$new_n77 Y=$abc$2385$new_n214 +.gate ANDNOT A=:1.test_2[3] B=$abc$2385$new_n91 Y=$abc$2385$new_n215 +.gate ANDNOT A=:1.test_2[2] B=$abc$2385$new_n103 Y=$abc$2385$new_n216 +.gate ANDNOT A=:1.test_2[2] B=$abc$2385$new_n115 Y=$abc$2385$new_n217 +.gate NAND A=$abc$2385$new_n174 B=$abc$2385$new_n217 Y=$abc$2385$new_n218 +.gate XOR A=$abc$2385$new_n190 B=$abc$2385$new_n216 Y=$abc$2385$new_n219 +.gate NAND A=$abc$2385$new_n215 B=$abc$2385$new_n219 Y=$abc$2385$new_n220 +.gate XOR A=$abc$2385$new_n215 B=$abc$2385$new_n219 Y=$abc$2385$new_n221 +.gate AND A=$abc$2385$new_n214 B=$abc$2385$new_n221 Y=$abc$2385$new_n222 +.gate XOR A=$abc$2385$new_n214 B=$abc$2385$new_n221 Y=$abc$2385$new_n223 +.gate NAND A=:1.test_2[4] B=$abc$2385$new_n65 Y=$abc$2385$new_n224 +.gate NAND A=:1.test_1[0] B=$abc$2385$new_n224 Y=$abc$2385$new_n225 +.gate AND A=:1.test_2[5] B=$abc$2385$new_n225 Y=$abc$2385$new_n226 +.gate NAND A=:1.test_2[4] B=$abc$2385$new_n163 Y=$abc$2385$new_n227 +.gate NAND A=$abc$2385$new_n226 B=$abc$2385$new_n227 Y=$abc$2385$new_n228 +.gate ORNOT A=:1.test_2[5] B=$abc$2385$new_n224 Y=$abc$2385$new_n229 +.gate AND A=$abc$2385$new_n228 B=$abc$2385$new_n229 Y=$abc$2385$new_n230 +.gate NAND A=$abc$2385$new_n191 B=$abc$2385$new_n194 Y=$abc$2385$new_n231 +.gate NAND A=$abc$2385$new_n230 B=$abc$2385$new_n231 Y=$abc$2385$new_n232 +.gate XOR A=$abc$2385$new_n230 B=$abc$2385$new_n231 Y=$abc$2385$new_n233 +.gate NAND A=$abc$2385$new_n199 B=$abc$2385$new_n233 Y=$abc$2385$new_n234 +.gate XOR A=$abc$2385$new_n199 B=$abc$2385$new_n233 Y=$abc$2385$new_n235 +.gate AND A=$abc$2385$new_n223 B=$abc$2385$new_n235 Y=$abc$2385$new_n236 +.gate XOR A=$abc$2385$new_n223 B=$abc$2385$new_n235 Y=$abc$2385$new_n237 +.gate NAND A=$abc$2385$new_n208 B=$abc$2385$new_n237 Y=$abc$2385$new_n238 +.gate XOR A=$abc$2385$new_n208 B=$abc$2385$new_n237 Y=$abc$2385$new_n239 +.gate NAND A=$abc$2385$new_n204 B=$abc$2385$new_n206 Y=$abc$2385$new_n240 +.gate NAND A=$abc$2385$new_n239 B=$abc$2385$new_n240 Y=$abc$2385$new_n241 +.gate XOR A=$abc$2385$new_n239 B=$abc$2385$new_n240 Y=$abc$2385$new_n242 +.gate AND A=$abc$2385$new_n211 B=$abc$2385$new_n242 Y=$abc$2385$new_n243 +.gate XOR A=$abc$2385$new_n211 B=$abc$2385$new_n242 Y=$abc$2385$new_n244 +.gate NAND A=$abc$2385$new_n213 B=$abc$2385$new_n244 Y=$abc$2385$new_n245 +.gate AND A=:1.test_2[0] B=$abc$2385$new_n163 Y=$abc$2385$new_n246 +.gate NAND A=:1.test_2[0] B=$abc$2385$new_n163 Y=$abc$2385$new_n247 +.gate XOR A=$abc$2385$new_n158 B=$abc$2385$new_n170 Y=$abc$2385$new_n248 +.gate AND A=$abc$2385$new_n246 B=$abc$2385$new_n248 Y=$abc$2385$new_n249 +.gate XOR A=$abc$2385$new_n169 B=$abc$2385$new_n186 Y=$abc$2385$new_n250 +.gate AND A=$abc$2385$new_n249 B=$abc$2385$new_n250 Y=$abc$2385$new_n251 +.gate XOR A=$abc$2385$new_n188 B=$abc$2385$new_n212 Y=$abc$2385$new_n252 +.gate AND A=$abc$2385$new_n251 B=$abc$2385$new_n252 Y=$abc$2385$new_n253 +.gate NAND A=$abc$2385$new_n244 B=$abc$2385$new_n253 Y=$abc$2385$new_n254 +.gate XNOR A=$abc$2385$new_n213 B=$abc$2385$new_n244 Y=$abc$2385$new_n255 +.gate NAND A=$abc$2385$new_n245 B=$abc$2385$new_n254 Y=$abc$2385$new_n256 +.gate NAND A=$abc$2385$new_n238 B=$abc$2385$new_n241 Y=$abc$2385$new_n257 +.gate ANDNOT A=:1.test_2[0] B=$abc$2385$new_n72 Y=$abc$2385$new_n258 +.gate ORNOT A=$abc$2385$new_n77 B=:1.test_2[1] Y=$abc$2385$new_n259 +.gate ANDNOT A=:1.test_2[1] B=$abc$2385$new_n72 Y=$abc$2385$new_n260 +.gate NAND A=$abc$2385$new_n214 B=$abc$2385$new_n260 Y=$abc$2385$new_n261 +.gate XNOR A=$abc$2385$new_n258 B=$abc$2385$new_n259 Y=$abc$2385$new_n262 +.gate ANDNOT A=:1.test_2[4] B=$abc$2385$new_n91 Y=$abc$2385$new_n263 +.gate ANDNOT A=:1.test_2[3] B=$abc$2385$new_n103 Y=$abc$2385$new_n264 +.gate ANDNOT A=:1.test_2[3] B=$abc$2385$new_n115 Y=$abc$2385$new_n265 +.gate NAND A=$abc$2385$new_n216 B=$abc$2385$new_n265 Y=$abc$2385$new_n266 +.gate XOR A=$abc$2385$new_n217 B=$abc$2385$new_n264 Y=$abc$2385$new_n267 +.gate NAND A=$abc$2385$new_n263 B=$abc$2385$new_n267 Y=$abc$2385$new_n268 +.gate XOR A=$abc$2385$new_n263 B=$abc$2385$new_n267 Y=$abc$2385$new_n269 +.gate AND A=$abc$2385$new_n262 B=$abc$2385$new_n269 Y=$abc$2385$new_n270 +.gate XOR A=$abc$2385$new_n262 B=$abc$2385$new_n269 Y=$abc$2385$new_n271 +.gate NAND A=$abc$2385$new_n222 B=$abc$2385$new_n271 Y=$abc$2385$new_n272 +.gate XOR A=$abc$2385$new_n222 B=$abc$2385$new_n271 Y=$abc$2385$new_n273 +.gate NAND A=:1.test_2[5] B=$abc$2385$new_n65 Y=$abc$2385$new_n274 +.gate NAND A=:1.test_1[0] B=$abc$2385$new_n274 Y=$abc$2385$new_n275 +.gate AND A=:1.test_2[6] B=$abc$2385$new_n275 Y=$abc$2385$new_n276 +.gate NAND A=:1.test_2[5] B=$abc$2385$new_n163 Y=$abc$2385$new_n277 +.gate NAND A=:1.test_2[6] B=$abc$2385$new_n65 Y=$abc$2385$new_n278 +.gate NAND A=$abc$2385$new_n276 B=$abc$2385$new_n277 Y=$abc$2385$new_n279 +.gate ORNOT A=:1.test_2[6] B=$abc$2385$new_n274 Y=$abc$2385$new_n280 +.gate AND A=$abc$2385$new_n279 B=$abc$2385$new_n280 Y=$abc$2385$new_n281 +.gate NAND A=$abc$2385$new_n218 B=$abc$2385$new_n220 Y=$abc$2385$new_n282 +.gate NAND A=$abc$2385$new_n281 B=$abc$2385$new_n282 Y=$abc$2385$new_n283 +.gate XOR A=$abc$2385$new_n281 B=$abc$2385$new_n282 Y=$abc$2385$new_n284 +.gate NAND A=$abc$2385$new_n226 B=$abc$2385$new_n284 Y=$abc$2385$new_n285 +.gate XOR A=$abc$2385$new_n226 B=$abc$2385$new_n284 Y=$abc$2385$new_n286 +.gate NAND A=$abc$2385$new_n273 B=$abc$2385$new_n286 Y=$abc$2385$new_n287 +.gate XOR A=$abc$2385$new_n273 B=$abc$2385$new_n286 Y=$abc$2385$new_n288 +.gate NAND A=$abc$2385$new_n236 B=$abc$2385$new_n288 Y=$abc$2385$new_n289 +.gate XOR A=$abc$2385$new_n236 B=$abc$2385$new_n288 Y=$abc$2385$new_n290 +.gate NAND A=$abc$2385$new_n232 B=$abc$2385$new_n234 Y=$abc$2385$new_n291 +.gate NAND A=$abc$2385$new_n290 B=$abc$2385$new_n291 Y=$abc$2385$new_n292 +.gate XOR A=$abc$2385$new_n290 B=$abc$2385$new_n291 Y=$abc$2385$new_n293 +.gate NAND A=$abc$2385$new_n257 B=$abc$2385$new_n293 Y=$abc$2385$new_n294 +.gate XOR A=$abc$2385$new_n257 B=$abc$2385$new_n293 Y=$abc$2385$new_n295 +.gate NAND A=$abc$2385$new_n243 B=$abc$2385$new_n295 Y=$abc$2385$new_n296 +.gate XOR A=$abc$2385$new_n243 B=$abc$2385$new_n295 Y=$abc$2385$new_n297 +.gate NAND A=$abc$2385$new_n256 B=$abc$2385$new_n297 Y=$abc$2385$new_n298 +.gate XNOR A=$abc$2385$new_n256 B=$abc$2385$new_n297 Y=$abc$2385$new_n299 +.gate NAND A=$abc$2385$new_n73 B=$abc$2385$new_n299 Y=$abc$2385$new_n300 +.gate OR A=$abc$2385$new_n73 B=$abc$2385$new_n299 Y=$abc$2385$new_n301 +.gate XOR A=$abc$2385$new_n253 B=$abc$2385$new_n255 Y=$abc$2385$new_n302 +.gate XNOR A=$abc$2385$new_n251 B=$abc$2385$new_n252 Y=$abc$2385$new_n303 +.gate XOR A=$abc$2385$new_n249 B=$abc$2385$new_n250 Y=$abc$2385$new_n304 +.gate XNOR A=$abc$2385$new_n249 B=$abc$2385$new_n250 Y=$abc$2385$new_n305 +.gate NAND A=$abc$2385$new_n103 B=$abc$2385$new_n304 Y=$abc$2385$new_n306 +.gate OR A=$abc$2385$new_n103 B=$abc$2385$new_n304 Y=$abc$2385$new_n307 +.gate XNOR A=$abc$2385$new_n247 B=$abc$2385$new_n248 Y=$abc$2385$new_n308 +.gate NAND A=:1.test_1[0] B=:1.test_2[1] Y=$abc$2385$new_n309 +.gate ANDNOT A=:1.test_2[0] B=$abc$2385$new_n64 Y=$abc$2385$new_n310 +.gate XNOR A=$abc$2385$new_n309 B=$abc$2385$new_n310 Y=$abc$2385$new_n311 +.gate NAND A=$abc$2385$new_n66 B=$abc$2385$new_n311 Y=$abc$2385$new_n312 +.gate OR A=:1.test_2[1] B=$abc$2385$new_n157 Y=$abc$2385$new_n313 +.gate NAND A=$abc$2385$new_n312 B=$abc$2385$new_n313 Y=$abc$2385$new_n314 +.gate OR A=$abc$2385$new_n308 B=$abc$2385$new_n314 Y=$abc$2385$new_n315 +.gate NAND A=$abc$2385$new_n91 B=$abc$2385$new_n315 Y=$abc$2385$new_n316 +.gate NAND A=$abc$2385$new_n308 B=$abc$2385$new_n314 Y=$abc$2385$new_n317 +.gate NAND A=$abc$2385$new_n316 B=$abc$2385$new_n317 Y=$abc$2385$new_n318 +.gate NAND A=$abc$2385$new_n307 B=$abc$2385$new_n318 Y=$abc$2385$new_n319 +.gate NAND A=$abc$2385$new_n247 B=$abc$2385$new_n311 Y=$abc$2385$new_n320 +.gate NAND A=$abc$2385$new_n306 B=$abc$2385$new_n319 Y=$abc$2385$new_n321 +.gate ORNOT A=$abc$2385$new_n115 B=$abc$2385$new_n303 Y=$abc$2385$new_n322 +.gate ORNOT A=$abc$2385$new_n303 B=$abc$2385$new_n115 Y=$abc$2385$new_n323 +.gate NAND A=$abc$2385$new_n321 B=$abc$2385$new_n322 Y=$abc$2385$new_n324 +.gate NAND A=$abc$2385$new_n323 B=$abc$2385$new_n324 Y=$abc$2385$new_n325 +.gate NAND A=$abc$2385$new_n77 B=$abc$2385$new_n325 Y=$abc$2385$new_n326 +.gate NAND A=$abc$2385$new_n302 B=$abc$2385$new_n326 Y=$abc$2385$new_n327 +.gate OR A=$abc$2385$new_n77 B=$abc$2385$new_n325 Y=$abc$2385$new_n328 +.gate AND A=$abc$2385$new_n327 B=$abc$2385$new_n328 Y=$abc$2385$new_n329 +.gate NAND A=$abc$2385$new_n300 B=$abc$2385$new_n329 Y=$abc$2385$new_n330 +.gate AND A=$abc$2385$new_n301 B=$abc$2385$new_n330 Y=$abc$2385$new_n331 +.gate NAND A=$abc$2385$new_n75 B=$abc$2385$new_n331 Y=$abc$2385$new_n332 +.gate OR A=in_b_var[5] B=$abc$2385$new_n302 Y=$abc$2385$new_n333 +.gate NAND A=in_b_var[4] B=$abc$2385$new_n303 Y=$abc$2385$new_n334 +.gate OR A=in_b_var[4] B=$abc$2385$new_n303 Y=$abc$2385$new_n335 +.gate AND A=in_b_var[1] B=$abc$2385$new_n320 Y=$abc$2385$new_n336 +.gate OR A=in_b_var[3] B=$abc$2385$new_n305 Y=$abc$2385$new_n337 +.gate ANDNOT A=in_b_var[2] B=$abc$2385$new_n308 Y=$abc$2385$new_n338 +.gate XNOR A=in_b_var[2] B=$abc$2385$new_n308 Y=$abc$2385$new_n339 +.gate NAND A=in_b_var[3] B=$abc$2385$new_n305 Y=$abc$2385$new_n340 +.gate XNOR A=in_b_var[3] B=$abc$2385$new_n304 Y=$abc$2385$new_n341 +.gate AND A=$abc$2385$new_n339 B=$abc$2385$new_n341 Y=$abc$2385$new_n342 +.gate NAND A=$abc$2385$new_n336 B=$abc$2385$new_n342 Y=$abc$2385$new_n343 +.gate NAND A=$abc$2385$new_n337 B=$abc$2385$new_n338 Y=$abc$2385$new_n344 +.gate AND A=$abc$2385$new_n340 B=$abc$2385$new_n344 Y=$abc$2385$new_n345 +.gate AND A=$abc$2385$new_n343 B=$abc$2385$new_n345 Y=$abc$2385$new_n346 +.gate AND A=in_b_var[0] B=$abc$2385$new_n157 Y=$abc$2385$new_n347 +.gate XOR A=in_b_var[1] B=$abc$2385$new_n320 Y=$abc$2385$new_n348 +.gate AND A=$abc$2385$new_n342 B=$abc$2385$new_n348 Y=$abc$2385$new_n349 +.gate NAND A=$abc$2385$new_n347 B=$abc$2385$new_n349 Y=$abc$2385$new_n350 +.gate NAND A=$abc$2385$new_n346 B=$abc$2385$new_n350 Y=$abc$2385$new_n351 +.gate NAND A=$abc$2385$new_n335 B=$abc$2385$new_n351 Y=$abc$2385$new_n352 +.gate NAND A=$abc$2385$new_n334 B=$abc$2385$new_n352 Y=$abc$2385$new_n353 +.gate NAND A=$abc$2385$new_n333 B=$abc$2385$new_n353 Y=$abc$2385$new_n354 +.gate NAND A=in_b_var[6] B=$abc$2385$new_n299 Y=$abc$2385$new_n355 +.gate NAND A=in_b_var[5] B=$abc$2385$new_n302 Y=$abc$2385$new_n356 +.gate AND A=$abc$2385$new_n355 B=$abc$2385$new_n356 Y=$abc$2385$new_n357 +.gate NAND A=$abc$2385$new_n354 B=$abc$2385$new_n357 Y=$abc$2385$new_n358 +.gate AND A=$abc$2385$new_n157 B=$abc$2385$new_n320 Y=$abc$2385$new_n359 +.gate ANDNOT A=$abc$2385$new_n359 B=$abc$2385$new_n308 Y=$abc$2385$new_n360 +.gate AND A=$abc$2385$new_n305 B=$abc$2385$new_n360 Y=$abc$2385$new_n361 +.gate AND A=$abc$2385$new_n303 B=$abc$2385$new_n361 Y=$abc$2385$new_n362 +.gate AND A=$abc$2385$new_n302 B=$abc$2385$new_n362 Y=$abc$2385$new_n363 +.gate NAND A=$abc$2385$new_n299 B=$abc$2385$new_n363 Y=$abc$2385$new_n364 +.gate AND A=$abc$2385$new_n296 B=$abc$2385$new_n298 Y=$abc$2385$new_n365 +.gate AND A=$abc$2385$new_n289 B=$abc$2385$new_n292 Y=$abc$2385$new_n366 +.gate OR A=:1.test_2[0] B=$abc$2385$new_n75 Y=$abc$2385$new_n367 +.gate AND A=$abc$2385$new_n261 B=$abc$2385$new_n367 Y=$abc$2385$new_n368 +.gate XNOR A=$abc$2385$new_n270 B=$abc$2385$new_n368 Y=$abc$2385$new_n369 +.gate XNOR A=$abc$2385$new_n276 B=$abc$2385$new_n369 Y=$abc$2385$new_n370 +.gate ANDNOT A=:1.test_2[2] B=$abc$2385$new_n77 Y=$abc$2385$new_n371 +.gate ANDNOT A=:1.test_2[5] B=$abc$2385$new_n91 Y=$abc$2385$new_n372 +.gate ANDNOT A=:1.test_2[4] B=$abc$2385$new_n103 Y=$abc$2385$new_n373 +.gate XNOR A=$abc$2385$new_n372 B=$abc$2385$new_n373 Y=$abc$2385$new_n374 +.gate XNOR A=$abc$2385$new_n371 B=$abc$2385$new_n374 Y=$abc$2385$new_n375 +.gate XOR A=$abc$2385$new_n260 B=$abc$2385$new_n265 Y=$abc$2385$new_n376 +.gate XNOR A=$abc$2385$new_n375 B=$abc$2385$new_n376 Y=$abc$2385$new_n377 +.gate NAND A=$abc$2385$new_n266 B=$abc$2385$new_n268 Y=$abc$2385$new_n378 +.gate ANDNOT A=:1.test_2[7] B=:1.test_1[0] Y=$abc$2385$new_n379 +.gate XNOR A=$abc$2385$new_n278 B=$abc$2385$new_n379 Y=$abc$2385$new_n380 +.gate XNOR A=$abc$2385$new_n75 B=$abc$2385$new_n380 Y=$abc$2385$new_n381 +.gate XNOR A=$abc$2385$new_n378 B=$abc$2385$new_n381 Y=$abc$2385$new_n382 +.gate XNOR A=$abc$2385$new_n377 B=$abc$2385$new_n382 Y=$abc$2385$new_n383 +.gate XNOR A=$abc$2385$new_n370 B=$abc$2385$new_n383 Y=$abc$2385$new_n384 +.gate NAND A=$abc$2385$new_n283 B=$abc$2385$new_n285 Y=$abc$2385$new_n385 +.gate AND A=$abc$2385$new_n272 B=$abc$2385$new_n287 Y=$abc$2385$new_n386 +.gate XNOR A=$abc$2385$new_n385 B=$abc$2385$new_n386 Y=$abc$2385$new_n387 +.gate XNOR A=$abc$2385$new_n384 B=$abc$2385$new_n387 Y=$abc$2385$new_n388 +.gate XNOR A=$abc$2385$new_n366 B=$abc$2385$new_n388 Y=$abc$2385$new_n389 +.gate XNOR A=:1.test_2[7] B=$abc$2385$new_n294 Y=$abc$2385$new_n390 +.gate XNOR A=$abc$2385$new_n389 B=$abc$2385$new_n390 Y=$abc$2385$new_n391 +.gate XNOR A=$abc$2385$new_n365 B=$abc$2385$new_n391 Y=$abc$2385$new_n392 +.gate OR A=in_b_var[6] B=$abc$2385$new_n299 Y=$abc$2385$new_n393 +.gate ORNOT A=in_b_var[6] B=in_a_var[6] Y=$abc$2385$new_n394 +.gate ORNOT A=in_a_var[5] B=in_b_var[5] Y=$abc$2385$new_n395 +.gate ORNOT A=in_b_var[5] B=in_a_var[5] Y=$abc$2385$new_n396 +.gate ORNOT A=in_b_var[4] B=in_a_var[4] Y=$abc$2385$new_n397 +.gate AND A=$abc$2385$new_n396 B=$abc$2385$new_n397 Y=$abc$2385$new_n398 +.gate ORNOT A=in_b_var[2] B=in_a_var[2] Y=$abc$2385$new_n399 +.gate ORNOT A=in_b_var[3] B=in_a_var[3] Y=$abc$2385$new_n400 +.gate NAND A=$abc$2385$new_n399 B=$abc$2385$new_n400 Y=$abc$2385$new_n401 +.gate ORNOT A=in_a_var[3] B=in_b_var[3] Y=$abc$2385$new_n402 +.gate NAND A=$abc$2385$new_n401 B=$abc$2385$new_n402 Y=$abc$2385$new_n403 +.gate ORNOT A=in_a_var[2] B=in_b_var[2] Y=$abc$2385$new_n404 +.gate NAND A=$abc$2385$new_n402 B=$abc$2385$new_n404 Y=$abc$2385$new_n405 +.gate NOR A=$abc$2385$new_n401 B=$abc$2385$new_n405 Y=$abc$2385$new_n406 +.gate ORNOT A=in_a_var[0] B=in_b_var[0] Y=$abc$2385$new_n407 +.gate ORNOT A=in_a_var[1] B=in_b_var[1] Y=$abc$2385$new_n408 +.gate NAND A=$abc$2385$new_n407 B=$abc$2385$new_n408 Y=$abc$2385$new_n409 +.gate ORNOT A=in_b_var[1] B=in_a_var[1] Y=$abc$2385$new_n410 +.gate NAND A=$abc$2385$new_n409 B=$abc$2385$new_n410 Y=$abc$2385$new_n411 +.gate NAND A=$abc$2385$new_n406 B=$abc$2385$new_n411 Y=$abc$2385$new_n412 +.gate NAND A=$abc$2385$new_n403 B=$abc$2385$new_n412 Y=$abc$2385$new_n413 +.gate ORNOT A=in_a_var[4] B=in_b_var[4] Y=$abc$2385$new_n414 +.gate NAND A=$abc$2385$new_n413 B=$abc$2385$new_n414 Y=$abc$2385$new_n415 +.gate NAND A=$abc$2385$new_n398 B=$abc$2385$new_n415 Y=$abc$2385$new_n416 +.gate NAND A=$abc$2385$new_n395 B=$abc$2385$new_n416 Y=$abc$2385$new_n417 +.gate NAND A=$abc$2385$new_n394 B=$abc$2385$new_n417 Y=$abc$2385$new_n418 +.gate NAND A=$abc$2385$new_n394 B=$abc$2385$new_n395 Y=$abc$2385$new_n419 +.gate NOR A=$abc$2385$new_n409 B=$abc$2385$new_n419 Y=$abc$2385$new_n420 +.gate AND A=$abc$2385$new_n398 B=$abc$2385$new_n420 Y=$abc$2385$new_n421 +.gate ORNOT A=in_b_var[0] B=in_a_var[0] Y=$abc$2385$new_n422 +.gate AND A=$abc$2385$new_n410 B=$abc$2385$new_n414 Y=$abc$2385$new_n423 +.gate AND A=$abc$2385$new_n422 B=$abc$2385$new_n423 Y=$abc$2385$new_n424 +.gate AND A=$abc$2385$new_n406 B=$abc$2385$new_n424 Y=$abc$2385$new_n425 +.gate NAND A=$abc$2385$new_n421 B=$abc$2385$new_n425 Y=$abc$2385$new_n426 +.gate ORNOT A=in_a_var[6] B=in_b_var[6] Y=$abc$2385$new_n427 +.gate AND A=$abc$2385$new_n151 B=$abc$2385$new_n427 Y=$abc$2385$new_n428 +.gate AND A=$abc$2385$new_n426 B=$abc$2385$new_n428 Y=$abc$2385$new_n429 +.gate AND A=$abc$2385$new_n418 B=$abc$2385$new_n429 Y=$abc$2385$new_n430 +.gate AND A=$abc$2385$new_n393 B=$abc$2385$new_n430 Y=$abc$2385$new_n431 +.gate AND A=$abc$2385$new_n392 B=$abc$2385$new_n431 Y=$abc$2385$new_n432 +.gate AND A=$abc$2385$new_n364 B=$abc$2385$new_n432 Y=$abc$2385$new_n433 +.gate AND A=$abc$2385$new_n358 B=$abc$2385$new_n433 Y=$abc$2385$new_n434 +.gate AND A=$abc$2385$new_n332 B=$abc$2385$new_n434 Y=$abc$2385$new_n435 +.gate AND A=$abc$2385$new_n157 B=$abc$2385$new_n435 Y=$abc$2385$new_n436 +.gate XNOR A=$abc$2385$new_n157 B=$abc$2385$new_n435 Y=$abc$2385$new_n437 +.gate ORNOT A=$abc$2385$new_n74 B=:1.test_1[0] Y=$abc$2385$new_n438 +.gate MUX A=:1.test_1[0] B=$abc$2385$new_n437 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[0] +.gate ORNOT A=:1.test_1[1] B=$abc$2385$new_n83 Y=$abc$2385$new_n440 +.gate XNOR A=$abc$2385$new_n320 B=$abc$2385$new_n436 Y=$abc$2385$new_n441 +.gate MUX A=$abc$2385$new_n440 B=$abc$2385$new_n441 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[1] +.gate ORNOT A=:1.test_1[2] B=$abc$2385$new_n83 Y=$abc$2385$new_n443 +.gate ANDNOT A=$abc$2385$new_n308 B=$abc$2385$new_n359 Y=$abc$2385$new_n444 +.gate XNOR A=$abc$2385$new_n308 B=$abc$2385$new_n359 Y=$abc$2385$new_n445 +.gate NAND A=$abc$2385$new_n435 B=$abc$2385$new_n445 Y=$abc$2385$new_n446 +.gate ORNOT A=$abc$2385$new_n435 B=$abc$2385$new_n308 Y=$abc$2385$new_n447 +.gate AND A=$abc$2385$new_n74 B=$abc$2385$new_n446 Y=$abc$2385$new_n448 +.gate NAND A=$abc$2385$new_n447 B=$abc$2385$new_n448 Y=$abc$2385$new_n449 +.gate AND A=$abc$2385$new_n443 B=$abc$2385$new_n449 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[2] +.gate ORNOT A=:1.test_1[3] B=$abc$2385$new_n83 Y=$abc$2385$new_n451 +.gate AND A=$abc$2385$new_n435 B=$abc$2385$new_n444 Y=$abc$2385$new_n452 +.gate AND A=$abc$2385$new_n304 B=$abc$2385$new_n452 Y=$abc$2385$new_n453 +.gate XNOR A=$abc$2385$new_n305 B=$abc$2385$new_n452 Y=$abc$2385$new_n454 +.gate MUX A=$abc$2385$new_n451 B=$abc$2385$new_n454 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[3] +.gate ORNOT A=:1.test_1[4] B=$abc$2385$new_n83 Y=$abc$2385$new_n456 +.gate ORNOT A=$abc$2385$new_n303 B=$abc$2385$new_n453 Y=$abc$2385$new_n457 +.gate XNOR A=$abc$2385$new_n303 B=$abc$2385$new_n453 Y=$abc$2385$new_n458 +.gate MUX A=$abc$2385$new_n456 B=$abc$2385$new_n458 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[4] +.gate ORNOT A=:1.test_1[5] B=$abc$2385$new_n83 Y=$abc$2385$new_n460 +.gate OR A=$abc$2385$new_n302 B=$abc$2385$new_n457 Y=$abc$2385$new_n461 +.gate XOR A=$abc$2385$new_n302 B=$abc$2385$new_n457 Y=$abc$2385$new_n462 +.gate NAND A=$abc$2385$new_n74 B=$abc$2385$new_n462 Y=$abc$2385$new_n463 +.gate NAND A=$abc$2385$new_n460 B=$abc$2385$new_n463 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[5] +.gate NAND A=$abc$2385$new_n299 B=$abc$2385$new_n461 Y=$abc$2385$new_n465 +.gate OR A=$abc$2385$new_n299 B=$abc$2385$new_n461 Y=$abc$2385$new_n466 +.gate AND A=$abc$2385$new_n74 B=$abc$2385$new_n466 Y=$abc$2385$new_n467 +.gate NAND A=$abc$2385$new_n465 B=$abc$2385$new_n467 Y=$abc$2385$new_n468 +.gate MUX A=$abc$2385$new_n73 B=$abc$2385$new_n137 S=$abc$2385$new_n76 Y=$abc$2385$new_n469 +.gate OR A=$abc$2385$new_n74 B=$abc$2385$new_n469 Y=$abc$2385$new_n470 +.gate NAND A=$abc$2385$new_n468 B=$abc$2385$new_n470 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[6] +.gate NAND A=$abc$2385$new_n392 B=$abc$2385$new_n467 Y=$abc$2385$new_n472 +.gate ANDNOT A=$abc$2385$new_n137 B=$abc$2385$new_n76 Y=$abc$2385$new_n473 +.gate XNOR A=$abc$2385$new_n150 B=$abc$2385$new_n473 Y=$abc$2385$new_n474 +.gate AND A=$abc$2385$new_n472 B=$abc$2385$new_n474 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[7] +.gate AND A=$abc$2385$new_n58 B=$abc$2385$new_n438 Y=:38.Y[0] +.gate NAND A=in_a_var[1] B=$abc$2385$new_n74 Y=$abc$2385$new_n477 +.gate NAND A=$abc$2385$new_n84 B=$abc$2385$new_n477 Y=:38.Y[1] +.gate NAND A=in_a_var[2] B=$abc$2385$new_n74 Y=$abc$2385$new_n479 +.gate NAND A=$abc$2385$new_n92 B=$abc$2385$new_n479 Y=:38.Y[2] +.gate NAND A=in_a_var[3] B=$abc$2385$new_n74 Y=$abc$2385$new_n481 +.gate NAND A=$abc$2385$new_n104 B=$abc$2385$new_n481 Y=:38.Y[3] +.gate NAND A=in_a_var[4] B=$abc$2385$new_n74 Y=$abc$2385$new_n483 +.gate NAND A=$abc$2385$new_n116 B=$abc$2385$new_n483 Y=:38.Y[4] +.gate NAND A=in_a_var[5] B=$abc$2385$new_n74 Y=$abc$2385$new_n485 +.gate NAND A=$abc$2385$new_n127 B=$abc$2385$new_n485 Y=:38.Y[5] +.gate NAND A=in_a_var[6] B=$abc$2385$new_n74 Y=$abc$2385$new_n487 +.gate NAND A=$abc$2385$new_n137 B=$abc$2385$new_n487 Y=:38.Y[6] +.gate NAND A=in_a_var[7] B=$abc$2385$new_n74 Y=$abc$2385$new_n489 +.gate NAND A=$abc$2385$new_n150 B=$abc$2385$new_n489 Y=:38.Y[7] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:114:fulladd$252.Y[0] Q=out_var[0] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.P[1] Q=out_var[1] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[2] Q=out_var[2] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[3] Q=out_var[3] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[4] Q=out_var[4] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[5] Q=out_var[5] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[6] Q=out_var[6] +.gate DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[7] Q=out_var[7] +.gate DFF C=clk D=:38.Y[0] Q=:1.test_1[0] +.gate DFF C=clk D=:38.Y[1] Q=:1.test_1[1] +.gate DFF C=clk D=:38.Y[2] Q=:1.test_1[2] +.gate DFF C=clk D=:38.Y[3] Q=:1.test_1[3] +.gate DFF C=clk D=:38.Y[4] Q=:1.test_1[4] +.gate DFF C=clk D=:38.Y[5] Q=:1.test_1[5] +.gate DFF C=clk D=:38.Y[6] Q=:1.test_1[6] +.gate DFF C=clk D=:38.Y[7] Q=:1.test_1[7] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[0] Q=:1.test_2[0] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[1] Q=:1.test_2[1] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[2] Q=:1.test_2[2] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[3] Q=:1.test_2[3] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[4] Q=:1.test_2[4] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[5] Q=:1.test_2[5] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[6] Q=:1.test_2[6] +.gate DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[7] Q=:1.test_2[7] +.gateinit :1.test_2[7]=0 +.gateinit :1.test_2[6]=0 +.gateinit :1.test_2[5]=0 +.gateinit :1.test_2[4]=0 +.gateinit :1.test_2[3]=0 +.gateinit :1.test_2[2]=0 +.gateinit :1.test_2[1]=0 +.gateinit :1.test_2[0]=0 +.gateinit :1.test_1[7]=1 +.gateinit :1.test_1[6]=1 +.gateinit :1.test_1[5]=1 +.gateinit :1.test_1[4]=1 +.gateinit :1.test_1[3]=1 +.gateinit :1.test_1[2]=1 +.gateinit :1.test_1[1]=1 +.gateinit :1.test_1[0]=1 +.end diff --git a/tests/blif/gatesi.blif.ok b/tests/blif/gatesi.blif.ok new file mode 100644 index 000000000..8213a8a89 --- /dev/null +++ b/tests/blif/gatesi.blif.ok @@ -0,0 +1,483 @@ + +.model test +.inputs clk in_a_var[0] in_a_var[1] in_a_var[2] in_a_var[3] in_a_var[4] in_a_var[5] in_a_var[6] in_a_var[7] in_b_var[0] in_b_var[1] in_b_var[2] in_b_var[3] in_b_var[4] in_b_var[5] in_b_var[6] in_b_var[7] +.outputs out_var[0] out_var[1] out_var[2] out_var[3] out_var[4] out_var[5] out_var[6] out_var[7] +.names $false +.names $true +1 +.names $undef +.subckt ORNOT A=:1.test_1[0] B=in_a_var[0] Y=$abc$2385$new_n57 +.subckt NOT A=$abc$2385$new_n65 Y=$abc$2385$new_n66 +.subckt XNOR A=$abc$2385$new_n62 B=$abc$2385$new_n88 Y=$abc$2385$auto$maccmap.cc:240:synth$253.P[1] +.subckt NAND A=:1.test_1[0] B=:1.test_2[0] Y=$abc$2385$new_n157 +.subckt ANDNOT A=:1.test_2[0] B=$abc$2385$new_n91 Y=$abc$2385$new_n158 +.subckt ANDNOT A=:1.test_2[1] B=$abc$2385$new_n64 Y=$abc$2385$new_n159 +.subckt AND A=:1.test_2[1] B=$abc$2385$new_n65 Y=$abc$2385$new_n160 +.subckt ORNOT A=$abc$2385$new_n160 B=:1.test_1[0] Y=$abc$2385$new_n161 +.subckt AND A=:1.test_2[2] B=$abc$2385$new_n161 Y=$abc$2385$new_n162 +.subckt ANDNOT A=:1.test_1[1] B=:1.test_1[0] Y=$abc$2385$new_n163 +.subckt ANDNOT A=:1.test_2[2] B=:1.test_1[0] Y=$abc$2385$new_n164 +.subckt XNOR A=$abc$2385$new_n160 B=$abc$2385$new_n164 Y=$abc$2385$new_n165 +.subckt AND A=:1.test_1[2] B=$abc$2385$new_n64 Y=$abc$2385$new_n67 +.subckt MUX A=$abc$2385$new_n160 B=$abc$2385$new_n165 S=:1.test_2[2] Y=$abc$2385$new_n166 +.subckt ORNOT A=:1.test_2[0] B=:1.test_1[0] Y=$abc$2385$new_n167 +.subckt AND A=$abc$2385$new_n159 B=$abc$2385$new_n167 Y=$abc$2385$new_n168 +.subckt AND A=$abc$2385$new_n166 B=$abc$2385$new_n168 Y=$abc$2385$new_n169 +.subckt XOR A=$abc$2385$new_n166 B=$abc$2385$new_n168 Y=$abc$2385$new_n170 +.subckt AND A=$abc$2385$new_n158 B=$abc$2385$new_n170 Y=$abc$2385$new_n171 +.subckt ANDNOT A=:1.test_2[0] B=$abc$2385$new_n103 Y=$abc$2385$new_n172 +.subckt ANDNOT A=:1.test_2[1] B=$abc$2385$new_n91 Y=$abc$2385$new_n173 +.subckt ANDNOT A=:1.test_2[1] B=$abc$2385$new_n103 Y=$abc$2385$new_n174 +.subckt AND A=$abc$2385$new_n158 B=$abc$2385$new_n174 Y=$abc$2385$new_n175 +.subckt AND A=:1.test_1[3] B=$abc$2385$new_n67 Y=$abc$2385$new_n68 +.subckt XOR A=$abc$2385$new_n172 B=$abc$2385$new_n173 Y=$abc$2385$new_n176 +.subckt NAND A=:1.test_2[2] B=$abc$2385$new_n65 Y=$abc$2385$new_n177 +.subckt AND A=:1.test_1[0] B=:1.test_2[3] Y=$abc$2385$new_n178 +.subckt NAND A=:1.test_1[0] B=$abc$2385$new_n177 Y=$abc$2385$new_n179 +.subckt XNOR A=$abc$2385$new_n177 B=$abc$2385$new_n178 Y=$abc$2385$new_n180 +.subckt NAND A=$abc$2385$new_n162 B=$abc$2385$new_n180 Y=$abc$2385$new_n181 +.subckt XOR A=$abc$2385$new_n162 B=$abc$2385$new_n180 Y=$abc$2385$new_n182 +.subckt NAND A=$abc$2385$new_n176 B=$abc$2385$new_n182 Y=$abc$2385$new_n183 +.subckt XOR A=$abc$2385$new_n176 B=$abc$2385$new_n182 Y=$abc$2385$new_n184 +.subckt NAND A=$abc$2385$new_n171 B=$abc$2385$new_n184 Y=$abc$2385$new_n185 +.subckt AND A=:1.test_1[4] B=$abc$2385$new_n68 Y=$abc$2385$new_n69 +.subckt XOR A=$abc$2385$new_n171 B=$abc$2385$new_n184 Y=$abc$2385$new_n186 +.subckt NAND A=$abc$2385$new_n169 B=$abc$2385$new_n186 Y=$abc$2385$new_n187 +.subckt NAND A=$abc$2385$new_n185 B=$abc$2385$new_n187 Y=$abc$2385$new_n188 +.subckt ANDNOT A=:1.test_2[0] B=$abc$2385$new_n115 Y=$abc$2385$new_n189 +.subckt ANDNOT A=:1.test_2[1] B=$abc$2385$new_n115 Y=$abc$2385$new_n190 +.subckt NAND A=$abc$2385$new_n172 B=$abc$2385$new_n190 Y=$abc$2385$new_n191 +.subckt XOR A=$abc$2385$new_n174 B=$abc$2385$new_n189 Y=$abc$2385$new_n192 +.subckt ANDNOT A=:1.test_2[2] B=$abc$2385$new_n91 Y=$abc$2385$new_n193 +.subckt NAND A=$abc$2385$new_n192 B=$abc$2385$new_n193 Y=$abc$2385$new_n194 +.subckt XOR A=$abc$2385$new_n192 B=$abc$2385$new_n193 Y=$abc$2385$new_n195 +.subckt AND A=:1.test_1[5] B=$abc$2385$new_n69 Y=$abc$2385$new_n70 +.subckt AND A=:1.test_2[3] B=$abc$2385$new_n179 Y=$abc$2385$new_n196 +.subckt NAND A=:1.test_2[3] B=$abc$2385$new_n65 Y=$abc$2385$new_n197 +.subckt NAND A=:1.test_1[0] B=$abc$2385$new_n197 Y=$abc$2385$new_n198 +.subckt AND A=:1.test_2[4] B=$abc$2385$new_n198 Y=$abc$2385$new_n199 +.subckt NAND A=:1.test_2[3] B=$abc$2385$new_n163 Y=$abc$2385$new_n200 +.subckt NAND A=$abc$2385$new_n199 B=$abc$2385$new_n200 Y=$abc$2385$new_n201 +.subckt ORNOT A=:1.test_2[4] B=$abc$2385$new_n197 Y=$abc$2385$new_n202 +.subckt AND A=$abc$2385$new_n201 B=$abc$2385$new_n202 Y=$abc$2385$new_n203 +.subckt NAND A=$abc$2385$new_n175 B=$abc$2385$new_n203 Y=$abc$2385$new_n204 +.subckt XOR A=$abc$2385$new_n175 B=$abc$2385$new_n203 Y=$abc$2385$new_n205 +.subckt AND A=:1.test_1[6] B=$abc$2385$new_n70 Y=$abc$2385$new_n71 +.subckt NAND A=$abc$2385$new_n196 B=$abc$2385$new_n205 Y=$abc$2385$new_n206 +.subckt XOR A=$abc$2385$new_n196 B=$abc$2385$new_n205 Y=$abc$2385$new_n207 +.subckt AND A=$abc$2385$new_n195 B=$abc$2385$new_n207 Y=$abc$2385$new_n208 +.subckt XOR A=$abc$2385$new_n195 B=$abc$2385$new_n207 Y=$abc$2385$new_n209 +.subckt NAND A=$abc$2385$new_n181 B=$abc$2385$new_n183 Y=$abc$2385$new_n210 +.subckt AND A=$abc$2385$new_n209 B=$abc$2385$new_n210 Y=$abc$2385$new_n211 +.subckt XOR A=$abc$2385$new_n209 B=$abc$2385$new_n210 Y=$abc$2385$new_n212 +.subckt AND A=$abc$2385$new_n188 B=$abc$2385$new_n212 Y=$abc$2385$new_n213 +.subckt ANDNOT A=:1.test_2[0] B=$abc$2385$new_n77 Y=$abc$2385$new_n214 +.subckt ANDNOT A=:1.test_2[3] B=$abc$2385$new_n91 Y=$abc$2385$new_n215 +.subckt XNOR A=:1.test_1[6] B=$abc$2385$new_n70 Y=$abc$2385$new_n72 +.subckt ANDNOT A=:1.test_2[2] B=$abc$2385$new_n103 Y=$abc$2385$new_n216 +.subckt ANDNOT A=:1.test_2[2] B=$abc$2385$new_n115 Y=$abc$2385$new_n217 +.subckt NAND A=$abc$2385$new_n174 B=$abc$2385$new_n217 Y=$abc$2385$new_n218 +.subckt XOR A=$abc$2385$new_n190 B=$abc$2385$new_n216 Y=$abc$2385$new_n219 +.subckt NAND A=$abc$2385$new_n215 B=$abc$2385$new_n219 Y=$abc$2385$new_n220 +.subckt XOR A=$abc$2385$new_n215 B=$abc$2385$new_n219 Y=$abc$2385$new_n221 +.subckt AND A=$abc$2385$new_n214 B=$abc$2385$new_n221 Y=$abc$2385$new_n222 +.subckt XOR A=$abc$2385$new_n214 B=$abc$2385$new_n221 Y=$abc$2385$new_n223 +.subckt NAND A=:1.test_2[4] B=$abc$2385$new_n65 Y=$abc$2385$new_n224 +.subckt NAND A=:1.test_1[0] B=$abc$2385$new_n224 Y=$abc$2385$new_n225 +.subckt NOT A=$abc$2385$new_n72 Y=$abc$2385$new_n73 +.subckt AND A=:1.test_2[5] B=$abc$2385$new_n225 Y=$abc$2385$new_n226 +.subckt NAND A=:1.test_2[4] B=$abc$2385$new_n163 Y=$abc$2385$new_n227 +.subckt NAND A=$abc$2385$new_n226 B=$abc$2385$new_n227 Y=$abc$2385$new_n228 +.subckt ORNOT A=:1.test_2[5] B=$abc$2385$new_n224 Y=$abc$2385$new_n229 +.subckt AND A=$abc$2385$new_n228 B=$abc$2385$new_n229 Y=$abc$2385$new_n230 +.subckt NAND A=$abc$2385$new_n191 B=$abc$2385$new_n194 Y=$abc$2385$new_n231 +.subckt NAND A=$abc$2385$new_n230 B=$abc$2385$new_n231 Y=$abc$2385$new_n232 +.subckt XOR A=$abc$2385$new_n230 B=$abc$2385$new_n231 Y=$abc$2385$new_n233 +.subckt NAND A=$abc$2385$new_n199 B=$abc$2385$new_n233 Y=$abc$2385$new_n234 +.subckt XOR A=$abc$2385$new_n199 B=$abc$2385$new_n233 Y=$abc$2385$new_n235 +.subckt AND A=:1.test_1[7] B=$abc$2385$new_n71 Y=$abc$2385$new_n74 +.subckt AND A=$abc$2385$new_n223 B=$abc$2385$new_n235 Y=$abc$2385$new_n236 +.subckt XOR A=$abc$2385$new_n223 B=$abc$2385$new_n235 Y=$abc$2385$new_n237 +.subckt NAND A=$abc$2385$new_n208 B=$abc$2385$new_n237 Y=$abc$2385$new_n238 +.subckt XOR A=$abc$2385$new_n208 B=$abc$2385$new_n237 Y=$abc$2385$new_n239 +.subckt NAND A=$abc$2385$new_n204 B=$abc$2385$new_n206 Y=$abc$2385$new_n240 +.subckt NAND A=$abc$2385$new_n239 B=$abc$2385$new_n240 Y=$abc$2385$new_n241 +.subckt XOR A=$abc$2385$new_n239 B=$abc$2385$new_n240 Y=$abc$2385$new_n242 +.subckt AND A=$abc$2385$new_n211 B=$abc$2385$new_n242 Y=$abc$2385$new_n243 +.subckt XOR A=$abc$2385$new_n211 B=$abc$2385$new_n242 Y=$abc$2385$new_n244 +.subckt NAND A=$abc$2385$new_n213 B=$abc$2385$new_n244 Y=$abc$2385$new_n245 +.subckt XNOR A=:1.test_1[7] B=$abc$2385$new_n71 Y=$abc$2385$new_n75 +.subckt AND A=:1.test_2[0] B=$abc$2385$new_n163 Y=$abc$2385$new_n246 +.subckt NAND A=:1.test_2[0] B=$abc$2385$new_n163 Y=$abc$2385$new_n247 +.subckt XOR A=$abc$2385$new_n158 B=$abc$2385$new_n170 Y=$abc$2385$new_n248 +.subckt AND A=$abc$2385$new_n246 B=$abc$2385$new_n248 Y=$abc$2385$new_n249 +.subckt XOR A=$abc$2385$new_n169 B=$abc$2385$new_n186 Y=$abc$2385$new_n250 +.subckt AND A=$abc$2385$new_n249 B=$abc$2385$new_n250 Y=$abc$2385$new_n251 +.subckt XOR A=$abc$2385$new_n188 B=$abc$2385$new_n212 Y=$abc$2385$new_n252 +.subckt AND A=$abc$2385$new_n251 B=$abc$2385$new_n252 Y=$abc$2385$new_n253 +.subckt NAND A=$abc$2385$new_n244 B=$abc$2385$new_n253 Y=$abc$2385$new_n254 +.subckt XNOR A=$abc$2385$new_n213 B=$abc$2385$new_n244 Y=$abc$2385$new_n255 +.subckt ORNOT A=in_a_var[0] B=:1.test_1[0] Y=$abc$2385$new_n58 +.subckt ANDNOT A=:1.test_1[5] B=$abc$2385$new_n69 Y=$abc$2385$new_n76 +.subckt NAND A=$abc$2385$new_n245 B=$abc$2385$new_n254 Y=$abc$2385$new_n256 +.subckt NAND A=$abc$2385$new_n238 B=$abc$2385$new_n241 Y=$abc$2385$new_n257 +.subckt ANDNOT A=:1.test_2[0] B=$abc$2385$new_n72 Y=$abc$2385$new_n258 +.subckt ORNOT A=$abc$2385$new_n77 B=:1.test_2[1] Y=$abc$2385$new_n259 +.subckt ANDNOT A=:1.test_2[1] B=$abc$2385$new_n72 Y=$abc$2385$new_n260 +.subckt NAND A=$abc$2385$new_n214 B=$abc$2385$new_n260 Y=$abc$2385$new_n261 +.subckt XNOR A=$abc$2385$new_n258 B=$abc$2385$new_n259 Y=$abc$2385$new_n262 +.subckt ANDNOT A=:1.test_2[4] B=$abc$2385$new_n91 Y=$abc$2385$new_n263 +.subckt ANDNOT A=:1.test_2[3] B=$abc$2385$new_n103 Y=$abc$2385$new_n264 +.subckt ANDNOT A=:1.test_2[3] B=$abc$2385$new_n115 Y=$abc$2385$new_n265 +.subckt XNOR A=:1.test_1[5] B=$abc$2385$new_n69 Y=$abc$2385$new_n77 +.subckt NAND A=$abc$2385$new_n216 B=$abc$2385$new_n265 Y=$abc$2385$new_n266 +.subckt XOR A=$abc$2385$new_n217 B=$abc$2385$new_n264 Y=$abc$2385$new_n267 +.subckt NAND A=$abc$2385$new_n263 B=$abc$2385$new_n267 Y=$abc$2385$new_n268 +.subckt XOR A=$abc$2385$new_n263 B=$abc$2385$new_n267 Y=$abc$2385$new_n269 +.subckt AND A=$abc$2385$new_n262 B=$abc$2385$new_n269 Y=$abc$2385$new_n270 +.subckt XOR A=$abc$2385$new_n262 B=$abc$2385$new_n269 Y=$abc$2385$new_n271 +.subckt NAND A=$abc$2385$new_n222 B=$abc$2385$new_n271 Y=$abc$2385$new_n272 +.subckt XOR A=$abc$2385$new_n222 B=$abc$2385$new_n271 Y=$abc$2385$new_n273 +.subckt NAND A=:1.test_2[5] B=$abc$2385$new_n65 Y=$abc$2385$new_n274 +.subckt NAND A=:1.test_1[0] B=$abc$2385$new_n274 Y=$abc$2385$new_n275 +.subckt NOR A=:1.test_1[3] B=:1.test_1[4] Y=$abc$2385$new_n78 +.subckt AND A=:1.test_2[6] B=$abc$2385$new_n275 Y=$abc$2385$new_n276 +.subckt NAND A=:1.test_2[5] B=$abc$2385$new_n163 Y=$abc$2385$new_n277 +.subckt NAND A=:1.test_2[6] B=$abc$2385$new_n65 Y=$abc$2385$new_n278 +.subckt NAND A=$abc$2385$new_n276 B=$abc$2385$new_n277 Y=$abc$2385$new_n279 +.subckt ORNOT A=:1.test_2[6] B=$abc$2385$new_n274 Y=$abc$2385$new_n280 +.subckt AND A=$abc$2385$new_n279 B=$abc$2385$new_n280 Y=$abc$2385$new_n281 +.subckt NAND A=$abc$2385$new_n218 B=$abc$2385$new_n220 Y=$abc$2385$new_n282 +.subckt NAND A=$abc$2385$new_n281 B=$abc$2385$new_n282 Y=$abc$2385$new_n283 +.subckt XOR A=$abc$2385$new_n281 B=$abc$2385$new_n282 Y=$abc$2385$new_n284 +.subckt NAND A=$abc$2385$new_n226 B=$abc$2385$new_n284 Y=$abc$2385$new_n285 +.subckt AND A=$abc$2385$new_n63 B=$abc$2385$new_n78 Y=$abc$2385$new_n79 +.subckt XOR A=$abc$2385$new_n226 B=$abc$2385$new_n284 Y=$abc$2385$new_n286 +.subckt NAND A=$abc$2385$new_n273 B=$abc$2385$new_n286 Y=$abc$2385$new_n287 +.subckt XOR A=$abc$2385$new_n273 B=$abc$2385$new_n286 Y=$abc$2385$new_n288 +.subckt NAND A=$abc$2385$new_n236 B=$abc$2385$new_n288 Y=$abc$2385$new_n289 +.subckt XOR A=$abc$2385$new_n236 B=$abc$2385$new_n288 Y=$abc$2385$new_n290 +.subckt NAND A=$abc$2385$new_n232 B=$abc$2385$new_n234 Y=$abc$2385$new_n291 +.subckt NAND A=$abc$2385$new_n290 B=$abc$2385$new_n291 Y=$abc$2385$new_n292 +.subckt XOR A=$abc$2385$new_n290 B=$abc$2385$new_n291 Y=$abc$2385$new_n293 +.subckt NAND A=$abc$2385$new_n257 B=$abc$2385$new_n293 Y=$abc$2385$new_n294 +.subckt XOR A=$abc$2385$new_n257 B=$abc$2385$new_n293 Y=$abc$2385$new_n295 +.subckt ANDNOT A=$abc$2385$new_n79 B=:1.test_1[2] Y=$abc$2385$new_n80 +.subckt NAND A=$abc$2385$new_n243 B=$abc$2385$new_n295 Y=$abc$2385$new_n296 +.subckt XOR A=$abc$2385$new_n243 B=$abc$2385$new_n295 Y=$abc$2385$new_n297 +.subckt NAND A=$abc$2385$new_n256 B=$abc$2385$new_n297 Y=$abc$2385$new_n298 +.subckt XNOR A=$abc$2385$new_n256 B=$abc$2385$new_n297 Y=$abc$2385$new_n299 +.subckt NAND A=$abc$2385$new_n73 B=$abc$2385$new_n299 Y=$abc$2385$new_n300 +.subckt OR A=$abc$2385$new_n73 B=$abc$2385$new_n299 Y=$abc$2385$new_n301 +.subckt XOR A=$abc$2385$new_n253 B=$abc$2385$new_n255 Y=$abc$2385$new_n302 +.subckt XNOR A=$abc$2385$new_n251 B=$abc$2385$new_n252 Y=$abc$2385$new_n303 +.subckt XOR A=$abc$2385$new_n249 B=$abc$2385$new_n250 Y=$abc$2385$new_n304 +.subckt XNOR A=$abc$2385$new_n249 B=$abc$2385$new_n250 Y=$abc$2385$new_n305 +.subckt AND A=$abc$2385$new_n77 B=$abc$2385$new_n80 Y=$abc$2385$new_n81 +.subckt NAND A=$abc$2385$new_n103 B=$abc$2385$new_n304 Y=$abc$2385$new_n306 +.subckt OR A=$abc$2385$new_n103 B=$abc$2385$new_n304 Y=$abc$2385$new_n307 +.subckt XNOR A=$abc$2385$new_n247 B=$abc$2385$new_n248 Y=$abc$2385$new_n308 +.subckt NAND A=:1.test_1[0] B=:1.test_2[1] Y=$abc$2385$new_n309 +.subckt ANDNOT A=:1.test_2[0] B=$abc$2385$new_n64 Y=$abc$2385$new_n310 +.subckt XNOR A=$abc$2385$new_n309 B=$abc$2385$new_n310 Y=$abc$2385$new_n311 +.subckt NAND A=$abc$2385$new_n66 B=$abc$2385$new_n311 Y=$abc$2385$new_n312 +.subckt OR A=:1.test_2[1] B=$abc$2385$new_n157 Y=$abc$2385$new_n313 +.subckt NAND A=$abc$2385$new_n312 B=$abc$2385$new_n313 Y=$abc$2385$new_n314 +.subckt OR A=$abc$2385$new_n308 B=$abc$2385$new_n314 Y=$abc$2385$new_n315 +.subckt NAND A=$abc$2385$new_n75 B=$abc$2385$new_n81 Y=$abc$2385$new_n82 +.subckt NAND A=$abc$2385$new_n91 B=$abc$2385$new_n315 Y=$abc$2385$new_n316 +.subckt NAND A=$abc$2385$new_n308 B=$abc$2385$new_n314 Y=$abc$2385$new_n317 +.subckt NAND A=$abc$2385$new_n316 B=$abc$2385$new_n317 Y=$abc$2385$new_n318 +.subckt NAND A=$abc$2385$new_n307 B=$abc$2385$new_n318 Y=$abc$2385$new_n319 +.subckt NAND A=$abc$2385$new_n247 B=$abc$2385$new_n311 Y=$abc$2385$new_n320 +.subckt NAND A=$abc$2385$new_n306 B=$abc$2385$new_n319 Y=$abc$2385$new_n321 +.subckt ORNOT A=$abc$2385$new_n115 B=$abc$2385$new_n303 Y=$abc$2385$new_n322 +.subckt ORNOT A=$abc$2385$new_n303 B=$abc$2385$new_n115 Y=$abc$2385$new_n323 +.subckt NAND A=$abc$2385$new_n321 B=$abc$2385$new_n322 Y=$abc$2385$new_n324 +.subckt NAND A=$abc$2385$new_n323 B=$abc$2385$new_n324 Y=$abc$2385$new_n325 +.subckt OR A=$abc$2385$new_n73 B=$abc$2385$new_n82 Y=$abc$2385$new_n83 +.subckt NAND A=$abc$2385$new_n77 B=$abc$2385$new_n325 Y=$abc$2385$new_n326 +.subckt NAND A=$abc$2385$new_n302 B=$abc$2385$new_n326 Y=$abc$2385$new_n327 +.subckt OR A=$abc$2385$new_n77 B=$abc$2385$new_n325 Y=$abc$2385$new_n328 +.subckt AND A=$abc$2385$new_n327 B=$abc$2385$new_n328 Y=$abc$2385$new_n329 +.subckt NAND A=$abc$2385$new_n300 B=$abc$2385$new_n329 Y=$abc$2385$new_n330 +.subckt AND A=$abc$2385$new_n301 B=$abc$2385$new_n330 Y=$abc$2385$new_n331 +.subckt NAND A=$abc$2385$new_n75 B=$abc$2385$new_n331 Y=$abc$2385$new_n332 +.subckt OR A=in_b_var[5] B=$abc$2385$new_n302 Y=$abc$2385$new_n333 +.subckt NAND A=in_b_var[4] B=$abc$2385$new_n303 Y=$abc$2385$new_n334 +.subckt OR A=in_b_var[4] B=$abc$2385$new_n303 Y=$abc$2385$new_n335 +.subckt AND A=$abc$2385$new_n66 B=$abc$2385$new_n83 Y=$abc$2385$new_n84 +.subckt AND A=in_b_var[1] B=$abc$2385$new_n320 Y=$abc$2385$new_n336 +.subckt OR A=in_b_var[3] B=$abc$2385$new_n305 Y=$abc$2385$new_n337 +.subckt ANDNOT A=in_b_var[2] B=$abc$2385$new_n308 Y=$abc$2385$new_n338 +.subckt XNOR A=in_b_var[2] B=$abc$2385$new_n308 Y=$abc$2385$new_n339 +.subckt NAND A=in_b_var[3] B=$abc$2385$new_n305 Y=$abc$2385$new_n340 +.subckt XNOR A=in_b_var[3] B=$abc$2385$new_n304 Y=$abc$2385$new_n341 +.subckt AND A=$abc$2385$new_n339 B=$abc$2385$new_n341 Y=$abc$2385$new_n342 +.subckt NAND A=$abc$2385$new_n336 B=$abc$2385$new_n342 Y=$abc$2385$new_n343 +.subckt NAND A=$abc$2385$new_n337 B=$abc$2385$new_n338 Y=$abc$2385$new_n344 +.subckt AND A=$abc$2385$new_n340 B=$abc$2385$new_n344 Y=$abc$2385$new_n345 +.subckt ORNOT A=$abc$2385$new_n84 B=in_a_var[1] Y=$abc$2385$new_n85 +.subckt AND A=$abc$2385$new_n343 B=$abc$2385$new_n345 Y=$abc$2385$new_n346 +.subckt AND A=in_b_var[0] B=$abc$2385$new_n157 Y=$abc$2385$new_n347 +.subckt XOR A=in_b_var[1] B=$abc$2385$new_n320 Y=$abc$2385$new_n348 +.subckt AND A=$abc$2385$new_n342 B=$abc$2385$new_n348 Y=$abc$2385$new_n349 +.subckt NAND A=$abc$2385$new_n347 B=$abc$2385$new_n349 Y=$abc$2385$new_n350 +.subckt NAND A=$abc$2385$new_n346 B=$abc$2385$new_n350 Y=$abc$2385$new_n351 +.subckt NAND A=$abc$2385$new_n335 B=$abc$2385$new_n351 Y=$abc$2385$new_n352 +.subckt NAND A=$abc$2385$new_n334 B=$abc$2385$new_n352 Y=$abc$2385$new_n353 +.subckt NAND A=$abc$2385$new_n333 B=$abc$2385$new_n353 Y=$abc$2385$new_n354 +.subckt NAND A=in_b_var[6] B=$abc$2385$new_n299 Y=$abc$2385$new_n355 +.subckt XNOR A=:1.test_1[0] B=in_a_var[0] Y=$abc$2385$new_n59 +.subckt XNOR A=in_a_var[1] B=$abc$2385$new_n84 Y=$abc$2385$new_n86 +.subckt NAND A=in_b_var[5] B=$abc$2385$new_n302 Y=$abc$2385$new_n356 +.subckt AND A=$abc$2385$new_n355 B=$abc$2385$new_n356 Y=$abc$2385$new_n357 +.subckt NAND A=$abc$2385$new_n354 B=$abc$2385$new_n357 Y=$abc$2385$new_n358 +.subckt AND A=$abc$2385$new_n157 B=$abc$2385$new_n320 Y=$abc$2385$new_n359 +.subckt ANDNOT A=$abc$2385$new_n359 B=$abc$2385$new_n308 Y=$abc$2385$new_n360 +.subckt AND A=$abc$2385$new_n305 B=$abc$2385$new_n360 Y=$abc$2385$new_n361 +.subckt AND A=$abc$2385$new_n303 B=$abc$2385$new_n361 Y=$abc$2385$new_n362 +.subckt AND A=$abc$2385$new_n302 B=$abc$2385$new_n362 Y=$abc$2385$new_n363 +.subckt NAND A=$abc$2385$new_n299 B=$abc$2385$new_n363 Y=$abc$2385$new_n364 +.subckt AND A=$abc$2385$new_n296 B=$abc$2385$new_n298 Y=$abc$2385$new_n365 +.subckt NAND A=in_b_var[1] B=$abc$2385$new_n86 Y=$abc$2385$new_n87 +.subckt AND A=$abc$2385$new_n289 B=$abc$2385$new_n292 Y=$abc$2385$new_n366 +.subckt OR A=:1.test_2[0] B=$abc$2385$new_n75 Y=$abc$2385$new_n367 +.subckt AND A=$abc$2385$new_n261 B=$abc$2385$new_n367 Y=$abc$2385$new_n368 +.subckt XNOR A=$abc$2385$new_n270 B=$abc$2385$new_n368 Y=$abc$2385$new_n369 +.subckt XNOR A=$abc$2385$new_n276 B=$abc$2385$new_n369 Y=$abc$2385$new_n370 +.subckt ANDNOT A=:1.test_2[2] B=$abc$2385$new_n77 Y=$abc$2385$new_n371 +.subckt ANDNOT A=:1.test_2[5] B=$abc$2385$new_n91 Y=$abc$2385$new_n372 +.subckt ANDNOT A=:1.test_2[4] B=$abc$2385$new_n103 Y=$abc$2385$new_n373 +.subckt XNOR A=$abc$2385$new_n372 B=$abc$2385$new_n373 Y=$abc$2385$new_n374 +.subckt XNOR A=$abc$2385$new_n371 B=$abc$2385$new_n374 Y=$abc$2385$new_n375 +.subckt XNOR A=in_b_var[1] B=$abc$2385$new_n86 Y=$abc$2385$new_n88 +.subckt XOR A=$abc$2385$new_n260 B=$abc$2385$new_n265 Y=$abc$2385$new_n376 +.subckt XNOR A=$abc$2385$new_n375 B=$abc$2385$new_n376 Y=$abc$2385$new_n377 +.subckt NAND A=$abc$2385$new_n266 B=$abc$2385$new_n268 Y=$abc$2385$new_n378 +.subckt ANDNOT A=:1.test_2[7] B=:1.test_1[0] Y=$abc$2385$new_n379 +.subckt XNOR A=$abc$2385$new_n278 B=$abc$2385$new_n379 Y=$abc$2385$new_n380 +.subckt XNOR A=$abc$2385$new_n75 B=$abc$2385$new_n380 Y=$abc$2385$new_n381 +.subckt XNOR A=$abc$2385$new_n378 B=$abc$2385$new_n381 Y=$abc$2385$new_n382 +.subckt XNOR A=$abc$2385$new_n377 B=$abc$2385$new_n382 Y=$abc$2385$new_n383 +.subckt XNOR A=$abc$2385$new_n370 B=$abc$2385$new_n383 Y=$abc$2385$new_n384 +.subckt NAND A=$abc$2385$new_n283 B=$abc$2385$new_n285 Y=$abc$2385$new_n385 +.subckt ANDNOT A=$abc$2385$new_n62 B=$abc$2385$new_n88 Y=$abc$2385$new_n89 +.subckt AND A=$abc$2385$new_n272 B=$abc$2385$new_n287 Y=$abc$2385$new_n386 +.subckt XNOR A=$abc$2385$new_n385 B=$abc$2385$new_n386 Y=$abc$2385$new_n387 +.subckt XNOR A=$abc$2385$new_n384 B=$abc$2385$new_n387 Y=$abc$2385$new_n388 +.subckt XNOR A=$abc$2385$new_n366 B=$abc$2385$new_n388 Y=$abc$2385$new_n389 +.subckt XNOR A=:1.test_2[7] B=$abc$2385$new_n294 Y=$abc$2385$new_n390 +.subckt XNOR A=$abc$2385$new_n389 B=$abc$2385$new_n390 Y=$abc$2385$new_n391 +.subckt XNOR A=$abc$2385$new_n365 B=$abc$2385$new_n391 Y=$abc$2385$new_n392 +.subckt OR A=in_b_var[6] B=$abc$2385$new_n299 Y=$abc$2385$new_n393 +.subckt ORNOT A=in_b_var[6] B=in_a_var[6] Y=$abc$2385$new_n394 +.subckt ORNOT A=in_a_var[5] B=in_b_var[5] Y=$abc$2385$new_n395 +.subckt AND A=$abc$2385$new_n85 B=$abc$2385$new_n87 Y=$abc$2385$new_n90 +.subckt ORNOT A=in_b_var[5] B=in_a_var[5] Y=$abc$2385$new_n396 +.subckt ORNOT A=in_b_var[4] B=in_a_var[4] Y=$abc$2385$new_n397 +.subckt AND A=$abc$2385$new_n396 B=$abc$2385$new_n397 Y=$abc$2385$new_n398 +.subckt ORNOT A=in_b_var[2] B=in_a_var[2] Y=$abc$2385$new_n399 +.subckt ORNOT A=in_b_var[3] B=in_a_var[3] Y=$abc$2385$new_n400 +.subckt NAND A=$abc$2385$new_n399 B=$abc$2385$new_n400 Y=$abc$2385$new_n401 +.subckt ORNOT A=in_a_var[3] B=in_b_var[3] Y=$abc$2385$new_n402 +.subckt NAND A=$abc$2385$new_n401 B=$abc$2385$new_n402 Y=$abc$2385$new_n403 +.subckt ORNOT A=in_a_var[2] B=in_b_var[2] Y=$abc$2385$new_n404 +.subckt NAND A=$abc$2385$new_n402 B=$abc$2385$new_n404 Y=$abc$2385$new_n405 +.subckt XNOR A=:1.test_1[2] B=$abc$2385$new_n64 Y=$abc$2385$new_n91 +.subckt NOR A=$abc$2385$new_n401 B=$abc$2385$new_n405 Y=$abc$2385$new_n406 +.subckt ORNOT A=in_a_var[0] B=in_b_var[0] Y=$abc$2385$new_n407 +.subckt ORNOT A=in_a_var[1] B=in_b_var[1] Y=$abc$2385$new_n408 +.subckt NAND A=$abc$2385$new_n407 B=$abc$2385$new_n408 Y=$abc$2385$new_n409 +.subckt ORNOT A=in_b_var[1] B=in_a_var[1] Y=$abc$2385$new_n410 +.subckt NAND A=$abc$2385$new_n409 B=$abc$2385$new_n410 Y=$abc$2385$new_n411 +.subckt NAND A=$abc$2385$new_n406 B=$abc$2385$new_n411 Y=$abc$2385$new_n412 +.subckt NAND A=$abc$2385$new_n403 B=$abc$2385$new_n412 Y=$abc$2385$new_n413 +.subckt ORNOT A=in_a_var[4] B=in_b_var[4] Y=$abc$2385$new_n414 +.subckt NAND A=$abc$2385$new_n413 B=$abc$2385$new_n414 Y=$abc$2385$new_n415 +.subckt AND A=$abc$2385$new_n83 B=$abc$2385$new_n91 Y=$abc$2385$new_n92 +.subckt NAND A=$abc$2385$new_n398 B=$abc$2385$new_n415 Y=$abc$2385$new_n416 +.subckt NAND A=$abc$2385$new_n395 B=$abc$2385$new_n416 Y=$abc$2385$new_n417 +.subckt NAND A=$abc$2385$new_n394 B=$abc$2385$new_n417 Y=$abc$2385$new_n418 +.subckt NAND A=$abc$2385$new_n394 B=$abc$2385$new_n395 Y=$abc$2385$new_n419 +.subckt NOR A=$abc$2385$new_n409 B=$abc$2385$new_n419 Y=$abc$2385$new_n420 +.subckt AND A=$abc$2385$new_n398 B=$abc$2385$new_n420 Y=$abc$2385$new_n421 +.subckt ORNOT A=in_b_var[0] B=in_a_var[0] Y=$abc$2385$new_n422 +.subckt AND A=$abc$2385$new_n410 B=$abc$2385$new_n414 Y=$abc$2385$new_n423 +.subckt AND A=$abc$2385$new_n422 B=$abc$2385$new_n423 Y=$abc$2385$new_n424 +.subckt AND A=$abc$2385$new_n406 B=$abc$2385$new_n424 Y=$abc$2385$new_n425 +.subckt ORNOT A=$abc$2385$new_n92 B=in_a_var[2] Y=$abc$2385$new_n93 +.subckt NAND A=$abc$2385$new_n421 B=$abc$2385$new_n425 Y=$abc$2385$new_n426 +.subckt ORNOT A=in_a_var[6] B=in_b_var[6] Y=$abc$2385$new_n427 +.subckt AND A=$abc$2385$new_n151 B=$abc$2385$new_n427 Y=$abc$2385$new_n428 +.subckt AND A=$abc$2385$new_n426 B=$abc$2385$new_n428 Y=$abc$2385$new_n429 +.subckt AND A=$abc$2385$new_n418 B=$abc$2385$new_n429 Y=$abc$2385$new_n430 +.subckt AND A=$abc$2385$new_n393 B=$abc$2385$new_n430 Y=$abc$2385$new_n431 +.subckt AND A=$abc$2385$new_n392 B=$abc$2385$new_n431 Y=$abc$2385$new_n432 +.subckt AND A=$abc$2385$new_n364 B=$abc$2385$new_n432 Y=$abc$2385$new_n433 +.subckt AND A=$abc$2385$new_n358 B=$abc$2385$new_n433 Y=$abc$2385$new_n434 +.subckt AND A=$abc$2385$new_n332 B=$abc$2385$new_n434 Y=$abc$2385$new_n435 +.subckt XNOR A=in_a_var[2] B=$abc$2385$new_n92 Y=$abc$2385$new_n94 +.subckt AND A=$abc$2385$new_n157 B=$abc$2385$new_n435 Y=$abc$2385$new_n436 +.subckt XNOR A=$abc$2385$new_n157 B=$abc$2385$new_n435 Y=$abc$2385$new_n437 +.subckt ORNOT A=$abc$2385$new_n74 B=:1.test_1[0] Y=$abc$2385$new_n438 +.subckt MUX A=:1.test_1[0] B=$abc$2385$new_n437 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[0] +.subckt ORNOT A=:1.test_1[1] B=$abc$2385$new_n83 Y=$abc$2385$new_n440 +.subckt XNOR A=$abc$2385$new_n320 B=$abc$2385$new_n436 Y=$abc$2385$new_n441 +.subckt MUX A=$abc$2385$new_n440 B=$abc$2385$new_n441 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[1] +.subckt ORNOT A=:1.test_1[2] B=$abc$2385$new_n83 Y=$abc$2385$new_n443 +.subckt ANDNOT A=$abc$2385$new_n308 B=$abc$2385$new_n359 Y=$abc$2385$new_n444 +.subckt XNOR A=$abc$2385$new_n308 B=$abc$2385$new_n359 Y=$abc$2385$new_n445 +.subckt NAND A=in_b_var[2] B=$abc$2385$new_n94 Y=$abc$2385$new_n95 +.subckt NAND A=$abc$2385$new_n435 B=$abc$2385$new_n445 Y=$abc$2385$new_n446 +.subckt ORNOT A=$abc$2385$new_n435 B=$abc$2385$new_n308 Y=$abc$2385$new_n447 +.subckt AND A=$abc$2385$new_n74 B=$abc$2385$new_n446 Y=$abc$2385$new_n448 +.subckt NAND A=$abc$2385$new_n447 B=$abc$2385$new_n448 Y=$abc$2385$new_n449 +.subckt AND A=$abc$2385$new_n443 B=$abc$2385$new_n449 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[2] +.subckt ORNOT A=:1.test_1[3] B=$abc$2385$new_n83 Y=$abc$2385$new_n451 +.subckt AND A=$abc$2385$new_n435 B=$abc$2385$new_n444 Y=$abc$2385$new_n452 +.subckt AND A=$abc$2385$new_n304 B=$abc$2385$new_n452 Y=$abc$2385$new_n453 +.subckt XNOR A=$abc$2385$new_n305 B=$abc$2385$new_n452 Y=$abc$2385$new_n454 +.subckt MUX A=$abc$2385$new_n451 B=$abc$2385$new_n454 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[3] +.subckt NAND A=in_b_var[0] B=$abc$2385$new_n59 Y=$abc$2385$new_n60 +.subckt XNOR A=in_b_var[2] B=$abc$2385$new_n94 Y=$abc$2385$new_n96 +.subckt ORNOT A=:1.test_1[4] B=$abc$2385$new_n83 Y=$abc$2385$new_n456 +.subckt ORNOT A=$abc$2385$new_n303 B=$abc$2385$new_n453 Y=$abc$2385$new_n457 +.subckt XNOR A=$abc$2385$new_n303 B=$abc$2385$new_n453 Y=$abc$2385$new_n458 +.subckt MUX A=$abc$2385$new_n456 B=$abc$2385$new_n458 S=$abc$2385$new_n74 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[4] +.subckt ORNOT A=:1.test_1[5] B=$abc$2385$new_n83 Y=$abc$2385$new_n460 +.subckt OR A=$abc$2385$new_n302 B=$abc$2385$new_n457 Y=$abc$2385$new_n461 +.subckt XOR A=$abc$2385$new_n302 B=$abc$2385$new_n457 Y=$abc$2385$new_n462 +.subckt NAND A=$abc$2385$new_n74 B=$abc$2385$new_n462 Y=$abc$2385$new_n463 +.subckt NAND A=$abc$2385$new_n460 B=$abc$2385$new_n463 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[5] +.subckt NAND A=$abc$2385$new_n299 B=$abc$2385$new_n461 Y=$abc$2385$new_n465 +.subckt OR A=$abc$2385$new_n90 B=$abc$2385$new_n96 Y=$abc$2385$new_n97 +.subckt OR A=$abc$2385$new_n299 B=$abc$2385$new_n461 Y=$abc$2385$new_n466 +.subckt AND A=$abc$2385$new_n74 B=$abc$2385$new_n466 Y=$abc$2385$new_n467 +.subckt NAND A=$abc$2385$new_n465 B=$abc$2385$new_n467 Y=$abc$2385$new_n468 +.subckt MUX A=$abc$2385$new_n73 B=$abc$2385$new_n137 S=$abc$2385$new_n76 Y=$abc$2385$new_n469 +.subckt OR A=$abc$2385$new_n74 B=$abc$2385$new_n469 Y=$abc$2385$new_n470 +.subckt NAND A=$abc$2385$new_n468 B=$abc$2385$new_n470 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[6] +.subckt NAND A=$abc$2385$new_n392 B=$abc$2385$new_n467 Y=$abc$2385$new_n472 +.subckt ANDNOT A=$abc$2385$new_n137 B=$abc$2385$new_n76 Y=$abc$2385$new_n473 +.subckt XNOR A=$abc$2385$new_n150 B=$abc$2385$new_n473 Y=$abc$2385$new_n474 +.subckt AND A=$abc$2385$new_n472 B=$abc$2385$new_n474 Y=$abc$1802$auto$ghdl.cc:825:import_module$22[7] +.subckt XOR A=$abc$2385$new_n90 B=$abc$2385$new_n96 Y=$abc$2385$new_n98 +.subckt AND A=$abc$2385$new_n58 B=$abc$2385$new_n438 Y=:38.Y[0] +.subckt NAND A=in_a_var[1] B=$abc$2385$new_n74 Y=$abc$2385$new_n477 +.subckt NAND A=$abc$2385$new_n84 B=$abc$2385$new_n477 Y=:38.Y[1] +.subckt NAND A=in_a_var[2] B=$abc$2385$new_n74 Y=$abc$2385$new_n479 +.subckt NAND A=$abc$2385$new_n92 B=$abc$2385$new_n479 Y=:38.Y[2] +.subckt NAND A=in_a_var[3] B=$abc$2385$new_n74 Y=$abc$2385$new_n481 +.subckt NAND A=$abc$2385$new_n104 B=$abc$2385$new_n481 Y=:38.Y[3] +.subckt NAND A=in_a_var[4] B=$abc$2385$new_n74 Y=$abc$2385$new_n483 +.subckt NAND A=$abc$2385$new_n116 B=$abc$2385$new_n483 Y=:38.Y[4] +.subckt NAND A=in_a_var[5] B=$abc$2385$new_n74 Y=$abc$2385$new_n485 +.subckt NAND A=$abc$2385$new_n89 B=$abc$2385$new_n98 Y=$abc$2385$new_n99 +.subckt NAND A=$abc$2385$new_n127 B=$abc$2385$new_n485 Y=:38.Y[5] +.subckt NAND A=in_a_var[6] B=$abc$2385$new_n74 Y=$abc$2385$new_n487 +.subckt NAND A=$abc$2385$new_n137 B=$abc$2385$new_n487 Y=:38.Y[6] +.subckt NAND A=in_a_var[7] B=$abc$2385$new_n74 Y=$abc$2385$new_n489 +.subckt NAND A=$abc$2385$new_n150 B=$abc$2385$new_n489 Y=:38.Y[7] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:114:fulladd$252.Y[0] Q=out_var[0] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.P[1] Q=out_var[1] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[2] Q=out_var[2] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[3] Q=out_var[3] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[4] Q=out_var[4] +.subckt XOR A=$abc$2385$new_n89 B=$abc$2385$new_n98 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[2] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[5] Q=out_var[5] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[6] Q=out_var[6] +.subckt DFF C=clk D=$abc$2385$auto$maccmap.cc:240:synth$253.Y[7] Q=out_var[7] +.subckt DFF C=clk D=:38.Y[0] Q=:1.test_1[0] +.subckt DFF C=clk D=:38.Y[1] Q=:1.test_1[1] +.subckt DFF C=clk D=:38.Y[2] Q=:1.test_1[2] +.subckt DFF C=clk D=:38.Y[3] Q=:1.test_1[3] +.subckt DFF C=clk D=:38.Y[4] Q=:1.test_1[4] +.subckt DFF C=clk D=:38.Y[5] Q=:1.test_1[5] +.subckt DFF C=clk D=:38.Y[6] Q=:1.test_1[6] +.subckt NAND A=$abc$2385$new_n97 B=$abc$2385$new_n99 Y=$abc$2385$new_n101 +.subckt DFF C=clk D=:38.Y[7] Q=:1.test_1[7] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[0] Q=:1.test_2[0] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[1] Q=:1.test_2[1] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[2] Q=:1.test_2[2] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[3] Q=:1.test_2[3] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[4] Q=:1.test_2[4] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[5] Q=:1.test_2[5] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[6] Q=:1.test_2[6] +.subckt DFF C=clk D=$abc$1802$auto$ghdl.cc:825:import_module$22[7] Q=:1.test_2[7] +.subckt AND A=$abc$2385$new_n93 B=$abc$2385$new_n95 Y=$abc$2385$new_n102 +.subckt XNOR A=:1.test_1[3] B=$abc$2385$new_n67 Y=$abc$2385$new_n103 +.subckt AND A=$abc$2385$new_n83 B=$abc$2385$new_n103 Y=$abc$2385$new_n104 +.subckt ORNOT A=$abc$2385$new_n104 B=in_a_var[3] Y=$abc$2385$new_n105 +.subckt XOR A=in_b_var[0] B=$abc$2385$new_n59 Y=$abc$2385$auto$maccmap.cc:114:fulladd$252.Y[0] +.subckt XNOR A=in_a_var[3] B=$abc$2385$new_n104 Y=$abc$2385$new_n106 +.subckt NAND A=in_b_var[3] B=$abc$2385$new_n106 Y=$abc$2385$new_n107 +.subckt XNOR A=in_b_var[3] B=$abc$2385$new_n106 Y=$abc$2385$new_n108 +.subckt OR A=$abc$2385$new_n102 B=$abc$2385$new_n108 Y=$abc$2385$new_n109 +.subckt XOR A=$abc$2385$new_n102 B=$abc$2385$new_n108 Y=$abc$2385$new_n110 +.subckt NAND A=$abc$2385$new_n101 B=$abc$2385$new_n110 Y=$abc$2385$new_n111 +.subckt XOR A=$abc$2385$new_n101 B=$abc$2385$new_n110 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[3] +.subckt NAND A=$abc$2385$new_n109 B=$abc$2385$new_n111 Y=$abc$2385$new_n113 +.subckt AND A=$abc$2385$new_n105 B=$abc$2385$new_n107 Y=$abc$2385$new_n114 +.subckt XNOR A=:1.test_1[4] B=$abc$2385$new_n68 Y=$abc$2385$new_n115 +.subckt NAND A=$abc$2385$new_n57 B=$abc$2385$new_n60 Y=$abc$2385$new_n62 +.subckt AND A=$abc$2385$new_n83 B=$abc$2385$new_n115 Y=$abc$2385$new_n116 +.subckt ORNOT A=$abc$2385$new_n116 B=in_a_var[4] Y=$abc$2385$new_n117 +.subckt XNOR A=in_a_var[4] B=$abc$2385$new_n116 Y=$abc$2385$new_n118 +.subckt NAND A=in_b_var[4] B=$abc$2385$new_n118 Y=$abc$2385$new_n119 +.subckt XNOR A=in_b_var[4] B=$abc$2385$new_n118 Y=$abc$2385$new_n120 +.subckt OR A=$abc$2385$new_n114 B=$abc$2385$new_n120 Y=$abc$2385$new_n121 +.subckt XOR A=$abc$2385$new_n114 B=$abc$2385$new_n120 Y=$abc$2385$new_n122 +.subckt NAND A=$abc$2385$new_n113 B=$abc$2385$new_n122 Y=$abc$2385$new_n123 +.subckt XOR A=$abc$2385$new_n113 B=$abc$2385$new_n122 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[4] +.subckt AND A=$abc$2385$new_n121 B=$abc$2385$new_n123 Y=$abc$2385$new_n125 +.subckt NOR A=:1.test_1[0] B=:1.test_1[1] Y=$abc$2385$new_n63 +.subckt AND A=$abc$2385$new_n117 B=$abc$2385$new_n119 Y=$abc$2385$new_n126 +.subckt AND A=$abc$2385$new_n77 B=$abc$2385$new_n83 Y=$abc$2385$new_n127 +.subckt ORNOT A=$abc$2385$new_n127 B=in_a_var[5] Y=$abc$2385$new_n128 +.subckt XNOR A=in_a_var[5] B=$abc$2385$new_n127 Y=$abc$2385$new_n129 +.subckt NAND A=in_b_var[5] B=$abc$2385$new_n129 Y=$abc$2385$new_n130 +.subckt XNOR A=in_b_var[5] B=$abc$2385$new_n129 Y=$abc$2385$new_n131 +.subckt OR A=$abc$2385$new_n126 B=$abc$2385$new_n131 Y=$abc$2385$new_n132 +.subckt NAND A=$abc$2385$new_n126 B=$abc$2385$new_n131 Y=$abc$2385$new_n133 +.subckt XOR A=$abc$2385$new_n126 B=$abc$2385$new_n131 Y=$abc$2385$new_n134 +.subckt XNOR A=$abc$2385$new_n125 B=$abc$2385$new_n134 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[5] +.subckt AND A=:1.test_1[0] B=:1.test_1[1] Y=$abc$2385$new_n64 +.subckt AND A=$abc$2385$new_n128 B=$abc$2385$new_n130 Y=$abc$2385$new_n136 +.subckt AND A=$abc$2385$new_n72 B=$abc$2385$new_n82 Y=$abc$2385$new_n137 +.subckt ORNOT A=$abc$2385$new_n137 B=in_a_var[6] Y=$abc$2385$new_n138 +.subckt XNOR A=in_a_var[6] B=$abc$2385$new_n137 Y=$abc$2385$new_n139 +.subckt NAND A=in_b_var[6] B=$abc$2385$new_n139 Y=$abc$2385$new_n140 +.subckt XNOR A=in_b_var[6] B=$abc$2385$new_n139 Y=$abc$2385$new_n141 +.subckt OR A=$abc$2385$new_n136 B=$abc$2385$new_n141 Y=$abc$2385$new_n142 +.subckt XOR A=$abc$2385$new_n136 B=$abc$2385$new_n141 Y=$abc$2385$new_n143 +.subckt NAND A=$abc$2385$new_n125 B=$abc$2385$new_n132 Y=$abc$2385$new_n144 +.subckt AND A=$abc$2385$new_n133 B=$abc$2385$new_n144 Y=$abc$2385$new_n145 +.subckt XOR A=:1.test_1[0] B=:1.test_1[1] Y=$abc$2385$new_n65 +.subckt NAND A=$abc$2385$new_n143 B=$abc$2385$new_n145 Y=$abc$2385$new_n146 +.subckt XOR A=$abc$2385$new_n143 B=$abc$2385$new_n145 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[6] +.subckt AND A=$abc$2385$new_n142 B=$abc$2385$new_n146 Y=$abc$2385$new_n148 +.subckt AND A=$abc$2385$new_n138 B=$abc$2385$new_n140 Y=$abc$2385$new_n149 +.subckt AND A=$abc$2385$new_n75 B=$abc$2385$new_n83 Y=$abc$2385$new_n150 +.subckt NOR A=in_b_var[7] B=in_a_var[7] Y=$abc$2385$new_n151 +.subckt XOR A=in_b_var[7] B=in_a_var[7] Y=$abc$2385$new_n152 +.subckt XNOR A=$abc$2385$new_n150 B=$abc$2385$new_n152 Y=$abc$2385$new_n153 +.subckt XNOR A=$abc$2385$new_n149 B=$abc$2385$new_n153 Y=$abc$2385$new_n154 +.subckt XNOR A=$abc$2385$new_n148 B=$abc$2385$new_n154 Y=$abc$2385$auto$maccmap.cc:240:synth$253.Y[7] +.gateinit :1.test_2[7]=0 +.gateinit :1.test_2[6]=0 +.gateinit :1.test_2[5]=0 +.gateinit :1.test_2[4]=0 +.gateinit :1.test_2[3]=0 +.gateinit :1.test_2[2]=0 +.gateinit :1.test_2[1]=0 +.gateinit :1.test_2[0]=0 +.gateinit :1.test_1[7]=1 +.gateinit :1.test_1[6]=1 +.gateinit :1.test_1[5]=1 +.gateinit :1.test_1[4]=1 +.gateinit :1.test_1[3]=1 +.gateinit :1.test_1[2]=1 +.gateinit :1.test_1[1]=1 +.gateinit :1.test_1[0]=1 +.end diff --git a/tests/blif/gatesi.ys b/tests/blif/gatesi.ys new file mode 100644 index 000000000..0f1ebd911 --- /dev/null +++ b/tests/blif/gatesi.ys @@ -0,0 +1,4 @@ +read_blif gatesi.blif +write_blif -gatesi gatesi.blif.out +! tail -n +2 gatesi.blif.out > gatesi.blif.out.tmp && mv gatesi.blif.out.tmp gatesi.blif.out +! diff gatesi.blif.out gatesi.blif.ok diff --git a/tests/blif/generate_mk.py b/tests/blif/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/blif/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/blif/run-test.sh b/tests/blif/run-test.sh deleted file mode 100755 index 2e3f5235c..000000000 --- a/tests/blif/run-test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done diff --git a/tests/bram/generate.py b/tests/bram/generate_mk.py similarity index 95% rename from tests/bram/generate.py rename to tests/bram/generate_mk.py index 79dd500a3..09f5c650b 100644 --- a/tests/bram/generate.py +++ b/tests/bram/generate_mk.py @@ -4,6 +4,10 @@ import argparse import os import sys import random +import glob + +sys.path.append("..") +import gen_tests_makefile debug_mode = False @@ -287,9 +291,11 @@ if args.seed is not None: else: seed = (int(os.times()[4]*100) + os.getpid()) % 900000 + 100000 -print("PRNG seed: %d" % seed) +print("bram PRNG seed: %d" % seed) random.seed(seed) +os.makedirs("temp", exist_ok=True) + for k1 in range(args.count): dsc_f = open("temp/brams_%02d.txt" % k1, "w") sim_f = open("temp/brams_%02d.v" % k1, "w") @@ -303,3 +309,19 @@ for k1 in range(args.count): for k2 in range(lenk2): create_bram(dsc_f, sim_f, ref_f, tb_f, k1, k2, random.randrange(2 if k2+1 < lenk2 else 1)) +configs = sorted(set( + os.path.basename(f).replace("brams_", "").replace(".txt", "") + for f in glob.glob("temp/brams_*.txt") +)) + +def create_tests(): + for i in configs: + for j in configs: + if i != j: + gen_tests_makefile.generate_cmd_test( + f"bram_{i}_{j}", + f"bash run-single.sh {i} {j}" + ) + +gen_tests_makefile.generate_custom(create_tests) + diff --git a/tests/bram/run-test.sh b/tests/bram/run-test.sh deleted file mode 100755 index 47f24f5dd..000000000 --- a/tests/bram/run-test.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -# run this test many times: -# MAKE="make -j8" time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' - -set -e - -OPTIND=1 -count=5 -seed="" # default to no seed specified -debug="" -while getopts "c:dS:" opt -do - case "$opt" in - c) count="$OPTARG" ;; - d) debug="-d" ;; - S) seed="-S $OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -rm -rf temp -mkdir -p temp - -echo "generating tests.." -python3 generate.py $debug -c $count $seed - -{ - echo -n "all:" - for i in $( ls temp/brams_*.txt | sed 's,.*_,,; s,\..*,,;' ); do - for j in $( ls temp/brams_*.txt | sed 's,.*_,,; s,\..*,,;' | grep -v $i ); do - echo -n " temp/job_${i}_${j}.ok" - done; done - echo - for i in $( ls temp/brams_*.txt | sed 's,.*_,,; s,\..*,,;' ); do - for j in $( ls temp/brams_*.txt | sed 's,.*_,,; s,\..*,,;' | grep -v $i ); do - echo "temp/job_${i}_${j}.ok:" - echo " @bash run-single.sh ${i} ${j}" - echo " @echo 'Passed memory_bram test ${i}_${j}.'" - echo " @touch \$@" - done; done -} > temp/makefile - -echo "running tests.." -${MAKE:-make} -f temp/makefile - -exit 0 diff --git a/tests/bugpoint/generate_mk.py b/tests/bugpoint/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/bugpoint/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/bugpoint/run-test.sh b/tests/bugpoint/run-test.sh deleted file mode 100755 index 006c731e3..000000000 --- a/tests/bugpoint/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../gen-tests-makefile.sh -generate_mk --yosys-scripts diff --git a/tests/common-env.sh b/tests/common-env.sh deleted file mode 100644 index f3a411280..000000000 --- a/tests/common-env.sh +++ /dev/null @@ -1 +0,0 @@ -export YOSYS_MAX_THREADS=4 diff --git a/tests/common.mk b/tests/common.mk new file mode 100644 index 000000000..044054e0c --- /dev/null +++ b/tests/common.mk @@ -0,0 +1,44 @@ +all: + +ifndef OVERRIDE_MAIN +clean: + @rm -f *.log *.result +endif + +define run_test + @set -e; \ + rc=0; \ + ( set -e; $(2) ) >/dev/null 2>&1 || rc=$$?; \ + if [ $$rc -eq 0 ]; then \ + echo "PASS $1"; \ + echo PASS > $1.result; \ + else \ + echo "FAIL $1"; \ + echo FAIL > $1.result; \ + fi +endef + +.PHONY: summary +summary: + @pass=$$(find . -type f -name '*.result' -exec grep '^PASS$$' {} + | wc -l); \ + fail=$$(find . -type f -name '*.result' -exec grep '^FAIL$$' {} + | wc -l); \ + total=$$((pass + fail)); \ + echo "=========================="; \ + echo "Tests: $$total"; \ + echo "Passed: $$pass"; \ + echo "Failed: $$fail"; \ + echo "=========================="; \ + if [ $$fail -ne 0 ]; then \ + echo; \ + $(MAKE) --no-print-directory report; \ + fi; \ + test $$fail -eq 0 + +.PHONY: report +report: + @echo "==========================" + @echo "Failing tests:" + @find . -name '*.result' -type f -exec grep -H '^FAIL$$' {} + \ + | cut -d: -f1 \ + | sed 's|^\./||; s|\.result$$||' + @echo "==========================" diff --git a/tests/cxxrtl/generate_mk.py b/tests/cxxrtl/generate_mk.py new file mode 100644 index 000000000..b75c78e97 --- /dev/null +++ b/tests/cxxrtl/generate_mk.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +def run_subtest(name): + gen_tests_makefile.generate_cmd_test(f"cxxrtl_{name}", [ + f"$${{CXX:-g++}} -std=c++11 -O2 -o cxxrtl-test-{name} -I../../backends/cxxrtl/runtime test_{name}.cc -lstdc++", + f"./cxxrtl-test-{name}", + ]) + +def compile_only(): + gen_tests_makefile.generate_cmd_test("cxxrtl_unconnected_output", [ + '$(YOSYS) -p "read_verilog test_unconnected_output.v; select =*; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc"', + f'$${{CXX:-g++}} -std=c++11 -c -o cxxrtl-test-unconnected_output -I../../backends/cxxrtl/runtime cxxrtl-test-unconnected_output.cc', + ]) + +def main(): + def callback(): + run_subtest("value") + run_subtest("value_fuzz") + compile_only() + + gen_tests_makefile.generate_custom(callback) + +if __name__ == "__main__": + main() diff --git a/tests/cxxrtl/run-test.sh b/tests/cxxrtl/run-test.sh deleted file mode 100755 index aa7a0c26c..000000000 --- a/tests/cxxrtl/run-test.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -source ../common-env.sh - -set -ex - -run_subtest () { - local subtest=$1; shift - - ${CXX:-g++} -std=c++11 -O2 -o cxxrtl-test-${subtest} -I../../backends/cxxrtl/runtime test_${subtest}.cc -lstdc++ - ./cxxrtl-test-${subtest} -} - -run_subtest value -run_subtest value_fuzz - -# Compile-only test. -../../yosys -p "read_verilog test_unconnected_output.v; select =*; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" -${CXX:-g++} -std=c++11 -c -o cxxrtl-test-unconnected_output -I../../backends/cxxrtl/runtime cxxrtl-test-unconnected_output.cc diff --git a/tests/fmt/generate_mk.py b/tests/fmt/generate_mk.py new file mode 100644 index 000000000..2e94d4500 --- /dev/null +++ b/tests/fmt/generate_mk.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +def initial_display(): + gen_tests_makefile.generate_cmd_test("initial_display", [ + f"$(YOSYS) -p \"read_verilog initial_display.v\" | awk '/<<>>/,/<<>>/ {{print $$0}}' >yosys-initial_display.log 2>&1", + "iverilog -o iverilog-initial_display initial_display.v", + "./iverilog-initial_display >iverilog-initial_display.log", + "diff yosys-initial_display.log iverilog-initial_display.log", + ]) + + +def always_display(): + cases = [ + ("clk", "-DEVENT_CLK"), + ("clk_rst", "-DEVENT_CLK_RST"), + ("star", "-DEVENT_STAR"), + ("clk_en", "-DEVENT_CLK -DCOND_EN"), + ("clk_rst_en", "-DEVENT_CLK_RST -DCOND_EN"), + ("star_en", "-DEVENT_STAR -DCOND_EN"), + ] + + for name, defs in cases: + gen_tests_makefile.generate_cmd_test(f"always_display_{name}", [ + f"$(YOSYS) -p \"read_verilog {defs} always_display.v; proc; opt_expr -mux_bool; clean\" -o yosys-always_display-{name}-1.v", + f"$(YOSYS) -p \"read_verilog yosys-always_display-{name}-1.v; proc; opt_expr -mux_bool; clean\" -o yosys-always_display-{name}-2.v", + f"diff yosys-always_display-{name}-1.v yosys-always_display-{name}-2.v", + ]) + + +def roundtrip(): + cases = [ + ("dec_unsigned", '-DBASE_DEC -DSIGN=""'), + ("dec_signed", '-DBASE_DEC -DSIGN="signed"'), + ("hex_unsigned", '-DBASE_HEX -DSIGN=""'), + ("hex_signed", '-DBASE_HEX -DSIGN="signed"'), + ("oct_unsigned", '-DBASE_HEX -DSIGN=""'), + ("oct_signed", '-DBASE_HEX -DSIGN="signed"'), + ("bin_unsigned", '-DBASE_HEX -DSIGN=""'), + ("bin_signed", '-DBASE_HEX -DSIGN="signed"'), + ] + + for name, defs in cases: + gen_tests_makefile.generate_cmd_test(f"roundtrip_{name}", [ + f"$(YOSYS) -p \"read_verilog {defs} roundtrip.v; proc; clean\" -o yosys-roundtrip-{name}-1.v", + f"$(YOSYS) -p \"read_verilog yosys-roundtrip-{name}-1.v; proc; clean\" -o yosys-roundtrip-{name}-2.v", + f"diff yosys-roundtrip-{name}-1.v yosys-roundtrip-{name}-2.v", + + f"iverilog {defs} -o iverilog-roundtrip-{name} roundtrip.v roundtrip_tb.v", + f"./iverilog-roundtrip-{name} >iverilog-roundtrip-{name}.log", + + f"iverilog {defs} -o iverilog-roundtrip-{name}-1 yosys-roundtrip-{name}-1.v roundtrip_tb.v", + f"./iverilog-roundtrip-{name}-1 >iverilog-roundtrip-{name}-1.log", + + f"iverilog {defs} -o iverilog-roundtrip-{name}-2 yosys-roundtrip-{name}-2.v roundtrip_tb.v", + f"./iverilog-roundtrip-{name}-2 >iverilog-roundtrip-{name}-2.log", + + f"diff iverilog-roundtrip-{name}.log iverilog-roundtrip-{name}-1.log", + f"diff iverilog-roundtrip-{name}-1.log iverilog-roundtrip-{name}-2.log", + ]) + + +def cxxrtl(): + cases = ["always_full", "always_comb"] + + for name in cases: + gen_tests_makefile.generate_cmd_test(f"cxxrtl_{name}", [ + f"$(YOSYS) -p \"read_verilog {name}.v; proc; clean; write_cxxrtl -print-output std::cerr yosys-{name}.cc\"", + f"$${{CXX:-g++}} -std=c++11 -o yosys-{name} -I../../backends/cxxrtl/runtime {name}_tb.cc -lstdc++", + f"./yosys-{name} 2>yosys-{name}.log", + + f"iverilog -o iverilog-{name} {name}.v {name}_tb.v", + f"./iverilog-{name} | grep -v \"$finish called\" >iverilog-{name}.log", + + f"diff iverilog-{name}.log yosys-{name}.log", + ]) + + +def extra(): + gen_tests_makefile.generate_cmd_test("always_full_equiv", [ + "$(YOSYS) -p \"read_verilog always_full.v; prep; clean\" -o yosys-always_full-1.v", + "iverilog -o iverilog-always_full-1 yosys-always_full-1.v always_full_tb.v", + "./iverilog-always_full-1 > tmp.log", + "grep -v '\\$finish called' tmp.log > iverilog-always_full-1.log", + "diff iverilog-always_full.log iverilog-always_full-1.log", + ], deps=["cxxrtl_always_full"]) + + gen_tests_makefile.generate_cmd_test("display_lm", [ + "$(YOSYS) -p \"read_verilog display_lm.v\" >yosys-display_lm.log 2>&1", + "$(YOSYS) -p \"read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc\"", + f"$${{CXX:-g++}} -std=c++11 -o yosys-display_lm_cc -I../../backends/cxxrtl/runtime display_lm_tb.cc -lstdc++", + "./yosys-display_lm_cc >yosys-display_lm_cc.log", + "grep \"^%l: \\\\\\bot\\$$\" \"yosys-display_lm.log\"", + "grep \"^%m: \\\\\\bot\\$$\" \"yosys-display_lm.log\"", + "grep \"^%l: \\\\\\bot\\$$\" \"yosys-display_lm_cc.log\"", + "grep \"^%m: \\\\\\bot\\$$\" \"yosys-display_lm_cc.log\"", + ]) + + +def main(): + def callback(): + initial_display() + always_display() + roundtrip() + cxxrtl() + extra() + + gen_tests_makefile.generate_custom(callback) + + +if __name__ == "__main__": + main() diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh deleted file mode 100644 index a3402f953..000000000 --- a/tests/fmt/run-test.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -set -ex - -../../yosys -p 'read_verilog initial_display.v' | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log -iverilog -o iverilog-initial_display initial_display.v -./iverilog-initial_display >iverilog-initial_display.log -diff yosys-initial_display.log iverilog-initial_display.log - -test_always_display () { - local subtest=$1; shift - ../../yosys -p "read_verilog $* always_display.v; proc; opt_expr -mux_bool; clean" -o yosys-always_display-${subtest}-1.v - ../../yosys -p "read_verilog yosys-always_display-${subtest}-1.v; proc; opt_expr -mux_bool; clean" -o yosys-always_display-${subtest}-2.v - diff yosys-always_display-${subtest}-1.v yosys-always_display-${subtest}-2.v -} - -test_always_display clk -DEVENT_CLK -test_always_display clk_rst -DEVENT_CLK_RST -test_always_display star -DEVENT_STAR - -test_always_display clk_en -DEVENT_CLK -DCOND_EN -test_always_display clk_rst_en -DEVENT_CLK_RST -DCOND_EN -test_always_display star_en -DEVENT_STAR -DCOND_EN - -test_roundtrip () { - local subtest=$1; shift - ../../yosys -p "read_verilog $* roundtrip.v; proc; clean" -o yosys-roundtrip-${subtest}-1.v - ../../yosys -p "read_verilog yosys-roundtrip-${subtest}-1.v; proc; clean" -o yosys-roundtrip-${subtest}-2.v - diff yosys-roundtrip-${subtest}-1.v yosys-roundtrip-${subtest}-2.v - - iverilog $* -o iverilog-roundtrip-${subtest} roundtrip.v roundtrip_tb.v - ./iverilog-roundtrip-${subtest} >iverilog-roundtrip-${subtest}.log - iverilog $* -o iverilog-roundtrip-${subtest}-1 yosys-roundtrip-${subtest}-1.v roundtrip_tb.v - ./iverilog-roundtrip-${subtest}-1 >iverilog-roundtrip-${subtest}-1.log - iverilog $* -o iverilog-roundtrip-${subtest}-2 yosys-roundtrip-${subtest}-2.v roundtrip_tb.v - ./iverilog-roundtrip-${subtest}-1 >iverilog-roundtrip-${subtest}-2.log - diff iverilog-roundtrip-${subtest}.log iverilog-roundtrip-${subtest}-1.log - diff iverilog-roundtrip-${subtest}-1.log iverilog-roundtrip-${subtest}-2.log -} - -test_roundtrip dec_unsigned -DBASE_DEC -DSIGN="" -test_roundtrip dec_signed -DBASE_DEC -DSIGN="signed" -test_roundtrip hex_unsigned -DBASE_HEX -DSIGN="" -test_roundtrip hex_signed -DBASE_HEX -DSIGN="signed" -test_roundtrip oct_unsigned -DBASE_HEX -DSIGN="" -test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" -test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" -test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" - -test_cxxrtl () { - local subtest=$1; shift - - ../../yosys -p "read_verilog ${subtest}.v; proc; clean; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" - ${CXX:-g++} -std=c++11 -o yosys-${subtest} -I../../backends/cxxrtl/runtime ${subtest}_tb.cc -lstdc++ - ./yosys-${subtest} 2>yosys-${subtest}.log - iverilog -o iverilog-${subtest} ${subtest}.v ${subtest}_tb.v - ./iverilog-${subtest} |grep -v '\$finish called' >iverilog-${subtest}.log - diff iverilog-${subtest}.log yosys-${subtest}.log -} - -test_cxxrtl always_full -test_cxxrtl always_comb - -# Ensure Verilog backend preserves behaviour of always block with multiple $displays. -../../yosys -p "read_verilog always_full.v; prep; clean" -o yosys-always_full-1.v -iverilog -o iverilog-always_full-1 yosys-always_full-1.v always_full_tb.v -./iverilog-always_full-1 |grep -v '\$finish called' >iverilog-always_full-1.log -diff iverilog-always_full.log iverilog-always_full-1.log - -../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log -../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" -${CXX:-g++} -std=c++11 -o yosys-display_lm_cc -I../../backends/cxxrtl/runtime display_lm_tb.cc -lstdc++ -./yosys-display_lm_cc >yosys-display_lm_cc.log -for log in yosys-display_lm.log yosys-display_lm_cc.log; do - grep "^%l: \\\\bot\$" "$log" - grep "^%m: \\\\bot\$" "$log" -done diff --git a/tests/fsm/.gitignore b/tests/fsm/.gitignore index 9c595a6fb..90ea6e92a 100644 --- a/tests/fsm/.gitignore +++ b/tests/fsm/.gitignore @@ -1 +1 @@ -temp +uut_*.* diff --git a/tests/fsm/generate.py b/tests/fsm/generate_mk.py similarity index 89% rename from tests/fsm/generate.py rename to tests/fsm/generate_mk.py index 784e5a054..dc3518009 100644 --- a/tests/fsm/generate.py +++ b/tests/fsm/generate_mk.py @@ -1,21 +1,18 @@ #!/usr/bin/env python3 +import sys +sys.path.append("..") + +import gen_tests_makefile + import argparse import sys import random -from contextlib import contextmanager +from pathlib import Path # set to 'True' to compare verific with yosys test_verific = False -@contextmanager -def redirect_stdout(new_target): - old_target, sys.stdout = sys.stdout, new_target - try: - yield new_target - finally: - sys.stdout = old_target - def random_expr(variables): c = random.choice(['bin', 'uni', 'var', 'const']) if c == 'bin': @@ -39,12 +36,16 @@ args = parser.parse_args() seed = args.seed if seed is None: seed = random.randrange(sys.maxsize) -print("PRNG seed: %d" % seed) +print("fsm PRNG seed: %d" % seed) random.seed(seed) +for path in Path(".").glob("uut_*.*"): + if path.is_file(): + path.unlink() + for idx in range(args.count): - with open('temp/uut_%05d.v' % idx, 'w') as f: - with redirect_stdout(f): + with open('uut_%05d.v' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): rst2 = random.choice([False, True]) if rst2: print('module uut_%05d(clk, rst1, rst2, rst, a, b, c, x, y, z);' % (idx)) @@ -99,16 +100,16 @@ for idx in range(args.count): print(' end') print(' end') print('endmodule') - with open('temp/uut_%05d.ys' % idx, 'w') as f: - with redirect_stdout(f): + with open('uut_%05d.ys' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): if test_verific: - print('read_verilog temp/uut_%05d.v' % idx) + print('read_verilog uut_%05d.v' % idx) print('proc;; rename uut_%05d gold' % idx) - print('verific -vlog2k temp/uut_%05d.v' % idx) + print('verific -vlog2k uut_%05d.v' % idx) print('verific -import uut_%05d' % idx) print('rename uut_%05d gate' % idx) else: - print('read_verilog temp/uut_%05d.v' % idx) + print('read_verilog uut_%05d.v' % idx) print('proc;;') print('copy uut_%05d gold' % idx) print('rename uut_%05d gate' % idx) @@ -118,3 +119,4 @@ for idx in range(args.count): print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 %s_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter' % ('gold' if rst2 else 'in')) +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh deleted file mode 100755 index 139ea8261..000000000 --- a/tests/fsm/run-test.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -# run this test many times: -# time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' - -set -e - -OPTIND=1 -count=50 -seed="" # default to no seed specified -while getopts "c:S:" opt -do - case "$opt" in - c) count="$OPTARG" ;; - S) seed="-S $OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -rm -rf temp -mkdir -p temp -echo "generating tests.." -python3 generate.py -c $count $seed - -{ - all_targets="all_targets:" - echo "all: all_targets" - echo " @echo" - for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do - idx=$( printf "%05d" $i ) - echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" - echo " @echo -n '[$i]'" - echo " @../../yosys -ql temp/uut_${idx}.out temp/uut_${idx}.ys" - echo " @mv temp/uut_${idx}.out temp/uut_${idx}.log" - echo " @grep -q 'SAT proof finished' temp/uut_${idx}.log && echo -n K || echo -n T" - all_targets="$all_targets temp/uut_${idx}.log" - done - echo "$all_targets" -} > temp/makefile - -echo "running tests.." -${MAKE:-make} -f temp/makefile - -exit 0 diff --git a/tests/functional/generate_mk.py b/tests/functional/generate_mk.py new file mode 100644 index 000000000..3d63d1fe9 --- /dev/null +++ b/tests/functional/generate_mk.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +def callback(): + gen_tests_makefile.generate_cmd_test("functional",f'pytest -v -m "not smt and not rkt" . "$$@"') + +gen_tests_makefile.generate_custom(callback) diff --git a/tests/functional/rtlil_cells.py b/tests/functional/rtlil_cells.py index 964d81ddf..9a44821d3 100644 --- a/tests/functional/rtlil_cells.py +++ b/tests/functional/rtlil_cells.py @@ -337,7 +337,7 @@ rtlil_cells = [ # ("tribuf", ["A", "EN", "Y"]), # ("specify2", ["EN", "SRC", "DST"]), # ("specify3", ["EN", "SRC", "DST", "DAT"]), -# ("specrule", ["EN_SRC", "EN_DST", "SRC", "DST"]), +# ("specrule", ["SRC_EN", "DST_EN", "SRC", "DST"]), BWCell("bweqx", [10, 16, 40]), BWCell("bwmux", [10, 16, 40]), FFCell("ff", [10, 20, 40]), diff --git a/tests/functional/run-test.sh b/tests/functional/run-test.sh index 7c38f3190..8f72f7c1b 100755 --- a/tests/functional/run-test.sh +++ b/tests/functional/run-test.sh @@ -1,6 +1,4 @@ #!/usr/bin/env bash -source ../common-env.sh - SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) pytest -v -m "not smt and not rkt" "$SCRIPT_DIR" "$@" diff --git a/tests/functional/test_smtbmc_witness_mismatch.py b/tests/functional/test_smtbmc_witness_mismatch.py new file mode 100644 index 000000000..f13620f1d --- /dev/null +++ b/tests/functional/test_smtbmc_witness_mismatch.py @@ -0,0 +1,190 @@ +import json +import shutil +import subprocess +from pathlib import Path + +import pytest + +base_path = Path(__file__).resolve().parent.parent.parent + +pytestmark = pytest.mark.skipif(shutil.which("z3") is None, reason="z3 not available") + +def run(cmd, **kwargs): + """Run a command and assert it succeeds.""" + status = subprocess.run(cmd, **kwargs) + assert status.returncode == 0, f"{cmd[0]} failed" + return status + + +def write_smt2(tmp_path, verilog_text): + """Write Verilog to temp and emit SMT2 via yosys.""" + vfile = tmp_path / "design.v" + smt2 = tmp_path / "design.smt2" + vfile.write_text(verilog_text) + run([base_path / "yosys", "-Q", "-p", + f"read_verilog {vfile}; prep -top top; write_smt2 {smt2}"]) + return smt2 + + +def witness_entries(smt2_path): + """Parse yosys-smt2-witness JSON records from an SMT2 file.""" + entries = [] + marker = "yosys-smt2-witness" + with open(smt2_path, "r") as f: + for line in f: + if marker not in line: + continue + payload = line.split(marker, 1)[1].strip() + entries.append(json.loads(payload)) + return entries + + +def find_entry(entries, entry_type): + """Return the first witness entry of the given type.""" + for entry in entries: + if entry.get("type") == entry_type: + return entry + return None + + +def write_yw(yw_path, signals, bits): + """Write a minimal Yosys witness file with one step of bits.""" + data = { + "format": "Yosys Witness Trace", + "clocks": [], + "signals": signals, + "steps": [{"bits": bits}], + } + yw_path.write_text(json.dumps(data)) + + +def run_smtbmc(smt2_path, yw_path): + """Run yosys-smtbmc on the SMT2 file with a witness trace.""" + cmd = [ + base_path / "yosys-smtbmc", + "-s", "z3", + "-m", "top", + "--check-witness", + "--yw", yw_path, + "-t", "1", + smt2_path, + ] + return subprocess.run(cmd, capture_output=True, text=True) + + +def assert_no_mismatch_message(result): + """Assert the mismatch error prefix is absent from outputs.""" + combined = (result.stderr or "") + (result.stdout or "") + assert "Yosys witness signal mismatch" not in combined + + +def assert_has_mismatch_message(result, msg): + """Assert the mismatch error prefix and substring are present.""" + combined = (result.stderr or "") + (result.stdout or "") + assert "Yosys witness signal mismatch" in combined + assert msg in combined + + +def test_missing_signal_path(tmp_path): + smt2 = write_smt2(tmp_path, "module top(input ok, output out); assign out = ok; endmodule") + yw_path = tmp_path / "trace.yw" + signals = [{"path": ["\\missing"], "offset": 0, "width": 1, "init_only": False}] + write_yw(yw_path, signals, "1") + result = run_smtbmc(smt2, yw_path) + assert result.returncode != 0 + assert_has_mismatch_message(result, "signal not found in design") + + +def test_width_mismatch(tmp_path): + smt2 = write_smt2(tmp_path, "module top(input ok, output out); assign out = ok; endmodule") + entries = witness_entries(smt2) + input_entry = find_entry(entries, "input") + assert input_entry is not None + yw_path = tmp_path / "trace.yw" + signals = [{ + "path": input_entry["path"], + "offset": 0, + "width": 2, + "init_only": False, + }] + write_yw(yw_path, signals, "10") + result = run_smtbmc(smt2, yw_path) + assert result.returncode != 0 + assert_has_mismatch_message(result, "signal width/offset mismatch") + + +def test_memory_address_oob(tmp_path): + verilog = """ +module top(input ok, output [7:0] mem_out); + reg [7:0] mem [0:1]; + assign mem_out = mem[0] ^ {8{ok}}; +endmodule +""" + smt2 = write_smt2(tmp_path, verilog) + entries = witness_entries(smt2) + mem_entry = find_entry(entries, "mem") + assert mem_entry is not None + addr = mem_entry["size"] + yw_path = tmp_path / "trace.yw" + signals = [{ + "path": mem_entry["path"] + [f"\\[{addr}]"], + "offset": 0, + "width": mem_entry["width"], + "init_only": False, + }] + bits = "0" * mem_entry["width"] + write_yw(yw_path, signals, bits) + result = run_smtbmc(smt2, yw_path) + assert result.returncode != 0 + assert_has_mismatch_message(result, "memory address out of bounds") + + +def test_allowed_extra_signal_in_design(tmp_path): + verilog = """ +module top(input ok, input extra, output [1:0] out); + assign out = {ok, extra}; +endmodule +""" + smt2 = write_smt2(tmp_path, verilog) + entries = witness_entries(smt2) + input_entry = find_entry(entries, "input") + assert input_entry is not None + yw_path = tmp_path / "trace.yw" + signals = [{ + "path": input_entry["path"], + "offset": 0, + "width": input_entry["width"], + "init_only": False, + }] + bits = "0" * input_entry["width"] + write_yw(yw_path, signals, bits) + result = run_smtbmc(smt2, yw_path) + # With --check-witness and no assertions, smtbmc can still exit non-zero. + # Thus we don't check the result.returncode here and in the other success + # cases. + assert_no_mismatch_message(result) + + +def test_allowed_extra_memory_in_design(tmp_path): + verilog = """ +module top(input ok, output [7:0] out); + reg [7:0] mem0 [0:1]; + reg [7:0] mem1 [0:3]; + assign out = mem0[0] ^ mem1[0]; +endmodule +""" + smt2 = write_smt2(tmp_path, verilog) + entries = witness_entries(smt2) + input_entry = find_entry(entries, "input") + assert input_entry is not None + yw_path = tmp_path / "trace.yw" + signals = [{ + "path": input_entry["path"], + "offset": 0, + "width": input_entry["width"], + "init_only": False, + }] + bits = "1" * input_entry["width"] + write_yw(yw_path, signals, bits) + result = run_smtbmc(smt2, yw_path) + assert_no_mismatch_message(result) diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh deleted file mode 100755 index a0fb23ac3..000000000 --- a/tests/gen-tests-makefile.sh +++ /dev/null @@ -1,110 +0,0 @@ -set -eu - -YOSYS_BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"/../ >/dev/null 2>&1 && pwd)" - -# $ generate_target target_name test_command -generate_target() { - target_name=$(basename $PWD)-$1 - test_command=$2 - echo "all: $target_name" - echo ".PHONY: $target_name" - echo "$target_name:" - printf "\t@YOSYS_MAX_THREADS=4 %s\n" "$test_command" - printf "\t@echo 'Passed %s'\n" "$target_name" -} - -# $ generate_ys_test ys_file [yosys_args] -generate_ys_test() { - ys_file=$1 - yosys_args_=${2:-} - generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file}.err $yosys_args_ $ys_file && mv ${ys_file}.err ${ys_file}.log" -} - -# $ 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}.err $yosys_args_ $tcl_file && mv ${tcl_file}.err ${tcl_file}.log" -} - -# $ generate_bash_test bash_file -generate_bash_test() { - bash_file=$1 - generate_target "$bash_file" "bash -v $bash_file >${bash_file}.err 2>&1 && mv ${bash_file}.err ${bash_file}.log" -} - -# $ 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="" - - while [[ $# -gt 0 ]]; do - arg="$1" - case "$arg" in - -y|--yosys-scripts) - do_ys=true - shift - ;; - -t|--tcl-scripts) - do_tcl=true - shift - ;; - -s|--prove-sv) - do_sv=true - shift - ;; - -b|--bash) - do_sh=true - shift - ;; - -a|--yosys-args) - yosys_args+="$2" - shift - shift - ;; - *) - echo >&2 "Unknown argument: $1" - exit 1 - esac - done - - if [[ ! ( $do_ys = true || $do_tcl = true || $do_sv = true || $do_sh = true ) ]]; then - echo >&2 "Error: No file types selected" - exit 1 - fi - - echo ".PHONY: all" - echo "all:" - - if [[ $do_ys = true ]]; then - for x in *.ys; do - 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 - generate_ys_test "$x" "-p \"prep -top top; async2sync; sat -enable_undef -verify -prove-asserts\" $yosys_args" - fi; - done - fi; - if [[ $do_sh == true ]]; then - for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - generate_bash_test "$s" - fi - done - fi -} - -generate_mk() { - generate_tests "$@" > run-test.mk -} diff --git a/tests/gen_tests_makefile.py b/tests/gen_tests_makefile.py new file mode 100644 index 000000000..38596f63b --- /dev/null +++ b/tests/gen_tests_makefile.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 + +import glob +import os +import sys +import argparse +from contextlib import contextmanager + +yosys_basedir = os.path.relpath(os.path.join(os.path.dirname(__file__), "..")) +common_mk = os.path.relpath(os.path.join(os.path.dirname(__file__), "common.mk")) + +def _cwd_base(): + return os.path.basename(os.getcwd()) + +def generate_target(name, command, deps = None): + #target = f"{_cwd_base()}-{name}" + target = f"{name}" + print(f"all: {target}") + print(f".PHONY: {target}") + print(f"{target}_cmd={command}") + if deps: + print(f"{target}: {' '.join(deps)}") + else: + print(f"{target}:") + + print(f"\t@$(call run_test,{target}, $({target}_cmd))") + +def generate_ys_test(ys_file, yosys_args="", commands=""): + cmd = f'$(YOSYS) -ql {ys_file}.err {yosys_args} {ys_file} && mv {ys_file}.err {ys_file}.log' + if commands: + cmd += f"; \\\n{commands}" + generate_target(ys_file, cmd) + +def generate_tcl_test(tcl_file, yosys_args="", commands=""): + cmd = f'$(YOSYS) -ql {tcl_file}.err {yosys_args} {tcl_file} && mv {tcl_file}.err {tcl_file}.log' + if commands: + cmd += f"; \\\n{commands}" + generate_target(tcl_file, cmd) + +def generate_sv_test(sv_file, yosys_args="", commands=""): + base = os.path.splitext(sv_file)[0] + if not os.path.exists(base + ".ys"): + yosys_cmd = '-p "prep -top top; async2sync; sat -enable_undef -verify -prove-asserts"' + cmd = f'$(YOSYS) -ql {sv_file}.err {yosys_cmd} {yosys_args} {sv_file} && mv {sv_file}.err {sv_file}.log' + if commands: + cmd += f"; \\\n{commands}" + generate_target(sv_file, cmd) + +def generate_bash_test(sh_file, commands=""): + cmd = f"bash -v {sh_file} >{sh_file}.err 2>&1 && mv {sh_file}.err {sh_file}.log" + if commands: + cmd += f"; \\\n{commands}" + generate_target(sh_file, cmd) + +def unpack_cmd(cmd): + if isinstance(cmd, str): + return cmd + if isinstance(cmd, (list, tuple)): + return " && \\\n".join(cmd) + raise TypeError("cmd must be a string or a list/tuple of strings") + +def generate_cmd_test(test_name, cmd, yosys_args="", deps = None): + generate_target(test_name, unpack_cmd(cmd), deps) + +def generate_tests(argv, cmds): + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument("-y", "--yosys-scripts", action="store_true") + parser.add_argument("-t", "--tcl-scripts", action="store_true") + parser.add_argument("-s", "--prove-sv", action="store_true") + parser.add_argument("-b", "--bash", action="store_true") + parser.add_argument("-a", "--yosys-args", default="") + + args = parser.parse_args(argv) + + if not (args.yosys_scripts or args.tcl_scripts or args.prove_sv or args.bash): + raise RuntimeError("No file types selected") + + if args.yosys_scripts: + for f in sorted(glob.glob("*.ys")): + generate_ys_test(f, args.yosys_args, cmds) + + if args.tcl_scripts: + for f in sorted(glob.glob("*.tcl")): + generate_tcl_test(f, args.yosys_args, cmds) + + if args.prove_sv: + for f in sorted(glob.glob("*.sv")): + generate_sv_test(f, args.yosys_args, cmds) + + if args.bash: + for f in sorted(glob.glob("*.sh")): + if f != "run-test.sh": + generate_bash_test(f, cmds) + +def print_header(extra=None): + print(f"include {common_mk}") + print(f"YOSYS ?= {yosys_basedir}/yosys") + print("") + print("export YOSYS_MAX_THREADS := 4") + if extra: + for line in extra: + print(line) + print("") + print(".PHONY: all") + print("all:") + +@contextmanager +def redirect_stdout(new_target): + old_target, sys.stdout = sys.stdout, new_target + try: + yield new_target + finally: + sys.stdout = old_target + +def generate(argv, extra=None, cmds=""): + with open("Makefile", "w") as f: + with redirect_stdout(f): + print_header(extra) + generate_tests(argv, cmds) + +def generate_custom(callback, extra=None): + with open("Makefile", "w") as f: + with redirect_stdout(f): + print_header(extra) + callback() + +def generate_autotest_file(test_file, commands): + cmd = f"../tools/autotest.sh -G -j ${{SEEDOPT}} ${{EXTRA_FLAGS}} {test_file}; \\\n{commands}" + generate_target(test_file, cmd) + +def generate_autotest(pattern, extra_flags, cmds=""): + with open("Makefile", "w") as f: + with redirect_stdout(f): + print_header([ f"EXTRA_FLAGS = {extra_flags}", + "SEED ?=", + "ifneq ($(strip $(SEED)),)", + " SEEDOPT=-S$(SEED)", + "endif", + ]) + for fn in sorted(glob.glob(pattern)): + generate_autotest_file(fn, cmds) diff --git a/tests/hana/generate_mk.py b/tests/hana/generate_mk.py new file mode 100644 index 000000000..0068c590a --- /dev/null +++ b/tests/hana/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate_autotest("test_*.v", "-l hana_vlib.v -n 300 -e") diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh deleted file mode 100755 index 8533e5544..000000000 --- a/tests/hana/run-test.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -OPTIND=1 -seed="" # default to no seed specified -while getopts "S:" opt -do - case "$opt" in - S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space - seed="SEED=$arg" ;; - esac -done -shift "$((OPTIND-1))" - -exec ${MAKE:-make} -f ../tools/autotest.mk $seed EXTRA_FLAGS="-l hana_vlib.v -n 300 -e" test_*.v diff --git a/tests/liberty/generate_mk.py b/tests/liberty/generate_mk.py new file mode 100644 index 000000000..b2559cced --- /dev/null +++ b/tests/liberty/generate_mk.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import glob +import os +import sys +sys.path.append("..") + +import gen_tests_makefile + +def lib_tests(): + for lib in sorted(glob.glob("*.lib")): + base = os.path.splitext(lib)[0] + + gen_tests_makefile.generate_cmd_test(lib, [ + f'$(YOSYS) -p "read_verilog small.v; synth -top small; dfflibmap -info -liberty {lib}" -ql {base}.log', + + f'$(YOSYS_FILTERLIB) - {lib} > {lib}.filtered', + f'$(YOSYS_FILTERLIB) -verilogsim {lib} > {lib}.verilogsim', + + f'diff {lib}.filtered {lib}.filtered.ok', + f'diff {lib}.verilogsim {lib}.verilogsim.ok', + + f'if [ -e {base}.log.ok ]; then ' + f'$(YOSYS) -p "dfflibmap -info -liberty {lib}" -TqqQl {base}.log; ' + f'diff {base}.log {base}.log.ok; ' + f'fi', + ]) + + +def ys_tests(): + for ys in sorted(glob.glob("*.ys")): + gen_tests_makefile.generate_ys_test(ys) + +def main(): + def callback(): + lib_tests() + ys_tests() + + gen_tests_makefile.generate_custom(callback, + [f"YOSYS_FILTERLIB ?= {gen_tests_makefile.yosys_basedir}/yosys-filterlib"]) + + +if __name__ == "__main__": + main() diff --git a/tests/liberty/run-test.sh b/tests/liberty/run-test.sh deleted file mode 100755 index d5fb65e16..000000000 --- a/tests/liberty/run-test.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -eo pipefail - -for x in *.lib; do - echo "Testing on $x.." - ../../yosys -p "read_verilog small.v; synth -top small; dfflibmap -info -liberty ${x}" -ql ${x%.lib}.log - ../../yosys-filterlib - $x 2>/dev/null > $x.filtered - ../../yosys-filterlib -verilogsim $x > $x.verilogsim - diff $x.filtered $x.filtered.ok - diff $x.verilogsim $x.verilogsim.ok - if [[ -e ${x%.lib}.log.ok ]]; then - ../../yosys -p "dfflibmap -info -liberty ${x}" -TqqQl ${x%.lib}.log - diff ${x%.lib}.log ${x%.lib}.log.ok - fi -done - -for x in *.ys; do - echo "Running $x.." - ../../yosys -q -s $x -l ${x%.ys}.log -done - diff --git a/tests/memfile/generate_mk.py b/tests/memfile/generate_mk.py new file mode 100644 index 000000000..e6351bc51 --- /dev/null +++ b/tests/memfile/generate_mk.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +def create_tests(): + setup = "mkdir -p temp && cp content1.dat temp/content2.dat" + + gen_tests_makefile.generate_cmd_test("parent_content1", [ + f"{setup}", + 'cd .. && $(YOSYS_ABS) -qp "read_verilog -defer memfile/memory.v; ' + 'chparam -set MEMFILE \\"content1.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("parent_content2_temp", [ + f"{setup}", + 'cd .. && $(YOSYS_ABS) -qp "read_verilog -defer memfile/memory.v; ' + 'chparam -set MEMFILE \\"temp/content2.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("parent_content2_full", [ + f"{setup}", + 'cd .. && $(YOSYS_ABS) -qp "read_verilog -defer memfile/memory.v; ' + 'chparam -set MEMFILE \\"memfile/temp/content2.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("same_content1", [ + f"{setup}", + '$(YOSYS) -qp "read_verilog -defer memory.v; ' + 'chparam -set MEMFILE \\"content1.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("same_content2", [ + f"{setup}", + '$(YOSYS) -qp "read_verilog -defer memory.v; ' + 'chparam -set MEMFILE \\"temp/content2.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("child_content1", [ + f"{setup}", + 'cd temp && ../$(YOSYS) -qp "read_verilog -defer ../memory.v; ' + 'chparam -set MEMFILE \\"content1.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("child_content2_temp", [ + f"{setup}", + 'cd temp && ../$(YOSYS) -qp "read_verilog -defer ../memory.v; ' + 'chparam -set MEMFILE \\"temp/content2.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("child_content2_direct", [ + f"{setup}", + 'cd temp && ../$(YOSYS) -qp "read_verilog -defer ../memory.v; ' + 'chparam -set MEMFILE \\"temp/content2.dat\\" memory"' + ]) + + gen_tests_makefile.generate_cmd_test("fail_empty_filename", + '! $(YOSYS) -qp "read_verilog memory.v"') + + gen_tests_makefile.generate_cmd_test("fail_missing_file", [ + '! $(YOSYS) -qp "read_verilog -defer memory.v; ' + 'chparam -set MEMFILE \\"content3.dat\\" memory"' + ]) + +extra = ["YOSYS_ABS := $(abspath $(YOSYS))"] +gen_tests_makefile.generate_custom(create_tests, extra) diff --git a/tests/memfile/run-test.sh b/tests/memfile/run-test.sh deleted file mode 100755 index 44c1e4821..000000000 --- a/tests/memfile/run-test.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -set -e - -mkdir -p temp -cp content1.dat temp/content2.dat - -cd .. - -echo "Running from the parent directory with content1.dat" -../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"content1.dat\" memory" -echo "Running from the parent directory with temp/content2.dat" -../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" -echo "Running from the parent directory with memfile/temp/content2.dat" -../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"memfile/temp/content2.dat\" memory" - -cd memfile - -echo "Running from the same directory with content1.dat" -../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content1.dat\" memory" -echo "Running from the same directory with temp/content2.dat" -../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" - -cd temp - -echo "Running from a child directory with content1.dat" -../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"content1.dat\" memory" -echo "Running from a child directory with temp/content2.dat" -../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" -echo "Running from a child directory with content2.dat" -../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory" - -cd .. - -echo "Checking a failure when zero length filename is provided" -if ../../yosys -qp "read_verilog memory.v"; then - echo "The execution should fail but it didn't happen, which is WRONG." - exit 1 -else - echo "Execution failed, which is OK." -fi - -echo "Checking a failure when not existing filename is provided" -if ../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content3.dat\" memory"; then - echo "The execution should fail but it didn't happen, which is WRONG." - exit 1 -else - echo "Execution failed, which is OK." -fi diff --git a/tests/memlib/generate.py b/tests/memlib/generate_mk.py similarity index 96% rename from tests/memlib/generate.py rename to tests/memlib/generate_mk.py index 46eff6b43..5f846a573 100644 --- a/tests/memlib/generate.py +++ b/tests/memlib/generate_mk.py @@ -1,3 +1,9 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") +import gen_tests_makefile + # TODO: # - priority logic @@ -319,8 +325,8 @@ if (OFFSET > 0) begin always @(mem_read, subaddr_r) rd <= mem_read[subaddr_r*RDBITS+:RDBITS]; -end -else +end +else begin always @(posedge clk) case (OFFSET) @@ -970,7 +976,7 @@ for (abits, wbits, words, defs, cells) in [ name, ENABLES.format(abits=abits, wbits=wbits, words=words), ["wren"], defs, cells )) - + # abits/dbits determination (aka general geometry picking) GEOMETRIC = """ module top(clk, rwa, rd, wd, we); @@ -991,7 +997,7 @@ always @(posedge clk) if (we) mem[rwa] <= wd; else - rd <= mem[rwa]; + rd <= mem[rwa]; endmodule """ @@ -1372,7 +1378,7 @@ for (abits, wbits, rwords, cntquad, cntoct) in [ (4, 2, 4, 1, 1), (4, 2, 5, 2, 1), (4, 2, 6, 2, 1), - (4, 2, 7, 2, 1), # Write port needs to be duplicated, so only 3 extra read + (4, 2, 7, 2, 1), # Write port needs to be duplicated, so only 3 extra read (4, 2, 8, 3, 1), # ports per quad port LUT (i.e. 7 ports in 2, 8 ports in 3) (4, 2, 9, 3, 2), (4, 4, 1, 2, 2), @@ -1440,7 +1446,7 @@ for (testname, reset_gate, rdwr, clk_en, add_logic) in [ write = "if (wren) \n\t\tmem[addr] <= wdata;" if rdwr == "new": - read = """if (rden) + read = """if (rden) if (wren) rdata <= wdata; else @@ -1466,7 +1472,7 @@ end""" TESTS.append(Test( testname, PRIORITY.format(code=code, abits=4, wbits=8, words=2), - ["block_sp_full"], ["USE_SRST"], + ["block_sp_full"], ["USE_SRST"], {"RAM_BLOCK_SP": 1, "$*": add_logic} )) @@ -1510,10 +1516,10 @@ end""" TESTS.append(Test( testname, PRIORITY.format(code=code, abits=4, wbits=1, words=2), - ["block_sp_full"], defs, + ["block_sp_full"], defs, {"RAM_BLOCK_SP": 1, "$*": add_logic} )) - + ROM_CASE = """ module rom(input clk, input [2:0] addr, {attr}output reg [7:0] data); @@ -1536,44 +1542,50 @@ endmodule TESTS.append(Test("rom_case", ROM_CASE.format(attr=""), ["block_sdp"], [], {"RAM_BLOCK_SDP" : 0})) TESTS.append(Test("rom_case_block", ROM_CASE.format(attr="(* rom_style = \"block\" *) "), ["block_sdp"], [], {"RAM_BLOCK_SDP" : 1})) -with open("run-test.mk", "w") as mf: - mf.write("ifneq ($(strip $(SEED)),)\n") - mf.write("SEEDOPT=-S$(SEED)\n") - mf.write("endif\n") - mf.write("all:") - for t in TESTS: - mf.write(" " + t.name) - mf.write("\n") - mf.write(".PHONY: all\n") - - for t in TESTS: - with open("t_{}.v".format(t.name), "w") as tf: - tf.write(t.src) - with open("t_{}.ys".format(t.name), "w") as sf: - sf.write("proc\n") - sf.write("opt\n") - sf.write("opt -full\n") - sf.write("memory -nomap\n") - sf.write("dump\n") - sf.write("memory_libmap") - for lib in t.libs: - sf.write(" -lib ../memlib_{}.txt".format(lib)) - for d in t.defs: - sf.write(" -D {}".format(d)) - sf.write("\n") - sf.write("memory_map\n") - for k, v in t.cells.items(): - if isinstance(v, tuple): - (cc, ca) = v - sf.write("select -assert-count {} t:{}\n".format(cc, k)) - for kk, vv in ca.items(): - sf.write("select -assert-count {} t:{} r:{}={} %i\n".format(cc, k, kk, vv)) - else: - sf.write("select -assert-count {} t:{}\n".format(v, k)) - mf.write("{}:\n".format(t.name)) - mf.write("\t@../tools/autotest.sh -G -j $(SEEDOPT) $(EXTRA_FLAGS) -p 'script ../t_{}.ys'".format(t.name)) +for t in TESTS: + with open("t_{}.v".format(t.name), "w") as tf: + tf.write(t.src) + with open("t_{}.ys".format(t.name), "w") as sf: + sf.write("proc\n") + sf.write("opt\n") + sf.write("opt -full\n") + sf.write("memory -nomap\n") + sf.write("dump\n") + sf.write("memory_libmap") for lib in t.libs: - mf.write(" -l memlib_{}.v".format(lib)) - mf.write(" t_{}.v || (cat t_{}.err; exit 1)\n".format(t.name, t.name)) - mf.write(".PHONY: {}\n".format(t.name)) + sf.write(" -lib ../memlib_{}.txt".format(lib)) + for d in t.defs: + sf.write(" -D {}".format(d)) + sf.write("\n") + sf.write("memory_map\n") + for k, v in t.cells.items(): + if isinstance(v, tuple): + (cc, ca) = v + sf.write("select -assert-count {} t:{}\n".format(cc, k)) + for kk, vv in ca.items(): + sf.write("select -assert-count {} t:{} r:{}={} %i\n".format(cc, k, kk, vv)) + else: + sf.write("select -assert-count {} t:{}\n".format(v, k)) + +def create_tests(): + for t in TESTS: + libs_args = "" + for lib in t.libs: + libs_args += f" -l memlib_{lib}.v" + cmd = ( + f"../tools/autotest.sh -G -j ${{SEEDOPT}} ${{EXTRA_FLAGS}} " + f"-p 'script ../t_{t.name}.ys'" + f"{libs_args} " + f"t_{t.name}.v || (cat t_{t.name}.err; exit 1)" + ) + gen_tests_makefile.generate_target(t.name, cmd) + +extra = [ + "SEED ?=", + "ifneq ($(strip $(SEED)),)", + " SEEDOPT=-S$(SEED)", + "endif", +] +gen_tests_makefile.generate_custom(create_tests, extra) + diff --git a/tests/memlib/run-test.sh b/tests/memlib/run-test.sh deleted file mode 100755 index 9e95fb255..000000000 --- a/tests/memlib/run-test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -eu - -OPTIND=1 -seed="" # default to no seed specified -while getopts "S:" opt -do - case "$opt" in - S) seed="$OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -python3 generate.py -exec ${MAKE:-make} -f run-test.mk SEED="$seed" diff --git a/tests/memories/generate_mk.py b/tests/memories/generate_mk.py new file mode 100644 index 000000000..cfb29acb9 --- /dev/null +++ b/tests/memories/generate_mk.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate_autotest("*.v", "", +"""if grep -Eq 'expect-(wr-ports|rd-ports|rd-clk)' $@; then \\ + $(YOSYS) -f verilog -qp "proc; opt; memory -nomap; dump -outfile $(@:.v=).dmp t:\\$$mem_v2" $@; \\ + if grep -q expect-wr-ports $@; then \\ + val=$$(gawk '/expect-wr-ports/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\WR_PORTS $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected number of write ports."; exit 1; }; \\ + fi; \\ + if grep -q expect-wr-wide-continuation $@; then \\ + val=$$(gawk '/expect-wr-wide-continuation/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\WR_WIDE_CONTINUATION $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected write wide continuation."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-ports $@; then \\ + val=$$(gawk '/expect-rd-ports/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\RD_PORTS $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected number of read ports."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-clk $@; then \\ + val=$$(gawk '/expect-rd-clk/ { print $$3; }' $@); \\ + grep -Fq "connect \\\\RD_CLK $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read clock."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-en $@; then \\ + val=$$(gawk '/expect-rd-en/ { print $$3; }' $@); \\ + grep -Fq "connect \\\\RD_EN $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read enable."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-srst-sig $@; then \\ + val=$$(gawk '/expect-rd-srst-sig/ { print $$3; }' $@); \\ + grep -Fq "connect \\\\RD_SRST $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read sync reset."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-srst-val $@; then \\ + val=$$(gawk '/expect-rd-srst-val/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\RD_SRST_VALUE $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read sync reset value."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-arst-sig $@; then \\ + val=$$(gawk '/expect-rd-arst-sig/ { print $$3; }' $@); \\ + grep -Fq "connect \\\\RD_ARST $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read async reset."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-arst-val $@; then \\ + val=$$(gawk '/expect-rd-arst-val/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\RD_ARST_VALUE $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read async reset value."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-init-val $@; then \\ + val=$$(gawk '/expect-rd-init-val/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\RD_INIT_VALUE $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read init value."; exit 1; }; \\ + fi; \\ + if grep -q expect-rd-wide-continuation $@; then \\ + val=$$(gawk '/expect-rd-wide-continuation/ { print $$3; }' $@); \\ + grep -Fq "parameter \\\\RD_WIDE_CONTINUATION $$val" $(@:.v=).dmp || { echo " ERROR: Unexpected read wide continuation."; exit 1; }; \\ + fi; \\ + if grep -q expect-no-rd-clk $@; then \\ + grep -Fq "connect \\\\RD_CLK 1'x" $(@:.v=).dmp || { echo " ERROR: Expected no read clock."; exit 1; }; \\ + fi; \\ +fi""") diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh deleted file mode 100755 index 8f83e11a1..000000000 --- a/tests/memories/run-test.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -set -e - -OPTIND=1 -seed="" # default to no seed specified -abcopt="" -while getopts "A:S:" opt -do - case "$opt" in - A) abcopt="-A $OPTARG" ;; - S) seed="$OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -${MAKE:-make} -f ../tools/autotest.mk SEED="$seed" EXTRA_FLAGS="$abcopt" *.v - -for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do - echo -n "Testing expectations for $f .." - ../../yosys -f verilog -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem_v2" $f - if grep -q expect-wr-ports $f; then - grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected number of write ports."; false; } - fi - if grep -q expect-wr-wide-continuation $f; then - grep -q "parameter \\\\WR_WIDE_CONTINUATION $(gawk '/expect-wr-wide-continuation/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected write wide continuation."; false; } - fi - if grep -q expect-rd-ports $f; then - grep -q "parameter \\\\RD_PORTS $(gawk '/expect-rd-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected number of read ports."; false; } - fi - if grep -q expect-rd-clk $f; then - grep -q "connect \\\\RD_CLK \\$(gawk '/expect-rd-clk/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read clock."; false; } - fi - if grep -q expect-rd-en $f; then - grep -q "connect \\\\RD_EN \\$(gawk '/expect-rd-en/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read enable."; false; } - fi - if grep -q expect-rd-srst-sig $f; then - grep -q "connect \\\\RD_SRST \\$(gawk '/expect-rd-srst-sig/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read sync reset."; false; } - fi - if grep -q expect-rd-srst-val $f; then - grep -q "parameter \\\\RD_SRST_VALUE $(gawk '/expect-rd-srst-val/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read sync reset value."; false; } - fi - if grep -q expect-rd-arst-sig $f; then - grep -q "connect \\\\RD_ARST \\$(gawk '/expect-rd-arst-sig/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read async reset."; false; } - fi - if grep -q expect-rd-arst-val $f; then - grep -q "parameter \\\\RD_ARST_VALUE $(gawk '/expect-rd-arst-val/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read async reset value."; false; } - fi - if grep -q expect-rd-init-val $f; then - grep -q "parameter \\\\RD_INIT_VALUE $(gawk '/expect-rd-init-val/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read init value."; false; } - fi - if grep -q expect-rd-wide-continuation $f; then - grep -q "parameter \\\\RD_WIDE_CONTINUATION $(gawk '/expect-rd-wide-continuation/ { print $3; }' $f)\$" ${f%.v}.dmp || - { echo " ERROR: Unexpected read wide continuation."; false; } - fi - if grep -q expect-no-rd-clk $f; then - grep -q "connect \\\\RD_CLK 1'x\$" ${f%.v}.dmp || - { echo " ERROR: Expected no read clock."; false; } - fi - echo " ok." -done - diff --git a/tests/opt/generate_mk.py b/tests/opt/generate_mk.py new file mode 100644 index 000000000..4c31c5a2b --- /dev/null +++ b/tests/opt/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--tcl-scripts"]) diff --git a/tests/opt/opt_balance_tree.ys b/tests/opt/opt_balance_tree.ys new file mode 100644 index 000000000..6f8b8b711 --- /dev/null +++ b/tests/opt/opt_balance_tree.ys @@ -0,0 +1,1246 @@ +# Test 1 +log -header "Simple AND chain" +log -push +design -reset +read_verilog <signed + + // Combine with unsigned offset + assign result = sum_full + $signed({6'b0, unsigned_offset}); +endmodule +EOF +check -assert + +# Check equivalence after opt_balance_tree +equiv_opt -assert opt_balance_tree +design -load postopt + +# Width reduction +equiv_opt -assert wreduce +design -load postopt + +design -reset +log -pop + + + +# Test 30 +log -header "Complex signedness with conditional sign extension" +log -push +design -reset +read_verilog < temp/makefile - -echo "running tests.." -${MAKE:-make} -f temp/makefile -echo - -failed_share=$( echo $( gawk '/^#job#/ { j=$2; db[j]=0; } /^Removing [246] cells/ { delete db[j]; } END { for (j in db) print(j); }' temp/all_share_log.txt ) ) -if [ -n "$failed_share" ]; then - echo "Resource sharing failed for the following test cases: $failed_share" - false -fi - -exit 0 diff --git a/tests/pass-fuzzing.md b/tests/pass-fuzzing.md new file mode 100644 index 000000000..993f36078 --- /dev/null +++ b/tests/pass-fuzzing.md @@ -0,0 +1,106 @@ +Suppose you're making significant changes to a pass that should not change +the pass's output in any way. It might be useful to run a large number of +automatically generated tests to try to find bugs where the output has +changed. This document describes how to do that. + +Basically we're going to use [AFL++](https://github.com/AFLplusplus/AFLplusplus) with the +[Grammar-Mutator](https://github.com/AFLplusplus/Grammar-Mutator) plugin to generate +RTLIL testcases. For each testcase, we run a Yosys script that applies both the old and new +implementation of the pass to the same design and compares the results. Testcase +generation is coverage-guided, i.e. the fuzzer will try to find testcases that exercise all +code in the old and new implementation of the pass (and in the RTLIL parser). + +## Setup + +These instructions clone tools into subdirectories of your home directory. They assume +you have a Yosys checkout under `$HOME/yosys`, and that you're testing the `opt_merge` pass. +They have been tested with AFL++ revision 68b492b2c7725816068718ef9437b72b40e67519 and Grammar-Mutator revision 05d8f537f8d656f0754e7ad5dcc653c42cb4f8ff. + +Clone and build AFL++ and Grammar-Mutator: +``` +cd $HOME +git clone https://github.com/AFLplusplus/AFLplusplus.git +git -C AFLplusplus checkout stable +git clone https://github.com/AFLplusplus/Grammar-Mutator.git +git -C Grammar-Mutator checkout stable +``` + +Check that `rtlil-fuzz-grammar.json` generates RTLIL constructs relevant to your pass. +Currently it's quite simple and generates a limited set of cells and wires; you may need to +extend it to generate different kinds of cells and other RTLIL constructs (e.g. `proc`). + +Build AFL++ and Grammar-Mutator: +``` +make -C $HOME/AFLplusplus -j all +make -C $HOME/Grammar-Mutator -j GRAMMAR_FILE=$HOME/yosys/tests/tools/rtlil-fuzz-grammar.json +``` + +Create a Yosys commit that adds the old version of your pass as a new command, e.g. copy +`opt_merge.cc` into `old_opt_merge.cc` and change the name of the command to `old_opt_merge`. +[Here's](https://github.com/YosysHQ/yosys/commit/827cd8c998f3e455b14ac990a3159030ddc19b21) an example. + +You may also need to patch in [this commit](https://github.com/YosysHQ/yosys/commit/121c52f514c4ca282b4e6b3b14f71184f3849ddf) to work around a bug involving `std::reverse` on +empty vectors in the RTLIL parser when building with fuzzing instrumentation. +I think this is a clang++ bug so hopefully it will get fixed eventually and that patch will not be +necessary. + +Rebuild Yosys with the AFL++ compiler wrapper. This assumes your config builds Yosys with clang++. +``` +(cd $HOME/yosys; patch -lp1 << EOF) +diff --git a/Makefile b/Makefile +index 9c361294d..c9a98f74c 100644 +--- a/Makefile ++++ b/Makefile +@@ -238,7 +238,7 @@ + LTOFLAGS := $(GCC_LTO) + + ifeq ($(CONFIG),clang) +-CXX = clang++ ++CXX = $(HOME)/AFLplusplus/afl-c++ + CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) + ifeq ($(ENABLE_LTO),1) + LINKFLAGS += -fuse-ld=lld +EOF +make -C yosys clean && make -C yosys -j +``` + +You probably need to configure coredumps to work normally instead of going through some OS service: +``` +echo core | sudo tee /proc/sys/kernel/core_pattern +``` + +## Running the fuzzer + +Generate some initial testcases using Grammar-Mutator: +``` +(cd $HOME/Grammar-Mutator; rm -rf seeds trees; ./grammar_generator-rtlil 100 1000 ./seeds ./trees) +``` + +Now run AFL++. +``` +(cd $HOME/Grammar-Mutator; \ + AFL_CUSTOM_MUTATOR_LIBRARY=./libgrammarmutator-rtlil.so \ + AFL_CUSTOM_MUTATOR_ONLY=1 \ + AFL_BENCH_UNTIL_CRASH=1 \ + YOSYS_WORK_UNITS_PER_THREAD=1 \ + YOSYS_ABORT_ON_LOG_ERROR=1 \ + $HOME/AFLplusplus/afl-fuzz -t 5000 -m none -i seeds -o out -- \ + $HOME/yosys/yosys -p 'read_rtlil -legalize @@; design -save init; old_opt_merge; design -save old; design -load init; opt_merge; design_equal old' \ +) +``` +This will run the fuzzer until the first crash (including any pass output mismatches) and then stop. +Or if you're lucky, the fuzzer will run indefinitely. This uses very little parallelism; if it doesn't find any errors right away, you can increase the test throughput by running AFL++ in parallel using the instructions [here](https://aflplus.plus/docs/parallel_fuzzing). + +## Working with fuzz test failures + +Any failing testcases will be dropped in `$HOME/Grammar-Mutator/out/default/crashes`. +Run `yosys -p 'read_rtlil -legalize ... ; dump'` to get the testcase as legalized RTLIL. + +## Notes on generating semantically valid RTLIL + +`Grammar-Mutator` generates RTLIL files according to the context-free grammar in `rtlil-fuzz-grammar.json`. +However, the testcases must also be semantically valid, e.g. references to wires should only refer to +wires that actually exist. These constraints cannot reasonably be expresed in a CFG. Therefore we +have added a `-legalize` option to the `read_rtlil` command. When `-legalize` is set, when `read_rtlil` +detects a failed semantic check, instead of erroring out it emits a warning and patches the incoming RTLIL +to make it valid. diff --git a/tests/peepopt/generate_mk.py b/tests/peepopt/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/peepopt/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/peepopt/run-test.sh b/tests/peepopt/run-test.sh deleted file mode 100644 index 2e3f5235c..000000000 --- a/tests/peepopt/run-test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done diff --git a/tests/proc/bug5572.ys b/tests/proc/bug5572.ys new file mode 100644 index 000000000..1d8f4e514 --- /dev/null +++ b/tests/proc/bug5572.ys @@ -0,0 +1,19 @@ +read_rtlil << EOT +attribute \top 1 +module \top + wire width 1 \sig + wire width 1 \val + + process $2 + switch \sig [0] + case 1'0 + case 1'1 + case + assign \val [0] 1'1 + end + end +end +EOT +proc_rmdead +proc_clean +select -assert-none p:* diff --git a/tests/proc/generate_mk.py b/tests/proc/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/proc/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/proc/run-test.sh b/tests/proc/run-test.sh deleted file mode 100755 index 2e3f5235c..000000000 --- a/tests/proc/run-test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done diff --git a/tests/pyosys/test_design_run_pass.py b/tests/pyosys/test_design_run_pass.py new file mode 100644 index 000000000..f0013577d --- /dev/null +++ b/tests/pyosys/test_design_run_pass.py @@ -0,0 +1,20 @@ +from pathlib import Path +from pyosys import libyosys as ys + +__file_dir__ = Path(__file__).absolute().parent +add_sub = __file_dir__.parent / "arch" / "common" / "add_sub.v" + +base = ys.Design() +base.run_pass(["read_verilog", str(add_sub)]) +base.run_pass("hierarchy -top top") +base.run_pass(["proc"]) +base.run_pass("equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5") + +postopt = ys.Design() +postopt.run_pass("design -load postopt") +postopt.run_pass(["cd", "top"]) +postopt.run_pass("select -assert-min 25 t:LUT4") +postopt.run_pass("select -assert-max 26 t:LUT4") +postopt.run_pass(["select", "-assert-count", "10", "t:PFUMX"]) +postopt.run_pass(["select", "-assert-count", "6", "t:L6MUX21"]) +postopt.run_pass("select -assert-none t:LUT4 t:PFUMX t:L6MUX21 %% t:* %D") diff --git a/tests/pyosys/test_dict.py b/tests/pyosys/test_dict.py index 717fed8ea..59342391c 100644 --- a/tests/pyosys/test_dict.py +++ b/tests/pyosys/test_dict.py @@ -33,12 +33,3 @@ assert repr_test == {'tomato': 'tomato', 'first': 'second', 'key': 'value', 'im before = len(repr_test) print(repr_test.popitem()) assert before - 1 == len(repr_test) - -# test noncomparable -## if ys.CellType ever gets an == operator just disable this section -uncomparable_value = ys.Globals.yosys_celltypes.cell_types[ys.IdString("$not")] - -x = ys.IdstringToCelltypeDict({ ys.IdString("\\a"): uncomparable_value}) -y = ys.IdstringToCelltypeDict({ ys.IdString("\\a"): uncomparable_value}) - -assert x != y # not comparable diff --git a/tests/realmath/.gitignore b/tests/realmath/.gitignore index 9c595a6fb..941856205 100644 --- a/tests/realmath/.gitignore +++ b/tests/realmath/.gitignore @@ -1 +1 @@ -temp +uut_* diff --git a/tests/realmath/generate.py b/tests/realmath/generate_mk.py similarity index 77% rename from tests/realmath/generate.py rename to tests/realmath/generate_mk.py index 2bedf38e4..bee55816e 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate_mk.py @@ -1,17 +1,12 @@ #!/usr/bin/env python3 +import sys +sys.path.append("..") +import gen_tests_makefile import argparse import sys import random -from contextlib import contextmanager -@contextmanager -def redirect_stdout(new_target): - old_target, sys.stdout = sys.stdout, new_target - try: - yield new_target - finally: - sys.stdout = old_target def random_expression(depth = 3, maxparam = 0): def recursion(): @@ -42,13 +37,15 @@ parser.add_argument('-S', '--seed', type = int, help = 'seed for PRNG') parser.add_argument('-c', '--count', type = int, default = 100, help = 'number of test cases to generate') args = parser.parse_args() -if args.seed is not None: - print("PRNG seed: %d" % args.seed) - random.seed(args.seed) +seed = args.seed +if seed is None: + seed = random.randrange(sys.maxsize) +print("realmath PRNG seed: %d" % seed) +random.seed(seed) for idx in range(args.count): - with open('temp/uut_%05d.v' % idx, 'w') as f: - with redirect_stdout(f): + with open('uut_%05d.v' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): print('module uut_%05d(output [63:0] %s);\n' % (idx, ', '.join(['y%02d' % i for i in range(100)]))) for i in range(30): if idx < 10: @@ -63,13 +60,13 @@ for idx in range(args.count): for i in range(100): print('assign y%02d = 65536 * (%s);' % (i, random_expression(maxparam = 60))) print('endmodule') - with open('temp/uut_%05d.ys' % idx, 'w') as f: - with redirect_stdout(f): + with open('uut_%05d.ys' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): print('read_verilog uut_%05d.v' % idx) print('rename uut_%05d uut_%05d_syn' % (idx, idx)) print('write_verilog uut_%05d_syn.v' % idx) - with open('temp/uut_%05d_tb.v' % idx, 'w') as f: - with redirect_stdout(f): + with open('uut_%05d_tb.v' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): print('module uut_%05d_tb;\n' % idx) print('wire [63:0] %s;' % (', '.join(['r%02d' % i for i in range(100)]))) print('wire [63:0] %s;' % (', '.join(['s%02d' % i for i in range(100)]))) @@ -99,3 +96,20 @@ for idx in range(args.count): print('end') print('endmodule') + +def create_tests(): + for idx in range(args.count): + cmd = [ + f"$(YOSYS) -qq uut_{idx:05d}.ys", + f"iverilog -o uut_{idx:05d}_tb uut_{idx:05d}_tb.v uut_{idx:05d}.v uut_{idx:05d}_syn.v", + f"./uut_{idx:05d}_tb" +# f"./uut_{idx:05d}_tb | tee uut_{idx:05d}.err;", +# f"if test -s uut_{idx:05d}.err; then", +# " echo \"Note: Make sure that iverilog is an up-to-date git checkout of Icarus Verilog.\";", +# " exit 1;", +# "fi;", +# f"rm -f uut_{idx:05d}.err" + ] + gen_tests_makefile.generate_cmd_test(f"uut_{idx:05d}", cmd) + +gen_tests_makefile.generate_custom(create_tests) diff --git a/tests/realmath/run-test.sh b/tests/realmath/run-test.sh deleted file mode 100755 index 833e8c3f4..000000000 --- a/tests/realmath/run-test.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -e - -OPTIND=1 -count=100 -seed="" # default to no seed specified -while getopts "c:S:" opt -do - case "$opt" in - c) count="$OPTARG" ;; - S) seed="-S $OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -rm -rf temp -mkdir -p temp -echo "generating tests.." -python3 generate.py -c $count $seed - -cd temp -echo "running tests.." -for ((i = 0; i < $count; i++)); do - echo -n "[$i]" - idx=$( printf "%05d" $i ) - ../../../yosys -qq uut_${idx}.ys - iverilog -o uut_${idx}_tb uut_${idx}_tb.v uut_${idx}.v uut_${idx}_syn.v - ./uut_${idx}_tb | tee uut_${idx}.err - if test -s uut_${idx}.err; then - echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of Icarus Verilog." - exit 1 - fi - rm -f uut_${idx}.err -done -echo - diff --git a/tests/rpc/generate_mk.py b/tests/rpc/generate_mk.py new file mode 100644 index 000000000..aca802ebe --- /dev/null +++ b/tests/rpc/generate_mk.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile +import glob + +def create_tests(): + yss = sorted(glob.glob("*.ys")) + for ys in yss: + gen_tests_makefile.generate_ys_test(ys) + + cmd = [ "python3 frontend.py unix-socket frontend.sock" ] + gen_tests_makefile.generate_cmd_test("frontend.py", cmd) + +gen_tests_makefile.generate_custom(create_tests) diff --git a/tests/rpc/run-test.sh b/tests/rpc/run-test.sh deleted file mode 100755 index 0d58b0de2..000000000 --- a/tests/rpc/run-test.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done -python3 frontend.py unix-socket frontend.sock diff --git a/tests/rtlil/generate_mk.py b/tests/rtlil/generate_mk.py new file mode 100644 index 000000000..aa88bca13 --- /dev/null +++ b/tests/rtlil/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash"]) diff --git a/tests/rtlil/run-test.sh b/tests/rtlil/run-test.sh deleted file mode 100755 index 83cdf8aeb..000000000 --- a/tests/rtlil/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../gen-tests-makefile.sh -generate_mk --bash --yosys-scripts diff --git a/tests/sat/generate_mk.py b/tests/sat/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/sat/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/sat/run-test.sh b/tests/sat/run-test.sh deleted file mode 100755 index 006c731e3..000000000 --- a/tests/sat/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../gen-tests-makefile.sh -generate_mk --yosys-scripts diff --git a/tests/sdc/generate_mk.py b/tests/sdc/generate_mk.py new file mode 100644 index 000000000..aa88bca13 --- /dev/null +++ b/tests/sdc/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash"]) diff --git a/tests/sdc/run-test.sh b/tests/sdc/run-test.sh deleted file mode 100755 index 971664bdb..000000000 --- a/tests/sdc/run-test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../gen-tests-makefile.sh -generate_mk --yosys-scripts --bash \ No newline at end of file diff --git a/tests/select/generate_mk.py b/tests/select/generate_mk.py new file mode 100644 index 000000000..6a921d5a0 --- /dev/null +++ b/tests/select/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/select/run-test.sh b/tests/select/run-test.sh deleted file mode 100755 index 2e3f5235c..000000000 --- a/tests/select/run-test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done diff --git a/tests/share/.gitignore b/tests/share/.gitignore index 9c595a6fb..90ea6e92a 100644 --- a/tests/share/.gitignore +++ b/tests/share/.gitignore @@ -1 +1 @@ -temp +uut_*.* diff --git a/tests/share/generate.py b/tests/share/generate_mk.py similarity index 80% rename from tests/share/generate.py rename to tests/share/generate_mk.py index 7e87bd648..6a40758e1 100644 --- a/tests/share/generate.py +++ b/tests/share/generate_mk.py @@ -1,17 +1,14 @@ #!/usr/bin/env python3 +import sys +sys.path.append("..") + +import gen_tests_makefile + import argparse import sys import random -from contextlib import contextmanager - -@contextmanager -def redirect_stdout(new_target): - old_target, sys.stdout = sys.stdout, new_target - try: - yield new_target - finally: - sys.stdout = old_target +from pathlib import Path def random_plus_x(): return "%s x" % random.choice(['+', '+', '+', '-', '-', '|', '&', '^']) @@ -27,13 +24,19 @@ parser.add_argument('-S', '--seed', type = int, help = 'seed for PRNG') parser.add_argument('-c', '--count', type = int, default = 100, help = 'number of test cases to generate') args = parser.parse_args() -if args.seed is not None: - print("PRNG seed: %d" % args.seed) - random.seed(args.seed) +seed = args.seed +if seed is None: + seed = random.randrange(sys.maxsize) +print("share PRNG seed: %d" % seed) +random.seed(seed) + +for path in Path(".").glob("uut_*.*"): + if path.is_file(): + path.unlink() for idx in range(args.count): - with open('temp/uut_%05d.v' % idx, 'w') as f: - with redirect_stdout(f): + with open('uut_%05d.v' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): if random.choice(['bin', 'uni']) == 'bin': print('module uut_%05d(a, b, c, d, x, s, y);' % (idx)) op = random.choice([ @@ -67,16 +70,16 @@ for idx in range(args.count): random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('b'), random_plus_x() if random.randint(0, 4) == 0 else '')) print('endmodule') - with open('temp/uut_%05d.ys' % idx, 'w') as f: - with redirect_stdout(f): - print('read_verilog temp/uut_%05d.v' % idx) - print('proc;;') + with open('uut_%05d.ys' % idx, 'w') as f: + with gen_tests_makefile.redirect_stdout(f): + print('read_verilog uut_%05d.v' % idx) + print('proc -noopt;;') print('copy uut_%05d gold' % idx) print('rename uut_%05d gate' % idx) - print('tee -a temp/all_share_log.txt log') - print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx) - print('tee -a temp/all_share_log.txt wreduce') - print('tee -a temp/all_share_log.txt share -aggressive gate') + print('tee -o uut_%05d.txt wreduce' % idx) + print('tee -a uut_%05d.txt share -aggressive gate' % idx) print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter') + print('! grep -q \'^Removing [246] cells\' uut_%05d.txt' % idx) +gen_tests_makefile.generate(["--yosys-scripts"]) diff --git a/tests/share/run-test.sh b/tests/share/run-test.sh deleted file mode 100755 index 0cef580a7..000000000 --- a/tests/share/run-test.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -# run this test many times: -# time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' - -set -e - -OPTIND=1 -count=100 -seed="" # default to no seed specified -while getopts "c:S:" opt -do - case "$opt" in - c) count="$OPTARG" ;; - S) seed="-S $OPTARG" ;; - esac -done -shift "$((OPTIND-1))" - -rm -rf temp -mkdir -p temp -echo "generating tests.." -python3 generate.py -c $count $seed - -echo "running tests.." -for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do - echo -n "[$i]" - idx=$( printf "%05d" $i ) - ../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys -done -echo - -failed_share=$( echo $( gawk '/^#job#/ { j=$2; db[j]=0; } /^Removing [246] cells/ { delete db[j]; } END { for (j in db) print(j); }' temp/all_share_log.txt ) ) -if [ -n "$failed_share" ]; then - echo "Resource sharing failed for the following test cases: $failed_share" - false -fi - -exit 0 diff --git a/tests/sim/generate_mk.py b/tests/sim/generate_mk.py new file mode 100644 index 000000000..57138762d --- /dev/null +++ b/tests/sim/generate_mk.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +import subprocess +from pathlib import Path + +print("Generate FST for sim models") + +for name in Path("tb").rglob("tb*.v"): + test_name = name.stem + print(f"Test {test_name}") + + verilog_name = f"{test_name[3:]}.v" + + out_file = Path("tb") / f"{test_name}.out" + + subprocess.run( + ["iverilog", "-o", str(out_file), str(name), verilog_name], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=True + ) + + subprocess.run( + [str(out_file), "-fst"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=True + ) + +gen_tests_makefile.generate(["--yosys-scripts", "--bash", "--yosys-args", "-w 'Yosys has only limited support for tri-state logic at the moment.'" ]) diff --git a/tests/sim/run-test.sh b/tests/sim/run-test.sh deleted file mode 100755 index 43571e057..000000000 --- a/tests/sim/run-test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -set -eu -source ../gen-tests-makefile.sh -echo "Generate FST for sim models" -find tb/* -name tb*.v | while read name; do - test_name=$(basename $name .v) - echo "Test $test_name" - verilog_name=${test_name:3}.v - iverilog -o tb/$test_name.out $name $verilog_name - ./tb/$test_name.out -fst -done -generate_mk --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/simple/generate_mk.py b/tests/simple/generate_mk.py new file mode 100644 index 000000000..f8e79bcaf --- /dev/null +++ b/tests/simple/generate_mk.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import shutil + +# ---------------------- +# Check if iverilog is installed +# ---------------------- +if shutil.which("iverilog") is None: + print("Error: Icarus Verilog 'iverilog' not found.", file=sys.stderr) + sys.exit(1) + +import gen_tests_makefile + +gen_tests_makefile.generate_autotest("*.*v", "") diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh deleted file mode 100755 index c3711fe3e..000000000 --- a/tests/simple/run-test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -OPTIND=1 -seed="" # default to no seed specified -while getopts "S:" opt -do - case "$opt" in - S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space - seed="SEED=$arg" ;; - esac -done -shift "$((OPTIND-1))" - -# check for Icarus Verilog -if ! command -v iverilog > /dev/null ; then - echo "$0: Error: Icarus Verilog 'iverilog' not found." - exit 1 -fi - -exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.{sv,v} diff --git a/tests/simple_abc9/generate_mk.py b/tests/simple_abc9/generate_mk.py new file mode 100644 index 000000000..44dd7e2b4 --- /dev/null +++ b/tests/simple_abc9/generate_mk.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import shutil +import os +from pathlib import Path + +# ---------------------- +# Check if iverilog is installed +# ---------------------- +if shutil.which("iverilog") is None: + print("Error: Icarus Verilog 'iverilog' not found.", file=sys.stderr) + sys.exit(1) + +src_dir = Path("../simple") +# ---------------------- +# Copy all files from ../simple to current directory +# ---------------------- +for file in src_dir.glob("*.v"): + shutil.copy(file, os.path.join(".", file.name)) + +for file in src_dir.glob("*.sv"): + shutil.copy(file, os.path.join(".", file.name)) + +# bug 2675 +bug_file = os.path.join(".", "specify.v") +if os.path.exists(bug_file): + os.remove(bug_file) + +import gen_tests_makefile + +gen_tests_makefile.generate_autotest("*.*v", "-f \"verilog -noblackbox -specify\" -n 300 -p '\ + read_verilog -icells -lib +/abc9_model.v; \ + hierarchy; \ + synth -run coarse; \ + opt -full; \ + techmap; \ + abc9 -lut 4; \ + clean; \ + check -assert * abc9_test037 %d; \ + select -assert-none t:?_NOT_ t:?_AND_ %%; \ + setattr -mod -unset blackbox -unset whitebox =*'") diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh deleted file mode 100755 index 0b3e5061f..000000000 --- a/tests/simple_abc9/run-test.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh - -OPTIND=1 -seed="" # default to no seed specified -while getopts "S:" opt -do - case "$opt" in - S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space - seed="SEED=$arg" ;; - esac -done -shift "$((OPTIND-1))" - -# check for Icarus Verilog -if ! command -v iverilog > /dev/null ; then - echo "$0: Error: Icarus Verilog 'iverilog' not found." - exit 1 -fi - -for file in `ls *.v *.sv`; do - if [ ! -f "../simple/$file" -a "$file" != "abc9.v" ]; then - echo "Warning: $file is in simple_abc9/, but not in simple/" - backup="$file.bak" - if [ -f "$backup" ]; then - if cmp "$file" "$backup" > /dev/null; then - echo " => $backup already exists and matches; removing $file" - rm "$file" - else - echo " => $backup already exists but differs; leaving $file in place" - fi - else - echo " => moving $file to $backup" - mv -i "$file" "$backup" - fi - fi -done - -cp ../simple/*.v . -cp ../simple/*.sv . -rm specify.v # bug 2675 -DOLLAR='?' -exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-f \"verilog -noblackbox -specify\" -n 300 -p '\ - read_verilog -icells -lib +/abc9_model.v; \ - hierarchy; \ - synth -run coarse; \ - opt -full; \ - techmap; \ - abc9 -lut 4; \ - clean; \ - check -assert * abc9_test037 %d; \ - select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \ - setattr -mod -unset blackbox -unset whitebox =*'" - -# NOTE: Skip 'check -assert' on abc9_test037 because it intentionally has a combinatorial loop diff --git a/tests/svinterfaces/generate_mk.py b/tests/svinterfaces/generate_mk.py new file mode 100644 index 000000000..4703e9c9e --- /dev/null +++ b/tests/svinterfaces/generate_mk.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +from pathlib import Path +import glob +import sys +sys.path.append("..") + +import gen_tests_makefile + +runone_tests = [ + "svinterface1", + #"svinterface_at_top" +] + +def run_one(): + for testname in runone_tests: + cmd_lines = [ + f'$(YOSYS) -p "read_verilog -sv {testname}.sv ; hierarchy -check -top TopModule ; synth ; write_verilog {testname}_syn.v" >> {testname}.log_stdout 2>> {testname}.log_stderr', + f'$(YOSYS) -p "read_verilog -sv {testname}_ref.v ; hierarchy -check -top TopModule ; synth ; write_verilog {testname}_ref_syn.v" >> {testname}.log_stdout 2>> {testname}.log_stderr', + f'rm -f a.out reference_result.txt dut_result.txt', + f'iverilog -g2012 {testname}_syn.v', + f'iverilog -g2012 {testname}_ref_syn.v', + f'iverilog -g2012 {testname}_tb.v {testname}_ref_syn.v', + f'./a.out', + f'mv output.txt reference_result.txt', + f'iverilog -g2012 {testname}_tb_wrapper.v {testname}_syn.v' if testname=="svinterface_at_top" else + f'iverilog -g2012 {testname}_tb.v {testname}_syn.v', + f'./a.out', + f'mv output.txt dut_result.txt', + f'diff reference_result.txt dut_result.txt > {testname}.diff', + ] + gen_tests_makefile.generate_cmd_test(testname, cmd_lines) + +def run_simple(): + for f in sorted(glob.glob("*.ys")): + gen_tests_makefile.generate_ys_test(f) + +def main(): + def callback(): + run_one() + run_simple() + + gen_tests_makefile.generate_custom(callback) + +if __name__ == "__main__": + main() diff --git a/tests/svinterfaces/run-test.sh b/tests/svinterfaces/run-test.sh deleted file mode 100755 index 28ce627d9..000000000 --- a/tests/svinterfaces/run-test.sh +++ /dev/null @@ -1,9 +0,0 @@ -#/bin/bash -e -source ../common-env.sh - -./runone.sh svinterface1 -./runone.sh svinterface_at_top - -./run_simple.sh load_and_derive -./run_simple.sh resolve_types -./run_simple.sh positional_args diff --git a/tests/svinterfaces/run_simple.sh b/tests/svinterfaces/run_simple.sh deleted file mode 100755 index 5bf044373..000000000 --- a/tests/svinterfaces/run_simple.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# Run a simple test with a .ys file - -if [ $# != 1 ]; then - echo >&2 "Expected 1 argument" - exit 1 -fi - -echo -n "Test: $1 ->" -../../yosys $1.ys >$1.log_stdout 2>$1.log_stderr || { - echo "ERROR!" - exit 1 -} -echo "ok" diff --git a/tests/svinterfaces/runone.sh b/tests/svinterfaces/runone.sh deleted file mode 100755 index 2d6e0463d..000000000 --- a/tests/svinterfaces/runone.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - - -TESTNAME=$1 - -STDOUTFILE=${TESTNAME}.log_stdout -STDERRFILE=${TESTNAME}.log_stderr - -echo "" > $STDOUTFILE -echo "" > $STDERRFILE - -echo -n "Test: ${TESTNAME} -> " - -set -e - -$PWD/../../yosys -p "read_verilog -sv ${TESTNAME}.sv ; hierarchy -check -top TopModule ; synth ; write_verilog ${TESTNAME}_syn.v" >> $STDOUTFILE 2>> $STDERRFILE -$PWD/../../yosys -p "read_verilog -sv ${TESTNAME}_ref.v ; hierarchy -check -top TopModule ; synth ; write_verilog ${TESTNAME}_ref_syn.v" >> $STDOUTFILE 2>> $STDERRFILE - -rm -f a.out reference_result.txt dut_result.txt - -iverilog -g2012 ${TESTNAME}_syn.v -iverilog -g2012 ${TESTNAME}_ref_syn.v - -set +e -iverilog -g2012 ${TESTNAME}_tb.v ${TESTNAME}_ref_syn.v -./a.out -mv output.txt reference_result.txt -if [ -f ${TESTNAME}_wrapper.v ] ; then - iverilog -g2012 ${TESTNAME}_tb_wrapper.v ${TESTNAME}_syn.v -else - iverilog -g2012 ${TESTNAME}_tb.v ${TESTNAME}_syn.v -fi -./a.out -mv output.txt dut_result.txt - -diff reference_result.txt dut_result.txt > ${TESTNAME}.diff -RET=$? -if [ "$RET" != "0" ] ; then - echo "ERROR!" - exit -1 -fi - -echo "ok" -exit 0 diff --git a/tests/svtypes/array_assign.sv b/tests/svtypes/array_assign.sv new file mode 100644 index 000000000..f23a08d27 --- /dev/null +++ b/tests/svtypes/array_assign.sv @@ -0,0 +1,168 @@ +// Test for array-to-array assignment and ternary expressions + +`define STRINGIFY(x) `"x`" +`define STATIC_ASSERT(x) if(!(x)) $error({"assert failed: ", `STRINGIFY(x)}) + +module top; + // Test 1: Basic array ternary with continuous assignment + reg [7:0] a1[4]; + reg [7:0] b1[4]; + wire [7:0] out1[4]; + wire sel1; + assign out1 = sel1 ? a1 : b1; + `STATIC_ASSERT($bits(out1) == 32); + + // Test 2: Non-zero base index + reg [7:0] a2[3:6]; + reg [7:0] b2[3:6]; + wire [7:0] out2[3:6]; + wire sel2; + assign out2 = sel2 ? a2 : b2; + `STATIC_ASSERT($bits(out2) == 32); + + // Test 3: Single-bit elements + reg a3[8]; + reg b3[8]; + wire out3[8]; + wire sel3; + assign out3 = sel3 ? a3 : b3; + `STATIC_ASSERT($bits(out3) == 8); + + // Test 4: Multi-dimensional array ternary + reg [7:0] a4[2][3]; + reg [7:0] b4[2][3]; + wire [7:0] out4[2][3]; + wire sel4; + assign out4 = sel4 ? a4 : b4; + `STATIC_ASSERT($bits(out4) == 48); + + // Test 5: Direct array assignment (continuous) + reg [7:0] a5[4]; + wire [7:0] b5[4]; + assign b5 = a5; + `STATIC_ASSERT($bits(b5) == 32); + + // Test 6: Multi-dimensional direct assignment (continuous) + reg [7:0] a6[2][3]; + wire [7:0] b6[2][3]; + assign b6 = a6; + `STATIC_ASSERT($bits(b6) == 48); + + // Test 7: Procedural direct assignment with different unpacked index ranges + // Covers the AST_BLOCK expansion path for AST_ASSIGN_EQ. + logic pa [1:0][1:0]; + logic pb [1:0][0:1]; + always_comb begin + pa[0][0] = 1'b0; + pa[0][1] = 1'b1; + pa[1][0] = 1'b1; + pa[1][1] = 1'b1; + + pb = pa; + + assert(pb[0][1] == 1'b0); + assert(pb[0][0] == 1'b1); + assert(pb[1][1] == 1'b1); + assert(pb[1][0] == 1'b1); + end + + // Test 8: Procedural ternary assignment on arrays + // Covers the AST_BLOCK expansion path for ternary RHS. + logic pt_a [1:0]; + logic pt_b [1:0]; + logic pt_o [1:0]; + logic pt_sel; + always_comb begin + pt_a[0] = 1'b0; + pt_a[1] = 1'b1; + pt_b[0] = 1'b1; + pt_b[1] = 1'b0; + pt_sel = 1'b1; + + pt_o = pt_sel ? pt_a : pt_b; + + assert(pt_o[0] == 1'b0); + assert(pt_o[1] == 1'b1); + end + + // Test 9: Positional assignment pattern on a whole unpacked array + // Covers the parser and continuous assignment expansion path for `'{...}. + wire ap_table [1]; + wire ap_i = 1'b0; + wire ap_out; + assign ap_table = '{1'h1}; + assign ap_out = ap_table[ap_i > 1'h0 ? 1'h0 : ap_i]; + always_comb begin + assert(ap_out == 1'b1); + end + + // Test 10: Positional assignment pattern preserves left-to-right element order. + wire ap_order [2]; + assign ap_order = '{1'b0, 1'b1}; + always_comb begin + assert(ap_order[0] == 1'b0); + assert(ap_order[1] == 1'b1); + end + + function automatic logic ap_identity(input logic value); + ap_identity = value; + endfunction + + // Test 11: The first assignment pattern element is a runtime expression. + wire ap_runtime_in = 1'b1; + wire ap_runtime [2]; + assign ap_runtime = '{ap_identity(ap_runtime_in), 1'b0}; + always_comb begin + assert(ap_runtime[0] == 1'b1); + assert(ap_runtime[1] == 1'b0); + end + + // Test 12: Nested positional assignment pattern on a multidimensional array. + wire ap_nested [2][2]; + assign ap_nested = '{'{1'b1, 1'b0}, '{1'b0, 1'b1}}; + always_comb begin + assert(ap_nested[0][0] == 1'b1); + assert(ap_nested[0][1] == 1'b0); + assert(ap_nested[1][0] == 1'b0); + assert(ap_nested[1][1] == 1'b1); + end + + // Test 13: Multidimensional assignment pattern with row expressions. + wire ap_row0 [2]; + wire ap_row1 [2]; + wire ap_rows [2][2]; + assign ap_row0 = '{1'b1, 1'b0}; + assign ap_row1 = '{1'b0, 1'b1}; + assign ap_rows = '{ap_row0, ap_row1}; + always_comb begin + assert(ap_rows[0][0] == 1'b1); + assert(ap_rows[0][1] == 1'b0); + assert(ap_rows[1][0] == 1'b0); + assert(ap_rows[1][1] == 1'b1); + end + + // Test 14: Procedural blocking assignment pattern preserves RHS values. + logic ap_swap [2]; + always_comb begin + ap_swap[0] = 1'b0; + ap_swap[1] = 1'b1; + ap_swap = '{ap_swap[1], ap_swap[0]}; + + assert(ap_swap[0] == 1'b1); + assert(ap_swap[1] == 1'b0); + end + + // Test 15: Assignment pattern elements use the target element width context. + logic [4:0] ap_width_ctx [1]; + assign ap_width_ctx = '{4'hf + 4'h1}; + always_comb begin + assert(ap_width_ctx[0] == 5'h10); + end + + // Test 16: Nested assignment pattern elements also use the target element width context. + logic [4:0] ap_nested_width_ctx [1][1]; + assign ap_nested_width_ctx = '{'{4'hf + 4'h1}}; + always_comb begin + assert(ap_nested_width_ctx[0][0] == 5'h10); + end +endmodule diff --git a/tests/svtypes/array_assign_flat_multidim_pattern.ys b/tests/svtypes/array_assign_flat_multidim_pattern.ys new file mode 100644 index 000000000..a2e57e2f5 --- /dev/null +++ b/tests/svtypes/array_assign_flat_multidim_pattern.ys @@ -0,0 +1,10 @@ +logger -expect error "Assignment pattern element count mismatch: got 4, expected 2" 1 + +read_verilog -sv < o) = 1; +endspecify +endmodule + +module top(input i, output o); + wire a, b, c, z; + $_AND_ a0(.A(b), .B(i), .Y(a)); + $_AND_ b0(.A(a), .B(c), .Y(b)); + $_AND_ c0(.A(b), .B(i), .Y(c)); + box1 u_box(.i(i), .o(z)); + assign o = c ^ z; +endmodule +EOT + +abc9 -lut 4 diff --git a/tests/techmap/abc9.ys b/tests/techmap/abc9.ys index 2140dde26..c7a97ec4f 100644 --- a/tests/techmap/abc9.ys +++ b/tests/techmap/abc9.ys @@ -17,7 +17,8 @@ design -save gold abc9 -lut 4 design -load gold -abc9 -lut 4 -fast +scratchpad -copy abc9.script.default.fast abc9.script +abc9 -lut 4 design -load gold scratchpad -copy abc9.script.default.area abc9.script diff --git a/tests/techmap/abc_speed_gia_only.script b/tests/techmap/abc_speed_gia_only.script deleted file mode 100644 index d3730fdb5..000000000 --- a/tests/techmap/abc_speed_gia_only.script +++ /dev/null @@ -1,28 +0,0 @@ -&st -&dch -r -&nf -&st -&syn2 -&if -g -K 6 -&synch2 -r -&nf -&st -&syn2 -&if -g -K 6 -&synch2 -r -&nf -&st -&syn2 -&if -g -K 6 -&synch2 -r -&nf -&st -&syn2 -&if -g -K 6 -&synch2 -r -&nf -&st -&syn2 -&if -g -K 6 -&synch2 -r -&nf diff --git a/tests/techmap/abc_temp_dir_sanitization.ys b/tests/techmap/abc_temp_dir_sanitization.ys new file mode 100644 index 000000000..ed87ff980 --- /dev/null +++ b/tests/techmap/abc_temp_dir_sanitization.ys @@ -0,0 +1,13 @@ +read_verilog < gate-level $_MUX_ +design -save gold +lut2mux +rename \top \gate +select -assert-count 3 gate/t:$_MUX_ +select -assert-count 0 gate/t:$mux +select -assert-count 0 gate/t:$lut + +# -word mode -> word-level $mux +design -copy-from gold -as top \top +select -none +select top +lut2mux -word +select -clear +rename \top \word +select -assert-count 3 word/t:$mux +select -assert-count 0 word/t:$_MUX_ +select -assert-count 0 gate/t:$lut + +# equivalence +equiv_make \gate \word equiv +hierarchy -top equiv +equiv_simple +equiv_induct +equiv_status -assert diff --git a/tests/techmap/module_not_derived.ys b/tests/techmap/module_not_derived.ys new file mode 100644 index 000000000..299e4b75b --- /dev/null +++ b/tests/techmap/module_not_derived.ys @@ -0,0 +1,31 @@ +# Test 1: internal cells from alumacc/techmap must not keep module_not_derived. +read_verilog <&2 if [ ! -f "$toolsdir/cmp_tbdata" -o "$toolsdir/cmp_tbdata.c" -nt "$toolsdir/cmp_tbdata" ]; then - ( set -ex; ${CXX:-g++} -Wall -o "$toolsdir/cmp_tbdata" "$toolsdir/cmp_tbdata.c"; ) || exit 1 + ( set -ex; ${CXX:-g++} -Wall ${CPPFLAGS} ${CXXFLAGS:-} -o "$toolsdir/cmp_tbdata" "$toolsdir/cmp_tbdata.c"; ) || exit 1 fi +flock -u "$lock"; exec {lock}>&- while getopts xmGl:wkjvref:s:p:n:S:I:A:-: opt; do case "$opt" in @@ -148,7 +150,7 @@ do rm -f ${bn}_ref.fir if [[ "$ext" == "v" ]]; then - egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext} + grep -Ev '^\s*`timescale' ../$fn > ${bn}_ref.${ext} elif [[ "$ext" == "aig" ]] || [[ "$ext" == "aag" ]]; then $abcprog -c "read_aiger ../${fn}; write ${bn}_ref.${refext}" else @@ -235,6 +237,7 @@ do echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of Icarus Verilog." fi fi + sed -e "s,^,${bn}: ," ${bn}.err $keeprunning || exit 1 fi done diff --git a/tests/tools/rtlil-fuzz-grammar.json b/tests/tools/rtlil-fuzz-grammar.json new file mode 100644 index 000000000..96af9bde3 --- /dev/null +++ b/tests/tools/rtlil-fuzz-grammar.json @@ -0,0 +1,106 @@ +{ + "": [ + [ + "module \\test\n", + "", "", + "", + "", + "end\n" + ] + ], + "": [ [ "", " wire width ", "", " ", "", " ", "", "\n" ] ], + "": [ [ "1" ], [ "2" ], [ "3" ], [ "4" ], [ "32" ], [ "128" ] ], + "": [ [ "input ", "" ], [ "output ", "" ], [ "inout ", "" ], [] ], + "": [ + [ + " cell $not ", "", "\n", + " parameter \\A_SIGNED 0\n", + " parameter \\A_WIDTH 0\n", + " parameter \\Y_WIDTH 0\n", + " connect \\A ", "", "\n", + " connect \\Y ", "", "\n", + " end\n" + ], + [ + " cell $and ", "", "\n", + " parameter \\A_SIGNED 0\n", + " parameter \\B_SIGNED 0\n", + " parameter \\A_WIDTH 0\n", + " parameter \\B_WIDTH 0\n", + " parameter \\Y_WIDTH 0\n", + " connect \\A ", "", "\n", + " connect \\B ", "", "\n", + " connect \\Y ", "", "\n", + " end\n" + ], + [ + " cell $or ", "", "\n", + " parameter \\A_SIGNED 0\n", + " parameter \\B_SIGNED 0\n", + " parameter \\A_WIDTH 0\n", + " parameter \\B_WIDTH 0\n", + " parameter \\Y_WIDTH 0\n", + " connect \\A ", "", "\n", + " connect \\B ", "", "\n", + " connect \\Y ", "", "\n", + " end\n" + ], + [ + " cell $xor ", "", "\n", + " parameter \\A_SIGNED 0\n", + " parameter \\B_SIGNED 0\n", + " parameter \\A_WIDTH 0\n", + " parameter \\B_WIDTH 0\n", + " parameter \\Y_WIDTH 0\n", + " connect \\A ", "", "\n", + " connect \\B ", "", "\n", + " connect \\Y ", "", "\n", + " end\n" + ], + [ + " cell ", "", " ", "", "\n", + " connect \\A ", "", "\n", + " connect \\Y ", "", "\n", + " end\n" + ], + [ + " cell ", "", " ", "", "\n", + " connect \\A ", "", "\n", + " connect \\B ", "", "\n", + " connect \\Y ", "", "\n", + " end\n" + ] + ], + "": [ [ " attribute \\init ", "", "\n" ] ], + "": [ [ "\\wire_a" ], [ "\\wire_b" ], [ "\\wire_c" ], [ "\\wire_d" ], [ "\\wire_e" ], [ "\\wire_f" ], [ "\\wire_g" ], [ "\\wire_h" ], [ "\\wire_i" ], [ "\\wire_j" ] ], + "": [ [ "\\cell_a" ], [ "\\cell_b" ], [ "\\cell_c" ], [ "\\cell_d" ], [ "\\cell_e" ], [ "\\cell_f" ], [ "\\cell_g" ], [ "\\cell_h" ], [ "\\cell_i" ], [ "\\cell_j" ] ], + "": [ [ "\\bb1" ], [ "\\bb2" ] ], + "": [ + [ "", " " ], + [ "{", "", " ", "", "}" ], + [ "" ], + [ "", "[", "", "]" ], + [ "", "[", "", ":", "", "]" ] + ], + "": [ + [ "0'", "" ], + [ "1'", "" ], + [ "2'", "" ], + [ "3'", "" ], + [ "4'", "" ], + [ "31'", "" ], + [ "32'", "" ], + [ "128'", "" ] + ], + "": [ [ "0" ], [ "1" ], [ "x" ], [ "z" ], [ "-" ], [ "m" ] ], + "": [ "0", "1", "2", "3", "31", "32" ], + "": [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ], + "": [ [ " connect ", "", " ", "", "\n" ] ], + + "": [ [ ], [ "", "" ] ], + "": [ [ ], [ "", "" ] ], + "": [ [ ], [ "", "" ] ], + "": [ [ ], [ "", "" ] ], + "": [ [ ], [ "", "" ] ], + "": [ [ ], [ "", " ", "" ] ] +} diff --git a/tests/unit/Makefile b/tests/unit/Makefile index b275d7f41..88f449bf8 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -4,10 +4,10 @@ UNAME_S := $(shell uname -s) GTEST_PREFIX := $(shell brew --prefix googletest 2>/dev/null) ifeq ($(GTEST_PREFIX),) GTEST_CXXFLAGS := - GTEST_LDFLAGS := -lgtest -lgtest_main + GTEST_LDFLAGS := -lgtest -lgmock -lgtest_main else GTEST_CXXFLAGS := -I$(GTEST_PREFIX)/include - GTEST_LDFLAGS := -L$(GTEST_PREFIX)/lib -lgtest -lgtest_main + GTEST_LDFLAGS := -L$(GTEST_PREFIX)/lib -lgtest -lgmock -lgtest_main endif ifeq ($(UNAME_S),Darwin) @@ -18,10 +18,11 @@ endif EXTRAFLAGS := -lyosys -pthread -OBJTEST := objtest -BINTEST := bintest +MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +OBJTEST := $(MAKEFILE_DIR)objtest +BINTEST := $(MAKEFILE_DIR)bintest -ALLTESTFILE := $(shell find . -name '*Test.cc' | sed 's|^\./||' | tr '\n' ' ') +ALLTESTFILE := $(shell cd $(MAKEFILE_DIR) && find . -name '*Test.cc' | sed 's|^\./||' | tr '\n' ' ') TESTDIRS := $(sort $(dir $(ALLTESTFILE))) TESTS := $(addprefix $(BINTEST)/, $(basename $(ALLTESTFILE:%Test.cc=%Test.o))) @@ -34,7 +35,7 @@ $(BINTEST)/%: $(OBJTEST)/%.o | prepare $(CXX) -L$(ROOTPATH) $(RPATH) $(LINKFLAGS) -o $@ $^ $(LIBS) \ $(GTEST_LDFLAGS) $(EXTRAFLAGS) -$(OBJTEST)/%.o: $(basename $(subst $(OBJTEST),.,%)).cc | prepare +$(OBJTEST)/%.o: $(MAKEFILE_DIR)/%.cc | prepare $(CXX) -o $@ -c -I$(ROOTPATH) $(CPPFLAGS) $(CXXFLAGS) $(GTEST_CXXFLAGS) $^ .PHONY: prepare run-tests clean diff --git a/tests/unit/kernel/cellTypesTest.cc b/tests/unit/kernel/cellTypesTest.cc new file mode 100644 index 000000000..f2c044df4 --- /dev/null +++ b/tests/unit/kernel/cellTypesTest.cc @@ -0,0 +1,87 @@ +#include +#include "kernel/yosys.h" +#include "kernel/yosys_common.h" +#include "kernel/celltypes.h" +#include "kernel/newcelltypes.h" + +#include + +YOSYS_NAMESPACE_BEGIN + +TEST(CellTypesTest, basic) +{ + yosys_setup(); + log_files.push_back(stdout); + CellTypes older; + NewCellTypes newer; + older.setup(nullptr); + newer.setup(nullptr); + older.setup_type(ID(bleh), {ID::G}, {ID::H, ID::I}, false, true); + newer.setup_type(ID(bleh), {ID::G}, {ID::H, ID::I}, false, true); + EXPECT_EQ(older.cell_known(ID(aaaaa)), newer.cell_known(ID(aaaaa))); + EXPECT_EQ(older.cell_known(ID($and)), newer.cell_known(ID($and))); + auto check_port = [&](auto type, auto port) { + EXPECT_EQ(older.cell_port_dir(type, port), newer.cell_port_dir(type, port)); + EXPECT_EQ(older.cell_input(type, port), newer.cell_input(type, port)); + EXPECT_EQ(older.cell_output(type, port), newer.cell_output(type, port)); + }; + + // ground truth + const pool expected_ff_types = { + ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), + ID($adff), ID($adffe), ID($aldff), ID($aldffe), + ID($sdff), ID($sdffe), ID($sdffce), + ID($dlatch), ID($adlatch), ID($dlatchsr), + ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), + ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), + ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), + ID($_DFFSRE_NNNN_), ID($_DFFSRE_NNNP_), ID($_DFFSRE_NNPN_), ID($_DFFSRE_NNPP_), + ID($_DFFSRE_NPNN_), ID($_DFFSRE_NPNP_), ID($_DFFSRE_NPPN_), ID($_DFFSRE_NPPP_), + ID($_DFFSRE_PNNN_), ID($_DFFSRE_PNNP_), ID($_DFFSRE_PNPN_), ID($_DFFSRE_PNPP_), + ID($_DFFSRE_PPNN_), ID($_DFFSRE_PPNP_), ID($_DFFSRE_PPPN_), ID($_DFFSRE_PPPP_), + ID($_DFF_N_), ID($_DFF_P_), + ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), + ID($_DFFE_NN0N_), ID($_DFFE_NN0P_), ID($_DFFE_NN1N_), ID($_DFFE_NN1P_), + ID($_DFFE_NP0N_), ID($_DFFE_NP0P_), ID($_DFFE_NP1N_), ID($_DFFE_NP1P_), + ID($_DFFE_PN0N_), ID($_DFFE_PN0P_), ID($_DFFE_PN1N_), ID($_DFFE_PN1P_), + ID($_DFFE_PP0N_), ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_), + ID($_ALDFF_NN_), ID($_ALDFF_NP_), ID($_ALDFF_PN_), ID($_ALDFF_PP_), + ID($_ALDFFE_NNN_), ID($_ALDFFE_NNP_), ID($_ALDFFE_NPN_), ID($_ALDFFE_NPP_), + ID($_ALDFFE_PNN_), ID($_ALDFFE_PNP_), ID($_ALDFFE_PPN_), ID($_ALDFFE_PPP_), + ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), + ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_), + ID($_SDFFE_NN0N_), ID($_SDFFE_NN0P_), ID($_SDFFE_NN1N_), ID($_SDFFE_NN1P_), + ID($_SDFFE_NP0N_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1N_), ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0N_), ID($_SDFFE_PN0P_), ID($_SDFFE_PN1N_), ID($_SDFFE_PN1P_), + ID($_SDFFE_PP0N_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1N_), ID($_SDFFE_PP1P_), + ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NN1P_), + ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1N_), ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PN1P_), + ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1N_), ID($_SDFFCE_PP1P_), + ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_), + ID($_DLATCH_N_), ID($_DLATCH_P_), + ID($_DLATCH_NN0_), ID($_DLATCH_NN1_), ID($_DLATCH_NP0_), ID($_DLATCH_NP1_), + ID($_DLATCH_PN0_), ID($_DLATCH_PN1_), ID($_DLATCH_PP0_), ID($_DLATCH_PP1_), + ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_), + ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), + ID($_FF_), + }; + + for (size_t i = 0; i < static_cast(RTLIL::StaticId::STATIC_ID_END); i++) { + IdString type; + type.index_ = i; + EXPECT_EQ(older.cell_known(type), newer.cell_known(type)); + if (older.cell_evaluable(type) != newer.cell_evaluable(type)) + std::cout << type.str() << "\n"; + EXPECT_EQ(older.cell_evaluable(type), newer.cell_evaluable(type)); + for (auto port : StaticCellTypes::builder.cells.data()->inputs.ports) + check_port(type, port); + for (auto port : StaticCellTypes::builder.cells.data()->outputs.ports) + check_port(type, port); + EXPECT_EQ(expected_ff_types.count(type) > 0, StaticCellTypes::categories.is_ff(type)); + } + yosys_shutdown(); +} + +YOSYS_NAMESPACE_END diff --git a/tests/unit/kernel/modindexTest.cc b/tests/unit/kernel/modindexTest.cc new file mode 100644 index 000000000..1921c9a93 --- /dev/null +++ b/tests/unit/kernel/modindexTest.cc @@ -0,0 +1,47 @@ +#include + +#include "kernel/modtools.h" +#include "kernel/rtlil.h" + +YOSYS_NAMESPACE_BEGIN + +TEST(ModIndexSwapTest, has) +{ + Design* d = new Design; + Module* m = d->addModule("$m"); + Wire* o = m->addWire("$o", 2); + o->port_input = true; + Wire* i = m->addWire("$i", 2); + i->port_input = true; + m->fixup_ports(); + m->addNot("$not", i, o); + auto mi = ModIndex(m); + mi.reload_module(); + for (auto [sb, info] : mi.database) { + EXPECT_TRUE(mi.database.find(sb) != mi.database.end()); + } + m->swap_names(i, o); + for (auto [sb, info] : mi.database) { + EXPECT_TRUE(mi.database.find(sb) != mi.database.end()); + } +} + +TEST(ModIndexDeleteTest, has) +{ + if (log_files.empty()) log_files.emplace_back(stdout); + Design* d = new Design; + Module* m = d->addModule("$m"); + Wire* w = m->addWire("$w"); + Wire* o = m->addWire("$o"); + o->port_output = true; + m->fixup_ports(); + Cell* not_ = m->addNotGate("$not", w, o); + auto mi = ModIndex(m); + mi.reload_module(); + mi.dump_db(); + Wire* a = m->addWire("\\a"); + not_->setPort(ID::A, a); + EXPECT_TRUE(mi.ok()); +} + +YOSYS_NAMESPACE_END diff --git a/tests/unit/kernel/rtlilHelpers.h b/tests/unit/kernel/rtlilHelpers.h new file mode 100644 index 000000000..99585f23b --- /dev/null +++ b/tests/unit/kernel/rtlilHelpers.h @@ -0,0 +1,71 @@ +#ifndef RTLIL_HELPERS_H +#define RTLIL_HELPERS_H + +#include + +#include "kernel/rtlil.h" + +YOSYS_NAMESPACE_BEGIN + +class SigSpecRepTest : public ::testing::Test { +protected: + Design* d; + Module* m; + + void SetUp() override { + d = new Design; + m = d->addModule("$test"); + } + + void TearDown() override { + delete d; + } + + // Create n wires with given width + std::vector createWires(int count, int width = 4) { + std::vector wires; + for (int i = 0; i < count; i++) { + Wire* w = m->addWire(stringf("$w%d", i), width); + wires.push_back(w); + } + return wires; + } + + // Append all wires to a SigSpec + SigSpec wiresAsSigSpec(const std::vector& wires) { + SigSpec sig; + for (auto w : wires) + sig.append(w); + return sig; + } + + // Create a SigSpec of constants + SigSpec constsAsSigSpec(int count, int width = 4) { + SigSpec sig; + for (int i = 0; i < count; i++) + sig.append(Const(i, width)); + return sig; + } + + // Convert wires to pool of SigBits + pool wiresToPool(const std::vector& wires) { + pool pool; + for (auto w : wires) + for (auto &bit : SigSpec(w)) + pool.insert(bit); + return pool; + } + + // Convert wires to set of SigBits + std::set wiresToSet(const std::vector& wires) { + std::set set; + for (auto w : wires) + for (auto &bit : SigSpec(w)) + set.insert(bit); + return set; + } +}; + +YOSYS_NAMESPACE_END + +#endif /* RTLIL_HELPERS_H */ diff --git a/tests/unit/kernel/rtlilStringTest.cc b/tests/unit/kernel/rtlilStringTest.cc new file mode 100644 index 000000000..26b296dd4 --- /dev/null +++ b/tests/unit/kernel/rtlilStringTest.cc @@ -0,0 +1,61 @@ +#include + +#include "kernel/rtlil.h" +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +namespace RTLIL { + + TEST(RtlilStrTest, DesignToString) { + Design design; + Module *mod = design.addModule(ID(my_module)); + mod->addWire(ID(my_wire), 1); + + std::string design_str = design.to_rtlil_str(); + + EXPECT_NE(design_str.find("module \\my_module"), std::string::npos); + EXPECT_NE(design_str.find("end"), std::string::npos); + } + + TEST(RtlilStrTest, ModuleToString) { + Design design; + Module *mod = design.addModule(ID(test_mod)); + Wire *wire = mod->addWire(ID(clk), 1); + wire->port_input = true; + + std::string mod_str = mod->to_rtlil_str(); + + EXPECT_NE(mod_str.find("module \\test_mod"), std::string::npos); + EXPECT_NE(mod_str.find("wire"), std::string::npos); + EXPECT_NE(mod_str.find("\\clk"), std::string::npos); + EXPECT_NE(mod_str.find("input"), std::string::npos); + } + + TEST(RtlilStrTest, WireToString) { + Design design; + Module *mod = design.addModule(ID(m)); + Wire *wire = mod->addWire(ID(data), 8); + + std::string wire_str = wire->to_rtlil_str(); + + EXPECT_NE(wire_str.find("wire"), std::string::npos); + EXPECT_NE(wire_str.find("width 8"), std::string::npos); + EXPECT_NE(wire_str.find("\\data"), std::string::npos); + } + + TEST(RtlilStrTest, CellToString) { + Design design; + Module *mod = design.addModule(ID(m)); + Cell *cell = mod->addCell(ID(u1), ID(my_cell_type)); + + std::string cell_str = cell->to_rtlil_str(); + + EXPECT_NE(cell_str.find("cell"), std::string::npos); + EXPECT_NE(cell_str.find("\\my_cell_type"), std::string::npos); + EXPECT_NE(cell_str.find("\\u1"), std::string::npos); + } + +} + +YOSYS_NAMESPACE_END diff --git a/tests/unit/kernel/sigspecExtractTest.cc b/tests/unit/kernel/sigspecExtractTest.cc new file mode 100644 index 000000000..87bd4f6da --- /dev/null +++ b/tests/unit/kernel/sigspecExtractTest.cc @@ -0,0 +1,89 @@ +#include + +#include "kernel/rtlil.h" +#include "tests/unit/kernel/rtlilHelpers.h" + +YOSYS_NAMESPACE_BEGIN + +namespace RTLIL { + TEST_F(SigSpecRepTest, Extract) + { + { + std::vector wires; + SigSpec sig; + for (int i = 0; i < 4; i++) + wires.push_back(m->addWire(stringf("$w%d", i), 4)); + for (auto w : wires) + sig.append(w); + + SigSpec extractedFirst = sig.extract(0, 4); + SigSpec extractedSecond = sig.extract(4, 4); + SigSpec extractedLast = sig.extract(12, 4); + EXPECT_EQ(extractedFirst.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedSecond.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedLast.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedFirst.as_wire(), wires[0]); + EXPECT_EQ(extractedSecond.as_wire(), wires[1]); + EXPECT_EQ(extractedLast.as_wire(), wires[3]); + } + + { + std::vector consts; + SigSpec sig; + for (int i = 0; i < 4; i++) + consts.push_back(Const(i, 4)); + for (auto c : consts) + sig.append(c); + + SigSpec extractedFirst = sig.extract(0, 4); + SigSpec extractedSecond = sig.extract(4, 4); + SigSpec extractedLast = sig.extract(12, 4); + EXPECT_EQ(extractedFirst.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedSecond.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedLast.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedFirst, consts[0]); + EXPECT_EQ(extractedSecond, consts[1]); + EXPECT_EQ(extractedLast, consts[3]); + } + + { + SigSpec sig; + sig.append(Const(0, 4)); + Wire* w = m->addWire("$foo", 4); + sig.append(w); + sig.append(Const(15, 4)); + + SigSpec extractedFirst = sig.extract(0, 4); + SigSpec extractedSecond = sig.extract(4, 4); + SigSpec extractedLast = sig.extract(8, 4); + EXPECT_EQ(extractedFirst.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedSecond.rep_, SigSpec::Representation::CHUNK); + EXPECT_EQ(extractedLast.rep_, SigSpec::Representation::CHUNK); + + SigSpec extractedFirstTwo = sig.extract(0, 8); + EXPECT_EQ(extractedFirstTwo.rep_, SigSpec::Representation::BITS); + SigSpec extractedLastTwo = sig.extract(4, 8); + EXPECT_EQ(extractedLastTwo.rep_, SigSpec::Representation::BITS); + + EXPECT_EQ(extractedFirstTwo[0], State::S0); + EXPECT_EQ(extractedFirstTwo[1], State::S0); + EXPECT_EQ(extractedFirstTwo[2], State::S0); + EXPECT_EQ(extractedFirstTwo[3], State::S0); + EXPECT_EQ(extractedFirstTwo[4], SigBit(w, 0)); + EXPECT_EQ(extractedFirstTwo[5], SigBit(w, 1)); + EXPECT_EQ(extractedFirstTwo[6], SigBit(w, 2)); + EXPECT_EQ(extractedFirstTwo[7], SigBit(w, 3)); + + EXPECT_EQ(extractedLastTwo[0], SigBit(w, 0)); + EXPECT_EQ(extractedLastTwo[1], SigBit(w, 1)); + EXPECT_EQ(extractedLastTwo[2], SigBit(w, 2)); + EXPECT_EQ(extractedLastTwo[3], SigBit(w, 3)); + EXPECT_EQ(extractedLastTwo[4], State::S1); + EXPECT_EQ(extractedLastTwo[5], State::S1); + EXPECT_EQ(extractedLastTwo[6], State::S1); + EXPECT_EQ(extractedLastTwo[7], State::S1); + } + } +}; + +YOSYS_NAMESPACE_END diff --git a/tests/unit/kernel/sigspecRemove2Test.cc b/tests/unit/kernel/sigspecRemove2Test.cc new file mode 100644 index 000000000..9d7bf4863 --- /dev/null +++ b/tests/unit/kernel/sigspecRemove2Test.cc @@ -0,0 +1,333 @@ +#include + +#include "kernel/rtlil.h" + +YOSYS_NAMESPACE_BEGIN + +// Test fixture with helper functions +class SigSpecRepTest : public ::testing::Test { +protected: + Design* d; + Module* m; + + void SetUp() override { + d = new Design; + m = d->addModule("$test"); + } + + void TearDown() override { + delete d; + } + + // Create n wires with given width + std::vector createWires(int count, int width = 4) { + std::vector wires; + for (int i = 0; i < count; i++) { + Wire* w = m->addWire(stringf("$w%d", i), width); + wires.push_back(w); + } + return wires; + } + + // Append all wires to a SigSpec + SigSpec wiresAsSigSpec(const std::vector& wires) { + SigSpec sig; + for (auto w : wires) + sig.append(w); + return sig; + } + + // Create a SigSpec of constants + SigSpec constsAsSigSpec(int count, int width = 4) { + SigSpec sig; + for (int i = 0; i < count; i++) + sig.append(Const(i, width)); + return sig; + } + + // Convert wires to pool of SigBits + pool wiresToPool(const std::vector& wires) { + pool pool; + for (auto w : wires) + for (auto &bit : SigSpec(w)) + pool.insert(bit); + return pool; + } + + // Convert wires to set of SigBits + std::set wiresToSet(const std::vector& wires) { + std::set set; + for (auto w : wires) + for (auto &bit : SigSpec(w)) + set.insert(bit); + return set; + } +}; + +TEST_F(SigSpecRepTest, WithSigSpecPattern) +{ + auto wires = createWires(4); + SigSpec sig = wiresAsSigSpec(wires); + SigSpec pattern(wires[1]); // Remove w2 + SigSpec other = constsAsSigSpec(4); + + EXPECT_EQ(sig.size(), 16); + sig.remove2(pattern, &other); + EXPECT_EQ(sig.size(), 12); + EXPECT_EQ(other.size(), 12); + + // Verify correct wires remain (w1, w3, w4) + SigSpec expected; + expected.append(wires[0]); + expected.append(wires[2]); + expected.append(wires[3]); + EXPECT_EQ(sig, expected); +} + +TEST_F(SigSpecRepTest, WithPoolPattern) +{ + auto wires = createWires(3); + SigSpec sig = wiresAsSigSpec(wires); + auto pattern = wiresToPool({wires[1]}); + SigSpec other = constsAsSigSpec(3); + + EXPECT_EQ(sig.size(), 12); + sig.remove2(pattern, &other); + EXPECT_EQ(sig.size(), 8); + EXPECT_EQ(other.size(), 8); + + // Verify correct wires remain (w0, w2) + SigSpec expected; + expected.append(wires[0]); + expected.append(wires[2]); + EXPECT_EQ(sig, expected); +} + +TEST_F(SigSpecRepTest, WithSetPattern) +{ + auto wires = createWires(3); + SigSpec sig = wiresAsSigSpec(wires); + auto pattern = wiresToSet({wires[1]}); + SigSpec other = constsAsSigSpec(3); + + EXPECT_EQ(sig.size(), 12); + sig.remove2(pattern, &other); + EXPECT_EQ(sig.size(), 8); + EXPECT_EQ(other.size(), 8); + + // Verify correct wires remain (w0, w2) + SigSpec expected; + expected.append(wires[0]); + expected.append(wires[2]); + EXPECT_EQ(sig, expected); +} + +TEST_F(SigSpecRepTest, ManyElements) +{ + const int num_wires = 100; + auto wires = createWires(num_wires); + SigSpec sig = wiresAsSigSpec(wires); + + // Remove every other wire + std::vector to_remove; + for (int i = 0; i < num_wires; i += 2) + to_remove.push_back(wires[i]); + auto pattern = wiresToPool(to_remove); + + EXPECT_EQ(sig.size(), num_wires * 4); + sig.remove2(pattern, nullptr); + EXPECT_EQ(sig.size(), (num_wires / 2) * 4); + + // Verify odd-indexed wires remain (w1, w3, w5, ..., w99) + SigSpec expected; + for (int i = 1; i < num_wires; i += 2) + expected.append(wires[i]); + EXPECT_EQ(sig, expected); +} + +// Test remove2 with very large dataset to check scaling +TEST_F(SigSpecRepTest, VeryLargeScalingTest) +{ + const int num_wires = 50000; + auto wires = createWires(num_wires); + SigSpec sig = wiresAsSigSpec(wires); + SigSpec other = constsAsSigSpec(num_wires); + + // Create pattern with many chunks (one per wire) + SigSpec pattern; + for (int i = 0; i < num_wires; i += 2) + pattern.append(wires[i]); + + EXPECT_EQ(sig.size(), num_wires * 4); + sig.remove2(pattern, &other); + EXPECT_EQ(sig.size(), (num_wires / 2) * 4); + EXPECT_EQ(other.size(), (num_wires / 2) * 4); + + // Spot-check: odd-indexed wires should remain at expected positions + for (int i = 0; i < num_wires / 2; i++) { + EXPECT_EQ(sig[i * 4 + 0].wire, wires[i * 2 + 1]); + EXPECT_EQ(sig[i * 4 + 1].wire, wires[i * 2 + 1]); + EXPECT_EQ(sig[i * 4 + 2].wire, wires[i * 2 + 1]); + EXPECT_EQ(sig[i * 4 + 3].wire, wires[i * 2 + 1]); + } +} + +// Test multiple sequential removals (simulates removeSignalFromCaseTree) +TEST_F(SigSpecRepTest, MultipleSequentialRemovals) +{ + const int num_wires = 512; + auto wires = createWires(num_wires); + + // Create many actions, each with one wire + std::vector actions; + for (auto w : wires) + actions.push_back(SigSpec(w)); + + // Remove half the wires from all actions + for (int i = 0; i < num_wires / 2; i++) { + SigSpec pattern(wires[i]); + for (auto &action : actions) + if (action.size() > 0) + action.remove2(pattern, nullptr); + } + + // Verify correct actions were cleared + for (int i = 0; i < num_wires; i++) { + EXPECT_EQ(actions[i].size(), i < num_wires / 2 ? 0 : 4); + } + + // Verify remaining actions contain the correct wires + for (int i = num_wires / 2; i < num_wires; i++) { + SigSpec expected(wires[i]); + EXPECT_EQ(actions[i], expected); + } +} + +// Test remove2 with very large dataset to check scaling +TEST_F(SigSpecRepTest, PoolOverloadLargeDataset) +{ + const int num_wires = 50000; + auto wires = createWires(num_wires, 1); + SigSpec sig = wiresAsSigSpec(wires); + SigSpec other = constsAsSigSpec(num_wires, 1); + + // Remove half + pool pattern; + for (int i = 0; i < num_wires; i += 2) + pattern.insert(SigBit(wires[i], 0)); + + EXPECT_EQ(sig.size(), num_wires); + sig.remove2(pattern, &other); + EXPECT_EQ(sig.size(), num_wires / 2); + EXPECT_EQ(other.size(), num_wires / 2); + + // Spot-check: odd-indexed wires should remain + for (int i = 0; i < num_wires / 2; i++) { + EXPECT_EQ(sig[i].wire, wires[i * 2 + 1]); + } +} + +// Test set overload (same perf characteristics as pool) +TEST_F(SigSpecRepTest, SetOverloadLargeDataset) +{ + const int num_wires = 50000; + auto wires = createWires(num_wires, 1); + SigSpec sig = wiresAsSigSpec(wires); + SigSpec other = constsAsSigSpec(num_wires, 1); + + // Remove half + std::set pattern; + for (int i = 0; i < num_wires; i += 2) + pattern.insert(SigBit(wires[i], 0)); + + EXPECT_EQ(sig.size(), num_wires); + sig.remove2(pattern, &other); + EXPECT_EQ(sig.size(), num_wires / 2); + EXPECT_EQ(other.size(), num_wires / 2); + + // Spot-check: odd-indexed wires should remain + for (int i = 0; i < num_wires / 2; i++) { + EXPECT_EQ(sig[i].wire, wires[i * 2 + 1]); + } +} + +// Worst case: remove almost all elements +TEST_F(SigSpecRepTest, RemoveAlmostAllElements) +{ + const int num_wires = 10000; + auto wires = createWires(num_wires, 1); + SigSpec sig = wiresAsSigSpec(wires); + + // Remove all but last + pool pattern; + for (int i = 0; i < num_wires - 1; i++) + pattern.insert(SigBit(wires[i], 0)); + + EXPECT_EQ(sig.size(), num_wires); + sig.remove2(pattern, nullptr); + EXPECT_EQ(sig.size(), 1); + EXPECT_EQ(sig[0].wire, wires[num_wires - 1]); +} + +TEST_F(SigSpecRepTest, EmptyPattern) +{ + auto wires = createWires(1); + SigSpec sig(wires[0]); + pool empty_pattern; + + EXPECT_EQ(sig.size(), 4); + sig.remove2(empty_pattern, nullptr); + EXPECT_EQ(sig.size(), 4); + + // Verify the wire is unchanged + SigSpec expected(wires[0]); + EXPECT_EQ(sig, expected); +} + +// Test that NULL wire bits (constants) are not removed +TEST_F(SigSpecRepTest, NullWireBitsStay) +{ + auto wires = createWires(1); + SigSpec sig; + sig.append(wires[0]); + sig.append(Const(15, 4)); + + // Try to remove the constants + pool pattern; + SigSpec const_spec(Const(15, 4)); + for (auto &bit : const_spec) + pattern.insert(bit); + + EXPECT_EQ(sig.size(), 8); + sig.remove2(pattern, nullptr); + EXPECT_EQ(sig.size(), 8); // Constants stay + + // Verify original content is preserved + SigSpec expected; + expected.append(wires[0]); + expected.append(Const(15, 4)); + EXPECT_EQ(sig, expected); +} + +TEST_F(SigSpecRepTest, PartialBitRemoval) +{ + Wire* w = m->addWire("$w1", 8); + SigSpec sig(w); + + // Remove bits 2-5 + pool pattern; + for (int i = 2; i < 6; i++) + pattern.insert(SigBit(w, i)); + + EXPECT_EQ(sig.size(), 8); + sig.remove2(pattern, nullptr); + EXPECT_EQ(sig.size(), 4); + + // Verify only bits 0,1,6,7 remain + EXPECT_EQ(sig[0], SigBit(w, 0)); + EXPECT_EQ(sig[1], SigBit(w, 1)); + EXPECT_EQ(sig[2], SigBit(w, 6)); + EXPECT_EQ(sig[3], SigBit(w, 7)); +} + +YOSYS_NAMESPACE_END diff --git a/tests/unit/kernel/threadingTest.cc b/tests/unit/kernel/threadingTest.cc new file mode 100644 index 000000000..cbab4d118 --- /dev/null +++ b/tests/unit/kernel/threadingTest.cc @@ -0,0 +1,442 @@ +#include +#include +#include "kernel/threading.h" + +YOSYS_NAMESPACE_BEGIN + +class ThreadingTest : public testing::Test { +protected: + ThreadingTest() { + if (log_files.empty()) + log_files.emplace_back(stdout); + } +}; + +TEST_F(ThreadingTest, ParallelDispatchThreadPoolCreate) { + // Test creating a pool with 0 threads (treated as 1) + ParallelDispatchThreadPool pool0(0); + EXPECT_EQ(pool0.num_threads(), 1); + + // Test creating a pool with 1 thread + ParallelDispatchThreadPool pool1(1); + EXPECT_EQ(pool1.num_threads(), 1); + + // Test creating a pool with 2 threads + ParallelDispatchThreadPool pool2(2); + // YOSYS_MAX_THREADS or system configuration could mean we + // decide to only use one thread. + EXPECT_GE(pool2.num_threads(), 1); + EXPECT_LE(pool2.num_threads(), 2); +} + +TEST_F(ThreadingTest, ParallelDispatchThreadPoolRunSimple) { + ParallelDispatchThreadPool pool(2); + + std::atomic counter{0}; + pool.run([&counter](const ParallelDispatchThreadPool::RunCtx &) { + counter.fetch_add(1, std::memory_order_relaxed); + }); + + EXPECT_EQ(counter.load(), pool.num_threads()); +} + +TEST_F(ThreadingTest, ParallelDispatchThreadPoolRunMultiple) { + ParallelDispatchThreadPool pool(2); + + std::atomic counter{0}; + // Run multiple times to verify the pool can be reused + for (int i = 0; i < 5; ++i) + pool.run([&counter](const ParallelDispatchThreadPool::RunCtx &) { + counter.fetch_add(1, std::memory_order_relaxed); + }); + + EXPECT_EQ(counter.load(), pool.num_threads() * 5); +} + +TEST_F(ThreadingTest, ParallelDispatchThreadPoolRunCtxThreadNums) { + ParallelDispatchThreadPool pool(4); + + std::vector thread_nums(pool.num_threads(), -1); + pool.run([&thread_nums](const ParallelDispatchThreadPool::RunCtx &ctx) { + thread_nums[ctx.thread_num] = ctx.thread_num; + }); + + // Every thread should have recorded its own thread number + for (int i = 0; i < pool.num_threads(); ++i) + EXPECT_EQ(thread_nums[i], i); +} + +TEST_F(ThreadingTest, ParallelDispatchThreadPoolItemRange) { + ParallelDispatchThreadPool pool(3); + + const int num_items = 100; + std::vector> item_counts(num_items); + for (std::atomic &c : item_counts) + c.store(0); + + pool.run([&item_counts](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i : ctx.item_range(num_items)) + item_counts[i].fetch_add(1); + }); + + // Each item should have been processed exactly once + for (int i = 0; i < num_items; ++i) + EXPECT_EQ(item_counts[i].load(), 1); +} + +TEST_F(ThreadingTest, ParallelDispatchThreadPoolSubpool) { + ParallelDispatchThreadPool pool(4); + + // Subpool limited to 2 threads + ParallelDispatchThreadPool::Subpool subpool(pool, 2); + EXPECT_LE(subpool.num_threads(), 2); + + std::atomic counter{0}; + subpool.run([&counter](const ParallelDispatchThreadPool::RunCtx &) { + counter.fetch_add(1, std::memory_order_relaxed); + }); + + EXPECT_EQ(counter.load(), subpool.num_threads()); +} + +TEST_F(ThreadingTest, IntRangeIteration) { + IntRange range{3, 7}; + std::vector values; + for (int i : range) + values.push_back(i); + EXPECT_THAT(values, testing::ElementsAre(3, 4, 5, 6)); +} + +TEST_F(ThreadingTest, IntRangeEmpty) { + IntRange range{5, 5}; + for (int _ : range) + FAIL(); +} + +TEST_F(ThreadingTest, ItemRangeForWorker) { + EXPECT_EQ(item_range_for_worker(10, 0, 3), (IntRange{0, 4})); + EXPECT_EQ(item_range_for_worker(10, 1, 3), (IntRange{4, 7})); + EXPECT_EQ(item_range_for_worker(10, 2, 3), (IntRange{7, 10})); +} + +TEST_F(ThreadingTest, ItemRangeForWorkerZeroThreads) { + EXPECT_EQ(item_range_for_worker(10, 0, 0), (IntRange{0, 10})); +} + +TEST_F(ThreadingTest, ShardedVectorBasic) { + ParallelDispatchThreadPool pool(2); + ShardedVector vec(pool); + pool.run([&vec](const ParallelDispatchThreadPool::RunCtx &ctx) { + vec.insert(ctx, ctx.thread_num * 10); + vec.insert(ctx, ctx.thread_num * 10 + 1); + }); + + EXPECT_FALSE(vec.empty()); + + // Count elements + std::vector elements; + for (int v : vec) { + elements.push_back(v); + } + + if (pool.num_threads() == 2) + EXPECT_THAT(elements, testing::ElementsAre(0, 1, 10, 11)); + else + EXPECT_THAT(elements, testing::ElementsAre(0, 1)); +} + +TEST_F(ThreadingTest, MonotonicFlagBasic) { + MonotonicFlag flag; + EXPECT_FALSE(flag.load()); + flag.set(); + EXPECT_TRUE(flag.load()); + flag.set(); + EXPECT_TRUE(flag.load()); +} + +TEST_F(ThreadingTest, MonotonicFlagSetAndReturnOld) { + MonotonicFlag flag; + EXPECT_FALSE(flag.set_and_return_old()); + EXPECT_TRUE(flag.load()); + EXPECT_TRUE(flag.set_and_return_old()); +} + +TEST_F(ThreadingTest, ConcurrentQueueBasic) { + ConcurrentQueue queue; + queue.push_back(1); + queue.push_back(2); + queue.push_back(3); + + auto v1 = queue.pop_front(); + auto v2 = queue.pop_front(); + auto v3 = queue.pop_front(); + + ASSERT_TRUE(v1.has_value()); + ASSERT_TRUE(v2.has_value()); + ASSERT_TRUE(v3.has_value()); + EXPECT_EQ(*v1, 1); + EXPECT_EQ(*v2, 2); + EXPECT_EQ(*v3, 3); +} + +TEST_F(ThreadingTest, ConcurrentQueueTryPopEmpty) { + ConcurrentQueue queue; + auto v = queue.try_pop_front(); + EXPECT_FALSE(v.has_value()); +} + +TEST_F(ThreadingTest, ConcurrentQueueClose) { + ConcurrentQueue queue; + queue.push_back(42); + queue.close(); + + // Can still pop existing elements + auto v1 = queue.pop_front(); + ASSERT_TRUE(v1.has_value()); + EXPECT_EQ(*v1, 42); + + // After close and empty, pop_front returns nullopt + auto v2 = queue.pop_front(); + EXPECT_FALSE(v2.has_value()); +} + +TEST_F(ThreadingTest, ThreadPoolCreate) { + // pool_size of 0 means no worker threads + ThreadPool pool0(0, [](int) {}); + EXPECT_EQ(pool0.num_threads(), 0); + + // pool_size of 1 means 1 worker thread + std::atomic counter{0}; + { + ThreadPool pool1(1, [&counter](int thread_num) { + EXPECT_EQ(thread_num, 0); + counter.fetch_add(1); + }); + } +#ifdef YOSYS_ENABLE_THREADS + EXPECT_EQ(counter.load(), 1); +#else + EXPECT_EQ(counter.load(), 0); +#endif +} + +TEST_F(ThreadingTest, ThreadPoolMultipleThreads) { + std::atomic counter{0}; + { + ThreadPool pool(2, [&counter](int) { + counter.fetch_add(1); + }); + EXPECT_LE(pool.num_threads(), 2); + } +#ifdef YOSYS_ENABLE_THREADS + EXPECT_GE(counter.load(), 1); + EXPECT_LE(counter.load(), 2); +#else + EXPECT_EQ(counter.load(), 0); +#endif +} + +// Helper types for ShardedHashtable tests +struct IntValue { + using Accumulated = IntValue; + int value; + operator int() const { return value; } +}; + +struct IntValueEquality { + bool operator()(int a, int b) const { return a == b; } +}; + +TEST_F(ThreadingTest, ShardedHashtableBasic) { + ParallelDispatchThreadPool pool(1); + + using HashSet = ShardedHashtable>; + HashSet::Builder builder(pool); + + // Insert some values + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + builder.insert(ctx, {{10}, 10}); + builder.insert(ctx, {{20}, 20}); + builder.insert(ctx, {{30}, 30}); + }); + + // Process + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + builder.process(ctx); + }); + + // Build and lookup + HashSet set(builder); + const IntValue *found10 = set.find({{10}, 10}); + const IntValue *found20 = set.find({{20}, 20}); + const IntValue *found99 = set.find({{99}, 99}); + + ASSERT_NE(found10, nullptr); + ASSERT_NE(found20, nullptr); + EXPECT_EQ(found99, nullptr); + EXPECT_EQ(*found10, 10); + EXPECT_EQ(*found20, 20); +} + +TEST_F(ThreadingTest, ShardedHashtableParallelInsert) { + ParallelDispatchThreadPool pool(3); + + using HashSet = ShardedHashtable>; + HashSet::Builder builder(pool); + + // Insert values from multiple threads + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + for (int i = 0; i < 10; ++i) { + int val = ctx.thread_num * 100 + i; + builder.insert(ctx, {{val}, static_cast(val)}); + } + }); + + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + builder.process(ctx); + }); + + HashSet set(builder); + + // Verify all values can be found + for (int t = 0; t < pool.num_threads(); ++t) { + for (int i = 0; i < 10; ++i) { + int val = t * 100 + i; + const IntValue *found = set.find({{val}, static_cast(val)}); + ASSERT_NE(found, nullptr) << "Value " << val << " not found"; + EXPECT_EQ(*found, val); + } + } +} + +// Helper types for ShardedHashtable tests +struct IntDictValue { + using Accumulated = IntDictValue; + int key; + int value; + bool operator==(const IntDictValue &other) const { return key == other.key && value == other.value; } + bool operator!=(const IntDictValue &other) const { return !(*this == other); } +}; + +struct IntDictKeyEquality { + bool operator()(const IntDictValue &a, const IntDictValue &b) const { return a.key == b.key; } +}; + +// Collision handler that sums values +struct SumCollisionHandler { + void operator()(IntDictValue &existing, IntDictValue &incoming) const { + existing.value += incoming.value; + } +}; + +TEST_F(ThreadingTest, ShardedHashtableCollision) { + ParallelDispatchThreadPool pool(1); + + using HashSet = ShardedHashtable; + HashSet::Builder builder(pool); + + // Insert duplicate keys with same hash - duplicates should collapse + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + builder.insert(ctx, {{5, 10}, 5}); + builder.insert(ctx, {{5, 12}, 5}); // Duplicate key/hash + builder.insert(ctx, {{5, 14}, 5}); // Another duplicate + }); + + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + builder.process(ctx); + }); + + HashSet set(builder); + const IntDictValue *found = set.find({{5, 0}, 5}); + ASSERT_NE(found, nullptr); + // With default collision handler, first value is kept + EXPECT_EQ(*found, (IntDictValue{5, 36})); +} + +TEST_F(ThreadingTest, ShardedHashtableEmpty) { + ParallelDispatchThreadPool pool(1); + + using HashSet = ShardedHashtable>; + HashSet::Builder builder(pool); + + // Don't insert anything, just process + pool.run([&builder](const ParallelDispatchThreadPool::RunCtx &ctx) { + builder.process(ctx); + }); + + HashSet set(builder); + const IntValue *found = set.find({{42}, 42}); + EXPECT_EQ(found, nullptr); +} + +TEST_F(ThreadingTest, ConcurrentWorkQueueSingleThread) { + ConcurrentWorkQueue queue(1, 10); // 1 thread, batch size 10 + EXPECT_EQ(queue.num_threads(), 1); + + ThreadIndex thread{0}; + + // Push some items (less than batch size) + for (int i = 0; i < 5; ++i) + queue.push(thread, i); + + // Pop should return those items + std::vector batch = queue.pop_batch(thread); + EXPECT_THAT(batch, testing::UnorderedElementsAre(0, 1, 2, 3, 4)); + + // Next pop should return empty (all threads "waiting") + std::vector empty_batch = queue.pop_batch(thread); + EXPECT_TRUE(empty_batch.empty()); +} + +TEST_F(ThreadingTest, ConcurrentWorkQueueBatching) { + ConcurrentWorkQueue queue(1, 3); // batch size 3 + ThreadIndex thread{0}; + + queue.push(thread, 10); + queue.push(thread, 20); + queue.push(thread, 30); + queue.push(thread, 40); + queue.push(thread, 50); + + std::vector popped; + while (true) { + std::vector batch = queue.pop_batch(thread); + if (batch.empty()) + break; + popped.insert(popped.end(), batch.begin(), batch.end()); + } + EXPECT_THAT(popped, testing::UnorderedElementsAre(10, 20, 30, 40, 50)); +} + +TEST_F(ThreadingTest, ConcurrentWorkQueueParallel) { + ParallelDispatchThreadPool pool(2); + if (pool.num_threads() < 2) { + // Skip test if we don't have multiple threads + return; + } + + ConcurrentWorkQueue queue(2, 3); + std::atomic sum{0}; + + pool.run([&queue, &sum](const ParallelDispatchThreadPool::RunCtx &ctx) { + // Each thread pushes some work + for (int i = 0; i < 10; ++i) + queue.push(ctx, ctx.thread_num * 100 + i); + + // Each thread processes work until done + while (true) { + std::vector batch = queue.pop_batch(ctx); + if (batch.empty()) + break; + for (int v : batch) + sum.fetch_add(v); + } + }); + + // Thread 0 pushes: 0+1+2+...+9 = 45 + // Thread 1 pushes: 100+101+...+109 = 1045 + // Total = 45 + 1045 = 1090 + EXPECT_EQ(sum.load(), 1090); +} + +YOSYS_NAMESPACE_END diff --git a/tests/unit/opt/optDffFindComplementaryPatternTest.cc b/tests/unit/opt/optDffFindComplementaryPatternTest.cc new file mode 100644 index 000000000..7a89da6cd --- /dev/null +++ b/tests/unit/opt/optDffFindComplementaryPatternTest.cc @@ -0,0 +1,179 @@ +#include +#include "kernel/pattern.h" + +YOSYS_NAMESPACE_BEGIN + +class FindComplementaryPatternVarTest : public ::testing::Test { +protected: + RTLIL::Design *design; + RTLIL::Module *module; + RTLIL::Wire *wire_a; + RTLIL::Wire *wire_b; + RTLIL::Wire *wire_c; + RTLIL::Wire *bus; + + void SetUp() override { + design = new RTLIL::Design; + module = design->addModule(ID(test_module)); + wire_a = module->addWire(ID(a)); + wire_b = module->addWire(ID(b)); + wire_c = module->addWire(ID(c)); + bus = module->addWire(ID(bus), 4); + } + + void TearDown() override { + delete design; + } + + RTLIL::SigBit bit(RTLIL::Wire *w, int offset = 0) { + return RTLIL::SigBit(w, offset); + } +}; + +TEST_F(FindComplementaryPatternVarTest, EmptyPatterns) { + pattern_t left, right; + + auto result = find_complementary_pattern_var(left, right); + EXPECT_FALSE(result.has_value()); +} + +TEST_F(FindComplementaryPatternVarTest, IdenticalSingleVar) { + pattern_t left, right; + left[bit(wire_a)] = true; + right[bit(wire_a)] = true; + + auto result = find_complementary_pattern_var(left, right); + EXPECT_FALSE(result.has_value()); +} + +TEST_F(FindComplementaryPatternVarTest, ComplementarySingleVar) { + pattern_t left, right; + left[bit(wire_a)] = true; + right[bit(wire_a)] = false; + + auto result = find_complementary_pattern_var(left, right); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(result.value(), bit(wire_a)); +} + +TEST_F(FindComplementaryPatternVarTest, MissingKeyInRight) { + pattern_t left, right; + left[bit(wire_a)] = true; + left[bit(wire_b)] = false; + right[bit(wire_a)] = true; + + auto result = find_complementary_pattern_var(left, right); + EXPECT_FALSE(result.has_value()); +} + +TEST_F(FindComplementaryPatternVarTest, TwoVarsOneComplementary) { + pattern_t left, right; + left[bit(wire_a)] = true; + left[bit(wire_b)] = false; + right[bit(wire_a)] = true; + right[bit(wire_b)] = true; + + auto result = find_complementary_pattern_var(left, right); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(result.value(), bit(wire_b)); +} + +TEST_F(FindComplementaryPatternVarTest, TwoVarsBothComplementary) { + pattern_t left, right; + left[bit(wire_a)] = true; + left[bit(wire_b)] = false; + right[bit(wire_a)] = false; + right[bit(wire_b)] = true; + + auto result = find_complementary_pattern_var(left, right); + EXPECT_FALSE(result.has_value()); +} + +TEST_F(FindComplementaryPatternVarTest, LeftSubsetOfRight) { + pattern_t left, right; + left[bit(wire_a)] = true; + left[bit(wire_b)] = false; + right[bit(wire_a)] = true; + right[bit(wire_b)] = true; + right[bit(wire_c)] = false; + + auto result = find_complementary_pattern_var(left, right); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(result.value(), bit(wire_b)); +} + +TEST_F(FindComplementaryPatternVarTest, ThreeVarsAllSame) { + pattern_t left, right; + left[bit(wire_a)] = true; + left[bit(wire_b)] = false; + left[bit(wire_c)] = true; + right[bit(wire_a)] = true; + right[bit(wire_b)] = false; + right[bit(wire_c)] = true; + + auto result = find_complementary_pattern_var(left, right); + EXPECT_FALSE(result.has_value()); +} + +TEST_F(FindComplementaryPatternVarTest, PracticalPatternSimplification) { + pattern_t pattern1, pattern2; + pattern1[bit(bus, 0)] = true; + pattern1[bit(bus, 1)] = true; + pattern2[bit(bus, 0)] = true; + pattern2[bit(bus, 1)] = false; + + auto result = find_complementary_pattern_var(pattern1, pattern2); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(result.value(), bit(bus, 1)); + + // Swapped args + auto result2 = find_complementary_pattern_var(pattern2, pattern1); + ASSERT_TRUE(result2.has_value()); + EXPECT_EQ(result2.value(), bit(bus, 1)); +} + +TEST_F(FindComplementaryPatternVarTest, MuxTreeClockEnableDetection) { + pattern_t feedback_path1, feedback_path2; + feedback_path1[bit(wire_a)] = true; + feedback_path1[bit(wire_b)] = true; + feedback_path2[bit(wire_a)] = true; + feedback_path2[bit(wire_b)] = false; + + auto comp = find_complementary_pattern_var(feedback_path1, feedback_path2); + ASSERT_TRUE(comp.has_value()); + EXPECT_EQ(comp.value(), bit(wire_b)); + + pattern_t simplified = feedback_path1; + simplified.erase(comp.value()); + + EXPECT_EQ(simplified.size(), 1); + EXPECT_TRUE(simplified.count(bit(wire_a))); + EXPECT_TRUE(simplified[bit(wire_a)]); +} + +TEST_F(FindComplementaryPatternVarTest, AsymmetricPatterns) { + pattern_t left, right; + left[bit(wire_a)] = true; + right[bit(wire_a)] = false; + right[bit(wire_b)] = true; + right[bit(wire_c)] = false; + + auto result = find_complementary_pattern_var(left, right); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(result.value(), bit(wire_a)); +} + +TEST_F(FindComplementaryPatternVarTest, WireOffsetDistinction) { + pattern_t left, right; + left[bit(bus, 0)] = true; + left[bit(bus, 1)] = false; + right[bit(bus, 0)] = true; + right[bit(bus, 1)] = true; + right[bit(bus, 2)] = false; + + auto result = find_complementary_pattern_var(left, right); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(result.value(), bit(bus, 1)); +} + +YOSYS_NAMESPACE_END diff --git a/tests/various/.gitignore b/tests/various/.gitignore index e116179ae..1431c4096 100644 --- a/tests/various/.gitignore +++ b/tests/various/.gitignore @@ -4,6 +4,9 @@ /plugin.so /plugin_search /plugin.so.dSYM +/ezcmdline_plugin.so +/ezcmdline_plugin.so.dSYM /temp /smtlib2_module.smt2 /smtlib2_module-filtered.smt2 +/*.aig diff --git a/tests/various/const_shift_empty_arg.ys b/tests/various/const_shift_empty_arg.ys new file mode 100644 index 000000000..4073e198d --- /dev/null +++ b/tests/various/const_shift_empty_arg.ys @@ -0,0 +1,49 @@ +# Regression test for #5684: const_shift_worker must not crash when arg1 is +# empty. + +read_json << EOF +{ + "modules": { + "sshl": { + "cells": { + "sshlCell": { + "connections": { + "A": [], + "B": [3], + "Y": [1] + }, + "parameters": { + "A_SIGNED": "1", + "A_WIDTH": "0", + "B_SIGNED": "0", + "B_WIDTH": "1", + "Y_WIDTH": "1" + }, + "port_directions": { + "A": "input", + "B": "input", + "Y": "output" + }, + "type": "$sshl" + } + }, + "ports": { + "A": { + "bits": [], + "direction": "input" + }, + "B": { + "bits": [3], + "direction": "input" + }, + "Y": { + "bits": [1], + "direction": "output" + } + } + } + } +} +EOF + +eval -set B 0 -show Y sshl diff --git a/tests/various/debugon.ys b/tests/various/debugon.ys new file mode 100644 index 000000000..a984a26bb --- /dev/null +++ b/tests/various/debugon.ys @@ -0,0 +1,14 @@ +# Test debug -on/-off modes + +design -reset + +read_verilog < exits 10 with v 1 +# - UNSAT: p cnf 1 2; clauses: "1 0" and "-1 0" -> exits 20 +set -e + +if [ "$#" -ne 1 ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +awk ' +BEGIN { + vars = 0; + clauses = 0; + clause_count = 0; + clause_data = ""; + current = ""; +} +$1 == "c" { + next; +} +$1 == "p" && $2 == "cnf" { + vars = $3; + clauses = $4; + next; +} +{ + for (i = 1; i <= NF; i++) { + lit = $i; + if (lit == 0) { + clause_count++; + if (clause_data != "") + clause_data = clause_data ";" current; + else + clause_data = current; + current = ""; + } else { + if (current == "") + current = lit; + else + current = current "," lit; + } + } +} +END { + if (vars == 1 && clause_count == 1 && clause_data == "1") { + print "s SATISFIABLE"; + print "v 1 0"; + exit 10; + } + if (vars == 1 && clause_count == 2 && clause_data == "1;-1") { + print "s UNSATISFIABLE"; + exit 20; + } + print "c unexpected CNF for dummy solver"; + print "c vars=" vars " header_clauses=" clauses " parsed_clauses=" clause_count " data=" clause_data; + exit 1; +} +' "$1" diff --git a/tests/various/ezcmdline_plugin.cc b/tests/various/ezcmdline_plugin.cc new file mode 100644 index 000000000..b775829b3 --- /dev/null +++ b/tests/various/ezcmdline_plugin.cc @@ -0,0 +1,53 @@ +#include "kernel/yosys.h" +#include "libs/ezsat/ezcmdline.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct EzCmdlineTestPass : public Pass { + EzCmdlineTestPass() : Pass("ezcmdline_test", "smoke-test ezCmdlineSAT") { } + void execute(std::vector args, RTLIL::Design *design) override + { + std::string cmd; + size_t argidx = 1; + + while (argidx < args.size()) { + if (args[argidx] == "-cmd" && argidx + 1 < args.size()) { + cmd = args[argidx + 1]; + argidx += 2; + continue; + } + break; + } + + extra_args(args, argidx, design); + + if (cmd.empty()) + log_error("Missing -cmd argument.\n"); + + ezCmdlineSAT sat(cmd); + sat.non_incremental(); + + // assume("A") adds a permanent CNF clause "A". + sat.assume(sat.VAR("A")); + + std::vector model_expressions; + std::vector model_values; + model_expressions.push_back(sat.VAR("A")); + + // Expect SAT with A=true. + if (!sat.solve(model_expressions, model_values)) + log_error("ezCmdlineSAT SAT case failed.\n"); + if (model_values.size() != 1 || !model_values[0]) + log_error("ezCmdlineSAT SAT model mismatch.\n"); + + // Passing NOT("A") here adds a temporary unit clause for this solve call, + // so the solver sees A && !A and must return UNSAT. + if (sat.solve(model_expressions, model_values, sat.NOT("A"))) + log_error("ezCmdlineSAT UNSAT case failed.\n"); + + log("ezcmdline_test passed!\n"); + } +} EzCmdlineTestPass; + +PRIVATE_NAMESPACE_END diff --git a/tests/various/ezcmdline_plugin.sh b/tests/various/ezcmdline_plugin.sh new file mode 100644 index 000000000..cad0475a8 --- /dev/null +++ b/tests/various/ezcmdline_plugin.sh @@ -0,0 +1,12 @@ +set -e + +DIR=$(cd "$(dirname "$0")" && pwd) +BASEDIR=$(cd "$DIR/../.." && pwd) +rm -f "$DIR/ezcmdline_plugin.so" +chmod +x "$DIR/ezcmdline_dummy_solver" +CXXFLAGS=$("$BASEDIR/yosys-config" --cxxflags) +DATDIR=$("$BASEDIR/yosys-config" --datdir) +DATDIR=${DATDIR//\//\\\/} +CXXFLAGS=${CXXFLAGS//$DATDIR/..\/..\/share} +"$BASEDIR/yosys-config" --exec --cxx ${CXXFLAGS} -I"$BASEDIR" --ldflags -shared -o "$DIR/ezcmdline_plugin.so" "$DIR/ezcmdline_plugin.cc" +"$BASEDIR/yosys" -m "$DIR/ezcmdline_plugin.so" -p "ezcmdline_test -cmd $DIR/ezcmdline_dummy_solver" | grep -q "ezcmdline_test passed!" diff --git a/tests/various/generate_mk.py b/tests/various/generate_mk.py new file mode 100644 index 000000000..aa88bca13 --- /dev/null +++ b/tests/various/generate_mk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import sys +sys.path.append("..") + +import gen_tests_makefile + +gen_tests_makefile.generate(["--yosys-scripts", "--bash"]) diff --git a/tests/various/json_param_defaults.v b/tests/various/json_param_defaults.v new file mode 100644 index 000000000..7d3b94a68 --- /dev/null +++ b/tests/various/json_param_defaults.v @@ -0,0 +1,10 @@ +module json_param_defaults #( + parameter WIDTH = 8, + parameter SIGNED = 1 +) ( + input [WIDTH-1:0] a, + output [WIDTH-1:0] y +); + wire [WIDTH-1:0] y_int = a << SIGNED; + assign y = y_int; +endmodule diff --git a/tests/various/json_param_defaults.ys b/tests/various/json_param_defaults.ys new file mode 100644 index 000000000..45e312de2 --- /dev/null +++ b/tests/various/json_param_defaults.ys @@ -0,0 +1,8 @@ +! mkdir -p temp +read_verilog -sv json_param_defaults.v +write_json temp/json_param_defaults.json +design -reset +read_json temp/json_param_defaults.json +write_verilog -noattr -defaultparams temp/json_param_defaults.v +! grep -qF "parameter WIDTH = 32'd8" temp/json_param_defaults.v +! grep -qF "parameter SIGNED = 32'd1" temp/json_param_defaults.v diff --git a/tests/various/muxpack_wide_y.ys b/tests/various/muxpack_wide_y.ys new file mode 100644 index 000000000..142119875 --- /dev/null +++ b/tests/various/muxpack_wide_y.ys @@ -0,0 +1,9 @@ +# Regression test for issue #5734: muxpack crash when $logic_not / $eq / $reduce_or +# has Y port width > 1 (e.g. boolean result assigned to a wide wire). +read_verilog < run-test.mk.tmp && mv run-test.mk.tmp run-test.mk diff --git a/tests/verilog/.gitignore b/tests/verilog/.gitignore index b16ed0890..6a226989c 100644 --- a/tests/verilog/.gitignore +++ b/tests/verilog/.gitignore @@ -1,3 +1,4 @@ +/bug5572.v /const_arst.v /const_sr.v /doubleslash.v diff --git a/tests/verilog/automatic_lifetime.ys b/tests/verilog/automatic_lifetime.ys new file mode 100644 index 000000000..84e21e088 --- /dev/null +++ b/tests/verilog/automatic_lifetime.ys @@ -0,0 +1,104 @@ +# Automatic reg as intermediate value in always @(*) +# The result must be provably equivalent to the direct expression. +# No latch or DFF must be created for tmp. +design -reset +read_verilog -sv <> 4) & 1'b1)); +endmodule +EOF +proc +async2sync +select -assert-none t:$dff t:$dlatch %% +sat -verify -prove-asserts -show-all + +# automatic in a clocked block — only the explicitly registered +# output (result) must get a DFF; the automatic temp must not. +design -reset +read_verilog -sv < test.log 2>&1 || echo {workdir}: failed > status\n" - f"\t@cat {workdir}/status\n" - f"\t@grep '^.*: ok' {workdir}/status\n" - , - file=makefile, - ) + with gen_tests_makefile.redirect_stdout(makefile): + gen_tests_makefile.generate_target(workdir, + f"cd {workdir} && python3 -u ../test.py -S {args.seed} -c {args.count}{seq_arg} > test.log 2>&1") def cell_test(name, cell, inputs, outputs, params, initial={}, defclock=False, seq=False): ports = [] @@ -119,10 +121,6 @@ def dff_test(width, pol, defclock): def dffe_test(width, pol, enpol, defclock): cell_test(f"dffe_{width}{'np'[pol]}{'np'[enpol]}{'xd'[defclock]}", 'dffe', {"CLK": 1, "EN": 1, "D": width}, {"Q": width}, {"WIDTH": width, "CLK_POLARITY": int(pol), "EN_POLARITY": int(enpol)}, defclock=defclock, seq=True) - -print(".PHONY: all", file=makefile) -print("all:\n\t@echo done\n", file=makefile) - for cell in ["not", "pos", "neg"]: if args.more: unary_test(cell, 1, False, 1) diff --git a/tests/xprop/run-test.sh b/tests/xprop/run-test.sh deleted file mode 100755 index 303c0bb3b..000000000 --- a/tests/xprop/run-test.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source ../common-env.sh -set -e - -python3 generate.py $@ -${MAKE:-make} -f run-test.mk