diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 9f1da94da..000000000 --- a/.dockerignore +++ /dev/null @@ -1,12 +0,0 @@ -.editorconfig -.gitignore -.gitmodules -.github -.git -Dockerfile -README.md -manual -guidelines -CodeOfConduct -.travis -.travis.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c758bf1f6..ce2780d6f 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -5,4 +5,3 @@ contact_links: - name: IRC Channel url: https://web.libera.chat/#yosys about: "#yosys on irc.libera.chat" - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 49d86f341..19785d22a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -22,4 +22,3 @@ body: description: "A clear and detailed description of the feature." validations: required: true - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d8d929f3f..428735733 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,4 +6,4 @@ _Explain how this is achieved._ _Make sure your change comes with tests. If not possible, share how a reviewer might evaluate it._ -_These template prompts can be deleted when you're done responding to them._ \ No newline at end of file +_These template prompts can be deleted when you're done responding to them._ diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml index c1d3e2b01..6f631ff30 100644 --- a/.github/actions/setup-build-env/action.yml +++ b/.github/actions/setup-build-env/action.yml @@ -33,21 +33,21 @@ runs: # and docs/source/getting_started/installation.rst to match. - name: Linux common dependencies if: runner.os == 'Linux' - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: gawk git make python3 version: ${{ inputs.runs-on }}-commonys - name: Linux build dependencies if: runner.os == 'Linux' && inputs.get-build-deps == 'true' - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: 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 if: runner.os == 'Linux' && inputs.get-docs-deps == 'true' - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: graphviz xdot version: ${{ inputs.runs-on }}-docsys @@ -56,7 +56,7 @@ runs: if: runner.os == 'macOS' shell: bash run: | - brew bundle + brew install bison flex gawk libffi git pkg-config python3 bash googletest tcl-tk llvm - name: Linux runtime environment if: runner.os == 'Linux' @@ -70,7 +70,7 @@ runs: shell: bash run: | echo "${{ github.workspace }}/.local/bin" >> $GITHUB_PATH - echo "$(brew --prefix llvm@20)/bin" >> $GITHUB_PATH + echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH echo "$(brew --prefix flex)/bin" >> $GITHUB_PATH echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV diff --git a/.github/actions/setup-iverilog/action.yml b/.github/actions/setup-iverilog/action.yml index 0acb582e3..3457303e2 100644 --- a/.github/actions/setup-iverilog/action.yml +++ b/.github/actions/setup-iverilog/action.yml @@ -11,7 +11,7 @@ runs: steps: - name: iverilog Linux deps if: steps.restore-iverilog.outputs.cache-hit != 'true' && runner.os == 'Linux' - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: autoconf gperf make gcc g++ bison flex libbz2-dev version: ${{ inputs.runs-on }}-iverilog @@ -40,7 +40,7 @@ runs: make -j$procs make install - - uses: actions/cache/restore@v4 + - uses: actions/cache/restore@v6 id: restore-iverilog with: path: .local/ @@ -62,7 +62,7 @@ runs: run: | iverilog -V - - uses: actions/cache/save@v4 + - uses: actions/cache/save@v6 id: save-iverilog if: steps.restore-iverilog.outputs.cache-hit != 'true' with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 74ecbe0ad..2c4d36a83 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -3,7 +3,7 @@ name: "CodeQL" on: workflow_dispatch: schedule: - - cron: '0 3 * * *' + - cron: '0 3 * * 6' jobs: analyze: @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: submodules: true persist-credentials: false @@ -29,7 +29,13 @@ jobs: queries: security-extended,security-and-quality - name: Build - run: make yosys -j6 + run: | + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + + cmake -C Configuration.cmake -B build . -DYOSYS_WITHOUT_ABC=ON -DYOSYS_WITHOUT_SLANG=ON + cmake --build build -j6 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/extra-builds.yml b/.github/workflows/extra-builds.yml index 7209b3645..4601f1b12 100644 --- a/.github/workflows/extra-builds.yml +++ b/.github/workflows/extra-builds.yml @@ -3,8 +3,8 @@ name: Test extra build flows on: pull_request: merge_group: - #push: - # branches: [ main ] + push: + branches: [ main ] workflow_dispatch: jobs: @@ -15,7 +15,7 @@ jobs: steps: - id: skip_check if: ${{ github.event_name != 'merge_group' }} - uses: fkirc/skip-duplicate-actions@v5 + uses: fkirc/skip-duplicate-actions@v5.3.2 with: # don't run on documentation changes paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' @@ -27,62 +27,136 @@ jobs: run: | if [ "${{ github.event_name }}" = "merge_group" ]; then echo "should_skip=false" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" = "push" ]; then + should_skip=false 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: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' - steps: - - 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@v7 - with: - name: vcxsrc - path: yosys-win32-vcxsrc-latest.zip - vs-build: name: Visual Studio build runs-on: windows-latest - needs: [vs-prep, pre_job] - if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' + needs: [pre_job] + if: (github.event_name == 'push' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' steps: - - uses: actions/download-artifact@v8 + - uses: actions/checkout@v7 with: - name: vcxsrc - path: . - - name: unzip - run: unzip yosys-win32-vcxsrc-latest.zip - - name: setup-msbuild - uses: microsoft/setup-msbuild@v2 - - name: MSBuild - working-directory: yosys-win32-vcxsrc-latest - run: msbuild YosysVS.sln /p:PlatformToolset=v142 /p:Configuration=Release /p:WindowsTargetPlatformVersion=10.0.26100.0 + submodules: true + persist-credentials: false + + - name: Setup MSVC + uses: TheMrMilchmann/setup-msvc-dev@v4 + with: + arch: x64 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: vs-build + save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + restore-keys: | + vs-build- + + - name: Install flex/bison + shell: pwsh + run: | + choco install winflexbison3 --no-progress + + # Make tools visible to CMake + echo "C:\Program Files (x86)\GnuWin32\bin" | Out-File -Append -FilePath $env:GITHUB_PATH + echo "C:\ProgramData\chocolatey\lib\winflexbison3\tools" | Out-File -Append -FilePath $env:GITHUB_PATH + + - name: Configure CMake + run: > + cmake -S . -B build + -G Ninja + -DCMAKE_BUILD_TYPE=Release + -DYOSYS_COMPILER_LAUNCHER=ccache + + - name: Build + run: > + cmake --build build + --config Release + --parallel + + mingw-build: + name: MINGW64 build + runs-on: windows-latest + needs: [pre_job] + if: (github.event_name == 'push' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' + steps: + - uses: actions/checkout@v7 + with: + submodules: true + persist-credentials: false + + - name: Setup MSYS2 (MINGW64) + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + + install: >- + base-devel + bison + flex + gawk + diffutils + make + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-cmake + mingw-w64-x86_64-gtest + mingw-w64-x86_64-pkgconf + mingw-w64-x86_64-python + mingw-w64-x86_64-tcl + mingw-w64-x86_64-libffi + mingw-w64-x86_64-git + mingw-w64-x86_64-ccache + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: mingw-build + save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + restore-keys: | + mingw-build- + + - name: Build Yosys + shell: msys2 {0} + run: | + set -e + procs=$(nproc) + rm -rf build + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DYOSYS_COMPILER_LAUNCHER=ccache + cmake --build build -j${procs} + ctest --test-dir build/tests/unit --output-on-failure wasi-build: name: WASI build needs: pre_job - if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'push' || 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@v5 + - uses: actions/checkout@v7 with: submodules: true persist-credentials: false + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: wasi-build + save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + restore-keys: | + wasi-build- + - name: Build run: | - 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 + WASI_VER=33 + WASI_SDK=wasi-sdk-${WASI_VER}.0-x86_64-linux + WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_VER}/${WASI_SDK}.tar.gz if ! [ -d ${WASI_SDK} ]; then curl -L ${WASI_SDK_URL} | tar xzf -; fi - + WASI_SDK_PATH=$(pwd)/${WASI_SDK} FLEX_VER=2.6.4 FLEX=flex-${FLEX_VER} FLEX_URL=https://github.com/westes/flex/releases/download/v${FLEX_VER}/${FLEX}.tar.gz @@ -94,50 +168,16 @@ jobs: make && make install) - mkdir -p build - cat > build/Makefile.conf <> Makefile.conf - echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf - echo "ENABLE_CCACHE := 1" >> Makefile.conf - echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf - make -j$procs + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + + cmake -C Configuration.cmake -B build . + cmake --build build -j$procs - name: Prepare docs shell: bash run: - make docs/prep -j$procs TARGETS= EXTRA_TARGETS= + cmake --build build --target docs-prepare -j$procs - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: cmd-ref-${{ github.sha }} path: | @@ -83,12 +83,12 @@ jobs: - name: Install doc prereqs shell: bash run: | - make docs/reqs + make -C docs reqs - name: Test build docs shell: bash run: | - make -C docs html -j$procs TARGETS= EXTRA_TARGETS= + cmake --build build --target docs-html -j$procs - name: Trigger RTDs build if: ${{ needs.check_docs_rebuild.outputs.docs_export == 'true' && github.repository == 'YosysHQ/yosys' }} diff --git a/.github/workflows/source-vendor.yml b/.github/workflows/source-vendor.yml index d85b2af08..b64306c29 100644 --- a/.github/workflows/source-vendor.yml +++ b/.github/workflows/source-vendor.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository with submodules - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: submodules: 'recursive' persist-credentials: false diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 5e990d0a5..783210254 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -3,8 +3,8 @@ name: Build and run tests on: pull_request: merge_group: - #push: - # branches: [ main ] + push: + branches: [ main ] workflow_dispatch: jobs: @@ -15,7 +15,7 @@ jobs: steps: - id: skip_check if: ${{ github.event_name != 'merge_group' }} - uses: fkirc/skip-duplicate-actions@v5 + uses: fkirc/skip-duplicate-actions@v5.3.2 with: # don't run on documentation changes paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' @@ -26,7 +26,7 @@ jobs: - id: set_output run: | if [ "${{ github.event_name }}" = "merge_group" ]; then - echo "should_skip=false" >> $GITHUB_OUTPUT + echo "should_skip=true" >> $GITHUB_OUTPUT else echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT fi @@ -38,7 +38,7 @@ jobs: steps: - id: skip_check if: ${{ github.event_name != 'merge_group' }} - uses: fkirc/skip-duplicate-actions@v5 + uses: fkirc/skip-duplicate-actions@v5.3.2 with: # don't run on readme changes paths_ignore: '["**/README.md"]' @@ -49,7 +49,9 @@ jobs: - id: set_output run: | if [ "${{ github.event_name }}" = "merge_group" ]; then - echo "should_skip=false" >> $GITHUB_OUTPUT + echo "should_skip=true" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" = "push" ]; then + should_skip=false else echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT fi @@ -68,7 +70,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: submodules: true persist-credentials: false @@ -79,24 +81,31 @@ jobs: runs-on: ${{ matrix.os }} get-build-deps: true + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: test-build-${{ matrix.os }} + save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + restore-keys: | + test-build-${{ matrix.os }}- + - name: Build shell: bash run: | - mkdir build - cd build - make -f ../Makefile config-$CC - make -f ../Makefile -j$procs - make -f ../Makefile unit-test -j$procs + rm -rf build + cmake -B build . -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DYOSYS_COMPILER_LAUNCHER=ccache -DYOSYS_USE_BUNDLED_LIBS=ON + cmake --build build -j$procs + ctest --test-dir build/tests/unit - name: Log yosys-config output run: | - ./yosys-config || true + ./build/yosys-config || true - name: Compress build shell: bash run: | cd build - tar -cvf ../build.tar share/ yosys yosys-* libyosys.so + tar -cvf ../build.tar share/ yosys yosys-* - name: Store build artifact uses: actions/upload-artifact@v7 @@ -109,7 +118,7 @@ jobs: name: Run tests runs-on: ${{ matrix.os }} needs: [build-yosys, pre_job] - if: needs.pre_job.outputs.should_skip != 'true' + if: github.event_name != 'push' && needs.pre_job.outputs.should_skip != 'true' env: CC: clang strategy: @@ -118,7 +127,7 @@ jobs: fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: persist-credentials: false @@ -136,17 +145,18 @@ jobs: - name: Uncompress build shell: bash - run: - tar -xvf build.tar + run: | + mkdir -p build + tar -xvf build.tar -C build - name: Log yosys-config output run: | - ./yosys-config || true + ./build/yosys-config || true - name: Run tests shell: bash run: | - make -j$procs vanilla-test TARGETS= EXTRA_TARGETS= CONFIG=$CC + make -C tests -j$procs vanilla-test - name: Report errors if: ${{ failure() }} @@ -158,7 +168,7 @@ jobs: name: Run test_cell runs-on: ${{ matrix.os }} needs: [build-yosys, pre_job] - if: needs.pre_job.outputs.should_skip != 'true' + if: github.event_name != 'push' && needs.pre_job.outputs.should_skip != 'true' env: CC: clang strategy: @@ -166,7 +176,7 @@ jobs: os: [ubuntu-latest] steps: - name: Checkout Yosys - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: persist-credentials: false @@ -197,16 +207,14 @@ jobs: name: Run docs tests runs-on: ${{ matrix.os }} needs: [build-yosys, pre_docs_job] - if: needs.pre_docs_job.outputs.should_skip != 'true' - env: - CC: clang + if: github.event_name != 'push' && needs.pre_job.outputs.should_skip != 'true' strategy: matrix: os: [ubuntu-latest] fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: persist-credentials: false @@ -224,12 +232,13 @@ jobs: - name: Uncompress build shell: bash - run: - tar -xvf build.tar + run: | + mkdir -p build + tar -xvf build.tar -C build - name: Log yosys-config output run: | - ./yosys-config || true + ./build/yosys-config || true - name: Run tests shell: bash @@ -240,14 +249,14 @@ 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_owner == 'YosysHQ' }} + if: ${{ github.event_name != 'push' && needs.pre_docs_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} strategy: matrix: docs-target: [html, latexpdf] fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: submodules: true persist-credentials: false @@ -258,23 +267,26 @@ jobs: - name: Build Yosys run: | - make config-clang - echo "ENABLE_CCACHE := 1" >> Makefile.conf - echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf - make -j$procs + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + + cmake -C Configuration.cmake -B build . + cmake --build build -j$procs - name: Install doc prereqs shell: bash run: | - make docs/reqs + make -C docs reqs - name: Build docs shell: bash run: | - make docs DOC_TARGET=${{ matrix.docs-target }} -j$procs + cmake --build build --target docs-${{ matrix.docs-target }} -j$procs - name: Store docs build artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: docs-build-${{ matrix.docs-target }} path: docs/build/ diff --git a/.github/workflows/test-compile.yml b/.github/workflows/test-compile.yml index 99e4973a7..b004959d3 100644 --- a/.github/workflows/test-compile.yml +++ b/.github/workflows/test-compile.yml @@ -3,8 +3,8 @@ name: Compiler testing on: pull_request: merge_group: - #push: - # branches: [ main ] + push: + branches: [ main ] workflow_dispatch: jobs: @@ -15,7 +15,7 @@ jobs: steps: - id: skip_check if: ${{ github.event_name != 'merge_group' }} - uses: fkirc/skip-duplicate-actions@v5 + uses: fkirc/skip-duplicate-actions@v5.3.2 with: # don't run on documentation changes paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' @@ -27,6 +27,8 @@ jobs: run: | if [ "${{ github.event_name }}" = "merge_group" ]; then echo "should_skip=false" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" = "push" ]; then + should_skip=false else echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT fi @@ -34,32 +36,28 @@ jobs: test-compile: runs-on: ${{ matrix.os }} needs: pre_job - if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' + if: (github.event_name == 'push' || 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' }} strategy: matrix: os: - ubuntu-latest compiler: # oldest supported - - 'clang-14' + - 'clang-16' - 'gcc-11' # newest, make sure to update maximum standard step to match - 'clang-22' - - 'gcc-15' + - 'gcc-16' include: - # macOS x86 - - os: macos-15-intel - compiler: 'clang-22' # macOS arm - os: macos-latest compiler: 'clang-22' fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: submodules: true persist-credentials: false @@ -70,11 +68,18 @@ jobs: runs-on: ${{ matrix.os }} get-build-deps: true + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: test-compile-${{ matrix.os }}-${{ matrix.compiler }} + save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + restore-keys: | + test-compile-${{ matrix.os }}-${{ matrix.compiler }}- + - name: Setup Cpp uses: aminya/setup-cpp@v1 with: compiler: ${{ matrix.compiler }} - gcc: ${{ (matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-14') && '12' || '' }} - name: Tool versions shell: bash @@ -82,25 +87,22 @@ jobs: $CC --version $CXX --version - - name: Fix clang-14 toolchain - if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-14' - run: | - echo 'CXXFLAGS=--gcc-toolchain=/usr -isystem /usr/include/c++/12 -isystem /usr/include/x86_64-linux-gnu/c++/12' >> $GITHUB_ENV - # minimum standard - name: Build C++20 shell: bash run: | - make config-$CC_SHORT - make -j$procs CXXSTD=c++20 compile-only + rm -rf build + cmake -B build -DCMAKE_CXX_STANDARD=20 -DYOSYS_COMPILER_LAUNCHER=ccache . --fresh + cmake --build build --target yosys -j$procs # maximum standard, only on newest compilers - name: Build C++26 - if: ${{ matrix.compiler == 'clang-22' || matrix.compiler == 'gcc-15' }} + if: ${{ matrix.compiler == 'clang-22' || matrix.compiler == 'gcc-16' }} shell: bash run: | - make config-$CC_SHORT - make -j$procs CXXSTD=c++26 compile-only + rm -rf build + cmake -B build -DCMAKE_CXX_STANDARD=26 -DYOSYS_COMPILER_LAUNCHER=ccache . --fresh + cmake --build build --target yosys -j$procs test-compile-result: runs-on: ubuntu-latest diff --git a/.github/workflows/test-sanitizers.yml b/.github/workflows/test-sanitizers.yml index 6f3c10903..0029fdd8b 100644 --- a/.github/workflows/test-sanitizers.yml +++ b/.github/workflows/test-sanitizers.yml @@ -15,7 +15,7 @@ jobs: steps: - id: skip_check if: ${{ github.event_name != 'merge_group' }} - uses: fkirc/skip-duplicate-actions@v5 + uses: fkirc/skip-duplicate-actions@v5.3.2 with: # don't run on documentation changes paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' @@ -27,54 +27,49 @@ jobs: run: | if [ "${{ github.event_name }}" = "merge_group" ]; then echo "should_skip=false" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" = "push" ]; then + should_skip=false else echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT fi - run_san: - name: Build and run tests - runs-on: ${{ matrix.os }} + test-sanitizers: + runs-on: [self-hosted, linux, x64, fast] needs: pre_job 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 + ASAN_OPTIONS: halt_on_error=1 detect_container_overflow=0 UBSAN_OPTIONS: halt_on_error=1 - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - sanitizer: ['undefined,address'] - fail-fast: false steps: - name: Checkout Yosys - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: submodules: true persist-credentials: false - - name: Setup environment - uses: ./.github/actions/setup-build-env - with: - runs-on: ${{ matrix.os }} - get-build-deps: true - get-test-deps: true - get-iverilog: true + - name: Runtime environment + run: | + echo "procs=$(nproc)" >> $GITHUB_ENV - name: Build shell: bash run: | - make config-$CC - echo 'SANITIZER = ${{ matrix.sanitizer }}' >> Makefile.conf - make -j$procs + rm -rf build + cmake -B build . \ + -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_BUILD_TYPE=Sanitize -DSANITIZE='undefined,address' \ + -DYOSYS_COMPILER_LAUNCHER=ccache + cmake --build build -j$procs - name: Log yosys-config output run: | - ./yosys-config || true + ./build/yosys-config || true - name: Run tests shell: bash run: | - make -j$procs vanilla-test TARGETS= EXTRA_TARGETS= + make -C tests -j$procs vanilla-test - name: Report errors if: ${{ failure() }} @@ -85,7 +80,7 @@ jobs: test-sanitizers-result: runs-on: ubuntu-latest needs: - - run_san + - test-sanitizers if: always() steps: - name: Check results @@ -96,4 +91,4 @@ jobs: echo "Some jobs failed or were cancelled" exit 1 fi - - run: echo "All good" \ No newline at end of file + - run: echo "All good" diff --git a/.github/workflows/test-verific-cfg.yml b/.github/workflows/test-verific-cfg.yml index 232ca6bd7..733eb2989 100644 --- a/.github/workflows/test-verific-cfg.yml +++ b/.github/workflows/test-verific-cfg.yml @@ -9,7 +9,7 @@ jobs: runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: persist-credentials: false submodules: true @@ -19,91 +19,77 @@ jobs: - 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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "systemverilog" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "vhdl" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "vhdl;systemverilog" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "systemverilog;hier_tree" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "vhdl;hier_tree" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "systemverilog;vhdl;hier_tree" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -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 + rm -rf build Configuration.cmake + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_FEATURES "systemverilog;vhdl;hier_tree;edif;liberty" CACHE STRING "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . + cmake --build build -j$procs diff --git a/.github/workflows/test-verific.yml b/.github/workflows/test-verific.yml index bdd35428a..54d582063 100644 --- a/.github/workflows/test-verific.yml +++ b/.github/workflows/test-verific.yml @@ -3,8 +3,8 @@ name: Build and run tests with Verific (Linux) on: pull_request: merge_group: - #push: - # branches: [ main ] + push: + branches: [ main ] workflow_dispatch: jobs: @@ -14,8 +14,8 @@ jobs: should_skip: ${{ steps.set_output.outputs.should_skip }} steps: - id: skip_check - if: ${{ github.event_name != 'merge_group' }} - uses: fkirc/skip-duplicate-actions@v5 + if: ${{ github.event_name != 'merge_group' && github.event_name != 'push' }} + uses: fkirc/skip-duplicate-actions@v5.3.2 with: # don't run on documentation changes paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' @@ -25,7 +25,7 @@ jobs: - id: set_output run: | - if [ "${{ github.event_name }}" = "merge_group" ]; then + if [ "${{ github.event_name }}" = "merge_group" ] || [ "${{ github.event_name }}" = "push" ]; then echo "should_skip=false" >> $GITHUB_OUTPUT else echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT @@ -37,7 +37,7 @@ jobs: runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: persist-credentials: false submodules: true @@ -47,29 +47,26 @@ jobs: mkdir -p "${GITHUB_WORKSPACE}/coverage" echo "LLVM_PROFILE_FILE=${GITHUB_WORKSPACE}/coverage/coverage_%p.profraw" >> $GITHUB_ENV echo "LLVM_PROFILE_FILE_BUFFER_SIZE=0" >> $GITHUB_ENV - - - name: Skip generating files - if: ${{ github.event_name != 'merge_group' && github.event_name != 'workflow_dispatch' }} - run: | - echo "LLVM_PROFILE_FILE=/dev/null" >> $GITHUB_ENV + echo "SEED=0" >> $GITHUB_ENV - name: Build Yosys run: | - make config-gcov - echo "ENABLE_VERIFIC := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf - echo "ENABLE_CCACHE := 1" >> Makefile.conf - echo "ENABLE_FUNCTIONAL_TESTS := 1" >> Makefile.conf - make -j$procs ENABLE_LTO=1 + rm -rf build Configuration.cmake coverage + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_ENABLE_COVERAGE ON CACHE BOOL "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + + cmake -C Configuration.cmake -B build . -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/.local -DCMAKE_BUILD_TYPE=Debug + cmake --build build -j$procs - name: Install Yosys run: | - make install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX= + cmake --build build --target install - name: Checkout SBY - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: repository: 'YosysHQ/sby' path: 'sby' @@ -79,52 +76,54 @@ jobs: run: | make -C sby install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX= + - name: Run unit tests + run: | + ctest --test-dir build/tests/unit --output-on-failure + - name: Run Yosys tests run: | - make -j$procs vanilla-test + make -C tests -j$procs vanilla-test - name: Run Verific specific Yosys tests run: | make -C tests/sva make -C tests/svtypes + - name: Run coverage + if: ${{ github.event_name != 'merge_group'}} + run: | + make -C tests coverage + + - name: Clean coverage + run: | + make -C tests clean_coverage + + - name: Upload coverage reports to Codecov + if: ${{ github.event_name != 'merge_group'}} + uses: codecov/codecov-action@v7 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: YosysHQ/yosys + files: build/coverage.info + disable_search: true + + - name: Skip generating files + if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} + run: | + echo "LLVM_PROFILE_FILE=/dev/null" >> $GITHUB_ENV + - name: Run SBY tests if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} run: | make -C sby run_ci - - name: Run coverage - if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} - run: | - make coverage - make clean_coverage - - - name: Push coverage - if: ${{ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' }} - run: | - git clone https://x-access-token:${{ secrets.REPORTS_TOKEN }}@github.com/YosysHQ/reports.git out - rm -rf out/coverage/main - mkdir -p out/coverage/main - cp -r coverage_html/* out/coverage/main/ - cd out - # find . -name "*.html" -type f -print0 | xargs -0 sed -i -z 's#\(Date:[[:space:]]*\)[^<]*\(\)#\1\2#g' - git config user.name "yosyshq-ci" - git config user.email "105224853+yosyshq-ci@users.noreply.github.com" - git add . - if ! git diff --cached --quiet; then - git commit -m "Update coverage" - git push - else - echo "No changes to commit" - fi - test-pyosys: needs: pre_job - if: ${{ needs.pre_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' }} + if: ${{ needs.pre_job.outputs.should_skip != 'true' && github.repository_owner == 'YosysHQ' && github.event_name != 'push' }} runs-on: [self-hosted, linux, x64, fast] steps: - name: Checkout Yosys - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: persist-credentials: false submodules: true @@ -138,19 +137,20 @@ jobs: - name: Build pyosys run: | - make config-clang - echo "ENABLE_VERIFIC := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf - echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf - echo "ENABLE_CCACHE := 1" >> Makefile.conf - echo "ENABLE_PYOSYS := 1" >> Makefile.conf - echo "PYTHON_DESTDIR := /usr/lib/python3/site-packages" >> Makefile.conf - make -j$procs + echo 'set(CMAKE_C_COMPILER clang CACHE STRING "")' >> Configuration.cmake + echo 'set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_COMPILER_LAUNCHER ccache CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_VERIFIC_DIR "/usr/local/src/verific_lib" CACHE STRING "")' >> Configuration.cmake + echo 'set(YOSYS_WITH_PYTHON ON CACHE BOOL "")' >> Configuration.cmake + echo 'set(YOSYS_INSTALL_PYTHON ON CACHE BOOL "")' >> Configuration.cmake + cmake -C Configuration.cmake -B build . \ + -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/.local \ + -DYOSYS_INSTALL_PYTHON_SITEDIR=$GITHUB_WORKSPACE/.local/usr/lib/python3/site-packages + cmake --build build -j$procs - name: Install pyosys run: | - make install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX= + cmake --build build --target install - name: Run pyosys tests run: | diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 9450534be..500431888 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -36,25 +36,25 @@ jobs: runner: "macos-15", archs: "arm64", }, - ## Windows is disabled because of an issue with compiling FFI as - ## under MinGW in the GitHub Actions environment (SHELL variable has - ## whitespace.) + ## Windows still needs to be tested. # { - # name: "Windows Server 2019", + # name: "Windows Server 2025", # family: "windows", - # runner: "windows-2019", + # runner: "windows-2025", # archs: "AMD64", # }, ] name: Build Wheels | ${{ matrix.os.name }} | ${{ matrix.os.archs }} runs-on: ${{ matrix.os.runner }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 with: fetch-depth: 0 submodules: true persist-credentials: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 + with: + python-version: "3.x" - name: Get FFI shell: bash run: | @@ -66,7 +66,6 @@ jobs: run: | mkdir -p bison curl -L https://ftpmirror.gnu.org/gnu/bison/bison-3.8.2.tar.gz | tar --strip-components=1 -xzC bison - sed -i 's/-Werror=unused//g' Makefile ## Software installed by default in GitHub Action Runner VMs: ## https://github.com/actions/runner-images - if: ${{ matrix.os.family == 'macos' }} @@ -78,18 +77,13 @@ jobs: name: "[Windows] Flex/Bison" run: | choco install winflexbison3 - - if: ${{ matrix.os.family == 'macos' && matrix.os.archs == 'arm64' }} - name: "[macOS/arm64] Install Python 3.8 (see: https://cibuildwheel.pypa.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64)" - uses: actions/setup-python@v5 - with: - python-version: 3.8 - name: Build wheels - uses: pypa/cibuildwheel@v2.21.1 + uses: pypa/cibuildwheel@v4.1.0 env: # * APIs not supported by PyPy # * Musllinux disabled because it increases build time from 48m to ~3h CIBW_SKIP: > - pp* + cp39* *musllinux* CIBW_ARCHS: ${{ matrix.os.archs }} CIBW_BUILD_VERBOSITY: "1" @@ -101,12 +95,13 @@ jobs: OPTFLAGS=-O3 PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig PATH="$PWD/bison/src:$PATH" + CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release" CIBW_ENVIRONMENT_MACOS: > OPTFLAGS=-O3 PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig MACOSX_DEPLOYMENT_TARGET=11 - makeFlags='CONFIG=clang' PATH="$PWD/bison/src:$PATH" + CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release" 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@v7 diff --git a/.github/workflows/wheels/_run_cibw_linux.py b/.github/workflows/wheels/_run_cibw_linux.py deleted file mode 100644 index 1e8a0f497..000000000 --- a/.github/workflows/wheels/_run_cibw_linux.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2024 Efabless Corporation -# -# 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. -""" -This runs the cibuildwheel step from the wheels workflow locally. -""" - -import os -import yaml -import platform -import subprocess -from pathlib import Path - -__yosys_root__ = Path(__file__).absolute().parents[3] - -for source in ["ffi", "bison"]: - if not (__yosys_root__ / source).is_dir(): - print( - "You need to download ffi and bison in a similar manner to wheels.yml first." - ) - exit(-1) - -with open(__yosys_root__ / ".github" / "workflows" / "wheels.yml") as f: - workflow = yaml.safe_load(f) - -env = os.environ.copy() - -steps = workflow["jobs"]["build_wheels"]["steps"] -cibw_step = None -for step in steps: - if (step.get("uses") or "").startswith("pypa/cibuildwheel"): - cibw_step = step - break - -for key, value in cibw_step["env"].items(): - if key.endswith("WIN") or key.endswith("MAC"): - continue - env[key] = value - -env["CIBW_ARCHS"] = os.getenv("CIBW_ARCHS", platform.machine()) -subprocess.check_call(["cibuildwheel"], env=env) diff --git a/.github/workflows/wheels/cibw_before_build.sh b/.github/workflows/wheels/cibw_before_build.sh index 1ce96b291..217cb8875 100644 --- a/.github/workflows/wheels/cibw_before_build.sh +++ b/.github/workflows/wheels/cibw_before_build.sh @@ -1,9 +1,6 @@ set -e set -x -# Don't use Python objects from previous compiles -make clean-py - # DEBUG: show python3 and python3-config outputs if [ "$(uname)" != "Linux" ]; then # https://github.com/pypa/cibuildwheel/issues/2021 diff --git a/.gitignore b/.gitignore index b39088088..bb1a08bba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ ## user config /Makefile.conf +/Configuration.cmake +/CMakeUserPresets.json ## homebrew /Brewfile.lock.json @@ -49,7 +51,9 @@ /tests/unit/objtest/ /tests/ystests /build +/build-* /result +/result-* /dist # pyosys @@ -86,3 +90,5 @@ __pycache__ /qtcreator.creator /qtcreator.creator.user /compile_commands.json +/.direnv +/.envrc diff --git a/.gitmodules b/.gitmodules index 9f18be11e..d951c8d01 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,22 @@ [submodule "cxxopts"] path = libs/cxxopts url = https://github.com/jarro2783/cxxopts +[submodule "fmt"] + path = libs/fmt + url = https://github.com/fmtlib/fmt +[submodule "tomlplusplus"] + path = libs/tomlplusplus + url = https://github.com/marzer/tomlplusplus +[submodule "boost_regex"] + path = libs/boost_regex + url = https://github.com/MikePopoloski/regex +[submodule "slang"] + path = libs/slang + url = https://github.com/MikePopoloski/slang +[submodule "sv-elab"] + path = frontends/slang/lib + url = https://github.com/povik/sv-elab +[submodule "symfpu"] + path = libs/symfpu + url = https://github.com/YosysHQ/symfpu + branch = floatWithStatusFlags diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..9aab6c2a8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,30 @@ +# To use: +# +# pre-commit run -a +# +# Or: +# +# pre-commit install # (runs every time you commit in git) +# +# To update this file: +# +# pre-commit autoupdate +# +# See https://github.com/pre-commit/pre-commit + +exclude: ^libs/ + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-illegal-windows-names + - id: check-yaml + args: [--allow-multiple-documents] + - id: end-of-file-fixer + - id: fix-byte-order-marker + - id: mixed-line-ending + args: [--fix,lf] + - id: trailing-whitespace diff --git a/Brewfile b/Brewfile index 2530b323c..838c13e5c 100644 --- a/Brewfile +++ b/Brewfile @@ -12,3 +12,4 @@ brew "bash" brew "llvm" brew "lld" brew "googletest" +brew "tcl-tk" diff --git a/CHANGELOG b/CHANGELOG index 61b221bc9..504a33308 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,16 +2,48 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.66 .. Yosys 0.67-dev +Yosys 0.67 .. Yosys 0.68-dev -------------------------- +Yosys 0.66 .. Yosys 0.67 +-------------------------- + * Various + - Project is now requiring CMake 3.28 or later as + build system. + - At least Clang-16 or GCC-13 are required, but we + recommend using later versions. + - Microsoft Visual Studio builds are now fully working + (including building ABC), but mingw-64 builds are + still recommended for Windows platform. + - For SystemVerilog support now using sv-elab, + built on top of slang library. + - FABulous techlib to removes all hardcoded mappings + and primitives, allowing them to be specified via + the options of "synth_fabulous". + - smtbmc: Latest bitwuzla is now supported. + + * New commands and options + - Added "abc_ops_reintegrate" pass as replacement + for "abc9_ops -reintegrate". + - Added "check_mem" pass to check for memory problems + in the design. + - Added "-strategy", "-final" and "-no-fma" options to + "arith_tree" pass. + - Added "-ignore-unknown-cells" option to "equiv_opt". + - Added "-no-undriven-check" and "-undriven-warn" options + to "sim" pass. + - Added "-latches" option to synth passes able to + produce latches for control of latch inference. + - Added "-nolatches" to "check" pass. + - Added "-latches" to "proc" and "proc_dlatch" passes. + Yosys 0.65 .. Yosys 0.66 -------------------------- * Various - C++ compiler with C++20 support is required. - Please be aware that next release will also migrate to CMake build system. - + * New commands and options - Added "lattice_dsp_nexus" pass for Lattice Nexus DSP inference. @@ -78,7 +110,7 @@ Yosys 0.61 .. Yosys 0.62 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 + - Added "-on" and "-off" options to "debug" pass for persistent debug logging. - Added "linux_perf" pass to control performance recording. @@ -92,7 +124,7 @@ Yosys 0.60 .. Yosys 0.61 * 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 + - Added "-legalize" option to "read_rtlil" pass to prevent semantic errors. Yosys 0.59 .. Yosys 0.60 @@ -196,7 +228,7 @@ Yosys 0.53 .. Yosys 0.54 - Enable single-bit vector wires in RTLIL. * Xilinx support - - Single-port URAM mapping to support memories 2048 x 144b + - Single-port URAM mapping to support memories 2048 x 144b Yosys 0.52 .. Yosys 0.53 -------------------------- @@ -222,7 +254,7 @@ Yosys 0.51 .. Yosys 0.52 -------------------------- * New commands and options - Added "-pattern-limit" option to "share" pass to limit analysis effort. - - Added "libcache" pass to control caching of technology library + - Added "libcache" pass to control caching of technology library data parsed from liberty files. - Added "read_verilog_file_list" to parse verilog file list. @@ -288,7 +320,7 @@ Yosys 0.47 .. Yosys 0.48 * Gowin support - Added "-family" option to "synth_gowin" pass. - - Cell definitions split by family. + - Cell definitions split by family. * Verific support - Improved blackbox support. @@ -315,7 +347,7 @@ Yosys 0.45 .. Yosys 0.46 - Added new "functional backend" infrastructure with three example backends (C++, SMTLIB and Rosette). - Added new coarse-grain buffer cell type "$buf" to RTLIL. - - Added "-y" command line option to execute a Python script with + - Added "-y" command line option to execute a Python script with libyosys available as a built-in module. - Added support for casting to type in Verilog frontend. @@ -323,7 +355,7 @@ Yosys 0.45 .. Yosys 0.46 - Added "clockgate" pass for automatic clock gating cell insertion. - Added "bufnorm" experimental pass to convert design into buffered-normalized form. - - Added experimental "aiger2" and "xaiger2" backends, and an + - Added experimental "aiger2" and "xaiger2" backends, and an experimental "abc_new" command - Added "-force-detailed-loop-check" option to "check" pass. - Added "-unit_delay" option to "read_liberty" pass. @@ -348,10 +380,10 @@ Yosys 0.43 .. Yosys 0.44 - Build support for Haiku OS. * New commands and options - - Added "keep_hierarchy" pass to add attribute with + - Added "keep_hierarchy" pass to add attribute with same name to modules based on cost. - Added options "-noopt","-bloat" and "-check_cost" to - "test_cell" pass. + "test_cell" pass. * New back-ends - Added initial PolarFire support. ( synth_microchip ) @@ -365,22 +397,22 @@ Yosys 0.42 .. Yosys 0.43 * Verific support - Support building Yosys with various Verific library - configurations. Can be built now without YosysHQ + configurations. Can be built now without YosysHQ specific patch and extension library. Yosys 0.41 .. Yosys 0.42 -------------------------- * New commands and options - Added "box_derive" pass to derive box modules. - - Added option "assert-mod-count" to "select" pass. - - Added option "-header","-push" and "-pop" to "log" pass. + - Added option "assert-mod-count" to "select" pass. + - Added option "-header","-push" and "-pop" to "log" pass. * Intel support - Dropped Quartus support in "synth_intel_alm" pass. Yosys 0.40 .. Yosys 0.41 -------------------------- * New commands and options - - Added "cellmatch" pass for picking out standard cells automatically. + - Added "cellmatch" pass for picking out standard cells automatically. * Various - Extended the experimental incremental JSON API to allow arbitrary @@ -394,7 +426,7 @@ Yosys 0.40 .. Yosys 0.41 Yosys 0.39 .. Yosys 0.40 -------------------------- * New commands and options - - Added option "-vhdl2019" to "read" and "verific" pass. + - Added option "-vhdl2019" to "read" and "verific" pass. * Various - Major documentation overhaul. @@ -408,7 +440,7 @@ Yosys 0.39 .. Yosys 0.40 Yosys 0.38 .. Yosys 0.39 -------------------------- * New commands and options - - Added option "-extra-map" to "synth" pass. + - Added option "-extra-map" to "synth" pass. - Added option "-dont_use" to "dfflibmap" pass. - Added option "-href" to "show" command. - Added option "-noscopeinfo" to "flatten" pass. @@ -422,7 +454,7 @@ Yosys 0.38 .. Yosys 0.39 the hierarchy during flattening. - Added sequential area output to "stat -liberty". - Added ability to record/replay diagnostics in cxxrtl backend. - + * Verific support - Added attributes to module instantiation. @@ -469,7 +501,7 @@ Yosys 0.35 .. Yosys 0.36 * QuickLogic support - Added "K6N10f" support. - - Added "-nodsp", "-nocarry", "-nobram" and "-bramtypes" options to + - Added "-nodsp", "-nocarry", "-nobram" and "-bramtypes" options to "synth_quicklogic" pass. - Added "ql_bram_merge" pass to merge 18K BRAM cells into TDP36K. - Added "ql_bram_types" pass to change TDP36K depending on configuration. @@ -564,7 +596,7 @@ Yosys 0.29 .. Yosys 0.30 - Added remaining primitives blackboxes. * Various - - "show -colorattr" will now color the cells, wires, and + - "show -colorattr" will now color the cells, wires, and connection arrows. - "show -viewer none" will not execute viewer. @@ -739,7 +771,7 @@ Yosys 0.19 .. Yosys 0.20 operators were not affected. * Verific support - - Proper import of port ranges into Yosys, may result in reversed + - Proper import of port ranges into Yosys, may result in reversed bit-order of top-level ports for some synthesis flows. Yosys 0.18 .. Yosys 0.19 @@ -833,7 +865,7 @@ Yosys 0.14 .. Yosys 0.15 * SystemVerilog - Added support for accessing whole sub-structures in expressions - + * New commands and options - Added glift command, used to create gate-level information flow tracking (GLIFT) models by the "constructive mapping" approach @@ -848,7 +880,7 @@ Yosys 0.13 .. Yosys 0.14 - Added $bmux and $demux cells and related optimization patterns. * New commands and options - - Added "bmuxmap" and "dmuxmap" passes + - Added "bmuxmap" and "dmuxmap" passes - Added "-fst" option to "sim" pass for writing FST files - Added "-r", "-scope", "-start", "-stop", "-at", "-sim", "-sim-gate", "-sim-gold" options to "sim" pass for co-simulation @@ -1802,4 +1834,3 @@ Yosys 0.1.0 .. Yosys 0.2.0 - Added "design -stash/-copy-from/-copy-to" - Added "copy" command - Added "splice" command - diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..bccf29049 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,607 @@ +if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) + set(rm "rm -rf") + if (WIN32) + set(rm "del /s /q") + endif() + message(FATAL_ERROR + "In-tree builds are not supported. Instead, run:\n" + "${rm} CMakeCache.txt CMakeFiles ; cmake -B build " + ) +endif() + +cmake_minimum_required(VERSION 3.28) +project(yosys LANGUAGES C CXX) + +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +include(CMakeDependentOption) +include(FeatureSummary) +include(CheckPIESupported) + +include(Condition) +include(CheckLibcFeatures) +include(PkgConfig) +include(PmgenCommand) +include(YosysVersion) +include(YosysInstallDirs) +include(YosysConfigScript) +include(YosysComponent) +include(YosysLinkTarget) +include(YosysAbc) +include(YosysAbcSubmodule) +include(YosysVerific) +include(UseHomebrew) + +# Fix for using Clang from nixpkgs +# see https://github.com/YosysHQ/yosys/pull/5936#issuecomment-4637319568 +set(CMAKE_CXX_SCAN_FOR_MODULES NO) + +# Build options. +set(YOSYS_COMPILER_LAUNCHER "" CACHE STRING "Compiler launcher (ccache, sccache)") +option(YOSYS_ENABLE_COVERAGE "Enable code coverage" OFF) +option(YOSYS_ENABLE_PROFILING "Enable instruction profiling" OFF) +option(YOSYS_ENABLE_FUNCTIONAL_TESTS "Enable running functional tests" OFF) + +set(YOSYS_PROGRAM_PREFIX "" CACHE STRING "Name prefix for programs, libraries, and data") +set(YOSYS_COMPONENTS "everything" CACHE STRING "List of components to build (use pass names)") +option(BUILD_SHARED_LIBS "Build libyosys as a shared library" ON) + +option(YOSYS_DISABLE_THREADS "Disable threading" OFF) +set(YOSYS_ABC_EXECUTABLE "" CACHE FILEPATH + "Path to the ABC executable (empty for vendored, 'INTEGRATED-NOTFOUND' for in-process)") +option(YOSYS_WITHOUT_ABC "Disable ABC support (not recommended)" OFF) +option(YOSYS_WITHOUT_ZLIB "Disable zlib integration" OFF) +option(YOSYS_WITHOUT_LIBFFI "Disable libffi integration" OFF) +option(YOSYS_WITHOUT_READLINE "Disable readline integration" OFF) +option(YOSYS_WITHOUT_EDITLINE "Disable editline integration" OFF) +option(YOSYS_WITHOUT_SLANG "Disable Slang integration" OFF) +option(YOSYS_WITHOUT_TCL "Disable Tcl integration" OFF) +option(YOSYS_WITH_PYTHON "Enable Python integration" OFF) + +option(YOSYS_USE_BUNDLED_LIBS "Use bundled third-party libraries" OFF) + +set(YOSYS_VERIFIC_DIR "" CACHE FILEPATH "Path to the Verific source code (empty to disable)") +set(YOSYS_VERIFIC_COMPONENTS "" CACHE STRING + "List of Verific components to link (empty for autodetect)") +set(YOSYS_VERIFIC_FEATURES "" CACHE STRING + "List of Yosys Verific frontend features to enable (empty for autodetect)") + +option(YOSYS_INSTALL_DRIVER "Install Yosys executable" ON) +option(YOSYS_INSTALL_LIBRARY "Install libyosys library" OFF) +cmake_dependent_option(YOSYS_INSTALL_PYTHON "Install Python extension module" OFF + YOSYS_WITH_PYTHON OFF) +set(YOSYS_INSTALL_PYTHON_SITEDIR "" CACHE STRING "Path to Python package installation directory") + +# This option is something of a hack to make Python wheels buildable in an environment that has +# the `Development.Module` component, but not `Development.Embed` (e.g. cibuildwheel). It is only +# present to be used in the wheel build and is not supported otherwise. +cmake_dependent_option(YOSYS_BUILD_PYTHON_ONLY "Build only Pyosys components" ON + "NOT (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY) AND YOSYS_INSTALL_PYTHON" OFF) +mark_as_advanced(YOSYS_BUILD_PYTHON_ONLY) + +# Configure compiler. +set(CMAKE_EXPORT_COMPILE_COMMANDS YES) + +if (YOSYS_COMPILER_LAUNCHER) + set(CMAKE_C_COMPILER_LAUNCHER "${YOSYS_COMPILER_LAUNCHER}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${YOSYS_COMPILER_LAUNCHER}") +endif() + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED YES) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +check_pie_supported() # opportunistically enable PIE + +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb") + set(CMAKE_CXX_FLAGS_RELEASE "-O3") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -ggdb") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os") + set(CMAKE_CXX_FLAGS_SANITIZE "-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls") + if ("${SANITIZE}" MATCHES "memory") + set(CMAKE_CXX_FLAGS_SANITIZE "${CMAKE_CXX_FLAGS_SANITIZE} -fsanitize-memory-track-origins") + endif() + set(no_abc_options + "$<$>>,$>:-fsanitize=${SANITIZE}>" + "$<$>>:-Wall;-Wextra;-Werror=unused>" + ) + add_compile_options("${no_abc_options}") + add_link_options("${no_abc_options}") +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS_DEBUG "/Od /DEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "/O2") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /DEBUG") + set(CMAKE_CXX_FLAGS_MINSIZEREL "/Os") + add_compile_options(/Zc:__cplusplus) + add_compile_definitions( + _CRT_NONSTDC_NO_DEPRECATE + _CRT_SECURE_NO_WARNINGS + ) +else() + # We have to do this because CMake adds `-DNDEBUG` in release builds by default, and there's + # no particularly good way to prevent this without also erasing optimization flags. + # If you see this message, reproduce the block above with the flags supported by your compiler. + message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} compiler is not supported") +endif() + +if (YOSYS_ENABLE_COVERAGE) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline -fno-inline-small-functions -fno-default-inline") + else() + message(FATAL_ERROR "Code coverage is not supported on ${CMAKE_CXX_COMPILER_ID} compiler") + endif() +endif() + +if (YOSYS_ENABLE_PROFILING) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + else() + message(FATAL_ERROR "Instruction profiling is not supported on ${CMAKE_CXX_COMPILER_ID} compiler") + endif() +endif() + +if (NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID) + message(FATAL_ERROR "C and C++ compilers must be provided by the same vendor") +endif() +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") +set(CMAKE_C_FLAGS_SANITIZE "${CMAKE_CXX_FLAGS_SANITIZE}") + +if (CMAKE_SYSTEM_NAME STREQUAL "WASI") + add_compile_options( + -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false + -D_WASI_EMULATED_PROCESS_CLOCKS + ) + add_link_options( + -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -lunwind + -lwasi-emulated-process-clocks + -Wl,--stack-first,-z,stack-size=8388608 + ) +endif() + +if (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "16.0.0") + # GCC 15.2 sometimes refuses to construct an import directory for yosys.exe/libyosys.dll with: + # .../ld.exe: error: export ordinal too large: 67035 + # The cause is unknown. + message(WARNING "MinGW GCC is supported starting with version 16.0.0") +endif() + +# Required dependencies. +if (APPLE) + # In practice, we can't expect paths to Homebrew packages to be configured. + use_homebrew() +endif() + +find_package(FLEX 2.6) +set_package_properties(FLEX PROPERTIES + URL "https://github.com/westes/flex" + DESCRIPTION "The Fast Lexical Analyzer" + PURPOSE "Compiling the Verilog lexer" + TYPE REQUIRED +) + +find_package(BISON 3.6) +set_package_properties(BISON PROPERTIES + URL "https://www.gnu.org/software/bison/" + DESCRIPTION "The Yacc-compatible Parser Generator" + PURPOSE "Compiling the Verilog parser" + TYPE REQUIRED +) + +find_package(Python3 3.7 COMPONENTS Interpreter) +set_package_properties(Python3 PROPERTIES + URL "https://www.python.org/" + DESCRIPTION "Dynamic programming language (Interpreter)" + PURPOSE "Generating data files\n Running external SMT2 solvers" + TYPE REQUIRED +) + +# Optional dependencies. +check_glob() +check_system() +check_popen() +find_package(Threads QUIET) +check_pthread_create() +find_package(Dlfcn QUIET) + +find_package(PkgConfig) +set_package_properties(PkgConfig PROPERTIES + URL "https://www.freedesktop.org/wiki/Software/pkg-config/" + DESCRIPTION "Library metadata manager" + PURPOSE "Discovering dependencies" + TYPE RECOMMENDED +) + +pkg_config_import(zlib) +set_package_properties(zlib PROPERTIES + URL "https://github.com/madler/zlib" + DESCRIPTION "A massively spiffy yet delicately unobtrusive compression library" + PURPOSE "Handling Gzip and FST file formats" +) + +pkg_config_import(libffi) +set_package_properties(libffi PROPERTIES + URL "https://sourceware.org/libffi/" + DESCRIPTION "A Portable Foreign Function Interface Library" + PURPOSE "Implementing Verilog DPI-C" +) + +pkg_config_import(editline MODULES libedit) +set_package_properties(editline PROPERTIES + URL "https://www.thrysoee.dk/editline/" + DESCRIPTION "Line editing and history library (BSD)" + PURPOSE "Enhancing the command prompt" + TYPE RECOMMENDED +) + +pkg_config_import(readline) +set_package_properties(readline PROPERTIES + URL "https://tiswww.case.edu/php/chet/readline/rltop.html" + DESCRIPTION "Line editing and history library (GPL)" + PURPOSE "Enhancing the command prompt" + TYPE RECOMMENDED +) + +# See https://core.tcl-lang.org/tips/doc/trunk/tip/538.md +pkg_config_import(tcl MODULES tcl) +set_package_properties(tcl PROPERTIES + URL "https://www.tcl-lang.org/" + DESCRIPTION "Dynamic programming language" + PURPOSE "Parsing SDC constraint files\n Binding Yosys API" +) + +if (tcl_FOUND) + get_target_property(tcl_options PkgConfig::tcl INTERFACE_COMPILE_OPTIONS) + if (tcl_options MATCHES "TCL_WITH_EXTERNAL_TOMMATH") + pkg_config_import(libtommath) + set_package_properties(libtommath PROPERTIES + URL "https://www.libtom.net/LibTomMath/" + DESCRIPTION "Multiple-precision integer library" + PURPOSE "Required by this build of Tcl" + TYPE REQUIRED + ) + # Unfortunately the pkg-config file for Tcl includes libtommath as a private dependency, + # while it should be public since it is exposed in the public API and necessary for its use. + target_link_libraries(PkgConfig::tcl INTERFACE PkgConfig::libtommath) + else() + # Vendored within Tcl itself. + set(libtommath_FOUND TRUE) + endif() +endif() + +if (YOSYS_WITH_PYTHON) + find_package(Python3Devel REQUIRED) + set_property(GLOBAL PROPERTY _CMAKE_Python3Devel_REQUIRED_VERSION "== ${Python3_VERSION}") + set_package_properties(Python3Devel PROPERTIES + URL "https://www.python.org/" + DESCRIPTION "Dynamic programming language (Embedding)" + PURPOSE "Binding Yosys API" + ) + + find_package(PyosysEnv REQUIRED) + set_package_properties(PyosysEnv PROPERTIES + DESCRIPTION "Pyosys wrapper generator environment" + PURPOSE "Either 'uv' or 'pybind11>3,<4 cxxheaderparser'" + ) +endif() + +find_package(GTest) +set_package_properties(GTest PROPERTIES + URL "https://google.github.io/googletest/" + DESCRIPTION "C++ testing and mocking framework by Google" + PURPOSE "Running unit tests" + TYPE RECOMMENDED +) + +# Configure features based on dependency availability. +message(VERBOSE "Conditional features:") +condition(YOSYS_ENABLE_GLOB HAVE_GLOB) +condition(YOSYS_ENABLE_SPAWN HAVE_SYSTEM AND HAVE_POPEN) +condition(YOSYS_ENABLE_THREADS Threads_FOUND AND HAVE_PTHREAD_CREATE AND NOT YOSYS_DISABLE_THREADS) +condition(YOSYS_ENABLE_PLUGINS Dlfcn_FOUND) +condition(YOSYS_ENABLE_ABC NOT YOSYS_WITHOUT_ABC) +condition(YOSYS_ENABLE_ZLIB zlib_FOUND AND NOT YOSYS_WITHOUT_ZLIB) +condition(YOSYS_ENABLE_LIBFFI Dlfcn_FOUND AND libffi_FOUND AND NOT YOSYS_WITHOUT_LIBFFI) +condition(YOSYS_ENABLE_READLINE readline_FOUND AND NOT YOSYS_WITHOUT_READLINE) +condition(YOSYS_ENABLE_EDITLINE editline_FOUND AND NOT YOSYS_WITHOUT_EDITLINE AND NOT YOSYS_ENABLE_READLINE) +condition(YOSYS_ENABLE_TCL tcl_FOUND AND libtommath_FOUND AND NOT YOSYS_WITHOUT_TCL) +condition(YOSYS_ENABLE_PYTHON Python3Devel_FOUND AND PyosysEnv_FOUND AND YOSYS_WITH_PYTHON) +condition(YOSYS_ENABLE_VERIFIC YOSYS_VERIFIC_DIR AND zlib_FOUND) +condition(YOSYS_ENABLE_SLANG NOT YOSYS_WITHOUT_SLANG) + +# Describe dependencies and features +# CMake 4.0 would let us use proper conditions, but that's too new for now. +add_feature_info(have_glob YOSYS_ENABLE_GLOB "Glob expansion in filenames") +add_feature_info(have_spawn YOSYS_ENABLE_SPAWN "Passes that invoke external tools") +add_feature_info(have_threads YOSYS_ENABLE_THREADS "Multithreaded netlist operations") +add_feature_info(have_plugins YOSYS_ENABLE_PLUGINS "Dynamically loadable binary plugins") +add_feature_info(with_abc YOSYS_ENABLE_ABC "Production-quality logic synthesis flow") +add_feature_info(with_zlib YOSYS_ENABLE_ZLIB "Transparent Gzip decompression and FST file format support") +add_feature_info(with_libffi YOSYS_ENABLE_LIBFFI "Verilog DPI-C foreign function interface") +add_feature_info(with_readline YOSYS_ENABLE_READLINE "Using readline for prompt editing and history") +add_feature_info(with_editline YOSYS_ENABLE_EDITLINE "Using editline for prompt editing and history") +add_feature_info(with_tcl YOSYS_ENABLE_TCL "Tcl scripting and SDC parsing") +add_feature_info(with_python YOSYS_ENABLE_PYTHON "Python scripting and embedding") +add_feature_info(with_verific YOSYS_ENABLE_VERIFIC "Verific frontend integration") +message(STATUS "") +feature_summary(WHAT PACKAGES_FOUND + DEFAULT_DESCRIPTION) +feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND + DEFAULT_DESCRIPTION QUIET_ON_EMPTY FATAL_ON_MISSING_REQUIRED_PACKAGES +) +feature_summary(WHAT PACKAGES_NOT_FOUND + DEFAULT_DESCRIPTION QUIET_ON_EMPTY +) +feature_summary(WHAT ENABLED_FEATURES + DEFAULT_DESCRIPTION QUIET_ON_EMPTY) +feature_summary(WHAT DISABLED_FEATURES + DEFAULT_DESCRIPTION QUIET_ON_EMPTY) + +# Describe project version. +yosys_extract_version() + +# Describe ABC integration. +if (YOSYS_ENABLE_ABC AND NOT YOSYS_ENABLE_SPAWN AND NOT YOSYS_ABC_EXECUTABLE STREQUAL "INTEGRATED-NOTFOUND") + message(WARNING "ABC support on this platform forces -DYOSYS_ABC_EXECUTABLE=INTEGRATED-NOTFOUND") + set(YOSYS_ABC_EXECUTABLE "INTEGRATED-NOTFOUND" CACHE FILEPATH "" FORCE) +endif() + +set(YOSYS_LINK_ABC 0) +if (YOSYS_ENABLE_ABC) + if (NOT YOSYS_ABC_EXECUTABLE AND NOT YOSYS_SKIP_ABC_SUBMODULE_CHECK) + yosys_check_abc_submodule() + endif() + if (YOSYS_ABC_EXECUTABLE STREQUAL "INTEGRATED-NOTFOUND") + set(YOSYS_LINK_ABC 1) + message(STATUS "Building ABC: (integrated)") + elseif (YOSYS_ABC_EXECUTABLE STREQUAL "") + set(abc_filename ${YOSYS_PROGRAM_PREFIX}yosys-abc${CMAKE_EXECUTABLE_SUFFIX}) + message(STATUS "Building ABC: ${YOSYS_INSTALL_FULL_BINDIR}/${abc_filename}") + else() + message(STATUS "External ABC: ${YOSYS_ABC_EXECUTABLE}") + endif() +endif() + +# Ensure invalid dependencies fail at configuration time, not link time. +set(CMAKE_LINK_LIBRARIES_ONLY_TARGETS ON) + +# Pseudo-library that injects common compilation options into every Yosys component. +add_library(yosys_common INTERFACE) +target_compile_definitions(yosys_common INTERFACE + _YOSYS_ + $<$:DEBUG> +) +target_include_directories(yosys_common INTERFACE + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} +) +if (SANITIZE) + target_compile_options(yosys_common INTERFACE + ${sanitize_options} + ) +endif() + +# Two pseudo-components used for dependency tracking only. +yosys_core(essentials BOOTSTRAP) +yosys_core(everything BOOTSTRAP) + +# All of the source code. +add_subdirectory(libs) +add_subdirectory(kernel) +add_subdirectory(passes) +add_subdirectory(frontends) +add_subdirectory(backends) +add_subdirectory(techlibs) +if (YOSYS_ENABLE_PYTHON) + add_subdirectory(pyosys) +endif() + +# ABC submodule. +if (YOSYS_ENABLE_ABC AND NOT YOSYS_ABC_EXECUTABLE) + set(YOSYS_ABC_INSTALL NO) + if (YOSYS_ABC_EXECUTABLE STREQUAL "" AND (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY)) + set(YOSYS_ABC_INSTALL YES) + endif() + yosys_abc_target(libyosys-abc yosys-abc + INSTALL_IF ${YOSYS_ABC_INSTALL} + ) +endif() + +# Compute a transitive closure of enabled components. +yosys_expand_components(library_components essentials ${YOSYS_COMPONENTS}) +if (NOT YOSYS_BUILD_PYTHON_ONLY) + yosys_expand_components(driver_components driver ${YOSYS_COMPONENTS}) +endif() + +# Main Yosys executable (compiler driver). +if (NOT YOSYS_BUILD_PYTHON_ONLY) + yosys_cxx_executable(yosys + OUTPUT_NAME yosys + INSTALL_IF ${YOSYS_INSTALL_DRIVER} + ) + yosys_link_components(yosys PRIVATE ${driver_components}) + set_property(TARGET yosys PROPERTY ENABLE_EXPORTS ON) + if (MINGW) + target_link_options(yosys PRIVATE LINKER:--export-all-symbols) + set_target_properties(yosys PROPERTIES + # Final name: `yosys.exe.a` (linked to explicitly) + IMPORT_PREFIX "" + IMPORT_SUFFIX ".exe.a" + ) + if (YOSYS_INSTALL_DRIVER) + install(FILES ${CMAKE_BINARY_DIR}/yosys.exe.a DESTINATION ${YOSYS_INSTALL_LIBDIR}) + endif() + endif() + + target_compile_options(yosys PRIVATE -fsanitize=undefined) +endif() + +# Yosys components as a library. +if (NOT YOSYS_BUILD_PYTHON_ONLY) + if (BUILD_SHARED_LIBS) + set(libyosys_type SHARED) + else() + set(libyosys_type STATIC) + endif() + yosys_cxx_library(libyosys ${libyosys_type} + OUTPUT_NAME libyosys + INSTALL_IF ${YOSYS_INSTALL_LIBRARY} + ) + yosys_link_components(libyosys PRIVATE ${library_components}) + add_library(Yosys::libyosys ALIAS libyosys) + if (MINGW) + set_target_properties(libyosys PROPERTIES + # Final name: `libyosys.dll.a` (linked to via `-lyosys`) + IMPORT_PREFIX "" + ) + endif() +endif() + +# Yosys data files (mainly headers and technological libraries). +if (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY) + yosys_install_component_data(${library_components} DESTINATION ${YOSYS_INSTALL_DATADIR}) +endif() + +# Python binary extension (for using Yosys as a Python library). +if (YOSYS_ENABLE_PYTHON) + yosys_cxx_library(pyosys MODULE + OUTPUT_NAME pyosys + ) + yosys_link_components(pyosys PRIVATE ${library_components}) + set_target_properties(pyosys PROPERTIES EXCLUDE_FROM_ALL FALSE) # build but not install + if (YOSYS_ENABLE_ABC AND YOSYS_ABC_EXECUTABLE STREQUAL "") + add_dependencies(pyosys yosys-abc) + endif() + + if (YOSYS_INSTALL_PYTHON) + string(REPLACE "-" "_" PYOSYS_MODULE_PREFIX "${YOSYS_PROGRAM_PREFIX}") + if (YOSYS_INSTALL_PYTHON_SITEDIR STREQUAL "") + set(YOSYS_INSTALL_PYTHON_SITEDIR ${Python3_SITEARCH}) + endif() + set(pyosys_install_dir ${YOSYS_INSTALL_PYTHON_SITEDIR}/${PYOSYS_MODULE_PREFIX}pyosys) + install(FILES pyosys/modinit.py + RENAME __init__.py + DESTINATION ${pyosys_install_dir} + ) + install(FILES $ + RENAME libyosys${CMAKE_SHARED_MODULE_SUFFIX} + DESTINATION ${pyosys_install_dir} + ) + if (YOSYS_ENABLE_ABC AND YOSYS_ABC_EXECUTABLE STREQUAL "") + # If ABC is vendored it needs to be installed as a part of pyosys. + install(TARGETS yosys-abc + DESTINATION ${pyosys_install_dir} + ) + endif() + yosys_install_component_data(${library_components} DESTINATION ${pyosys_install_dir}/share) + endif() +endif() + +# Plugin build tool. +yosys_config_script(BUILD) +if (YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY) + yosys_config_script(INSTALL) +endif() + +# Configuration for Makefile-based steps. +# (The use of `${makefile_vars}` in `add_custom_{target,command}()` adds dependencies for +# all of the targets specified via `$`.) +set(makefile_vars + BUILD_DIR=${CMAKE_BINARY_DIR} + PROGRAM_PREFIX=${YOSYS_PROGRAM_PREFIX} + ABC=$,$,${YOSYS_ABC_EXECUTABLE}> + YOSYS=$ + YOSYS_CONFIG=${CMAKE_BINARY_DIR}/${YOSYS_PROGRAM_PREFIX}yosys-config + YOSYS_FILTERLIB=$<$:$> + YOSYS_SMTBMC=${CMAKE_BINARY_DIR}/${YOSYS_PROGRAM_PREFIX}yosys-smtbmc + YOSYS_WITNESS=${CMAKE_BINARY_DIR}/${YOSYS_PROGRAM_PREFIX}yosys-witness +) +set(makefile_depends + # abc is implied via $ + # yosys is implied via $ + # yosys-filterlib is implied via $ + $<$:yosys-smtbmc> + $<$:yosys-witness> +) + +if (NOT YOSYS_BUILD_PYTHON_ONLY) + # Tests. + add_subdirectory(tests/unit) + + add_custom_target(test-unit + COMMAND ${CMAKE_CTEST_COMMAND} --test-dir tests/unit --output-on-failure + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + DEPENDS $<$:yosys-gtest-all> + ) + + add_custom_target(test-vanilla + COMMAND make vanilla-test ${makefile_vars} + ENABLE_FUNCTIONAL_TESTS=$,1,0> + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests + DEPENDS ${makefile_depends} + USES_TERMINAL + JOB_SERVER_AWARE TRUE + ) + + add_custom_target(test-functional + COMMAND make functional ${makefile_vars} + ENABLE_FUNCTIONAL_TESTS=$,1,0> + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests + DEPENDS ${makefile_depends} + USES_TERMINAL + JOB_SERVER_AWARE TRUE + ) + + add_custom_target(test + DEPENDS test-unit test-vanilla + ) + + # Docs. + add_custom_target(docs-prepare + COMMAND make gen ${makefile_vars} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs + DEPENDS ${makefile_depends} + JOB_SERVER_AWARE TRUE + ) + foreach (format html latexpdf) + add_custom_target(docs-${format} + COMMAND make ${format} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs + DEPENDS docs-prepare + ) + endforeach() + add_custom_target(test-docs + COMMAND make test ${makefile_vars} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs + DEPENDS ${makefile_depends} + JOB_SERVER_AWARE TRUE + ) +endif() + +# Utilities. +add_custom_target(print-version + COMMAND ${CMAKE_COMMAND} -E echo ${YOSYS_VERSION} + VERBATIM +) + +yosys_expand_components(all_components everything QUIET) +list(TRANSFORM all_components PREPEND "COMMAND;${CMAKE_COMMAND};-E;echo;" OUTPUT_VARIABLE echo_all_components) +add_custom_target(print-yosys-components + ${echo_all_components} + VERBATIM +) + +math(EXPR YOSYS_VERSION_MINOR_next "${YOSYS_VERSION_MINOR} + 1") +add_custom_target(increment-minor-version + COMMAND ${CMAKE_COMMAND} -E echo + "set(YOSYS_VERSION_MAJOR ${YOSYS_VERSION_MAJOR})" + > ${CMAKE_SOURCE_DIR}/cmake/YosysVersionData.cmake + COMMAND ${CMAKE_COMMAND} -E echo + "set(YOSYS_VERSION_MINOR ${YOSYS_VERSION_MINOR_next})" + >> ${CMAKE_SOURCE_DIR}/cmake/YosysVersionData.cmake + VERBATIM +) diff --git a/CODEOWNERS b/CODEOWNERS index 4617c39bb..5693e90f3 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -15,7 +15,6 @@ passes/cmds/scratchpad.cc @nakengelhardt frontends/rpc/ @whitequark backends/cxxrtl/ @whitequark passes/cmds/bugpoint.cc @whitequark -passes/techmap/flowmap.cc @whitequark passes/opt/opt_lut.cc @whitequark passes/techmap/abc9*.cc @eddiehung @Ravenslofty backends/aiger/xaiger.cc @eddiehung @@ -36,6 +35,7 @@ frontends/ast/ @widlarizer techlibs/intel_alm/ @Ravenslofty techlibs/gowin/ @pepijndevos techlibs/gatemate/ @pu-cc +techlibs/fabulous/ fpga.research.group@gmail.com # pyosys pyosys/* @donn diff --git a/Makefile b/Makefile deleted file mode 100644 index 8bb1c0b2a..000000000 --- a/Makefile +++ /dev/null @@ -1,1219 +0,0 @@ - -CONFIG := none -# CONFIG := clang -# CONFIG := gcc -# CONFIG := wasi -# CONFIG := msys2-32 -# CONFIG := msys2-64 - -# features (the more the better) -ENABLE_TCL := 1 -ENABLE_ABC := 1 -ENABLE_GLOB := 1 -ENABLE_PLUGINS := 1 -ENABLE_READLINE := 1 -ENABLE_EDITLINE := 0 -ENABLE_GHDL := 0 -ENABLE_VERIFIC := 0 -ENABLE_VERIFIC_SYSTEMVERILOG := 1 -ENABLE_VERIFIC_VHDL := 1 -ENABLE_VERIFIC_HIER_TREE := 1 -ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0 -ENABLE_VERIFIC_EDIF := 0 -ENABLE_VERIFIC_LIBERTY := 0 -ENABLE_LIBYOSYS := 0 -ENABLE_LIBYOSYS_STATIC := 0 -ENABLE_ZLIB := 1 -ENABLE_HELP_SOURCE := 0 - -# python wrappers -ENABLE_PYOSYS := 0 -PYOSYS_USE_UV := 1 - -# other configuration flags -ENABLE_GCOV := 0 -ENABLE_GPROF := 0 -ENABLE_DEBUG := 0 -ENABLE_LTO := 0 -ENABLE_CCACHE := 0 -# sccache is not always a drop-in replacement for ccache in practice -ENABLE_SCCACHE := 0 -ENABLE_FUNCTIONAL_TESTS := 0 -LINK_CURSES := 0 -LINK_TERMCAP := 0 -LINK_ABC := 0 -# Needed for environments that can't run executables (i.e. emscripten, wasm) -DISABLE_SPAWN := 0 -# Needed for environments that don't have proper thread support (i.e. emscripten, wasm--for now) -ENABLE_THREADS := 1 -ifeq ($(ENABLE_THREADS),1) -DISABLE_ABC_THREADS := 0 -else -DISABLE_ABC_THREADS := 1 -endif - -# clang sanitizers -SANITIZER = -# SANITIZER = address -# SANITIZER = memory -# SANITIZER = undefined -# SANITIZER = cfi - -# Prefer using ENABLE_DEBUG over setting these -OPT_LEVEL := -O3 -GCC_LTO := -CLANG_LTO := -flto=thin - -PROGRAM_PREFIX := - -OS := $(shell uname -s) -PREFIX ?= /usr/local -INSTALL_SUDO := -ifneq ($(filter MINGW%,$(OS)),) -OS := MINGW -endif - -ifneq ($(wildcard Makefile.conf),) -include Makefile.conf -endif - -ifeq ($(ENABLE_PYOSYS),1) -ENABLE_LIBYOSYS := 1 -endif - -BINDIR := $(PREFIX)/bin -LIBDIR := $(PREFIX)/lib/$(PROGRAM_PREFIX)yosys -DATDIR := $(PREFIX)/share/$(PROGRAM_PREFIX)yosys - -EXE = -OBJS = -GENFILES = -EXTRA_OBJS = -EXTRA_TARGETS = -TARGETS = $(PROGRAM_PREFIX)yosys$(EXE) $(PROGRAM_PREFIX)yosys-config - -PRETTY = 1 -SMALL = 0 - -all: top-all - -YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) -VPATH := $(YOSYS_SRC) - -# Unit test -UNITESTPATH := $(YOSYS_SRC)/tests/unit - -export CXXSTD ?= c++20 -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 := -EXE_LINKFLAGS := -EXE_LIBS := -ifeq ($(OS), MINGW) -EXE_LINKFLAGS := -Wl,--export-all-symbols -Wl,--out-implib,libyosys_exe.a -PLUGIN_LINKFLAGS += -L"$(LIBDIR)" -PLUGIN_LIBS := -lyosys_exe -endif - -ifeq ($(ENABLE_HELP_SOURCE),1) -CXXFLAGS += -DYOSYS_ENABLE_HELP_SOURCE -endif - -PKG_CONFIG ?= pkg-config -SED ?= sed -BISON ?= bison -STRIP ?= strip -AWK ?= awk - -ifeq ($(OS), Darwin) -PLUGIN_LINKFLAGS += -undefined dynamic_lookup -LINKFLAGS += -rdynamic - -# homebrew search paths -ifneq ($(shell :; command -v brew),) -BREW_PREFIX := $(shell brew --prefix)/opt -$(info $$BREW_PREFIX is [${BREW_PREFIX}]) -CXXFLAGS += -I$(BREW_PREFIX)/readline/include -I$(BREW_PREFIX)/flex/include -LINKFLAGS += -L$(BREW_PREFIX)/readline/lib -L$(BREW_PREFIX)/flex/lib -PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) -PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH) -export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) - -# macports search paths -else ifneq ($(shell :; command -v port),) -PORT_PREFIX := $(patsubst %/bin/port,%,$(shell :; command -v port)) -CXXFLAGS += -I$(PORT_PREFIX)/include -LINKFLAGS += -L$(PORT_PREFIX)/lib -PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) -export PATH := $(PORT_PREFIX)/bin:$(PATH) -endif - -else -LINKFLAGS += -rdynamic -ifneq ($(OS), OpenBSD) -LIBS += -lrt -endif -endif - -ifeq ($(OS), Haiku) -# Allow usage of non-posix vasprintf, mkstemps functions -CXXFLAGS += -D_DEFAULT_SOURCE -endif - -YOSYS_VER := 0.66 - -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) -CXXFLAGS += -DYOSYS_VER=\\"$(YOSYS_VER)\\" \ - -DYOSYS_MAJOR=$(YOSYS_MAJOR) \ - -DYOSYS_MINOR=$(YOSYS_MINOR) \ - -DYOSYS_COMMIT=$(YOSYS_COMMIT) - -# Note: We arrange for .gitcommit to contain the (short) commit hash in -# tarballs generated with git-archive(1) using .gitattributes. The git repo -# will have this file in its unexpanded form tough, in which case we fall -# back to calling git directly. -TARBALL_GIT_REV := $(shell cat $(YOSYS_SRC)/.gitcommit) -ifneq ($(findstring Format:,$(TARBALL_GIT_REV)),) -GIT_REV := $(shell GIT_DIR=$(YOSYS_SRC)/.git git rev-parse --short=9 HEAD || echo UNKNOWN) -GIT_DIRTY := $(shell GIT_DIR=$(YOSYS_SRC)/.git git diff --exit-code --quiet 2>/dev/null; if [ $$? -ne 0 ]; then echo "-dirty"; fi) -else -GIT_REV := $(TARBALL_GIT_REV) -GIT_DIRTY := "" -endif - -OBJS = kernel/version_$(GIT_REV).o - -ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) - -# set ABCEXTERNAL = to use an external ABC instance -# Note: The in-tree ABC (yosys-abc) will not be installed when ABCEXTERNAL is set. -ABCEXTERNAL ?= - -define newline - - -endef - -ifneq ($(wildcard Makefile.conf),) -# don't echo Makefile.conf contents when invoked to print source versions -ifeq ($(findstring echo-,$(MAKECMDGOALS)),) -$(info $(subst $$--$$,$(newline),$(shell sed 's,^,[Makefile.conf] ,; s,$$,$$--$$,;' < Makefile.conf | tr -d '\n' | sed 's,\$$--\$$$$,,'))) -endif -include Makefile.conf -endif - -PYTHON_EXECUTABLE ?= $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi) -ifeq ($(ENABLE_PYOSYS),1) -PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)" -PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"") -PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.) - -PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config -PYTHON_CONFIG_FOR_EXE := $(PYTHON_CONFIG) -PYTHON_CONFIG_EMBED_AVAILABLE ?= $(shell $(PYTHON_EXECUTABLE)-config --embed --libs > /dev/null && echo 1) -ifeq ($(PYTHON_CONFIG_EMBED_AVAILABLE),1) -PYTHON_CONFIG_FOR_EXE := $(PYTHON_CONFIG) --embed -endif - -PYTHON_DESTDIR := $(shell $(PYTHON_EXECUTABLE) -c "import site; print(site.getsitepackages()[-1]);") - -# Reload Makefile.conf to override python specific variables if defined -ifneq ($(wildcard Makefile.conf),) -include Makefile.conf -endif - -endif - -ABC_ARCHFLAGS = "" -ifeq ($(OS), OpenBSD) -ABC_ARCHFLAGS += "-DABC_NO_RLIMIT" -endif - -# This gets overridden later. -LTOFLAGS := $(GCC_LTO) - -ifeq ($(CONFIG),clang) -CXX = clang++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ifeq ($(ENABLE_LTO),1) -LINKFLAGS += -fuse-ld=lld -endif -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" -LTOFLAGS := $(CLANG_LTO) - -ifneq ($(SANITIZER),) -$(info [Clang Sanitizer] $(SANITIZER)) -CXXFLAGS += -g -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=$(SANITIZER) -LINKFLAGS += -g -fsanitize=$(SANITIZER) -ifneq ($(findstring memory,$(SANITIZER)),) -CXXFLAGS += -fPIE -fsanitize-memory-track-origins -LINKFLAGS += -fPIE -fsanitize-memory-track-origins -endif -ifneq ($(findstring cfi,$(SANITIZER)),) -CXXFLAGS += -flto -LINKFLAGS += -flto -LTOFLAGS = -endif -endif - -else ifeq ($(CONFIG),gcc) -CXX = g++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" - -else ifeq ($(CONFIG),gcc-static) -LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -static -LIBS := $(filter-out -lrt,$(LIBS)) -CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ABCMKARGS = CC="$(CC)" CXX="$(CXX)" LD="$(CXX)" ABC_USE_LIBSTDCXX=1 LIBS="-lm -lpthread -static" OPTFLAGS="-O" \ - ARCHFLAGS="-DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING=1 -Wno-unused-but-set-variable $(ARCHFLAGS)" ABC_USE_NO_READLINE=1 -ifeq ($(DISABLE_ABC_THREADS),1) -ABCMKARGS += "ABC_USE_NO_PTHREADS=1" -endif - -else ifeq ($(CONFIG),wasi) -ifeq ($(WASI_SDK),) -CXX = clang++ -AR = llvm-ar -RANLIB = llvm-ranlib -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 -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 - -ifeq ($(ENABLE_ABC),1) -LINK_ABC := 1 -ENABLE_THREADS := 0 -DISABLE_ABC_THREADS := 1 -endif - -else ifeq ($(CONFIG),msys2-32) -CXX = i686-w64-mingw32-g++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR -CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s -LIBS := $(filter-out -lrt,$(LIBS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w" -ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="i686-w64-mingw32-gcc" CXX="$(CXX)" -EXE = .exe - -else ifeq ($(CONFIG),msys2-64) -CXX = x86_64-w64-mingw32-g++ -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR -CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) -LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s -LIBS := $(filter-out -lrt,$(LIBS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w" -ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gcc" CXX="$(CXX)" -EXE = .exe - -else ifeq ($(CONFIG),none) -CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)" -LTOFLAGS = - -else -$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, msys2-32, msys2-64, none) -endif - - -ifeq ($(ENABLE_LTO),1) -CXXFLAGS += $(LTOFLAGS) -LINKFLAGS += $(LTOFLAGS) -endif - -ifeq ($(ENABLE_LIBYOSYS),1) -TARGETS += libyosys.so -ifeq ($(ENABLE_LIBYOSYS_STATIC),1) -TARGETS += libyosys.a -endif -endif - -PY_WRAPPER_FILE = pyosys/wrappers - -# running make clean on just those and then recompiling saves a lot of -# time when running cibuildwheel -PYTHON_OBJECTS = pyosys/wrappers.o kernel/drivers.o kernel/yosys.o passes/cmds/plugin.o - -ifeq ($(ENABLE_PYOSYS),1) -# python-config --ldflags includes -l and -L, but LINKFLAGS is only -L - -UV_ENV := -ifeq ($(PYOSYS_USE_UV),1) -UV_ENV := uv run --no-project --with 'pybind11>3,<4' --with 'cxxheaderparser' -endif - -LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags)) -LIBS += $(shell $(PYTHON_CONFIG) --libs) -EXE_LIBS += $(filter-out $(LIBS),$(shell $(PYTHON_CONFIG_FOR_EXE) --libs)) -PYBIND11_INCLUDE ?= $(shell $(UV_ENV) $(PYTHON_EXECUTABLE) -m pybind11 --includes) -CXXFLAGS += -I$(PYBIND11_INCLUDE) -DYOSYS_ENABLE_PYTHON -CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DYOSYS_ENABLE_PYTHON - -OBJS += $(PY_WRAPPER_FILE).o -PY_GEN_SCRIPT = $(YOSYS_SRC)/pyosys/generator.py -PY_WRAP_INCLUDES := $(shell $(UV_ENV) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) --print-includes) -endif # ENABLE_PYOSYS - -ifeq ($(ENABLE_READLINE),1) -CXXFLAGS += -DYOSYS_ENABLE_READLINE -ifeq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD)) -CXXFLAGS += -I/usr/local/include -endif -LIBS += -lreadline -ifeq ($(LINK_CURSES),1) -LIBS += -lcurses -ABCMKARGS += "ABC_READLINE_LIBRARIES=-lcurses -lreadline" -endif -ifeq ($(LINK_TERMCAP),1) -LIBS += -ltermcap -ABCMKARGS += "ABC_READLINE_LIBRARIES=-lreadline -ltermcap" -endif -else -ifeq ($(ENABLE_EDITLINE),1) -CXXFLAGS += -DYOSYS_ENABLE_EDITLINE -LIBS += -ledit -endif -ABCMKARGS += "ABC_USE_NO_READLINE=1" -endif - -ifeq ($(DISABLE_ABC_THREADS),1) -ABCMKARGS += "ABC_USE_NO_PTHREADS=1" -endif - -ifeq ($(LINK_ABC),1) -ABCMKARGS += "ABC_USE_PIC=1" -endif - -ifeq ($(DISABLE_SPAWN),1) -CXXFLAGS += -DYOSYS_DISABLE_SPAWN -endif - -ifeq ($(ENABLE_PLUGINS),1) -CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags libffi) -DYOSYS_ENABLE_PLUGINS -ifeq ($(OS), MINGW) -CXXFLAGS += -Ilibs/dlfcn-win32 -endif -LIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libffi || echo -lffi) -ifneq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD MINGW)) -LIBS += -ldl -endif -endif - -ifeq ($(ENABLE_GLOB),1) -CXXFLAGS += -DYOSYS_ENABLE_GLOB -endif - -ifeq ($(ENABLE_ZLIB),1) -CXXFLAGS += -DYOSYS_ENABLE_ZLIB -LIBS += -lz -endif - - -ifeq ($(ENABLE_TCL),1) -TCL_VERSION ?= tcl$(shell bash -c "tclsh <(echo 'puts [info tclversion]')") -ifeq ($(OS), $(filter $(OS),FreeBSD OpenBSD NetBSD)) -# BSDs usually use tcl8.6, but the lib is named "libtcl86" -TCL_INCLUDE ?= /usr/local/include/$(TCL_VERSION) -TCL_LIBS ?= -l$(subst .,,$(TCL_VERSION)) -else -TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) -TCL_LIBS ?= -l$(TCL_VERSION) -endif - -CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags tcl || echo -I$(TCL_INCLUDE)) -DYOSYS_ENABLE_TCL -LIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs tcl || echo $(TCL_LIBS)) -ifneq (,$(findstring TCL_WITH_EXTERNAL_TOMMATH,$(CXXFLAGS))) -LIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libtommath || echo) -endif -endif - -ifeq ($(ENABLE_GCOV),1) -LLVM_PROFILE_FILE ?= $(realpath $(YOSYS_SRC))/coverage/coverage_%p.profraw -export LLVM_PROFILE_FILE -export LLVM_PROFILE_FILE_BUFFER_SIZE=0 -CXXFLAGS += -fprofile-instr-generate -fcoverage-mapping -LINKFLAGS+= -fprofile-instr-generate -endif - -ifeq ($(ENABLE_GPROF),1) -CXXFLAGS += -pg -LINKFLAGS += -pg -endif - -ifeq ($(ENABLE_DEBUG),1) -CXXFLAGS := -Og -DDEBUG $(filter-out $(OPT_LEVEL),$(CXXFLAGS)) -STRIP := -endif - -ifeq ($(ENABLE_THREADS),1) -CXXFLAGS += -DYOSYS_ENABLE_THREADS -LIBS += -lpthread -endif - -ifeq ($(ENABLE_ABC),1) -CXXFLAGS += -DYOSYS_ENABLE_ABC -ifeq ($(LINK_ABC),1) -CXXFLAGS += -DYOSYS_LINK_ABC -ifeq ($(DISABLE_ABC_THREADS),0) -LIBS += -lpthread -endif -else -ifeq ($(ABCEXTERNAL),) -TARGETS := $(PROGRAM_PREFIX)yosys-abc$(EXE) $(TARGETS) -endif -ifeq ($(DISABLE_SPAWN),1) -$(error ENABLE_ABC=1 requires either LINK_ABC=1 or DISABLE_SPAWN=0) -endif -endif -endif - -ifeq ($(ENABLE_GHDL),1) -GHDL_PREFIX ?= $(PREFIX) -GHDL_INCLUDE_DIR ?= $(GHDL_PREFIX)/include -GHDL_LIB_DIR ?= $(GHDL_PREFIX)/lib -CXXFLAGS += -I$(GHDL_INCLUDE_DIR) -DYOSYS_ENABLE_GHDL -LIBS += $(GHDL_LIB_DIR)/libghdl.a $(file <$(GHDL_LIB_DIR)/libghdl.link) -endif - -LIBS_VERIFIC = -ifeq ($(ENABLE_VERIFIC),1) -VERIFIC_DIR ?= /usr/local/src/verific_lib -VERIFIC_COMPONENTS ?= database util containers -ifeq ($(ENABLE_VERIFIC_HIER_TREE),1) -VERIFIC_COMPONENTS += hier_tree -CXXFLAGS += -DVERIFIC_HIER_TREE_SUPPORT -else -ifneq ($(wildcard $(VERIFIC_DIR)/hier_tree),) -VERIFIC_COMPONENTS += hier_tree -endif -endif -ifeq ($(ENABLE_VERIFIC_SYSTEMVERILOG),1) -VERIFIC_COMPONENTS += verilog -CXXFLAGS += -DVERIFIC_SYSTEMVERILOG_SUPPORT -else -ifneq ($(wildcard $(VERIFIC_DIR)/verilog),) -VERIFIC_COMPONENTS += verilog -endif -endif -ifeq ($(ENABLE_VERIFIC_VHDL),1) -VERIFIC_COMPONENTS += vhdl -CXXFLAGS += -DVERIFIC_VHDL_SUPPORT -else -ifneq ($(wildcard $(VERIFIC_DIR)/vhdl),) -VERIFIC_COMPONENTS += vhdl -endif -endif -ifeq ($(ENABLE_VERIFIC_EDIF),1) -VERIFIC_COMPONENTS += edif -CXXFLAGS += -DVERIFIC_EDIF_SUPPORT -endif -ifeq ($(ENABLE_VERIFIC_LIBERTY),1) -VERIFIC_COMPONENTS += synlib -CXXFLAGS += -DVERIFIC_LIBERTY_SUPPORT -endif -ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1) -VERIFIC_COMPONENTS += extensions -CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS -else -# YosysHQ flavor of Verific always needs extensions linked -# if disabled it will just not be invoked but parts -# are required for it to initialize properly -ifneq ($(wildcard $(VERIFIC_DIR)/extensions),) -VERIFIC_COMPONENTS += extensions -OBJS += kernel/log_compat.o -endif -endif -CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC -ifeq ($(OS), Darwin) -LIBS_VERIFIC += $(foreach comp,$(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)),-Wl,-force_load $(comp)) -lz -else -LIBS_VERIFIC += -Wl,--whole-archive $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) -Wl,--no-whole-archive -lz -endif -endif - -ifeq ($(ENABLE_CCACHE),1) -CXX := ccache $(CXX) -else -ifeq ($(ENABLE_SCCACHE),1) -CXX := sccache $(CXX) -endif -endif - -define add_share_file -EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2))) -$(subst //,/,$(1)/$(notdir $(2))): $(2) - $$(P) mkdir -p $(1) - $$(Q) cp "$(YOSYS_SRC)"/$(2) $(subst //,/,$(1)/$(notdir $(2))) -endef - -define add_share_file_and_rename -EXTRA_TARGETS += $(subst //,/,$(1)/$(3)) -$(subst //,/,$(1)/$(3)): $(2) - $$(P) mkdir -p $(1) - $$(Q) cp "$(YOSYS_SRC)"/$(2) $(subst //,/,$(1)/$(3)) -endef - -define add_gen_share_file -EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2))) -$(subst //,/,$(1)/$(notdir $(2))): $(2) - $$(P) mkdir -p $(1) - $$(Q) cp $(2) $(subst //,/,$(1)/$(notdir $(2))) -endef - -define add_include_file -$(eval $(call add_share_file,$(dir share/include/$(1)),$(1))) -endef - -define add_extra_objs -EXTRA_OBJS += $(1) -.SECONDARY: $(1) -endef - -ifeq ($(PRETTY), 1) -P_STATUS = 0 -P_OFFSET = 0 -P_UPDATE = $(eval P_STATUS=$(shell echo $(OBJS) $(PROGRAM_PREFIX)yosys$(EXE) | $(AWK) 'BEGIN { RS = " "; I = $(P_STATUS)+0; } $$1 == "$@" && NR > I { I = NR; } END { print I; }')) -P_SHOW = [$(shell $(AWK) "BEGIN { N=$(words $(OBJS) $(PROGRAM_PREFIX)yosys$(EXE)); printf \"%3d\", $(P_OFFSET)+90*$(P_STATUS)/N; exit; }")%] -P = @echo "$(if $(findstring $@,$(TARGETS) $(EXTRA_TARGETS)),$(eval P_OFFSET = 10))$(call P_UPDATE)$(call P_SHOW) Building $@"; -Q = @ -S = -s -else -P_SHOW = -> -P = -Q = -S = -endif - -$(eval $(call add_include_file,kernel/binding.h)) -$(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)) -$(eval $(call add_include_file,kernel/drivertools.h)) -$(eval $(call add_include_file,kernel/ff.h)) -$(eval $(call add_include_file,kernel/ffinit.h)) -$(eval $(call add_include_file,kernel/ffmerge.h)) -$(eval $(call add_include_file,kernel/fmt.h)) -ifeq ($(ENABLE_ZLIB),1) -$(eval $(call add_include_file,kernel/fstdata.h)) -endif -$(eval $(call add_include_file,kernel/gzip.h)) -$(eval $(call add_include_file,kernel/hashlib.h)) -$(eval $(call add_include_file,kernel/io.h)) -$(eval $(call add_include_file,kernel/json.h)) -$(eval $(call add_include_file,kernel/log.h)) -$(eval $(call add_include_file,kernel/macc.h)) -$(eval $(call add_include_file,kernel/modtools.h)) -$(eval $(call add_include_file,kernel/mem.h)) -$(eval $(call add_include_file,kernel/qcsat.h)) -$(eval $(call add_include_file,kernel/register.h)) -$(eval $(call add_include_file,kernel/rtlil.h)) -$(eval $(call add_include_file,kernel/satgen.h)) -$(eval $(call add_include_file,kernel/scopeinfo.h)) -$(eval $(call add_include_file,kernel/sexpr.h)) -$(eval $(call add_include_file,kernel/sigtools.h)) -$(eval $(call add_include_file,kernel/threading.h)) -$(eval $(call add_include_file,kernel/timinginfo.h)) -$(eval $(call add_include_file,kernel/utils.h)) -$(eval $(call add_include_file,kernel/yosys.h)) -$(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 -$(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/blif/blifparse.h)) -$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) - -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o -OBJS += kernel/rtlil_bufnorm.o -OBJS += kernel/log_help.o -ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1) -OBJS += kernel/log_compat.o -endif -OBJS += kernel/binding.o kernel/tclapi.o -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o -OBJS += kernel/drivertools.o kernel/functional.o kernel/threading.o -ifeq ($(ENABLE_ZLIB),1) -OBJS += kernel/fstdata.o -endif -ifeq ($(ENABLE_PLUGINS),1) -ifeq ($(OS), MINGW) -OBJS += libs/dlfcn-win32/dlfcn.o -endif -endif - -kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' -kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' -ifeq ($(ENABLE_ABC),1) -ifneq ($(ABCEXTERNAL),) -kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' -endif -endif - -OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o -OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o - -OBJS += libs/sha1/sha1.o - -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 -OBJS += libs/minisat/Solver.o -OBJS += libs/minisat/System.o - -ifeq ($(ENABLE_ZLIB),1) -OBJS += libs/fst/fstapi.o -OBJS += libs/fst/fastlz.o -OBJS += libs/fst/lz4.o -endif - -techlibs/%_pm.h: passes/pmgen/pmgen.py techlibs/%.pmg - $(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p $(notdir $*) $(filter-out $<,$^) - -ifneq ($(SMALL),1) - -OBJS += libs/subcircuit/subcircuit.o - -include $(YOSYS_SRC)/frontends/*/Makefile.inc -include $(YOSYS_SRC)/passes/*/Makefile.inc -include $(YOSYS_SRC)/backends/*/Makefile.inc -include $(YOSYS_SRC)/techlibs/*/Makefile.inc - -else - -include $(YOSYS_SRC)/frontends/verilog/Makefile.inc -ifeq ($(ENABLE_VERIFIC),1) -include $(YOSYS_SRC)/frontends/verific/Makefile.inc -endif -include $(YOSYS_SRC)/frontends/rtlil/Makefile.inc -include $(YOSYS_SRC)/frontends/ast/Makefile.inc -include $(YOSYS_SRC)/frontends/blif/Makefile.inc - -OBJS += passes/hierarchy/hierarchy.o -OBJS += passes/cmds/select.o -OBJS += passes/cmds/show.o -OBJS += passes/cmds/stat.o -OBJS += passes/cmds/design.o -OBJS += passes/cmds/plugin.o - -include $(YOSYS_SRC)/passes/proc/Makefile.inc -include $(YOSYS_SRC)/passes/opt/Makefile.inc -include $(YOSYS_SRC)/passes/techmap/Makefile.inc - -include $(YOSYS_SRC)/backends/verilog/Makefile.inc -include $(YOSYS_SRC)/backends/rtlil/Makefile.inc - -include $(YOSYS_SRC)/techlibs/common/Makefile.inc - -endif - -ifeq ($(LINK_ABC),1) -OBJS += $(PROGRAM_PREFIX)yosys-libabc.a -endif - -# prevent the CXXFLAGS set by this Makefile from reaching abc/Makefile, -# especially the -MD flag which will break the build when CXX is clang -unexport CXXFLAGS - -top-all: $(TARGETS) $(EXTRA_TARGETS) - @echo "" - @echo " Build successful." - @echo "" - -.PHONY: compile-only -compile-only: $(OBJS) $(GENFILES) $(EXTRA_TARGETS) - @echo "" - @echo " Compile successful." - @echo "" - -.PHONY: share -share: $(EXTRA_TARGETS) - @echo "" - @echo " Share directory created." - @echo "" - -$(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) - $(P) $(CXX) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LINKFLAGS) $(LINKFLAGS) $(OBJS) $(EXE_LIBS) $(LIBS) $(LIBS_VERIFIC) - -libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) -ifeq ($(OS), Darwin) - $(P) $(CXX) -o libyosys.so -shared -undefined dynamic_lookup -Wl,-install_name,libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC) -else - $(P) $(CXX) -o libyosys.so -shared -Wl,-soname,libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC) -endif - -libyosys.a: $(filter-out kernel/driver.o,$(OBJS)) - $(P) $(AR) rcs $@ $^ - -%.o: %.cc - $(Q) mkdir -p $(dir $@) - $(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $< - -%.pyh: %.h - $(Q) mkdir -p $(dir $@) - $(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(CXX) $(CXXFLAGS) -x c++ -o $@ -E -P - - -ifeq ($(ENABLE_PYOSYS),1) -$(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT) pyosys/wrappers_tpl.cc $(PY_WRAP_INCLUDES) pyosys/hashlib.h - $(Q) mkdir -p $(dir $@) - $(P) $(UV_ENV) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) $(PY_WRAPPER_FILE).cc -endif - -%.o: %.cpp - $(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 - $(Q) mkdir -p kernel && echo "namespace Yosys { extern const char *yosys_version_str; const char *yosys_version_str=\"$(YOSYS_VER_STR)\"; const char *yosys_git_hash_str=\"$(YOSYS_GIT_STR)\"; }" > kernel/version_$(GIT_REV).cc - -ifeq ($(ENABLE_VERIFIC),1) -CXXFLAGS_NOVERIFIC = $(foreach v,$(CXXFLAGS),$(if $(findstring $(VERIFIC_DIR),$(v)),,$(v))) -LIBS_NOVERIFIC = $(foreach v,$(LIBS),$(if $(findstring $(VERIFIC_DIR),$(v)),,$(v))) -else -CXXFLAGS_NOVERIFIC = $(CXXFLAGS) -LIBS_NOVERIFIC = $(LIBS) -endif - -$(PROGRAM_PREFIX)yosys-config: misc/yosys-config.in $(YOSYS_SRC)/Makefile - $(P) $(SED) -e 's#@CXXFLAGS@#$(subst -Ilibs/dlfcn-win32,,$(subst -I. -I"$(YOSYS_SRC)",-I"$(DATDIR)/include",$(strip $(CXXFLAGS_NOVERIFIC))))#;' \ - -e 's#@CXX@#$(strip $(CXX))#;' -e 's#@LINKFLAGS@#$(strip $(LINKFLAGS) $(PLUGIN_LINKFLAGS))#;' -e 's#@LIBS@#$(strip $(LIBS_NOVERIFIC) $(PLUGIN_LIBS))#;' \ - -e 's#@BINDIR@#$(strip $(BINDIR))#;' -e 's#@DATDIR@#$(strip $(DATDIR))#;' < $< > $(PROGRAM_PREFIX)yosys-config - $(Q) chmod +x $(PROGRAM_PREFIX)yosys-config - -.PHONY: check-git-abc - -check-git-abc: - @if [ ! -d "$(YOSYS_SRC)/abc" ] && git -C "$(YOSYS_SRC)" status >/dev/null 2>&1; then \ - echo "Error: The 'abc' directory does not exist."; \ - echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \ - exit 1; \ - elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^ '; then \ - exit 0; \ - elif [ -f "$(YOSYS_SRC)/abc/.gitcommit" ] && ! grep -q '\$$Format:%[hH]\$$' "$(YOSYS_SRC)/abc/.gitcommit"; then \ - echo "'abc' comes from a tarball. Continuing."; \ - exit 0; \ - elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^+'; then \ - echo "'abc' submodule does not match expected commit."; \ - echo "Run 'git submodule update' to check out the correct version."; \ - echo "Note: If testing a different version of abc, call 'git commit abc' in the Yosys source directory to update the expected commit."; \ - exit 1; \ - elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^U'; then \ - echo "'abc' submodule has merge conflicts."; \ - echo "Please resolve merge conflicts before continuing."; \ - exit 1; \ - elif [ -f "$(YOSYS_SRC)/abc/.gitcommit" ] && grep -q '\$$Format:%[hH]\$$' "$(YOSYS_SRC)/abc/.gitcommit"; then \ - echo "Error: 'abc' is not configured as a git submodule."; \ - echo "To resolve this:"; \ - echo "1. Back up your changes: Save any modifications from the 'abc' directory to another location."; \ - echo "2. Remove the existing 'abc' directory: Delete the 'abc' directory and all its contents."; \ - echo "3. Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \ - echo "4. Reapply your changes: Move your saved changes back to the 'abc' directory, if necessary."; \ - exit 1; \ - elif ! git -C "$(YOSYS_SRC)" status >/dev/null 2>&1; then \ - echo "$(realpath $(YOSYS_SRC)) is not configured as a git repository, and 'abc' folder is missing."; \ - echo "If you already have ABC, set 'ABCEXTERNAL' make variable to point to ABC executable."; \ - echo "Otherwise, download release archive 'yosys.tar.gz' from https://github.com/YosysHQ/yosys/releases."; \ - echo " ('Source code' archive does not contain submodules.)"; \ - exit 1; \ - else \ - echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \ - exit 1; \ - fi - -.git-abc-submodule-hash: FORCE - @new=$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null || echo none); \ - old=$$(cat .git-abc-submodule-hash 2>/dev/null || echo none); \ - if [ "$$new" != "$$old" ]; then \ - echo "$$new" > .git-abc-submodule-hash; \ - fi - -abc/abc$(EXE) abc/libabc.a: .git-abc-submodule-hash | check-git-abc - @if [ "$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null)" != "$$(cat ../.git-abc-submodule-hash 2>/dev/null || echo none)" ]; then \ - rm -f abc/abc$(EXE); \ - fi - $(P) - $(Q) mkdir -p abc && $(MAKE) -C $(PROGRAM_PREFIX)abc -f "$(realpath $(YOSYS_SRC)/abc/Makefile)" ABCSRC="$(realpath $(YOSYS_SRC)/abc/)" $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc",PROG="abc$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc.a) - -$(PROGRAM_PREFIX)yosys-abc$(EXE): abc/abc$(EXE) - $(P) cp $< $(PROGRAM_PREFIX)yosys-abc$(EXE) - -$(PROGRAM_PREFIX)yosys-libabc.a: abc/libabc.a - $(P) cp $< $(PROGRAM_PREFIX)yosys-libabc.a - -ifneq ($(SEED),) -SEEDOPT="-S $(SEED)" -else -SEEDOPT="" -endif - -ifneq ($(ABCEXTERNAL),) -ABCOPT="-A $(ABCEXTERNAL)" -else -ABCOPT="" -endif - -test: vanilla-test unit-test - -.PHONY: vanilla-test - -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 - -vgtest: $(TARGETS) $(EXTRA_TARGETS) - $(VALGRIND) ./yosys -p 'setattr -mod -unset top; synth' $$( ls tests/simple/*.v | grep -v repwhile.v ) - @echo "" - @echo " Passed \"make vgtest\"." - @echo "" - -vloghtb: $(TARGETS) $(EXTRA_TARGETS) - +cd tests/vloghtb && bash run-test.sh - @echo "" - @echo " Passed \"make vloghtb\"." - @echo "" - -ystests: $(TARGETS) $(EXTRA_TARGETS) - rm -rf tests/ystests - git clone https://github.com/YosysHQ/yosys-tests.git tests/ystests - +$(MAKE) PATH="$$PWD:$$PATH" -C tests/ystests - @echo "" - @echo " Finished \"make ystests\"." - @echo "" - -# Unit test -unit-test: libyosys.so - @$(MAKE) -f $(UNITESTPATH)/Makefile CXX="$(CXX)" CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" \ - CXXFLAGS="$(CXXFLAGS)" LINKFLAGS="$(LINKFLAGS)" LIBS="$(LIBS)" ROOTPATH="$(CURDIR)" - -clean-unit-test: - @$(MAKE) -f $(UNITESTPATH)/Makefile clean - -install-dev: $(PROGRAM_PREFIX)yosys-config share - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR) - $(INSTALL_SUDO) cp $(PROGRAM_PREFIX)yosys-config $(DESTDIR)$(BINDIR) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR) - $(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/. - -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$(EXE),$(TARGETS)),) - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys$(EXE); fi -endif -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$(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)/. -ifeq ($(ENABLE_LIBYOSYS),1) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(LIBDIR) - $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)/ - if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so; fi -ifeq ($(ENABLE_LIBYOSYS_STATIC),1) - $(INSTALL_SUDO) cp libyosys.a $(DESTDIR)$(LIBDIR)/ -endif -ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys - $(INSTALL_SUDO) cp $(YOSYS_SRC)/pyosys/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py - $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys -ifeq ($(ENABLE_ABC),1) -ifeq ($(ABCEXTERNAL),) - $(INSTALL_SUDO) cp $(PROGRAM_PREFIX)yosys-abc$(EXE) $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc$(EXE) -endif -endif -endif -endif -ifeq ($(ENABLE_PLUGINS),1) -ifeq ($(OS), MINGW) - $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(LIBDIR) - $(INSTALL_SUDO) cp libyosys_exe.a $(DESTDIR)$(LIBDIR)/ -endif -endif - -uninstall: - $(INSTALL_SUDO) rm -vf $(addprefix $(DESTDIR)$(BINDIR)/,$(notdir $(TARGETS))) - $(INSTALL_SUDO) rm -rvf $(DESTDIR)$(DATDIR) -ifeq ($(ENABLE_LIBYOSYS),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so -ifeq ($(ENABLE_LIBYOSYS_STATIC),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.a -endif -ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py - $(INSTALL_SUDO) rmdir $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys -endif -endif - -docs/source/generated/cmds.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cmds-json $@' - -docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@' - -docs/source/generated/%.cc: backends/%.cc - $(Q) mkdir -p $(@D) - $(Q) cp $< $@ - -# diff returns exit code 1 if the files are different, but it's not an error -docs/source/generated/functional/rosette.diff: backends/functional/smtlib.cc backends/functional/smtlib_rosette.cc - $(Q) mkdir -p $(@D) - $(Q) diff -U 20 $^ > $@ || exit 0 - -PHONY: docs/gen/functional_ir -docs/gen/functional_ir: docs/source/generated/functional/smtlib.cc docs/source/generated/functional/rosette.diff - -docs/source/generated/%.log: docs/source/generated $(TARGETS) $(EXTRA_TARGETS) - $(Q) ./$(PROGRAM_PREFIX)yosys -qQT -h '$*' -l $@ - -docs/source/generated/chformal.cc: passes/cmds/chformal.cc docs/source/generated - $(Q) cp $< $@ - -PHONY: docs/gen/chformal -docs/gen/chformal: docs/source/generated/chformal.log docs/source/generated/chformal.cc - -PHONY: docs/gen docs/usage docs/reqs -docs/gen: $(TARGETS) - $(Q) $(MAKE) -C docs gen - -docs/source/generated: - $(Q) mkdir -p docs/source/generated - -# some commands return an error and print the usage text to stderr -define DOC_USAGE_STDERR -docs/source/generated/$(1): $(TARGETS) docs/source/generated FORCE - -$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@ -endef -DOCS_USAGE_STDERR := yosys-filterlib - -# The in-tree ABC (yosys-abc) is only built when ABCEXTERNAL is not set. -ifeq ($(ABCEXTERNAL),) -DOCS_USAGE_STDERR += yosys-abc -endif - -$(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) - -# others print to stdout -define DOC_USAGE_STDOUT -docs/source/generated/$(1): $(TARGETS) docs/source/generated - $(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ || rm $$@ -endef -DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness yosys-config -$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) - -docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) - -docs/reqs: - $(Q) $(MAKE) -C docs reqs - -.PHONY: docs/prep -docs/prep: docs/source/generated/cells.json docs/source/generated/cmds.json docs/gen docs/usage docs/gen/functional_ir docs/gen/chformal - -DOC_TARGET ?= html -docs: docs/prep - $(Q) $(MAKE) -C docs $(DOC_TARGET) - -clean: clean-py clean-unit-test - rm -rf share - 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 vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_* - -$(MAKE) -C $(YOSYS_SRC)/tests clean - -$(MAKE) -C $(YOSYS_SRC)/docs clean - rm -rf docs/util/__pycache__ - rm -f libyosys.so - -clean-py: - rm -f $(PY_WRAPPER_FILE).inc.cc $(PY_WRAPPER_FILE).cc - rm -f $(PYTHON_OBJECTS) - rm -f *.whl - rm -f libyosys.so libyosys.a - rm -rf kernel/*.pyh - -clean-abc: - $(MAKE) -C $(YOSYS_SRC)/abc DEP= clean - rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a .git-abc-submodule-hash - -mrproper: clean - git clean -xdf - -coverage: - ./$(PROGRAM_PREFIX)yosys -qp 'help; help -all' - rm -rf coverage_html - llvm-profdata merge -sparse coverage/coverage_*.profraw -o yosys.profdata - llvm-cov show ./$(PROGRAM_PREFIX)yosys -instr-profile=yosys.profdata -format=html -output-dir=coverage_html --compilation-dir=. -ignore-filename-regex='(^|.*/)libs/.*|/usr/include/.*|$(subst /,\/,$(VERIFIC_DIR))/.*' - -clean_coverage: - rm -rf coverage - rm -f yosys.profdata - -FUNC_KERNEL := functional.cc functional.h sexpr.cc sexpr.h compute_graph.h -FUNC_INCLUDES := $(addprefix --include *,functional/* $(FUNC_KERNEL)) -coverage_functional: - rm -rf coverage.info coverage_html - lcov --capture -d backends/functional -d kernel $(FUNC_INCLUDES) --no-external -o coverage.info - genhtml coverage.info --output-directory coverage_html - -qtcreator: - echo "$(CXXFLAGS)" | grep -o '\-D[^ ]*' | tr ' ' '\n' | sed 's/-D/#define /' | sed 's/=/ /'> qtcreator.config - { for file in $(basename $(OBJS)); do \ - for prefix in cc y l; do if [ -f $${file}.$${prefix} ]; then echo $$file.$${prefix}; fi; done \ - done; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \); } > qtcreator.files - { echo .; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \) -printf '%h\n' | sort -u; } > qtcreator.includes - touch qtcreator.creator - -VCX_DIR_NAME := yosys-win32-vcxsrc-$(YOSYS_VER) -vcxsrc: $(GENFILES) $(EXTRA_TARGETS) kernel/version_$(GIT_REV).cc - rm -rf $(VCX_DIR_NAME){,.zip} - cp -f kernel/version_$(GIT_REV).cc kernel/version.cc - set -e; for f in `ls $(filter %.cc %.cpp,$(GENFILES)) $(addsuffix .cc,$(basename $(OBJS))) $(addsuffix .cpp,$(basename $(OBJS))) 2> /dev/null`; do \ - echo "Analyse: $$f" >&2; cpp -std=c++20 -MM -I. -D_YOSYS_ $$f; done | sed 's,.*:,,; s,//*,/,g; s,/[^/]*/\.\./,/,g; y, \\,\n\n,;' | grep '^[^/]' | sort -u | grep -v kernel/version_ > srcfiles.txt - echo "libs/fst/fst_win_unistd.h" >> srcfiles.txt - echo "kernel/version.cc" >> srcfiles.txt - bash misc/create_vcxsrc.sh $(VCX_DIR_NAME) $(YOSYS_VER) - zip $(VCX_DIR_NAME)/genfiles.zip $(GENFILES) kernel/version.cc - zip -r $(VCX_DIR_NAME).zip $(VCX_DIR_NAME)/ - rm -f srcfiles.txt kernel/version.cc - -config-clean: clean - rm -f Makefile.conf - -config-clang: clean - echo 'CONFIG := clang' > Makefile.conf - -config-gcc: clean - echo 'CONFIG := gcc' > Makefile.conf - -config-gcc-static: clean - echo 'CONFIG := gcc-static' > Makefile.conf - echo 'ENABLE_PLUGINS := 0' >> Makefile.conf - echo 'ENABLE_READLINE := 0' >> Makefile.conf - echo 'ENABLE_TCL := 0' >> Makefile.conf - -config-wasi: clean - echo 'CONFIG := wasi' > Makefile.conf - echo 'ENABLE_TCL := 0' >> Makefile.conf - echo 'ENABLE_ABC := 0' >> Makefile.conf - echo 'ENABLE_PLUGINS := 0' >> Makefile.conf - echo 'ENABLE_READLINE := 0' >> Makefile.conf - echo 'ENABLE_ZLIB := 0' >> Makefile.conf - -config-msys2-32: clean - echo 'CONFIG := msys2-32' > Makefile.conf - echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf - -config-msys2-64: clean - echo 'CONFIG := msys2-64' > Makefile.conf - echo "PREFIX := $(MINGW_PREFIX)" >> Makefile.conf - -config-gcov: clean - echo 'CONFIG := clang' > Makefile.conf - echo 'ENABLE_GCOV := 1' >> Makefile.conf - echo 'ENABLE_DEBUG := 1' >> Makefile.conf - -config-gprof: clean - echo 'CONFIG := gcc' > Makefile.conf - echo 'ENABLE_GPROF := 1' >> Makefile.conf - -config-sudo: - echo "INSTALL_SUDO := sudo" >> Makefile.conf - -echo-yosys-ver: - @echo "$(YOSYS_VER)" - -echo-git-rev: - @echo "$(GIT_REV)" - -echo-cxx: - @echo "$(CXX)" - --include libs/*/*.d --include frontends/*/*.d --include passes/*/*.d --include backends/*/*.d --include kernel/*.d --include techlibs/*/*.d - -FORCE: - -.PHONY: all top-all abc test install-dev install install-abc docs clean mrproper qtcreator coverage vcxsrc -.PHONY: config-clean config-clang config-gcc config-gcc-static config-gprof config-sudo diff --git a/README.md b/README.md index df65a6a10..7dc02522e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ This is a framework for RTL synthesis tools. It currently has extensive Verilog-2005 support and provides a basic set of synthesis algorithms for various application domains. +Yosys is using [sv-elab](https://github.com/povik/sv-elab) and [slang](https://github.com/MikePopoloski/slang) libraries to provide comprehensive SystemVerilog support. +It supports an (informally defined) synthesizable subset of SystemVerilog in version IEEE 1800-2017 or IEEE 1800-2023. + Yosys can be adapted to perform any synthesis job by combining the existing passes (algorithms) using synthesis scripts and adding additional passes as needed by extending the yosys C++ @@ -67,18 +70,15 @@ on Read the Docs. When cloning Yosys, some required libraries are included as git submodules. Make sure to call e.g. - $ git clone --recurse-submodules https://github.com/YosysHQ/yosys.git - -or - $ git clone https://github.com/YosysHQ/yosys.git $ cd yosys - $ git submodule update --init --recursive + $ git submodule update --init -You need a C++ compiler with C++17 support (up-to-date CLANG or GCC is -recommended) and some standard tools such as GNU Flex, GNU Bison, and GNU Make. -TCL, readline and libffi are optional (see ``ENABLE_*`` settings in Makefile). -Xdot (graphviz) is used by the ``show`` command in yosys to display schematics. +A C++ compiler with C++20 support is required as well as some standard tools +such as GNU Flex, GNU Bison (>=3.8), CMake (>=3.28), Make (or other CMake +generator such as Ninja), and Python (>=3.11). Some additional tools: readline, +libffi, Tcl and zlib; will be used if available but are optional. Graphviz and +Xdot are used by the `show` command to display schematics. For example on Ubuntu Linux 22.04 LTS the following commands will install all prerequisites for building yosys: @@ -86,45 +86,66 @@ prerequisites for building yosys: $ sudo apt-get install gawk git make python3 lld bison clang flex \ libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev \ graphviz xdot - $ curl -LsSf https://astral.sh/uv/install.sh | sh -The environment variable `CXX` can be used to control the C++ compiler used, or -run one of the following to override it: +**NOTE**: By default, Ubuntu 22.04 LTS is limited to CMake 3.22 via `apt`. To +install a newer version and meet the minimum required for building Yosys, use +`sudo snap install cmake --classic`. - $ make config-clang - $ make config-gcc +CMake is used for build configuration, and requires a separate build directory: -The Makefile has many variables influencing the build process. These can be -adjusted by modifying the Makefile.conf file which is created at the `make -config-...` step (see above), or they can be set by passing an option to the -make command directly: + $ cmake -B build . - $ make CXX=$CXX +Once generated, available build variables can be inspected and modified with +`ccmake` or opening the generated `build/CMakeCache.txt` file: -For other compilers and build configurations it might be necessary to make some -changes to the config section of the Makefile. It's also an alternative way to -set the make variables mentioned above. + $ ccmake build #..or.. + $ vi build/CMakeCache.txt - $ vi Makefile # ..or.. - $ vi Makefile.conf +When setting one-off variables, CMake provides the `-D =` command +line option. For example, disabling zlib support: -To build Yosys simply type 'make' in this directory. + $ cmake -B build . -DYOSYS_WITHOUT_ZLIB=ON - $ make - $ sudo make install +For a more persistent configuration, we recommend creating and using a +`CMakeUserPresets.json` file in the root `yosys` directory. Below is an example +file which enables ccache and sets the default compiler to clang when calling +`cmake --preset clang`: -Tests are located in the tests subdirectory and can be executed using the test +```json +{ + "version": 1, + "configurePresets": [ + { + "name": "default", + "binaryDir": "build", + "generator": "Unix Makefiles", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++", + "YOSYS_COMPILER_LAUNCHER": "ccache" + } + } + ] +} +``` + +Once generated, the build system can be run as follows: + + $ cmake --build build #..or.. + $ cd build + $ cmake --build . + +To quickly install Yosys with the default settings: + + $ cmake -B build . -DCMAKE_BUILD_TYPE=Release + $ cmake --build build --config Release --parallel $(nproc) + $ sudo cmake --install build --strip + +Tests are located in the tests subdirectory and can be executed using the `test` target. Note that you need gawk, a recent version of iverilog, and gtest. Execute tests via: - $ make test - -To use a separate (out-of-tree) build directory, provide a path to the Makefile. - - $ mkdir build; cd build - $ make -f ../Makefile - -Out-of-tree builds require a clean source tree. + $ cmake --build build --target test --parallel $(nproc) Getting Started @@ -134,7 +155,7 @@ Yosys can be used with the interactive command shell, with synthesis scripts or with command line arguments. Let's perform a simple synthesis job using the interactive command shell: - $ ./yosys + $ ./build/yosys yosys> the command ``help`` can be used to print a list of all available @@ -256,7 +277,7 @@ following are used for building the website: Or for MacOS, using homebrew: - $ brew install pdf2svg libfaketime + $ brew install pdf2svg libfaketime PDFLaTeX, included with most LaTeX distributions, is also needed during the build process for the website. Or, run the following: @@ -265,24 +286,19 @@ build process for the website. Or, run the following: Or for MacOS, using homebrew: - $ brew install basictex - $ sudo tlmgr update --self - $ sudo tlmgr install collection-latexextra latexmk tex-gyre + $ brew install basictex + $ sudo tlmgr update --self + $ sudo tlmgr install collection-latexextra latexmk tex-gyre The Python package, Sphinx, is needed along with those listed in `docs/source/requirements.txt`: $ pip install -U sphinx -r docs/source/requirements.txt -From the root of the repository, run `make docs`. This will build/rebuild yosys -as necessary before generating the website documentation from the yosys help -commands. To build for pdf instead of html, call -`make docs DOC_TARGET=latexpdf`. +DOCS (e.g.) -It is recommended to use the `ENABLE_HELP_SOURCE` make option for Yosys builds -that will be used to build the documentation. This option enables source -location tracking for passes and improves the command reference through grouping -related commands and allowing for the documentation to link to the corresponding -source files. Without this, a warning will be raised during the Sphinx build -about `Found commands assigned to group unknown` and `make docs` is configured -to fail on warnings by default. + $ cmake --build build --target docs-html --parallel + +This will build/rebuild yosys as necessary before generating the website +documentation from the yosys help commands. To build for pdf instead of html, +use the `docs-latexpdf` target. diff --git a/abc b/abc index 5d51a5e42..e026ed538 160000 --- a/abc +++ b/abc @@ -1 +1 @@ -Subproject commit 5d51a5e420f5de493d07bf61109a977248c86ffb +Subproject commit e026ed5380f3bdc3beea2ff9ffc23236fc549d5b diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt new file mode 100644 index 000000000..a38c2ec94 --- /dev/null +++ b/backends/CMakeLists.txt @@ -0,0 +1,18 @@ +add_subdirectory(aiger) +add_subdirectory(aiger2) +add_subdirectory(blif) +add_subdirectory(btor) +add_subdirectory(cxxrtl) +add_subdirectory(edif) +add_subdirectory(firrtl) +add_subdirectory(functional) +add_subdirectory(intersynth) +add_subdirectory(jny) +add_subdirectory(json) +add_subdirectory(rtlil) +add_subdirectory(simplec) +add_subdirectory(smt2) +add_subdirectory(smv) +add_subdirectory(spice) +add_subdirectory(table) +add_subdirectory(verilog) diff --git a/backends/aiger/CMakeLists.txt b/backends/aiger/CMakeLists.txt new file mode 100644 index 000000000..4cf940196 --- /dev/null +++ b/backends/aiger/CMakeLists.txt @@ -0,0 +1,8 @@ +yosys_backend(aiger + aiger.cc + REQUIRES + json11 +) +yosys_backend(xaiger + xaiger.cc +) diff --git a/backends/aiger/Makefile.inc b/backends/aiger/Makefile.inc deleted file mode 100644 index 4a4cf30bd..000000000 --- a/backends/aiger/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ - -OBJS += backends/aiger/aiger.o -OBJS += backends/aiger/xaiger.o - diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index cc1085f96..522929c50 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -95,7 +95,7 @@ struct XAigerWriter } bit2aig_stack.push_back(bit); - + // NB: Cannot use iterator returned from aig_map.insert() // since this function is called recursively diff --git a/backends/aiger2/CMakeLists.txt b/backends/aiger2/CMakeLists.txt new file mode 100644 index 000000000..f77b8d9ee --- /dev/null +++ b/backends/aiger2/CMakeLists.txt @@ -0,0 +1,5 @@ +yosys_backend(aiger2 + aiger.cc + PROVIDES + write_xaiger2 +) diff --git a/backends/aiger2/Makefile.inc b/backends/aiger2/Makefile.inc deleted file mode 100644 index 494b8d6c6..000000000 --- a/backends/aiger2/Makefile.inc +++ /dev/null @@ -1 +0,0 @@ -OBJS += backends/aiger2/aiger.o diff --git a/backends/blif/CMakeLists.txt b/backends/blif/CMakeLists.txt new file mode 100644 index 000000000..06b177513 --- /dev/null +++ b/backends/blif/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(blif + blif.cc +) diff --git a/backends/blif/Makefile.inc b/backends/blif/Makefile.inc deleted file mode 100644 index 517dabaf2..000000000 --- a/backends/blif/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/blif/blif.o - diff --git a/backends/btor/CMakeLists.txt b/backends/btor/CMakeLists.txt new file mode 100644 index 000000000..ca40d538e --- /dev/null +++ b/backends/btor/CMakeLists.txt @@ -0,0 +1,7 @@ +yosys_backend(btor + btor.cc + REQUIRES + bmuxmap + demuxmap + bwmuxmap +) diff --git a/backends/btor/Makefile.inc b/backends/btor/Makefile.inc deleted file mode 100644 index af7ab14dc..000000000 --- a/backends/btor/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/btor/btor.o - diff --git a/backends/btor/test_cells.sh b/backends/btor/test_cells.sh index fc7f5b75c..dc044ec29 100755 --- a/backends/btor/test_cells.sh +++ b/backends/btor/test_cells.sh @@ -27,4 +27,3 @@ for fn in test_*.il; do done echo "OK." - diff --git a/backends/cxxrtl/CMakeLists.txt b/backends/cxxrtl/CMakeLists.txt new file mode 100644 index 000000000..f5d10539a --- /dev/null +++ b/backends/cxxrtl/CMakeLists.txt @@ -0,0 +1,19 @@ +yosys_backend(cxxrtl + cxxrtl_backend.cc + DATA_DIR + include/backends/cxxrtl + DATA_FILES + runtime/README.txt + runtime/cxxrtl/cxxrtl.h + runtime/cxxrtl/cxxrtl_vcd.h + runtime/cxxrtl/cxxrtl_time.h + runtime/cxxrtl/cxxrtl_replay.h + runtime/cxxrtl/capi/cxxrtl_capi.cc + runtime/cxxrtl/capi/cxxrtl_capi.h + runtime/cxxrtl/capi/cxxrtl_capi_vcd.cc + runtime/cxxrtl/capi/cxxrtl_capi_vcd.h + REQUIRES + hierarchy + flatten + proc +) diff --git a/backends/cxxrtl/Makefile.inc b/backends/cxxrtl/Makefile.inc deleted file mode 100644 index dd77d2ad3..000000000 --- a/backends/cxxrtl/Makefile.inc +++ /dev/null @@ -1,11 +0,0 @@ - -OBJS += backends/cxxrtl/cxxrtl_backend.o - -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl_vcd.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl_time.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/cxxrtl_replay.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi.cc)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi.h)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi_vcd.cc)) -$(eval $(call add_include_file,backends/cxxrtl/runtime/cxxrtl/capi/cxxrtl_capi_vcd.h)) diff --git a/backends/cxxrtl/runtime/README.txt b/backends/cxxrtl/runtime/README.txt index 9ae7051cd..f6e2d6c92 100644 --- a/backends/cxxrtl/runtime/README.txt +++ b/backends/cxxrtl/runtime/README.txt @@ -15,4 +15,4 @@ file of the simulation toplevel). The interfaces declared in `cxxrtl*.h` (without `capi`) are unstable and may change without notice. For clarity, all of the files in this directory and its subdirectories have unique names regardless -of the directory where they are placed. \ No newline at end of file +of the directory where they are placed. diff --git a/backends/edif/CMakeLists.txt b/backends/edif/CMakeLists.txt new file mode 100644 index 000000000..126d09f07 --- /dev/null +++ b/backends/edif/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(edif + edif.cc +) diff --git a/backends/edif/Makefile.inc b/backends/edif/Makefile.inc deleted file mode 100644 index 93de0e24f..000000000 --- a/backends/edif/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/edif/edif.o - diff --git a/backends/edif/runtest.py b/backends/edif/runtest.py index 826876a86..7af6433c1 100644 --- a/backends/edif/runtest.py +++ b/backends/edif/runtest.py @@ -118,4 +118,3 @@ os.system("set -x; ./test_gold > test_gold.out") os.system("set -x; ./test_gate > test_gate.out") os.system("set -x; md5sum test_gold.out test_gate.out") - diff --git a/backends/firrtl/CMakeLists.txt b/backends/firrtl/CMakeLists.txt new file mode 100644 index 000000000..2f38cd208 --- /dev/null +++ b/backends/firrtl/CMakeLists.txt @@ -0,0 +1,8 @@ +yosys_backend(firrtl + firrtl.cc + REQUIRES + pmuxtree + bmuxmap + demuxmap + bwmuxmap +) diff --git a/backends/firrtl/Makefile.inc b/backends/firrtl/Makefile.inc deleted file mode 100644 index fdf100d34..000000000 --- a/backends/firrtl/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/firrtl/firrtl.o - diff --git a/backends/functional/CMakeLists.txt b/backends/functional/CMakeLists.txt new file mode 100644 index 000000000..5e7a6e92f --- /dev/null +++ b/backends/functional/CMakeLists.txt @@ -0,0 +1,12 @@ +yosys_backend(functional_cxx + cxx.cc +) +yosys_backend(functional_smt2 + smtlib.cc +) +yosys_backend(functional_rosette + smtlib_rosette.cc +) +yosys_test_pass(generic + test_generic.cc +) diff --git a/backends/functional/Makefile.inc b/backends/functional/Makefile.inc deleted file mode 100644 index 16d1c0542..000000000 --- a/backends/functional/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ -OBJS += backends/functional/cxx.o -OBJS += backends/functional/smtlib.o -OBJS += backends/functional/smtlib_rosette.o -OBJS += backends/functional/test_generic.o diff --git a/backends/functional/smtlib.cc b/backends/functional/smtlib.cc index 0451af4c7..128dbda6c 100644 --- a/backends/functional/smtlib.cc +++ b/backends/functional/smtlib.cc @@ -187,7 +187,7 @@ struct SmtModule { Functional::IR ir; SmtScope scope; std::string name; - + SmtStruct input_struct; SmtStruct output_struct; SmtStruct state_struct; @@ -256,7 +256,7 @@ struct SmtModule { } void write(std::ostream &out) - { + { SExprWriter w(out); input_struct.write_definition(w); @@ -266,7 +266,7 @@ struct SmtModule { w << list("declare-datatypes", list(list("Pair", 2)), list(list("par", list("X", "Y"), list(list("pair", list("first", "X"), list("second", "Y")))))); - + write_eval(w); write_initial(w); } diff --git a/backends/functional/smtlib_rosette.cc b/backends/functional/smtlib_rosette.cc index b37f948b6..1adceddd5 100644 --- a/backends/functional/smtlib_rosette.cc +++ b/backends/functional/smtlib_rosette.cc @@ -304,7 +304,7 @@ struct SmtrModule { } void write(std::ostream &out) - { + { SExprWriter w(out); input_struct.write_definition(w); diff --git a/backends/functional/test_generic.cc b/backends/functional/test_generic.cc index 343fcfc0f..d6a1ce4af 100644 --- a/backends/functional/test_generic.cc +++ b/backends/functional/test_generic.cc @@ -46,7 +46,7 @@ struct MemContentsTest { error: printf("FAIL\n"); int digits = (data_width + 3) / 4; - + for(auto addr = 0; addr < (1<connections()) { + for (auto& con : port_cell->connections()) { if (!first_port) f << ",\n"; diff --git a/backends/json/CMakeLists.txt b/backends/json/CMakeLists.txt new file mode 100644 index 000000000..99c404d92 --- /dev/null +++ b/backends/json/CMakeLists.txt @@ -0,0 +1,5 @@ +yosys_backend(json + json.cc + PROVIDES + json +) diff --git a/backends/json/Makefile.inc b/backends/json/Makefile.inc deleted file mode 100644 index a463daf91..000000000 --- a/backends/json/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/json/json.o - diff --git a/backends/rtlil/CMakeLists.txt b/backends/rtlil/CMakeLists.txt new file mode 100644 index 000000000..40b3cffe0 --- /dev/null +++ b/backends/rtlil/CMakeLists.txt @@ -0,0 +1,11 @@ +yosys_backend(rtlil + rtlil_backend.cc + rtlil_backend.h + PROVIDES + dump + DATA_DIR + include/backends/rtlil + DATA_FILES + rtlil_backend.h + ESSENTIAL +) diff --git a/backends/rtlil/Makefile.inc b/backends/rtlil/Makefile.inc deleted file mode 100644 index f691282ca..000000000 --- a/backends/rtlil/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/rtlil/rtlil_backend.o - diff --git a/backends/simplec/CMakeLists.txt b/backends/simplec/CMakeLists.txt new file mode 100644 index 000000000..1a9feed9f --- /dev/null +++ b/backends/simplec/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(simplec + simplec.cc +) diff --git a/backends/simplec/Makefile.inc b/backends/simplec/Makefile.inc deleted file mode 100644 index fee1376c5..000000000 --- a/backends/simplec/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/simplec/simplec.o - diff --git a/backends/simplec/test00_uut.v b/backends/simplec/test00_uut.v index 92329a6f9..15ff4391d 100644 --- a/backends/simplec/test00_uut.v +++ b/backends/simplec/test00_uut.v @@ -11,4 +11,3 @@ endmodule module unit_y(input [31:0] a, b, c, output [31:0] y); assign y = a & (b | c); endmodule - diff --git a/backends/smt2/CMakeLists.txt b/backends/smt2/CMakeLists.txt new file mode 100644 index 000000000..c60bace7b --- /dev/null +++ b/backends/smt2/CMakeLists.txt @@ -0,0 +1,20 @@ +yosys_backend(smt2 + smt2.cc + REQUIRES + json11 + DATA_DIR + python3 + DATA_FILES + smtio.py + ywio.py + REQUIRES + bmuxmap + demuxmap +) + +yosys_python_executable(yosys-smtbmc smtbmc.py + INSTALL_IF YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY +) +yosys_python_executable(yosys-witness witness.py + INSTALL_IF YOSYS_INSTALL_DRIVER OR YOSYS_INSTALL_LIBRARY +) diff --git a/backends/smt2/Makefile.inc b/backends/smt2/Makefile.inc deleted file mode 100644 index 3afe990e7..000000000 --- a/backends/smt2/Makefile.inc +++ /dev/null @@ -1,46 +0,0 @@ - -OBJS += backends/smt2/smt2.o - -ifneq ($(CONFIG),mxe) -ifneq ($(CONFIG),emcc) - -# MSYS targets support yosys-smtbmc, but require a launcher script -ifeq ($(CONFIG),$(filter $(CONFIG),msys2 msys2-64)) -TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc.exe $(PROGRAM_PREFIX)yosys-smtbmc-script.py -TARGETS += $(PROGRAM_PREFIX)yosys-witness.exe $(PROGRAM_PREFIX)yosys-witness-script.py -# Needed to find the Python interpreter for yosys-smtbmc scripts. -# Override if necessary, it is only used for msys2 targets. -PYTHON := $(shell cygpath -w -m $(PREFIX)/bin/python3) - -$(PROGRAM_PREFIX)yosys-smtbmc-script.py: backends/smt2/smtbmc.py - $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \ - -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ - -$(PROGRAM_PREFIX)yosys-witness-script.py: backends/smt2/witness.py - $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \ - -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ - -$(PROGRAM_PREFIX)yosys-smtbmc.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-smtbmc-script.py - $(P) $(CXX) -DGUI=0 -O -s -o $@ $< - -$(PROGRAM_PREFIX)yosys-witness.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-witness-script.py - $(P) $(CXX) -DGUI=0 -O -s -o $@ $< -# Other targets -else -TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc $(PROGRAM_PREFIX)yosys-witness - -$(PROGRAM_PREFIX)yosys-smtbmc: backends/smt2/smtbmc.py - $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new - $(Q) chmod +x $@.new - $(Q) mv $@.new $@ - -$(PROGRAM_PREFIX)yosys-witness: backends/smt2/witness.py - $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new - $(Q) chmod +x $@.new - $(Q) mv $@.new $@ -endif - -$(eval $(call add_share_file,share/python3,backends/smt2/smtio.py)) -$(eval $(call add_share_file,share/python3,backends/smt2/ywio.py)) -endif -endif diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index a9030e18a..66ae4d51c 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -788,7 +788,7 @@ struct Smt2Worker if (has_async_wr && has_sync_wr) log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", cell, module); - decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", mem->memid.unescape(), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); + decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", get_id(mem->memid), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); decls.push_back(witness_memory(get_id(mem->memid), cell, mem)); string memstate; diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py old mode 100644 new mode 100755 index 9dfbd2a25..60fa97e36 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!@PYTHON_SHEBANG@ # # yosys -- Yosys Open SYnthesis Suite # @@ -18,7 +18,7 @@ # import os, sys, getopt, re, bisect, json -##yosys-sys-path## +sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/@YOSYS_PROGRAM_PREFIX@yosys/python3"]] from smtio import SmtIo, SmtOpts, MkVcd from ywio import ReadWitness, WriteWitness, WitnessValues from collections import defaultdict diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 2bc7daddc..b7897fa99 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -226,7 +226,7 @@ class SmtIo: print('timeout option is not supported for mathsat.') sys.exit(1) - if self.solver in ["boolector", "bitwuzla"]: + if self.solver == "boolector": if self.noincr: self.popen_vargs = [self.solver, '--smt2'] + self.solver_opts else: @@ -236,6 +236,29 @@ class SmtIo: print('timeout option is not supported for %s.' % self.solver) sys.exit(1) + if self.solver == "bitwuzla": + try: + help_text = subprocess.check_output([self.solver, "--help"], text=True) + except FileNotFoundError: + print("%s SMT Solver '%s' not found in path." % (self.timestamp(), self.solver), flush=True) + sys.exit(1) + if "--lang" in help_text: + self.popen_vargs = [self.solver, '--lang', 'smt2'] + self.solver_opts + self.unroll = True + if self.timeout != 0: + self.popen_vargs.append('--time-limit') + self.popen_vargs.append('%d000' % self.timeout) + else: + # Versions before 0.3 + if self.noincr: + self.popen_vargs = [self.solver, '--smt2'] + self.solver_opts + else: + self.popen_vargs = [self.solver, '--smt2', '-i'] + self.solver_opts + self.unroll = True + if self.timeout != 0: + print('timeout option is not supported for %s.' % self.solver) + sys.exit(1) + if self.solver == "abc": if len(self.solver_opts) > 0: self.popen_vargs = ['yosys-abc', '-S', '; '.join(self.solver_opts)] diff --git a/backends/smt2/test_cells.sh b/backends/smt2/test_cells.sh index 33c1b9989..bf13b5fb3 100644 --- a/backends/smt2/test_cells.sh +++ b/backends/smt2/test_cells.sh @@ -52,4 +52,3 @@ echo "" echo " All tests passed." echo "" exit 0 - diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py old mode 100644 new mode 100755 index b7e25851c..8c7d455bd --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!@PYTHON_SHEBANG@ # # yosys -- Yosys Open SYnthesis Suite # @@ -18,7 +18,7 @@ # import os, sys, itertools, re -##yosys-sys-path## +sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/@YOSYS_PROGRAM_PREFIX@yosys/python3"]] import json import click @@ -192,8 +192,10 @@ def aiw2yw(input, mapfile, output, skip_x, present_only): header_lines = list(itertools.islice(input, 0, 2)) - if len(header_lines) == 2 and header_lines[1][0] in ".bcjf": + if len(header_lines) == 2 and header_lines[1][0] in ".bj": status = header_lines[0].strip() + if header_lines[1][0]=='j': + raise click.ClickException(f"{input_name}: justice property in AIGER witness not yet supported") if status == "0": raise click.ClickException(f"{input_name}: file contains no trace, the AIGER status is unsat") elif status == "2": diff --git a/backends/smt2/ywio.py b/backends/smt2/ywio.py index 023a2d351..170d2099b 100644 --- a/backends/smt2/ywio.py +++ b/backends/smt2/ywio.py @@ -398,13 +398,13 @@ class ReadWitness: def init_step(self): return self.step(0) - + def non_init_bits(self): if len(self) > 1: return len(self.bits[1]) else: return sum([sig.width for sig in self.signals if not sig.init_only]) - + def first_step(self): values = WitnessValues() # may have issues when non_init_bits is 0 diff --git a/backends/smv/CMakeLists.txt b/backends/smv/CMakeLists.txt new file mode 100644 index 000000000..ea9e85f28 --- /dev/null +++ b/backends/smv/CMakeLists.txt @@ -0,0 +1,7 @@ +yosys_backend(smv + smv.cc + REQUIRES + bmuxmap + demuxmap + bwmuxmap +) diff --git a/backends/smv/Makefile.inc b/backends/smv/Makefile.inc deleted file mode 100644 index 66c192d80..000000000 --- a/backends/smv/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/smv/smv.o - diff --git a/backends/smv/test_cells.sh b/backends/smv/test_cells.sh index f2c5ff09d..2497edc6b 100644 --- a/backends/smv/test_cells.sh +++ b/backends/smv/test_cells.sh @@ -30,4 +30,3 @@ for fn in test_*.il; do done grep '^-- invariant .* is false' *.out || echo 'All OK.' - diff --git a/backends/spice/CMakeLists.txt b/backends/spice/CMakeLists.txt new file mode 100644 index 000000000..efbfc84d0 --- /dev/null +++ b/backends/spice/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(spice + spice.cc +) diff --git a/backends/spice/Makefile.inc b/backends/spice/Makefile.inc deleted file mode 100644 index 9c8530cb2..000000000 --- a/backends/spice/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/spice/spice.o - diff --git a/backends/table/CMakeLists.txt b/backends/table/CMakeLists.txt new file mode 100644 index 000000000..371d1e8f0 --- /dev/null +++ b/backends/table/CMakeLists.txt @@ -0,0 +1,3 @@ +yosys_backend(table + table.cc +) diff --git a/backends/table/Makefile.inc b/backends/table/Makefile.inc deleted file mode 100644 index 8cd1dc619..000000000 --- a/backends/table/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/table/table.o - diff --git a/backends/verilog/CMakeLists.txt b/backends/verilog/CMakeLists.txt new file mode 100644 index 000000000..6de8dd1f6 --- /dev/null +++ b/backends/verilog/CMakeLists.txt @@ -0,0 +1,8 @@ +yosys_backend(verilog + verilog_backend.cc + verilog_backend.h + REQUIRES + bmuxmap + demuxmap + clean_zerowidth +) diff --git a/backends/verilog/Makefile.inc b/backends/verilog/Makefile.inc deleted file mode 100644 index c2dffef7a..000000000 --- a/backends/verilog/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/verilog/verilog_backend.o - diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 473918264..1db3eb298 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -38,7 +38,7 @@ USING_YOSYS_NAMESPACE using namespace VERILOG_BACKEND; -const pool VERILOG_BACKEND::verilog_keywords() { +const pool &VERILOG_BACKEND::verilog_keywords() { static const pool res = { // IEEE 1800-2017 Annex B "accept_on", "alias", "always", "always_comb", "always_ff", "always_latch", "and", "assert", "assign", "assume", "automatic", "before", @@ -197,14 +197,22 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) reg_name = id(chunk.wire->name); if (sig.size() != chunk.wire->width) { - if (sig.size() == 1) - reg_name += stringf("[%d]", chunk.wire->start_offset + chunk.offset); - else if (chunk.wire->upto) - reg_name += stringf("[%d:%d]", (chunk.wire->width - (chunk.offset + chunk.width - 1) - 1) + chunk.wire->start_offset, - (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); + int idx; + if (chunk.wire->upto) + idx = (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset; else - reg_name += stringf("[%d:%d]", chunk.wire->start_offset + chunk.offset + chunk.width - 1, - chunk.wire->start_offset + chunk.offset); + idx = chunk.wire->start_offset + chunk.offset; + + if (sig.size() == 1) + reg_name += stringf("[%d]", idx); + else { + int left_idx; + if (chunk.wire->upto) + left_idx = (chunk.wire->width - (chunk.offset + chunk.width - 1) - 1) + chunk.wire->start_offset; + else + left_idx = chunk.wire->start_offset + chunk.offset + chunk.width - 1; + reg_name += stringf("[%d:%d]", left_idx, idx); + } } return true; @@ -456,21 +464,22 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) if (wire->attributes.count(ID::single_bit_vector)) range = stringf(" [%d:%d]", wire->start_offset, wire->start_offset); } + std::string sign = wire->is_signed ? " signed" : ""; if (wire->port_input && !wire->port_output) - f << stringf("%s" "input%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "input%s%s %s;\n", indent, sign, range, id(wire->name)); if (!wire->port_input && wire->port_output) - f << stringf("%s" "output%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "output%s%s %s;\n", indent, sign, range, id(wire->name)); if (wire->port_input && wire->port_output) - f << stringf("%s" "inout%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "inout%s%s %s;\n", indent, sign, range, id(wire->name)); if (reg_wires.count(wire->name)) { - f << stringf("%s" "reg%s %s", indent, range, id(wire->name)); + f << stringf("%s" "reg%s%s %s", indent, sign, range, id(wire->name)); if (wire->attributes.count(ID::init)) { f << stringf(" = "); dump_const(f, wire->attributes.at(ID::init)); } f << stringf(";\n"); } else - f << stringf("%s" "wire%s %s;\n", indent, range, id(wire->name)); + f << stringf("%s" "wire%s%s %s;\n", indent, sign, range, id(wire->name)); #endif } diff --git a/backends/verilog/verilog_backend.h b/backends/verilog/verilog_backend.h index 7e550a37c..affad995b 100644 --- a/backends/verilog/verilog_backend.h +++ b/backends/verilog/verilog_backend.h @@ -29,7 +29,7 @@ YOSYS_NAMESPACE_BEGIN namespace VERILOG_BACKEND { - const pool verilog_keywords(); + const pool &verilog_keywords(); bool char_is_verilog_escaped(char c); bool id_is_verilog_escaped(const std::string &str); diff --git a/cmake/CheckLibcFeatures.cmake b/cmake/CheckLibcFeatures.cmake new file mode 100644 index 000000000..3fc32afe3 --- /dev/null +++ b/cmake/CheckLibcFeatures.cmake @@ -0,0 +1,40 @@ +include(CMakePushCheckState) +include(CheckSourceCompiles) +include(CheckCXXSymbolExists) + +function(check_glob) + check_cxx_symbol_exists(glob "glob.h" HAVE_GLOB) + return (PROPAGATE HAVE_BLOB) +endfunction() + +function(check_pthread_create) + if (Threads_FOUND) + # On WASI, `pthread_create()` is always available, but always fails on triples without threading + # support. Probe for it while requesting the stub implementation to be hidden, otherwise we will + # end up always crashing at runtime on thread creation. + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_DEFINITIONS -D_WASI_STRICT_PTHREAD) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + check_source_compiles(CXX [[ + #include + int main() { + pthread_create(0, 0, 0, 0); + } + ]] HAVE_PTHREAD_CREATE) + cmake_pop_check_state() + endif() + return (PROPAGATE HAVE_PTHREAD_CREATE) +endfunction() + +function(check_system) + check_cxx_symbol_exists(system "stdlib.h" HAVE_SYSTEM) +endfunction() + +function(check_popen) + check_cxx_symbol_exists(popen "stdio.h" HAVE_POPEN) + if (NOT HAVE_POPEN) + unset(HAVE_POPEN CACHE) + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/popen-wpopen + check_cxx_symbol_exists(_popen "stdio.h" HAVE_POPEN) + endif() +endfunction() diff --git a/cmake/Condition.cmake b/cmake/Condition.cmake new file mode 100644 index 000000000..6ef400a32 --- /dev/null +++ b/cmake/Condition.cmake @@ -0,0 +1,35 @@ +# Syntax: +# +# condition( ...) +# +# If `...` is truthful (evaluated as in `if()`) then assigns 1 to ``, else assigns 0. +# The assigned value is `0`/`1` rather than `TRUE`/`FALSE` for ease of use in generator expressions. +# Note that `...` *must* be unquoted. +# +# To understand how a certain outcome is reached, reconfigure the project with `--log-level VERBOSE`. +# +# Believe it or not, CMake doesn't have this built in! +# +macro(condition var) + if (${ARGN}) + set(${var} 1) + else() + set(${var} 0) + endif() + + set(_debug_expr) + foreach (token ${ARGN}) + if (DEFINED ${token}) + if (${${token}}) + list(APPEND _debug_expr "${token}:1") + else() + list(APPEND _debug_expr "${token}:0") + endif() + else() + list(APPEND _debug_expr "${token}") + endif() + endforeach() + string(JOIN " " _debug_expr ${_debug_expr}) + message(VERBOSE " ${var} = ${${var}} (${_debug_expr})") + unset(_debug_expr) +endmacro() diff --git a/cmake/FindBISON.cmake b/cmake/FindBISON.cmake new file mode 100644 index 000000000..11851fd05 --- /dev/null +++ b/cmake/FindBISON.cmake @@ -0,0 +1,346 @@ +# Based on CMake v3.31.0 `Modules/FindBISON.cmake`, changed as follows: +# - Continue searching for Bison if an executable does not match the requested +# version constraint. +# - Search for a usable M4 and run Bison with the `M4` environment variable. + +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindBISON +--------- + +Find ``bison`` executable and provide a macro to generate custom build rules. + +The module defines the following variables: + +``BISON_EXECUTABLE`` + path to the ``bison`` program + +``BISON_VERSION`` + version of ``bison`` + +``BISON_FOUND`` + "True" if the program was found + +The minimum required version of ``bison`` can be specified using the +standard CMake syntax, e.g. :command:`find_package(BISON 2.1.3)`. + +If ``bison`` is found, the module defines the macro:: + + BISON_TARGET( + [COMPILE_FLAGS ] + [DEFINES_FILE ] + [VERBOSE []] + [REPORT_FILE ] + ) + +which will create a custom rule to generate a parser. ```` is +the path to a yacc file. ```` is the name of the source file +generated by bison. A header file is also be generated, and contains +the token list. + +.. versionchanged:: 3.14 + When :policy:`CMP0088` is set to ``NEW``, ``bison`` runs in the + :variable:`CMAKE_CURRENT_BINARY_DIR` directory. + +The options are: + +``COMPILE_FLAGS `` + Specify flags to be added to the ``bison`` command line. + +``DEFINES_FILE `` + .. versionadded:: 3.4 + + Specify a non-default header ```` to be generated by ``bison``. + +``VERBOSE []`` + Tell ``bison`` to write a report file of the grammar and parser. + + .. deprecated:: 3.7 + If ```` is given, it specifies path the report file is copied to. + ``[]`` is left for backward compatibility of this module. + Use ``VERBOSE REPORT_FILE ``. + +``REPORT_FILE `` + .. versionadded:: 3.7 + + Specify a non-default report ````, if generated. + +The macro defines the following variables: + +``BISON__DEFINED`` + ``True`` is the macro ran successfully + +``BISON__INPUT`` + The input source file, an alias for + +``BISON__OUTPUT_SOURCE`` + The source file generated by bison + +``BISON__OUTPUT_HEADER`` + The header file generated by bison + +``BISON__OUTPUTS`` + All files generated by bison including the source, the header and the report + +``BISON__COMPILE_FLAGS`` + Options used in the ``bison`` command line + +Example usage: + +.. code-block:: cmake + + find_package(BISON) + BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp + DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h) + add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS}) +#]=======================================================================] + +function(BISON_m4_validator result_var executable) + execute_process(COMMAND ${executable} --version + OUTPUT_QUIET + ERROR_QUIET + RESULT_VARIABLE M4_version_result + ) + if (NOT M4_version_result EQUAL 0) + set(${result_var} FALSE PARENT_SCOPE) + endif() +endfunction() + +find_program(BISON_M4_EXECUTABLE + NAMES m4 + VALIDATOR BISON_m4_validator + DOC "path to the m4 executable (used by bison)" +) + +function(BISON_get_version result_var executable) + # the bison commands should be executed with the C locale, otherwise + # the message (which are parsed) may be translated + set(_Bison_SAVED_LC_ALL "$ENV{LC_ALL}") + set(ENV{LC_ALL} C) + + execute_process(COMMAND ${executable} --version + OUTPUT_VARIABLE BISON_version_output + ERROR_VARIABLE BISON_version_error + RESULT_VARIABLE BISON_version_result + OUTPUT_STRIP_TRAILING_WHITESPACE) + + set(ENV{LC_ALL} ${_Bison_SAVED_LC_ALL}) + + if(NOT ${BISON_version_result} EQUAL 0) + message(SEND_ERROR "Command \"${executable} --version\" failed with output:\n${BISON_version_error}") + else() + # Bison++ + if("${BISON_version_output}" MATCHES "^bison\\+\\+ Version ([^,]+)") + set(${result_var} "${CMAKE_MATCH_1}") + # GNU Bison + elseif("${BISON_version_output}" MATCHES "^bison \\(GNU Bison\\) ([^\n]+)\n") + set(${result_var} "${CMAKE_MATCH_1}") + elseif("${BISON_version_output}" MATCHES "^GNU Bison (version )?([^\n]+)") + set(${result_var} "${CMAKE_MATCH_2}") + endif() + endif() + + return(PROPAGATE ${result_var}) +endfunction() + +function(BISON_validator result_var executable) + BISON_get_version(bison_version ${executable}) + find_package_check_version("${bison_version}" ${result_var}) + return(PROPAGATE ${result_var}) +endfunction() + +find_program(BISON_EXECUTABLE + NAMES bison win-bison win_bison + VALIDATOR BISON_validator + DOC "path to the bison executable" +) +mark_as_advanced(BISON_EXECUTABLE) + +if(BISON_EXECUTABLE) + BISON_get_version(BISON_VERSION ${BISON_EXECUTABLE}) + + # internal macro + # sets BISON_TARGET_cmdopt + macro(BISON_TARGET_option_extraopts Options) + set(BISON_TARGET_cmdopt "") + set(BISON_TARGET_extraopts "${Options}") + separate_arguments(BISON_TARGET_extraopts) + list(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts}) + endmacro() + + # internal macro + # sets BISON_TARGET_output_header and BISON_TARGET_cmdopt + macro(BISON_TARGET_option_defines BisonOutput Header) + if("${Header}" STREQUAL "") + # default header path generated by bison (see option -d) + string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${BisonOutput}") + string(REPLACE "c" "h" _fileext ${_fileext}) + string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}" + BISON_TARGET_output_header "${BisonOutput}") + list(APPEND BISON_TARGET_cmdopt "-d") + else() + set(BISON_TARGET_output_header "${Header}") + list(APPEND BISON_TARGET_cmdopt "--defines=${BISON_TARGET_output_header}") + endif() + endmacro() + + # internal macro + # sets BISON_TARGET_verbose_file and BISON_TARGET_cmdopt + macro(BISON_TARGET_option_report_file BisonOutput ReportFile) + if("${ReportFile}" STREQUAL "") + get_filename_component(BISON_TARGET_output_path "${BisonOutput}" PATH) + get_filename_component(BISON_TARGET_output_name "${BisonOutput}" NAME_WE) + set(BISON_TARGET_verbose_file + "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output") + else() + set(BISON_TARGET_verbose_file "${ReportFile}") + list(APPEND BISON_TARGET_cmdopt "--report-file=${BISON_TARGET_verbose_file}") + endif() + if(NOT IS_ABSOLUTE "${BISON_TARGET_verbose_file}") + cmake_policy(GET CMP0088 _BISON_CMP0088 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if("x${_BISON_CMP0088}x" STREQUAL "xNEWx") + set(BISON_TARGET_verbose_file "${CMAKE_CURRENT_BINARY_DIR}/${BISON_TARGET_verbose_file}") + else() + set(BISON_TARGET_verbose_file "${CMAKE_CURRENT_SOURCE_DIR}/${BISON_TARGET_verbose_file}") + endif() + unset(_BISON_CMP0088) + endif() + endmacro() + + # internal macro + # adds a custom command and sets + # BISON_TARGET_cmdopt, BISON_TARGET_extraoutputs + macro(BISON_TARGET_option_verbose Name BisonOutput filename) + cmake_policy(GET CMP0088 _BISON_CMP0088 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + if("x${_BISON_CMP0088}x" STREQUAL "xNEWx") + set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + unset(_BISON_CMP0088) + + list(APPEND BISON_TARGET_cmdopt "--verbose") + list(APPEND BISON_TARGET_outputs + "${BISON_TARGET_verbose_file}") + if (NOT "${filename}" STREQUAL "") + if(IS_ABSOLUTE "${filename}") + set(BISON_TARGET_verbose_extra_file "${filename}") + else() + set(BISON_TARGET_verbose_extra_file "${_BISON_WORKING_DIRECTORY}/${filename}") + endif() + + add_custom_command(OUTPUT ${BISON_TARGET_verbose_extra_file} + COMMAND ${CMAKE_COMMAND} -E copy + "${BISON_TARGET_verbose_file}" + "${filename}" + VERBATIM + DEPENDS + "${BISON_TARGET_verbose_file}" + COMMENT "[BISON][${Name}] Copying bison verbose table to ${filename}" + WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY}) + list(APPEND BISON_TARGET_extraoutputs + "${BISON_TARGET_verbose_extra_file}") + unset(BISON_TARGET_verbose_extra_file) + unset(_BISON_WORKING_DIRECTORY) + endif() + endmacro() + + #============================================================ + # BISON_TARGET (public macro) + #============================================================ + # + macro(BISON_TARGET Name BisonInput BisonOutput) + set(BISON_TARGET_outputs "${BisonOutput}") + set(BISON_TARGET_extraoutputs "") + + # Parsing parameters + set(BISON_TARGET_PARAM_OPTIONS + ) + set(BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS + COMPILE_FLAGS + DEFINES_FILE + REPORT_FILE + ) + set(BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS + VERBOSE + ) + cmake_parse_arguments( + BISON_TARGET_ARG + "${BISON_TARGET_PARAM_OPTIONS}" + "${BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS}" + "${BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS}" + ${ARGN} + ) + + if(NOT "${BISON_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "") + message(SEND_ERROR "Usage") + elseif("${BISON_TARGET_ARG_VERBOSE}" MATCHES ";") + # [VERBOSE [] hack: is non-multi value by usage + message(SEND_ERROR "Usage") + else() + + BISON_TARGET_option_extraopts("${BISON_TARGET_ARG_COMPILE_FLAGS}") + BISON_TARGET_option_defines("${BisonOutput}" "${BISON_TARGET_ARG_DEFINES_FILE}") + BISON_TARGET_option_report_file("${BisonOutput}" "${BISON_TARGET_ARG_REPORT_FILE}") + if(NOT "${BISON_TARGET_ARG_VERBOSE}" STREQUAL "") + BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${BISON_TARGET_ARG_VERBOSE}") + else() + # [VERBOSE []] is used with no argument or is not used + set(BISON_TARGET_args "${ARGN}") + list(FIND BISON_TARGET_args "VERBOSE" BISON_TARGET_args_indexof_verbose) + if(${BISON_TARGET_args_indexof_verbose} GREATER -1) + # VERBOSE is used without + BISON_TARGET_option_verbose(${Name} ${BisonOutput} "") + endif() + endif() + + list(APPEND BISON_TARGET_outputs "${BISON_TARGET_output_header}") + + cmake_policy(GET CMP0088 _BISON_CMP0088 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set(_BisonInput "${BisonInput}") + if("x${_BISON_CMP0088}x" STREQUAL "xNEWx") + set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + if(NOT IS_ABSOLUTE "${_BisonInput}") + set(_BisonInput "${CMAKE_CURRENT_SOURCE_DIR}/${_BisonInput}") + endif() + endif() + unset(_BISON_CMP0088) + + add_custom_command(OUTPUT ${BISON_TARGET_outputs} + COMMAND ${CMAKE_COMMAND} -E env "M4=${BISON_M4_EXECUTABLE}" + ${BISON_EXECUTABLE} ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${_BisonInput} + VERBATIM + DEPENDS ${_BisonInput} + COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}" + WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY}) + + unset(_BISON_WORKING_DIRECTORY) + + # define target variables + set(BISON_${Name}_DEFINED TRUE) + set(BISON_${Name}_INPUT ${_BisonInput}) + set(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs} ${BISON_TARGET_extraoutputs}) + set(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt}) + set(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}") + set(BISON_${Name}_OUTPUT_HEADER "${BISON_TARGET_output_header}") + + unset(_BisonInput) + + endif() + endmacro() + # + #============================================================ + +endif() + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE + VERSION_VAR BISON_VERSION) diff --git a/cmake/FindDlfcn.cmake b/cmake/FindDlfcn.cmake new file mode 100644 index 000000000..201745a3f --- /dev/null +++ b/cmake/FindDlfcn.cmake @@ -0,0 +1,24 @@ +include(CMakePushCheckState) +include(CheckCXXSymbolExists) +include(FindPackageHandleStandardArgs) + +if (WIN32 OR MSYS) + # Windows; dlopen is available via a polyfill `libs/dlfcn-win32`. + set(Dlfcn_LIBRARIES dlfcn) +else() + # Unix and Wasm; dlopen may or may not be available depending on platform. + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS}) + check_cxx_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN) + cmake_pop_check_state() + + if (HAVE_DLOPEN) + add_library(dlfcn INTERFACE) + target_link_libraries(dlfcn INTERFACE ${CMAKE_DL_LIBS}) + set(Dlfcn_LIBRARIES dlfcn) + endif() +endif() + +find_package_handle_standard_args(Dlfcn + REQUIRED_VARS Dlfcn_LIBRARIES +) diff --git a/cmake/FindPyosysEnv.cmake b/cmake/FindPyosysEnv.cmake new file mode 100644 index 000000000..59fd386fc --- /dev/null +++ b/cmake/FindPyosysEnv.cmake @@ -0,0 +1,44 @@ +# We need a *third* `FindPython`-style call in this codebase because the host +# `Python3_EXECUTABLE` may not have pybind11 and cxxheaderparser installed, +# and installing it can be onerous. To work around this problem we try to detect +# whether the host interpreter has the necessary dependencies first, and if it +# does not, fall back to using `uv`. + +foreach (strategy virtualenv host uv fail) + if (strategy STREQUAL "virtualenv") + set(PyosysEnv_PYTHON $ENV{VIRTUAL_ENV}/bin/python) + elseif (strategy STREQUAL "host") + set(PyosysEnv_PYTHON ${Python3_EXECUTABLE}) + elseif (strategy STREQUAL "uv") + set(PyosysEnv_PYTHON uv run --no-project --with pybind11>3,<4 --with cxxheaderparser python) + else() + set(PyosysEnv_PYTHON) + break() + endif() + + execute_process( + COMMAND ${PyosysEnv_PYTHON} -m pybind11 --includes + RESULT_VARIABLE result + OUTPUT_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if (result EQUAL 0) + string(REGEX REPLACE " ?-I" ";" pybind11_INCLUDE_DIR "${output}") + list(FILTER pybind11_INCLUDE_DIR INCLUDE REGEX "/pybind11/") + + execute_process( + COMMAND ${PyosysEnv_PYTHON} ${CMAKE_SOURCE_DIR}/pyosys/generator.py --help + RESULT_VARIABLE result + OUTPUT_QUIET + ERROR_QUIET + ) + if (result EQUAL 0) + break() + endif() + endif() +endforeach() + +find_package_handle_standard_args(PyosysEnv + REQUIRED_VARS PyosysEnv_PYTHON pybind11_INCLUDE_DIR +) diff --git a/cmake/FindPython3Devel.cmake b/cmake/FindPython3Devel.cmake new file mode 100644 index 000000000..b3589a96d --- /dev/null +++ b/cmake/FindPython3Devel.cmake @@ -0,0 +1,28 @@ +# Wrapper to improve behavior of `FindPython3` during cross-compilation. +# Does not entirely fix the problem; CMake 4.0 introduces `Python_ARTIFACTS_PREFIX`, which will. + +# Stash the package found status +get_property(packages_found GLOBAL PROPERTY PACKAGES_FOUND) +get_property(packages_not_found GLOBAL PROPERTY PACKAGES_NOT_FOUND) +get_property(required_version GLOBAL PROPERTY _CMAKE_Python3_REQUIRED_VERSION) + +# A hack to make pyosys buildable in wheel-only environments. +# `Interpreter` is a part of the component set to ensure that a Python implementation without +# an interpreter that's earlier in the search order won't be selected instead of the desired one. +# (This is awful and should be removed once CMake 4.0 is here.) +if (YOSYS_BUILD_PYTHON_ONLY) + set(components Interpreter Development.Module) +else() + set(components Interpreter Development) +endif() + +# The `EXACT` specifier prevents the situation of `FindPython3` discovering a newer libpython-dev +# than the interpreter found in the past, rejecting it because it is too new, and giving up. +find_package(Python3 EXACT ${Python3_VERSION} COMPONENTS ${components}) +if (Python3_Development.Embed_FOUND OR Python3_Development.Module_FOUND) + set(Python3Devel_FOUND YES) +endif() + +set_property(GLOBAL PROPERTY PACKAGES_FOUND "${packages_found}") +set_property(GLOBAL PROPERTY PACKAGES_NOT_FOUND "${packages_not_found}") +set_property(GLOBAL PROPERTY _CMAKE_Python3_REQUIRED_VERSION "${required_version}") diff --git a/cmake/GetPyosysVersion.cmake b/cmake/GetPyosysVersion.cmake new file mode 100644 index 000000000..ae5122d23 --- /dev/null +++ b/cmake/GetPyosysVersion.cmake @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.27) +set(CMAKE_MESSAGE_LOG_LEVEL ERROR) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +include(YosysVersion) + +yosys_extract_version() +if (YOSYS_VERSION_COMMIT EQUAL "0") + set(yosys_version "${YOSYS_VERSION_MAJOR}.${YOSYS_VERSION_MINOR}") +elseif (YOSYS_VERSION_COMMIT STREQUAL "") + set(yosys_version "${YOSYS_VERSION_MAJOR}.${YOSYS_VERSION_MINOR}.post9999") +else() + set(yosys_version "${YOSYS_VERSION_MAJOR}.${YOSYS_VERSION_MINOR}.post${YOSYS_VERSION_COMMIT}") +endif() +execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${yosys_version}") diff --git a/cmake/PkgConfig.cmake b/cmake/PkgConfig.cmake new file mode 100644 index 000000000..b37d74622 --- /dev/null +++ b/cmake/PkgConfig.cmake @@ -0,0 +1,43 @@ +# Syntax: +# +# pkg_config_import() +# +# To use this command, `find_package(PkgConfig)` must be used beforehand, but it does +# not have to succeed. If the `PkgConfig` package is not found, all imports silently fail. +# +# Imports `` as a CMake `IMPORTED` target `PkgConfig::`. +# Updates the global `PACKAGES_FOUND` and `PACKAGES_NOT_FOUND` properties and defines +# the `_FOUND` variable. +# +function(pkg_config_import arg_PREFIX) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "MODULES") + if (NOT arg_MODULES) + set(arg_MODULES ${arg_PREFIX}) + endif() + + if (PkgConfig_FOUND) + # Once CMake 4.1 is available, this call should be replaced with `cmake_pkg_config()`. + pkg_check_modules(${arg_PREFIX} IMPORTED_TARGET ${arg_MODULES}) + if (${arg_PREFIX}_FOUND) + # We found the pkgconfig file, but is it actually a usable package? + # The main cause of failure here would be cross-compiling, which pkg-config does not + # handle very well (especially pre-`cmake_pkg_config()`). + try_compile(is_usable + SOURCE_FROM_CONTENT "main.cc" "int main() {}" + LINK_LIBRARIES PkgConfig::${arg_PREFIX} + LOG_DESCRIPTION "Checking if PkgConfig::${arg_PREFIX} is usable" + ) + if (NOT is_usable) + message(STATUS "Modules '${arg_MODULES}' unusable (bad \$PKG_CONFIG_LIBDIR?)") + set(${arg_PREFIX}_FOUND 0) + endif() + endif() + endif() + + if (${arg_PREFIX}_FOUND) + set_property(GLOBAL APPEND PROPERTY PACKAGES_FOUND ${arg_PREFIX}) + else() + set_property(GLOBAL APPEND PROPERTY PACKAGES_NOT_FOUND ${arg_PREFIX}) + endif() + return (PROPAGATE ${arg_PREFIX}_FOUND) +endfunction() diff --git a/cmake/PmgenCommand.cmake b/cmake/PmgenCommand.cmake new file mode 100644 index 000000000..889d7653e --- /dev/null +++ b/cmake/PmgenCommand.cmake @@ -0,0 +1,60 @@ +# Syntax: +# +# pmgen_command( +# [...] +# [PREFIX ] +# [DEBUG] +# ) +# +# Builds `_pm.h` in the current binary directory from pmgen source files ``, which must have +# the `*.pmg` extension. If `...` contains more than one file, `` must be provided. +# +# Defines the following variables: +# - `PMGEN__DEFINED`: Boolean indicating whether this command was successfully invoked. +# - `PMGEN__OUTPUT`: The header file generated by `pmgen`. +# +# Usage example: +# +# pmgen_command(my_dsp +# my_dsp.pmg +# ) +# yosys_pass(my_dsp +# my_dsp.cc +# ${PMGEN_my_dsp_OUTPUT} +# ) +# +# Usage example with multiple files: +# +# pmgen_command(my_dsp +# my_dsp_macc.pmg +# my_dsp_carry.pmg +# PREFIX +# my_dsp +# ) +# +function(pmgen_command arg_NAME) + cmake_parse_arguments(PARSE_ARGV 1 arg "DEBUG" "PREFIX" "") + set(arg_INPUTS ${arg_UNPARSED_ARGUMENTS}) + + set(pmgen_script ${CMAKE_SOURCE_DIR}/passes/pmgen/pmgen.py) + set(pmgen_output ${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}_pm.h) + cmake_path(RELATIVE_PATH pmgen_output BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE pmgen_output_rel) + add_custom_command( + DEPENDS ${pmgen_script} ${arg_INPUTS} + OUTPUT ${pmgen_output} + COMMAND ${Python3_EXECUTABLE} + ${pmgen_script} + "$<$:-g>" + "$<$:-p;${arg_PREFIX}>" + -o ${pmgen_output} + ${arg_INPUTS} + COMMAND_EXPAND_LISTS + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM + COMMENT "Compiling pattern matcher ${pmgen_output_rel}" + ) + + # The usage of this command is somewhat inspired by `flex_target()` and `bison_target()`. + set(PMGEN_${arg_NAME}_DEFINED TRUE) + set(PMGEN_${arg_NAME}_OUTPUT ${pmgen_output} PARENT_SCOPE) +endfunction() diff --git a/cmake/UseHomebrew.cmake b/cmake/UseHomebrew.cmake new file mode 100644 index 000000000..e94441109 --- /dev/null +++ b/cmake/UseHomebrew.cmake @@ -0,0 +1,22 @@ +# Syntax: +# +# use_homebrew([ROOT ]) +# +# Includes all packages installed in `` (`/opt/homebrew/Cellar` if not specified) +# in `CMAKE_FIND_ROOT_PATH`. +# +function(use_homebrew) + cmake_parse_arguments(PARSE_ARGV 0 arg "" "ROOT" "") + if (NOT arg_ROOT) + set(arg_ROOT /opt/homebrew/Cellar) + endif() + + file(GLOB package_roots ${arg_ROOT}/*/*) # e.g. `/opt/homebrew/Cellar/bison/3.8.2/` + foreach (package_root ${package_roots}) + if (IS_DIRECTORY ${package_root}) + list(APPEND CMAKE_FIND_ROOT_PATH ${package_root}) + endif() + endforeach() + + return(PROPAGATE CMAKE_FIND_ROOT_PATH) +endfunction() diff --git a/cmake/YosysAbc.cmake b/cmake/YosysAbc.cmake new file mode 100644 index 000000000..696752e76 --- /dev/null +++ b/cmake/YosysAbc.cmake @@ -0,0 +1,112 @@ +include(CheckCompilerFlag) + +define_property(TARGET PROPERTY YOSYS_IS_ABC) + +function(target_safe_compile_options target scope) + foreach (lang C CXX) + foreach (flag ${ARGN}) + check_compiler_flag(${lang} ${flag} HAVE_${lang}_${flag}) + if (HAVE_${lang}_${flag}) + target_compile_options(${target} ${scope} $<$:${flag}>) + endif() + endforeach() + endforeach() +endfunction() + +function(_yosys_abc_extract_makefile result vardecl filename) + # Parse a Makefile fragment and extracts the first matching variable assignment into + # a list of values. + file(READ ${filename} contents) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filename}) + if ("${contents}" MATCHES "${vardecl}(\\\\\n|[ \t])*(([^\\\\\n]|\\\\\n)+)") + string(REGEX REPLACE "(\\\\\n|[ \t])+" ";" ${result} "${CMAKE_MATCH_2}") + endif() + return (PROPAGATE ${result}) +endfunction() + +function(yosys_abc_target arg_LIBNAME arg_EXENAME) + cmake_parse_arguments(PARSE_ARGV 2 arg "" "INSTALL_IF" "") + + # Instead of using either the ABC Make or CMake build system, we parse the source + # of truth: ABC's `module.make` files. This turns out to be quite trivial. + # This way, no assumptions about the environment are made, and Yosys can be compiled + # on Windows without MSYS as a result (while benefitting other platforms as well). + set(all_sources) + _yosys_abc_extract_makefile(module_files "MODULES :=" ${CMAKE_SOURCE_DIR}/abc/Makefile) + _yosys_abc_extract_makefile(module_files_cudd "MODULES \\+=" ${CMAKE_SOURCE_DIR}/abc/Makefile) + list(REMOVE_ITEM module_files "$(wildcard" "src/ext*)") + foreach (module_file ${module_files} ${module_files_cudd}) + _yosys_abc_extract_makefile(module_sources "SRC \\+=" ${CMAKE_SOURCE_DIR}/abc/${module_file}/module.make) + list(APPEND all_sources ${module_sources}) + endforeach() + list(TRANSFORM all_sources PREPEND abc/) + + # Required to get `-DABC_NAMESPACE` below to work consistently. + if(NOT MSVC) + set_source_files_properties(${all_sources} PROPERTIES LANGUAGE CXX) + endif() + + set(main_source abc/src/base/main/main.c) + list(REMOVE_ITEM all_sources ${main_source}) + + find_package(Threads) + yosys_cxx_library(${arg_LIBNAME} STATIC + OUTPUT_NAME ${arg_LIBNAME} + ) + target_sources(${arg_LIBNAME} PRIVATE ${all_sources}) + target_include_directories(${arg_LIBNAME} PRIVATE abc/src) + target_compile_definitions(${arg_LIBNAME} PUBLIC + WIN32_NO_DLL + $<$>:ABC_NAMESPACE=abc> + ABC_USE_STDINT_H=1 + ABC_USE_CUDD=1 + ABC_NO_HISTORY=1 + ABC_NO_DYNAMIC_LINKING + $<${YOSYS_ENABLE_THREADS}:ABC_USE_PTHREADS> + $<${YOSYS_ENABLE_READLINE}:ABC_USE_READLINE> + $<$:ABC_USE_PTHREADS> + $<$:_WINSOCKAPI_> + $<$:HAVE_STRUCT_TIMESPEC> + ABC_NO_RLIMIT + ) + target_compile_options(${arg_LIBNAME} PRIVATE + $<$:/wd4576> + $<$:/Zc:strictStrings-> + ) + + target_safe_compile_options(${arg_LIBNAME} PRIVATE + -fpermissive + -fno-exceptions + -Wno-write-strings + -Wno-changes-meaning + -Wno-attributes + -Wno-deprecated-declarations + -Wno-deprecated-comma-subscript + -Wno-format + -Wno-constant-logical-operand + -Wno-sizeof-pointer-memaccess + ) + target_link_libraries(${arg_LIBNAME} PUBLIC + $<${YOSYS_ENABLE_THREADS}:Threads::Threads> + $<${YOSYS_ENABLE_READLINE}:PkgConfig::readline> + $<$:-lshlwapi> + $<$:${CMAKE_SOURCE_DIR}/abc/lib/x64/pthreadVC2.lib> + ) + set_target_properties(${arg_LIBNAME} PROPERTIES + YOSYS_IS_ABC ON + ) + if(MSVC) + install(FILES "${CMAKE_SOURCE_DIR}/abc/lib/x64/pthreadVC2.dll" DESTINATION bin) + endif() + + yosys_cxx_executable(${arg_EXENAME} + OUTPUT_NAME ${arg_EXENAME} + INSTALL_IF "${arg_INSTALL_IF}" + ) + target_sources(${arg_EXENAME} PRIVATE ${main_source}) + target_include_directories(${arg_EXENAME} PRIVATE abc/src) + target_link_libraries(${arg_EXENAME} PRIVATE ${arg_LIBNAME}) + set_target_properties(${arg_EXENAME} PROPERTIES + YOSYS_IS_ABC ON + ) +endfunction() diff --git a/cmake/YosysAbcSubmodule.cmake b/cmake/YosysAbcSubmodule.cmake new file mode 100644 index 000000000..ee0dcb4c3 --- /dev/null +++ b/cmake/YosysAbcSubmodule.cmake @@ -0,0 +1,64 @@ +# depends on YosysVersion.cmake + +function(yosys_check_abc_submodule) + yosys_call_git(status) + set(yosys_status "tarball") + if (git_result EQUAL 0) + set(yosys_status "git") + endif() + + yosys_call_git(submodule status abc) + set(git_commit) + if (EXISTS "${CMAKE_SOURCE_DIR}/abc/.gitcommit") + file(READ "${CMAKE_SOURCE_DIR}/abc/.gitcommit" git_commit) + string(STRIP "${git_commit}" git_commit) + endif() + set(abc_status "none") + if (git_result EQUAL 0 AND git_output MATCHES "^ ") + set(abc_status "git") + elseif (git_result EQUAL 0 AND git_output MATCHES "^\\+") + set(abc_status "git-changed") + elseif (git_result EQUAL 0 AND git_output MATCHES "^U") + set(abc_status "git-conflict") + elseif (git_commit MATCHES "^[0-9a-fA-F]+$") + set(abc_status "tarball") + elseif (git_commit MATCHES "\\$Format:%[hH]\\$") + set(abc_status "unknown") + endif() + + if (abc_status STREQUAL "git" OR abc_status STREQUAL "tarball") + # Normal submodule or a tarball. + elseif (abc_status STREQUAL "git-changed") + message(FATAL_ERROR + "'abc' submodule does not match expected commit.\n" + "Run 'git submodule update' to check out the correct version.\n" + "Note: If testing a different version of ABC, call 'git commit abc' " + "in the Yosys source directory to update the expected commit.\n" + ) + elseif (abc_status STREQUAL "git-conflict") + message(FATAL_ERROR + "'abc' submodule has merge conflicts.\n" + "Please resolve merge conflicts before continuing.\n" + ) + elseif (abc_status STREQUAL "unknown") # OK + message(FATAL_ERROR + "Error: 'abc' is not configured as a git submodule.\n" + "To resolve this:\n" + "1. Back up your changes: Save any modifications from the 'abc' directory to another location.\n" + "2. Remove the existing 'abc' directory: Delete the 'abc' directory and all its contents.\n" + "3. Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule.\n" + "4. Reapply your changes: Move your saved changes back to the 'abc' directory, if necessary.\n" + ) + elseif (yosys_status STREQUAL "git") # OK + message(FATAL_ERROR + "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule.\n" + ) + else() # + message(FATAL_ERROR + "${CMAKE_SOURCE_DIR} is not configured as a git repository, and 'abc' folder is missing.\n" + "If you already have ABC, set 'YOSYS_ABC_EXECUTABLE' CMake variable to point to ABC executable.\n" + "Otherwise, download release archive 'yosys.tar.gz' from https://github.com/YosysHQ/yosys/releases.\n" + " ('Source code' archive does not contain submodules.)\n" + ) + endif() +endfunction() diff --git a/cmake/YosysComponent.cmake b/cmake/YosysComponent.cmake new file mode 100644 index 000000000..9786ba156 --- /dev/null +++ b/cmake/YosysComponent.cmake @@ -0,0 +1,321 @@ +set(namespace "yosys") + +# Properties internal to the component system. +define_property(TARGET PROPERTY YOSYS_COMPONENT) +define_property(TARGET PROPERTY YOSYS_PROVIDES) +define_property(TARGET PROPERTY YOSYS_REQUIRES) +define_property(TARGET PROPERTY YOSYS_DATA_FILES) +define_property(TARGET PROPERTY YOSYS_ENABLE_IF) + +# Syntax: +# +# yosys_component( [INTERFACE] +# [...] +# [DEFINITIONS ...] +# [INCLUDE_DIRS ...] +# [LIBRARIES ...] +# [PROVIDES ...] +# [REQUIRES ...] +# [DATA_DIR ] +# [DATA_FILES ...] +# [DATA_EXPLICIT [ ]...] +# [ESSENTIAL] +# [ENABLE_IF ""] +# ) +# +# Creates a target `yosys_` (if `` is empty) or `yosys__` (if `` is not empty). +# This target is an library target with some Yosys-specific behavior that simplifies partitioning the compiler +# into small pieces with explicitly defined compile-time and run-time dependency metadata. Circular dependencies +# between compilation units in different components are allowed. +# +# Parameter description: +# - `INTERFACE` should be specified for header-only libraries. +# - `...` is a shortcut for `target_sources(PRIVATE)`. +# - `DEFINITIONS ...` is a shortcut for `target_compile_definitions(PRIVATE)`. +# - `INCLUDE_DIRS ...` is a shortcut for `target_include_directories(PRIVATE)`. +# - `LIBRARIES ...` is a shortcut for `target_link_libraries(PRIVATE)`. +# - `PROVIDES ...` creates aliases to each `` component name. +# - `REQUIRES ...` ensures that if this target is linked into the Yosys binary, then every +# `` component is also linked in. +# - `DATA_DIR ` configures a base directory for installing data files; this directory +# is (relative to the root build directory or the installation prefix) `share/` if +# `DATA_DIR` is provided, and `share` if not. +# - `DATA_FILES ...` installs each of `` as `share///`, +# where `` is the directory name of `` and `` is the filename of ``. +# - `DATA_EXPLICIT [ ]...` installs each `` as `share//`. +# Where possible, `DATA_FILES` should be used instead. +# - `ESSENTIAL` ensures that this target is always linked into the Yosys binary. +# - `ENABLE_IF ""` marks the component as available only when `if()` would run. +# +# Avoid using this function directly. Instead, use one of the wrappers below as follows: +# - to define a normal pass, use `yosys_pass()` to add a component called ``. +# - to define a test pass, use `yosys_test_pass()` to add a component called `test_`. +# - to define a frontend, use `yosys_frontend()` to add a component called `read_`. +# - to define a backend, use `yosys_backend()` to add a component called `write_`. +# - if the component sources define more than one pass, use `PROVIDES` with names of the other passes. +# - if the component uses `Pass::call()`, `Frontend::frontend_call()`, `Backend::backend_call()`, or other +# similar functions, use `REQUIRES` with names of all possibly needed passes. +# - if the component needs an essential pass, add the latter to `REQUIRES` anyway for completeness. +# - if the component subclasses a `ScriptPass`, build Yosys, then run `misc/script_pass_depends.py ` +# to extract the names of all referenced passes. +# - in general, component names should be the same as corresponding pass names (as used in the REPL), +# but this is not a hard requirement and any suitable name can be used if desired. +# +function(yosys_component arg_PREFIX arg_NAME) + cmake_parse_arguments(PARSE_ARGV 2 arg + "INTERFACE;ESSENTIAL;BOOTSTRAP" + "DATA_DIR;ENABLE_IF" + "DEFINITIONS;INCLUDE_DIRS;LIBRARIES;DATA_FILES;DATA_EXPLICIT;PROVIDES;REQUIRES" + ) + set(arg_SOURCES ${arg_UNPARSED_ARGUMENTS}) + if ("${arg_ENABLE_IF}" STREQUAL "") + set(arg_ENABLE_IF TRUE) + endif() + + if (arg_PREFIX STREQUAL "") + set(component "${arg_NAME}") + else() + set(component "${arg_PREFIX}_${arg_NAME}") + endif() + set(target "${namespace}_${component}") + list(TRANSFORM arg_PROVIDES PREPEND ${namespace}_ OUTPUT_VARIABLE provides_targets) + + # An OBJECT library is used to allow for circular symbol dependencies between any source files. + # Unfortunately, public dependencies between OBJECT libraries aren't handled correctly, so we have + # to do it ourselves. + if (arg_SOURCES AND NOT arg_INTERFACE) + add_library(${target} EXCLUDE_FROM_ALL OBJECT) + target_sources(${target} PRIVATE ${arg_SOURCES}) + target_include_directories(${target} PRIVATE ${arg_INCLUDE_DIRS}) + target_compile_definitions(${target} PRIVATE ${arg_DEFINITIONS}) + target_link_libraries(${target} PUBLIC yosys_common ${arg_LIBRARIES}) + foreach (alias ${provides_targets}) + add_library(${alias} ALIAS ${target}) + endforeach() + else() + add_library(${target} EXCLUDE_FROM_ALL INTERFACE) + endif() + set_target_properties(${target} PROPERTIES + YOSYS_COMPONENT YES + YOSYS_PROVIDES "${arg_PROVIDES}" + YOSYS_REQUIRES "${arg_REQUIRES}" + YOSYS_DATA_FILES "" + YOSYS_ENABLE_IF "${arg_ENABLE_IF}" + ) + + set(share_file_pairs) + foreach (share_file ${arg_DATA_FILES}) + list(APPEND share_file_pairs ${share_file} ${share_file}) + endforeach() + list(APPEND share_file_pairs ${arg_DATA_EXPLICIT}) + if (share_file_pairs) + set(data_depends) + set(share_root ${CMAKE_BINARY_DIR}/share) + while (share_file_pairs) + list(LENGTH share_file_pairs share_file_unpaired) + if (share_file_unpaired EQUAL 1) + message(FATAL_ERROR "Unpaired DATA_EXPLICIT argument: ${share_file_pairs}") + endif() + list(POP_FRONT share_file_pairs dst_file src_file) + cmake_path(ABSOLUTE_PATH src_file BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set(out_dir ${arg_DATA_DIR}) + cmake_path(GET dst_file PARENT_PATH dst_parent) + cmake_path(APPEND out_dir ${dst_parent}) + cmake_path(GET dst_file FILENAME dst_filename) + cmake_path(APPEND out_dir ${dst_filename} OUTPUT_VARIABLE out_file) + file(MAKE_DIRECTORY ${share_root}/${out_dir}) + add_custom_command( + DEPENDS ${src_file} + OUTPUT ${share_root}/${out_file} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${share_root}/${out_file} + VERBATIM + COMMENT "Copying share/${out_file}" + ) + set_property(TARGET ${target} APPEND PROPERTY YOSYS_DATA_FILES ${out_file}) + list(APPEND data_depends ${share_root}/${out_file}) + endwhile() + add_custom_target(${target}-data DEPENDS ${data_depends}) + add_dependencies(${target} ${target}-data) + endif() + + if (NOT arg_BOOTSTRAP) + set_property(TARGET yosys_everything APPEND PROPERTY YOSYS_REQUIRES ${component}) + if (arg_ESSENTIAL) + set_property(TARGET yosys_essentials APPEND PROPERTY YOSYS_REQUIRES ${component}) + endif() + endif() +endfunction() + +# Syntax: +# +# yosys_core( [