3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-08-05 05:43:37 +00:00

Merge 'origin/main' into emil/muxpack-fix-chain.

This commit is contained in:
nella 2026-08-03 11:50:21 +02:00
commit abe32c86a0
1203 changed files with 25682 additions and 17005 deletions

View file

@ -1,12 +0,0 @@
.editorconfig
.gitignore
.gitmodules
.github
.git
Dockerfile
README.md
manual
guidelines
CodeOfConduct
.travis
.travis.yml

View file

@ -5,4 +5,3 @@ contact_links:
- name: IRC Channel
url: https://web.libera.chat/#yosys
about: "#yosys on irc.libera.chat"

View file

@ -22,4 +22,3 @@ body:
description: "A clear and detailed description of the feature."
validations:
required: true

View file

@ -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._
_These template prompts can be deleted when you're done responding to them._

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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 <<END
export PATH := $(pwd)/${WASI_SDK}/bin:$(pwd)/flex-prefix/bin:${PATH}
WASI_SYSROOT := $(pwd)/${WASI_SDK}/share/wasi-sysroot
CONFIG := wasi
PREFIX := /
ENABLE_TCL := 0
ENABLE_READLINE := 0
ENABLE_PLUGINS := 0
ENABLE_ZLIB := 0
CXXFLAGS += -I$(pwd)/flex-prefix/include
LINKFLAGS += -Wl,-z,stack-size=8388608 -Wl,--stack-first -Wl,--strip-all
END
make -C build -f ../Makefile CXX=clang -j$(nproc)
nix-build:
name: "Build nix flake"
needs: pre_job
if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
fail-fast: false
steps:
- uses: actions/checkout@v5
with:
submodules: true
persist-credentials: false
- uses: cachix/install-nix-action@v31
with:
install_url: https://releases.nixos.org/nix/nix-2.30.0/install
- run: nix build .?submodules=1 -L
export PATH=${WASI_SDK_PATH}/bin:$(pwd)/flex-prefix/bin:${PATH}
cmake -B build -DCMAKE_TOOLCHAIN_FILE=${WASI_SDK_PATH}/share/cmake/wasi-sdk-p1.cmake -DCMAKE_BUILD_TYPE=Release -DYOSYS_COMPILER_LAUNCHER=ccache .
cmake --build build -j$(nproc)
extra-builds-result:
runs-on: ubuntu-latest
needs:
- vs-build
- mingw-build
- wasi-build
- nix-build
if: always()
steps:
- name: Check results

24
.github/workflows/nix.yml vendored Normal file
View file

@ -0,0 +1,24 @@
name: Test nix build
on:
workflow_dispatch:
schedule:
- cron: '0 5 * * 6'
jobs:
nix-build:
name: "Build nix flake"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
fail-fast: false
steps:
- uses: actions/checkout@v7
with:
submodules: true
persist-credentials: false
- uses: cachix/install-nix-action@v31
with:
install_url: https://releases.nixos.org/nix/nix-2.30.0/install
- run: nix build -L

View file

@ -18,7 +18,7 @@ jobs:
docs_export: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/docs-preview') || startsWith(github.ref, 'refs/tags/') }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
uses: fkirc/skip-duplicate-actions@v5.3.2
with:
paths_ignore: '["**/README.md"]'
# don't cancel in case we're updating docs
@ -46,7 +46,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
@ -57,22 +57,22 @@ jobs:
- name: Build Yosys
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_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' }}

View file

@ -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

View file

@ -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/

View file

@ -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-10'
- 'gcc-10'
- 'clang-16'
- 'gcc-11'
# newest, make sure to update maximum standard step to match
- 'clang-19'
- 'gcc-14'
- 'clang-22'
- 'gcc-16'
include:
# macOS x86
- os: macos-15-intel
compiler: 'clang-19'
# macOS arm
- os: macos-latest
compiler: 'clang-19'
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,6 +68,14 @@ 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:
@ -82,19 +88,21 @@ jobs:
$CXX --version
# minimum standard
- name: Build C++17
- name: Build C++20
shell: bash
run: |
make config-$CC_SHORT
make -j$procs CXXSTD=c++17 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++20
if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }}
- name: Build C++26
if: ${{ matrix.compiler == 'clang-22' || matrix.compiler == 'gcc-16' }}
shell: bash
run: |
make config-$CC_SHORT
make -j$procs CXXSTD=c++20 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

View file

@ -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"
- run: echo "All good"

View file

@ -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

View file

@ -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,31 +37,36 @@ 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
- name: Runtime environment
run: |
echo "procs=$(nproc)" >> $GITHUB_ENV
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
echo "SEED=0" >> $GITHUB_ENV
- name: Build Yosys
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_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'
@ -71,15 +76,42 @@ 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: |
@ -87,11 +119,11 @@ jobs:
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
@ -105,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: |

View file

@ -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: |
@ -77,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"
@ -98,14 +93,15 @@ jobs:
CIBW_BEFORE_ALL: bash ./.github/workflows/wheels/cibw_before_all.sh
CIBW_ENVIRONMENT: >
OPTFLAGS=-O3
PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig
PATH="$PWD/bison/src:$PATH"
PKG_CONFIG_PATH={project}/ffi/pfx/lib/pkgconfig
PATH="{project}/bison/src:$PATH"
CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release"
CIBW_ENVIRONMENT_MACOS: >
OPTFLAGS=-O3
PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig
PKG_CONFIG_PATH={project}/ffi/pfx/lib/pkgconfig
MACOSX_DEPLOYMENT_TARGET=11
makeFlags='CONFIG=clang'
PATH="$PWD/bison/src:$PATH"
PATH="{project}/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

View file

@ -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)

View file

@ -29,9 +29,7 @@ fi
set -e -x
cd ffi
## Ultimate libyosys.so will be shared, so we need fPIC for the static libraries
CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PWD/pfx
LDFLAGS=-fPIC CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PWD/pfx --enable-static --disable-shared
make clean
make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu)
## Forces static library to be used in all situations
sed -i.bak 's@-L${toolexeclibdir} -lffi@${toolexeclibdir}/libffi.a@' ./pfx/lib/pkgconfig/libffi.pc
)

View file

@ -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

10
.gitignore vendored
View file

@ -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
@ -65,10 +69,10 @@
/viz.js
# other
/coverage.info
/yosys.profdata
/coverage
/coverage_html
# these really belong in global gitignore since they're not specific to this project but rather to user tool choice
# but too many people don't have a global gitignore configured:
# https://docs.github.com/en/get-started/git-basics/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer
@ -86,3 +90,5 @@ __pycache__
/qtcreator.creator
/qtcreator.creator.user
/compile_commands.json
/.direnv
/.envrc

19
.gitmodules vendored
View file

@ -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

30
.pre-commit-config.yaml Normal file
View file

@ -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

View file

@ -12,3 +12,4 @@ brew "bash"
brew "llvm"
brew "lld"
brew "googletest"
brew "tcl-tk"

101
CHANGELOG
View file

@ -2,9 +2,65 @@
List of major changes and improvements between releases
=======================================================
Yosys 0.64 .. Yosys 0.65-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.
- Added "-scopename" option to "synth_gatemate" pass
that is propagated to "flatten".
Yosys 0.64 .. Yosys 0.65
--------------------------
* New commands and options
- Added "arith_tree" pass to convert add/sub/macc chains
to carry-save adder trees.
- Removed "-force" option from "share" pass.
* Various
- read_verilog: support positional assignment patterns
for unpacked arrays.
Yosys 0.63 .. Yosys 0.64
--------------------------
* New commands and options
@ -54,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.
@ -68,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
@ -172,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
--------------------------
@ -198,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.
@ -264,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.
@ -291,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.
@ -299,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.
@ -324,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 )
@ -341,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
@ -370,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.
@ -384,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.
@ -398,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.
@ -445,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.
@ -540,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.
@ -715,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
@ -809,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
@ -824,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
@ -1778,4 +1834,3 @@ Yosys 0.1.0 .. Yosys 0.2.0
- Added "design -stash/-copy-from/-copy-to"
- Added "copy" command
- Added "splice" command

607
CMakeLists.txt Normal file
View file

@ -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 <options>"
)
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
"$<$<AND:$<NOT:$<BOOL:$<TARGET_PROPERTY:YOSYS_IS_ABC>>>,$<CONFIG:Sanitize>>:-fsanitize=${SANITIZE}>"
"$<$<NOT:$<BOOL:$<TARGET_PROPERTY:YOSYS_IS_ABC>>>:-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_
$<$<CONFIG:Debug,RelWithDebInfo>: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 $<TARGET_FILE:pyosys>
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 `$<TARGET_FILE:tgt>`.)
set(makefile_vars
BUILD_DIR=${CMAKE_BINARY_DIR}
PROGRAM_PREFIX=${YOSYS_PROGRAM_PREFIX}
ABC=$<IF:$<TARGET_EXISTS:yosys-abc>,$<TARGET_FILE:yosys-abc>,${YOSYS_ABC_EXECUTABLE}>
YOSYS=$<TARGET_FILE:yosys>
YOSYS_CONFIG=${CMAKE_BINARY_DIR}/${YOSYS_PROGRAM_PREFIX}yosys-config
YOSYS_FILTERLIB=$<$<TARGET_EXISTS:yosys-filterlib>:$<TARGET_FILE: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 $<TARGET_FILE>
# yosys is implied via $<TARGET_FILE>
# yosys-filterlib is implied via $<TARGET_FILE>
$<$<TARGET_EXISTS:yosys-smtbmc>:yosys-smtbmc>
$<$<TARGET_EXISTS:yosys-witness>: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 $<$<TARGET_EXISTS:yosys-gtest-all>:yosys-gtest-all>
)
add_custom_target(test-vanilla
COMMAND make vanilla-test ${makefile_vars}
ENABLE_FUNCTIONAL_TESTS=$<IF:$<BOOL:${YOSYS_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=$<IF:$<BOOL:${YOSYS_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
)

View file

@ -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

1215
Makefile

File diff suppressed because it is too large Load diff

120
README.md
View file

@ -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 <var>=<value>` 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.

2
abc

@ -1 +1 @@
Subproject commit d217b351925ffc5e3036073776fef1810d258499
Subproject commit 2a9e9c2a00e44abd90fc593edfc2c0ff4573f318

18
backends/CMakeLists.txt Normal file
View file

@ -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)

View file

@ -0,0 +1,8 @@
yosys_backend(aiger
aiger.cc
REQUIRES
json11
)
yosys_backend(xaiger
xaiger.cc
)

View file

@ -1,4 +0,0 @@
OBJS += backends/aiger/aiger.o
OBJS += backends/aiger/xaiger.o

View file

@ -340,7 +340,7 @@ struct AigerWriter
if (cell->type == ID($scopeinfo))
continue;
log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
log_error("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell);
}
for (auto bit : unused_bits)
@ -349,10 +349,10 @@ struct AigerWriter
if (!undriven_bits.empty()) {
undriven_bits.sort();
for (auto bit : undriven_bits) {
log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit));
log_warning("Treating undriven bit %s.%s like $anyseq.\n", module, log_signal(bit));
input_bits.insert(bit);
}
log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module));
log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), module);
}
init_map.sort();
@ -635,35 +635,35 @@ struct AigerWriter
int a = aig_map.at(sig[i]);
log_assert((a & 1) == 0);
if (GetSize(wire) != 1)
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s[%d]", log_id(wire), i));
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s[%d]", wire, i));
else
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", log_id(wire)));
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", wire));
}
if (wire->port_output) {
int o = ordered_outputs.at(SigSpec(wire, i));
if (GetSize(wire) != 1)
symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", log_id(wire), i));
symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", wire, i));
else
symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s", log_id(wire)));
symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s", wire));
}
if (init_inputs.count(sig[i])) {
int a = init_inputs.at(sig[i]);
log_assert((a & 1) == 0);
if (GetSize(wire) != 1)
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s[%d]", log_id(wire), i));
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s[%d]", wire, i));
else
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s", log_id(wire)));
symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("init:%s", wire));
}
if (ordered_latches.count(sig[i])) {
int l = ordered_latches.at(sig[i]);
const char *p = (zinit_mode && (aig_latchinit.at(l) == 1)) ? "!" : "";
if (GetSize(wire) != 1)
symbols[stringf("l%d", l)].push_back(stringf("%s%s[%d]", p, log_id(wire), i));
symbols[stringf("l%d", l)].push_back(stringf("%s%s[%d]", p, wire, i));
else
symbols[stringf("l%d", l)].push_back(stringf("%s%s", p, log_id(wire)));
symbols[stringf("l%d", l)].push_back(stringf("%s%s", p, wire));
}
}
}
@ -705,30 +705,30 @@ struct AigerWriter
int index = no_startoffset ? i : (wire->start_offset+i);
if (verbose_map)
wire_lines[a] += stringf("wire %d %d %s\n", a, index, log_id(wire));
wire_lines[a] += stringf("wire %d %d %s\n", a, index, wire);
if (wire->port_input) {
log_assert((a & 1) == 0);
input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, index, log_id(wire));
input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, index, wire);
}
if (wire->port_output) {
int o = ordered_outputs.at(SigSpec(wire, i));
output_lines[o] += stringf("output %d %d %s\n", o, index, log_id(wire));
output_lines[o] += stringf("output %d %d %s\n", o, index, wire);
}
if (init_inputs.count(sig[i])) {
int a = init_inputs.at(sig[i]);
log_assert((a & 1) == 0);
init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, index, log_id(wire));
init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, index, wire);
}
if (ordered_latches.count(sig[i])) {
int l = ordered_latches.at(sig[i]);
if (zinit_mode && (aig_latchinit.at(l) == 1))
latch_lines[l] += stringf("invlatch %d %d %s\n", l, index, log_id(wire));
latch_lines[l] += stringf("invlatch %d %d %s\n", l, index, wire);
else
latch_lines[l] += stringf("latch %d %d %s\n", l, index, log_id(wire));
latch_lines[l] += stringf("latch %d %d %s\n", l, index, wire);
}
}
}
@ -1027,12 +1027,12 @@ struct AigerBackend : public Backend {
log_error("Can't find top module in current design!\n");
if (!design->selected_whole_module(top_module))
log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module));
log_cmd_error("Can't handle partially selected module %s!\n", top_module);
if (!top_module->processes.empty())
log_error("Found unmapped processes in module %s: unmapped processes are not supported in AIGER backend!\n", log_id(top_module));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in AIGER backend!\n", top_module);
if (!top_module->memories.empty())
log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", log_id(top_module));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", top_module);
AigerWriter writer(top_module, no_sort, zinit_mode, imode, omode, bmode, lmode);
writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode);

View file

@ -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
@ -268,7 +268,7 @@ struct XAigerWriter
if (ys_debug(1)) {
static pool<std::pair<IdString,TimingInfo::NameBit>> seen;
if (seen.emplace(inst_module->name, i.first).second) log("%s.%s[%d] abc9_arrival = %d\n",
log_id(cell->type), log_id(i.first.name), offset, d);
cell->type.unescape(), i.first.name.unescape(), offset, d);
}
#endif
arrival_times[rhs[offset]] = d;
@ -285,7 +285,7 @@ struct XAigerWriter
auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first);
auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first);
if (!is_input && !is_output)
log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type));
log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", c.first.unescape(), cell, cell->type.unescape());
if (is_input)
for (auto b : c.second) {
@ -303,7 +303,7 @@ struct XAigerWriter
}
}
//log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
//log_warning("Unsupported cell type: %s (%s)\n", cell->type.unescape(), cell);
}
dict<IdString, std::vector<IdString>> box_ports;
@ -325,12 +325,12 @@ struct XAigerWriter
if (w->get_bool_attribute(ID::abc9_carry)) {
if (w->port_input) {
if (carry_in != IdString())
log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module));
log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", box_module);
carry_in = port_name;
}
if (w->port_output) {
if (carry_out != IdString())
log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(box_module));
log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", box_module);
carry_out = port_name;
}
}
@ -339,9 +339,9 @@ struct XAigerWriter
}
if (carry_in != IdString() && carry_out == IdString())
log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(box_module));
log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", box_module);
if (carry_in == IdString() && carry_out != IdString())
log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module));
log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", box_module);
if (carry_in != IdString()) {
r.first->second.push_back(carry_in);
r.first->second.push_back(carry_out);
@ -612,7 +612,7 @@ struct XAigerWriter
write_r_buffer(mergeability);
State init = init_map.at(q, State::Sx);
log_debug("Cell '%s' (type %s) has (* init *) value '%s'.\n", log_id(cell), log_id(cell->type), log_signal(init));
log_debug("Cell '%s' (type %s) has (* init *) value '%s'.\n", cell, cell->type.unescape(), log_signal(init));
if (init == State::S1)
write_s_buffer(1);
else if (init == State::S0)
@ -692,12 +692,12 @@ struct XAigerWriter
if (input_bits.count(b)) {
int a = aig_map.at(b);
log_assert((a & 1) == 0);
input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, wire->start_offset+i, log_id(wire));
input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, wire->start_offset+i, wire);
}
if (output_bits.count(b)) {
int o = ordered_outputs.at(b);
output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), wire->start_offset+i, log_id(wire));
output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), wire->start_offset+i, wire);
}
}
}
@ -709,7 +709,7 @@ struct XAigerWriter
int box_count = 0;
for (auto cell : box_list)
f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name));
f << stringf("box %d %d %s\n", box_count++, 0, cell->name.unescape());
output_lines.sort();
for (auto &it : output_lines)
@ -774,12 +774,12 @@ struct XAigerBackend : public Backend {
log_error("Can't find top module in current design!\n");
if (!design->selected_whole_module(top_module))
log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module));
log_cmd_error("Can't handle partially selected module %s!\n", top_module);
if (!top_module->processes.empty())
log_error("Found unmapped processes in module %s: unmapped processes are not supported in XAIGER backend!\n", log_id(top_module));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in XAIGER backend!\n", top_module);
if (!top_module->memories.empty())
log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", log_id(top_module));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", top_module);
XAigerWriter writer(top_module, dff_mode);
writer.write_aiger(*f, ascii_mode);

View file

@ -0,0 +1,5 @@
yosys_backend(aiger2
aiger.cc
PROVIDES
write_xaiger2
)

View file

@ -1 +0,0 @@
OBJS += backends/aiger2/aiger.o

View file

@ -132,7 +132,7 @@ struct Index {
continue;
if (!submodule || submodule->get_blackbox_attribute())
log_error("Unsupported cell type: %s (%s in %s)\n",
log_id(cell->type), log_id(cell), log_id(m));
cell->type.unescape(), cell, m);
}
}
}
@ -537,7 +537,7 @@ struct Index {
Design *design = index.design;
auto &minfo = leaf_minfo(index);
if (!minfo.suboffsets.count(cell))
log_error("Reached unsupported cell %s (%s in %s)\n", log_id(cell->type), log_id(cell), log_id(cell->module));
log_error("Reached unsupported cell %s (%s in %s)\n", cell->type.unescape(), cell, cell->module);
Module *def = design->module(cell->type);
log_assert(def);
levels.push_back(Level(index.modules.at(def), cell));
@ -560,9 +560,9 @@ struct Index {
if (!first)
ret += ".";
if (!cell)
ret += RTLIL::unescape_id(minfo.module->name);
ret += minfo.module->name.unescape();
else
ret += RTLIL::unescape_id(cell->name);
ret += cell->name.unescape();
first = false;
}
return ret;
@ -636,10 +636,10 @@ struct Index {
Wire *w = def->wire(portname);
if (!w)
log_error("Output port %s on instance %s of %s doesn't exist\n",
log_id(portname), log_id(driver), log_id(def));
portname.unescape(), driver, def);
if (bit.offset >= w->width)
log_error("Bit position %d of output port %s on instance %s of %s is out of range (port has width %d)\n",
bit.offset, log_id(portname), log_id(driver), log_id(def), w->width);
bit.offset, portname.unescape(), driver, def, w->width);
ret = visit(cursor, SigBit(w, bit.offset));
}
cursor.exit(*this);
@ -655,11 +655,11 @@ struct Index {
IdString portname = bit.wire->name;
if (!instance->hasPort(portname))
log_error("Input port %s on instance %s of %s unconnected\n",
log_id(portname), log_id(instance), log_id(instance->type));
portname.unescape(), instance, instance->type);
auto &port = instance->getPort(portname);
if (bit.offset >= port.size())
log_error("Bit %d of input port %s on instance %s of %s unconnected\n",
bit.offset, log_id(portname), log_id(instance), log_id(instance->type));
bit.offset, portname.unescape(), instance, instance->type.unescape());
ret = visit(cursor, port[bit.offset]);
}
cursor.enter(*this, instance);
@ -844,7 +844,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
char buf[32];
snprintf(buf, sizeof(buf), "o%d ", i);
f->write(buf, strlen(buf));
std::string name = RTLIL::unescape_id(bit.wire->name);
std::string name = bit.wire->name.unescape();
f->write(name.data(), name.size());
f->put('\n');
}
@ -857,7 +857,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
char buf[32];
snprintf(buf, sizeof(buf), "i%d ", i);
f->write(buf, strlen(buf));
std::string name = RTLIL::unescape_id(bit.wire->name);
std::string name = bit.wire->name.unescape();
f->write(name.data(), name.size());
f->put('\n');
}
@ -1048,7 +1048,7 @@ struct XAigerWriter : AigerWriter {
} else if (!is_input && !inputs) {
for (auto &bit : conn.second) {
if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output))
log_error("Bad connection %s/%s ~ %s\n", log_id(box), log_id(conn.first), log_signal(conn.second));
log_error("Bad connection %s/%s ~ %s\n", box, conn.first.unescape(), log_signal(conn.second));
ensure_pi(bit, cursor);
@ -1073,9 +1073,9 @@ struct XAigerWriter : AigerWriter {
void prep_boxes(int pending_pos_num)
{
XAigerAnalysis analysis;
log_debug("preforming analysis on '%s'\n", log_id(top));
log_debug("preforming analysis on '%s'\n", top);
analysis.analyze(top);
log_debug("analysis on '%s' done\n", log_id(top));
log_debug("analysis on '%s' done\n", top);
// boxes which have timing data, maybe a whitebox model
std::vector<std::tuple<HierCursor, Cell *, Module *>> nonopaque_boxes;
@ -1088,8 +1088,8 @@ struct XAigerWriter : AigerWriter {
for (auto box : minfo.found_blackboxes) {
log_debug(" - %s.%s (type %s): ", cursor.path(),
RTLIL::unescape_id(box->name),
log_id(box->type));
box,
box->type.unescape());
Module *box_module = design->module(box->type), *box_derived;
@ -1158,7 +1158,7 @@ struct XAigerWriter : AigerWriter {
} else {
// FIXME: hierarchical path
log_warning("connection on port %s[%d] of instance %s (type %s) missing, using 1'bx\n",
log_id(port_id), i, log_id(box), log_id(box->type));
port_id.unescape(), i, box, box->type.unescape());
bit = RTLIL::Sx;
}
@ -1193,7 +1193,7 @@ struct XAigerWriter : AigerWriter {
} else {
// FIXME: hierarchical path
log_warning("connection on port %s[%d] of instance %s (type %s) missing\n",
log_id(port_id), i, log_id(box), log_id(box->type));
port_id.unescape(), i, box, box->type.unescape());
pad_pi();
continue;
}
@ -1210,7 +1210,7 @@ struct XAigerWriter : AigerWriter {
holes_wb->setPort(port_id, w);
} else {
log_error("Ambiguous port direction on %s/%s\n",
log_id(box->type), log_id(port_id));
box->type.unescape(), port_id.unescape());
}
}
}
@ -1405,7 +1405,7 @@ struct Aiger2Backend : Backend {
continue;
if (known_ops(cell.type))
continue;
std::string name = log_id(cell.type);
std::string name = cell.type.unescape();
if (col + name.size() + 2 > 72) {
log("\n ");
col = 0;
@ -1427,7 +1427,7 @@ struct Aiger2Backend : Backend {
continue;
if (known_ops(cell.type))
continue;
std::string name = log_id(cell.type);
std::string name = cell.type.unescape();
if (col + name.size() + 2 > 72) {
log("\n ");
col = 0;

View file

@ -0,0 +1,3 @@
yosys_backend(blif
blif.cc
)

View file

@ -1,3 +0,0 @@
OBJS += backends/blif/blif.o

View file

@ -91,7 +91,7 @@ struct BlifDumper
const std::string str(RTLIL::IdString id)
{
std::string str = RTLIL::unescape_id(id);
std::string str = id.unescape();
for (size_t i = 0; i < str.size(); i++)
if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>')
str[i] = '?';
@ -108,7 +108,7 @@ struct BlifDumper
return config->undef_type == "-" || config->undef_type == "+" ? config->undef_out.c_str() : "$undef";
}
std::string str = RTLIL::unescape_id(sig.wire->name);
std::string str = sig.wire->name.unescape();
for (size_t i = 0; i < str.size(); i++)
if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>')
str[i] = '?';
@ -150,7 +150,7 @@ struct BlifDumper
void dump_params(const char *command, dict<IdString, Const> &params)
{
for (auto &param : params) {
f << stringf("%s %s ", command, log_id(param.first));
f << stringf("%s %s ", command, param.first.unescape());
if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
std::string str = param.second.decode_string();
f << stringf("\"");
@ -678,9 +678,9 @@ struct BlifBackend : public Backend {
continue;
if (module->processes.size() != 0)
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", log_id(module->name));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", module->name.unescape());
if (module->memories.size() != 0)
log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", log_id(module->name));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", module->name.unescape());
if (module->name == RTLIL::escape_id(top_module_name)) {
BlifDumper::dump(*f, module, design, config);

View file

@ -0,0 +1,7 @@
yosys_backend(btor
btor.cc
REQUIRES
bmuxmap
demuxmap
bwmuxmap
)

View file

@ -1,3 +0,0 @@
OBJS += backends/btor/btor.o

View file

@ -119,7 +119,7 @@ struct BtorWorker
template<typename T>
string getinfo(T *obj, bool srcsym = false)
{
string infostr = log_id(obj);
string infostr = obj->name.unescape();
if (!srcsym && !print_internal_names && infostr[0] == '$') return "";
if (obj->attributes.count(ID::src)) {
string src = obj->attributes.at(ID::src).decode_string().c_str();
@ -243,12 +243,12 @@ struct BtorWorker
if (cell_recursion_guard.count(cell)) {
string cell_list;
for (auto c : cell_recursion_guard)
cell_list += stringf("\n %s", log_id(c));
log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list);
cell_list += stringf("\n %s", c);
log_error("Found topological loop while processing cell %s. Active cells:%s\n", cell, cell_list);
}
cell_recursion_guard.insert(cell);
btorf_push(log_id(cell));
btorf_push(cell->name.unescape());
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx),
ID($concat), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_)))
@ -726,7 +726,7 @@ struct BtorWorker
if (symbol.empty() || (!print_internal_names && symbol[0] == '$'))
btorf("%d state %d\n", nid, sid);
else
btorf("%d state %d %s\n", nid, sid, log_id(symbol));
btorf("%d state %d %s\n", nid, sid, symbol.unescape());
if (cell->get_bool_attribute(ID(clk2fflogic)))
ywmap_state(cell->getPort(ID::D)); // For a clk2fflogic FF the named signal is the D input not the Q output
@ -804,12 +804,12 @@ struct BtorWorker
if (asyncwr && syncwr)
log_error("Memory %s.%s has mixed async/sync write ports.\n",
log_id(module), log_id(mem->memid));
module, mem->memid.unescape());
for (auto &port : mem->rd_ports) {
if (port.clk_enable)
log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n",
log_id(module), log_id(mem->memid));
module, mem->memid.unescape());
}
int data_sid = get_bv_sid(mem->width);
@ -871,7 +871,7 @@ struct BtorWorker
if (mem->memid[0] == '$')
btorf("%d state %d\n", nid, sid);
else
btorf("%d state %d %s\n", nid, sid, log_id(mem->memid));
btorf("%d state %d %s\n", nid, sid, mem->memid.unescape());
ywmap_state(cell);
@ -948,21 +948,20 @@ struct BtorWorker
if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_btor`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
log_error("Unsupported cell type %s for cell %s.%s.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
okay:
btorf_pop(log_id(cell));
btorf_pop(cell->name.unescape());
cell_recursion_guard.erase(cell);
}
@ -1167,7 +1166,7 @@ struct BtorWorker
f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), print_internal_names(print_internal_names), info_filename(info_filename)
{
if (!info_filename.empty())
infof("name %s\n", log_id(module));
infof("name %s\n", module);
if (!ywmap_filename.empty())
ywmap_json.write_to_file(ywmap_filename);
@ -1257,19 +1256,19 @@ struct BtorWorker
if (!wire->port_id || !wire->port_output)
continue;
btorf_push(stringf("output %s", log_id(wire)));
btorf_push(stringf("output %s", wire));
int nid = get_sig_nid(wire);
btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire));
btorf_pop(stringf("output %s", log_id(wire)));
btorf_pop(stringf("output %s", wire));
}
for (auto cell : module->cells())
{
if (cell->type == ID($assume))
{
btorf_push(log_id(cell));
btorf_push(cell->name.unescape());
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(ID::A));
@ -1284,12 +1283,12 @@ struct BtorWorker
if (ywmap_json.active()) ywmap_assumes.emplace_back(cell);
btorf_pop(log_id(cell));
btorf_pop(cell->name.unescape());
}
if (cell->type == ID($assert))
{
btorf_push(log_id(cell));
btorf_push(cell->name.unescape());
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(ID::A));
@ -1313,12 +1312,12 @@ struct BtorWorker
}
}
btorf_pop(log_id(cell));
btorf_pop(cell->name.unescape());
}
if (cell->type == ID($cover) && cover_mode)
{
btorf_push(log_id(cell));
btorf_push(cell->name.unescape());
int sid = get_bv_sid(1);
int nid_a = get_sig_nid(cell->getPort(ID::A));
@ -1334,7 +1333,7 @@ struct BtorWorker
btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true));
}
btorf_pop(log_id(cell));
btorf_pop(cell->name.unescape());
}
}
@ -1343,7 +1342,7 @@ struct BtorWorker
if (wire->port_id || wire->name[0] == '$')
continue;
btorf_push(stringf("wire %s", log_id(wire)));
btorf_push(stringf("wire %s", wire));
int sid = get_bv_sid(GetSize(wire));
int nid = get_sig_nid(sigmap(wire));
@ -1356,7 +1355,7 @@ struct BtorWorker
if (info_clocks.count(nid))
info_clocks[this_nid] |= info_clocks[nid];
btorf_pop(stringf("wire %s", log_id(wire)));
btorf_pop(stringf("wire %s", wire));
continue;
}
@ -1370,14 +1369,14 @@ struct BtorWorker
int nid = it.first;
Cell *cell = it.second;
btorf_push(stringf("next %s", log_id(cell)));
btorf_push(stringf("next %s", cell));
SigSpec sig = sigmap(cell->getPort(ID::D));
int nid_q = get_sig_nid(sig);
int sid = get_bv_sid(GetSize(sig));
btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell));
btorf_pop(stringf("next %s", log_id(cell)));
btorf_pop(stringf("next %s", cell));
}
vector<pair<int, Mem*>> mtodo;
@ -1388,7 +1387,7 @@ struct BtorWorker
int nid = it.first;
Mem *mem = it.second;
btorf_push(stringf("next %s", log_id(mem->memid)));
btorf_push(stringf("next %s", mem->memid.unescape()));
int abits = ceil_log2(mem->size);
@ -1436,7 +1435,7 @@ struct BtorWorker
int nid2 = next_nid++;
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)));
btorf_pop(stringf("next %s", log_id(mem->memid)));
btorf_pop(stringf("next %s", mem->memid.unescape()));
}
}
@ -1630,7 +1629,7 @@ struct BtorBackend : public Backend {
log_cmd_error("No top module found.\n");
*f << stringf("; BTOR description generated by %s for module %s.\n",
yosys_maybe_version(), log_id(topmod));
yosys_maybe_version(), topmod);
BtorWorker(*f, topmod, verbose, single_bad, cover_mode, print_internal_names, info_filename, ywmap_filename);

View file

@ -27,4 +27,3 @@ for fn in test_*.il; do
done
echo "OK."

View file

@ -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
)

View file

@ -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))

View file

@ -251,7 +251,7 @@ CxxrtlPortType cxxrtl_port_type(RTLIL::Module *module, RTLIL::IdString port)
bool is_sync = output_wire->get_bool_attribute(ID(cxxrtl_sync));
if (is_comb && is_sync)
log_cmd_error("Port `%s.%s' is marked as both `cxxrtl_comb` and `cxxrtl_sync`.\n",
log_id(module), log_signal(output_wire));
module, log_signal(output_wire));
else if (is_comb)
return CxxrtlPortType::COMB;
else if (is_sync)
@ -851,7 +851,7 @@ struct CxxrtlWorker {
return {};
if (!(module->attributes.at(ID(cxxrtl_template)).flags & RTLIL::CONST_FLAG_STRING))
log_cmd_error("Attribute `cxxrtl_template' of module `%s' is not a string.\n", log_id(module));
log_cmd_error("Attribute `cxxrtl_template' of module `%s' is not a string.\n", module);
std::vector<std::string> param_names = split_by(module->get_string_attribute(ID(cxxrtl_template)), " \t");
for (const auto &param_name : param_names) {
@ -861,7 +861,7 @@ struct CxxrtlWorker {
if (!isupper(param_name[0]))
log_cmd_error("Attribute `cxxrtl_template' of module `%s' includes a parameter `%s', "
"which does not start with an uppercase letter.\n",
log_id(module), param_name.c_str());
module, param_name.c_str());
}
return param_names;
}
@ -907,12 +907,12 @@ struct CxxrtlWorker {
RTLIL::IdString id_param_name = '\\' + param_name;
if (!cell->hasParam(id_param_name))
log_cmd_error("Cell `%s.%s' does not have a parameter `%s', which is required by the templated module `%s'.\n",
log_id(cell->module), log_id(cell), param_name.c_str(), log_id(cell_module));
cell->module, cell, param_name.c_str(), cell_module);
RTLIL::Const param_value = cell->getParam(id_param_name);
if (((param_value.flags & ~RTLIL::CONST_FLAG_SIGNED) != 0) || param_value.as_int() < 0)
log_cmd_error("Parameter `%s' of cell `%s.%s', which is required by the templated module `%s', "
"is not a positive integer.\n",
param_name.c_str(), log_id(cell->module), log_id(cell), log_id(cell_module));
param_name.c_str(), cell->module, cell, cell_module);
params += std::to_string(cell->getParam(id_param_name).as_int());
}
params += ">";
@ -2576,7 +2576,7 @@ struct CxxrtlWorker {
}
dec_indent();
log_debug("Debug information statistics for module `%s':\n", log_id(module));
log_debug("Debug information statistics for module `%s':\n", module);
log_debug(" Scopes: %zu", count_scopes);
log_debug(" Public wires: %zu, of which:\n", count_public_wires);
log_debug(" Member wires: %zu, of which:\n", count_member_wires);
@ -2940,7 +2940,7 @@ struct CxxrtlWorker {
RTLIL::Const edge_attr = wire->attributes[ID(cxxrtl_edge)];
if (!(edge_attr.flags & RTLIL::CONST_FLAG_STRING) || (int)edge_attr.decode_string().size() != GetSize(wire))
log_cmd_error("Attribute `cxxrtl_edge' of port `%s.%s' is not a string with one character per bit.\n",
log_id(module), log_signal(wire));
module, log_signal(wire));
std::string edges = wire->get_string_attribute(ID(cxxrtl_edge));
for (int i = 0; i < GetSize(wire); i++) {
@ -2953,7 +2953,7 @@ struct CxxrtlWorker {
default:
log_cmd_error("Attribute `cxxrtl_edge' of port `%s.%s' contains specifiers "
"other than '-', 'p', 'n', or 'a'.\n",
log_id(module), log_signal(wire));
module, log_signal(wire));
}
}
}
@ -2978,7 +2978,7 @@ struct CxxrtlWorker {
for (auto cell : module->cells()) {
if (!cell->known())
log_cmd_error("Unknown cell `%s'.\n", log_id(cell->type));
log_cmd_error("Unknown cell `%s'.\n", cell->type.unescape());
if (cell->is_mem_cell())
continue;
@ -2987,7 +2987,7 @@ struct CxxrtlWorker {
if (cell_module &&
cell_module->get_blackbox_attribute() &&
!cell_module->get_bool_attribute(ID(cxxrtl_blackbox)))
log_cmd_error("External blackbox cell `%s' is not marked as a CXXRTL blackbox.\n", log_id(cell->type));
log_cmd_error("External blackbox cell `%s' is not marked as a CXXRTL blackbox.\n", cell->type.unescape());
if (cell_module &&
cell_module->get_bool_attribute(ID(cxxrtl_blackbox)) &&
@ -3116,9 +3116,9 @@ struct CxxrtlWorker {
}
if (!feedback_wires.empty()) {
has_feedback_arcs = true;
log("Module `%s' contains feedback arcs through wires:\n", log_id(module));
log("Module `%s' contains feedback arcs through wires:\n", module);
for (auto wire : feedback_wires)
log(" %s\n", log_id(wire));
log(" %s\n", wire);
}
// Conservatively assign wire types. Assignment of types BUFFERED and MEMBER is final, but assignment
@ -3189,7 +3189,7 @@ struct CxxrtlWorker {
if (wire->name.isPublic() && !inline_public) continue;
if (flow.is_inlinable(wire, live_wires[wire])) {
if (flow.wire_comb_defs[wire].size() > 1)
log_cmd_error("Wire %s.%s has multiple drivers!\n", log_id(module), log_id(wire));
log_cmd_error("Wire %s.%s has multiple drivers!\n", module, wire);
log_assert(flow.wire_comb_defs[wire].size() == 1);
FlowGraph::Node *node = *flow.wire_comb_defs[wire].begin();
switch (node->type) {
@ -3237,9 +3237,9 @@ struct CxxrtlWorker {
buffered_comb_wires.insert(wire);
if (!buffered_comb_wires.empty()) {
has_buffered_comb_wires = true;
log("Module `%s' contains buffered combinatorial wires:\n", log_id(module));
log("Module `%s' contains buffered combinatorial wires:\n", module);
for (auto wire : buffered_comb_wires)
log(" %s\n", log_id(wire));
log(" %s\n", wire);
}
// Record whether eval() requires only one delta cycle in this module.
@ -3420,7 +3420,7 @@ struct CxxrtlWorker {
if (!design->selected_whole_module(module))
if (design->selected_module(module))
log_cmd_error("Can't handle partially selected module `%s'!\n", id2cstr(module->name));
log_cmd_error("Can't handle partially selected module `%s'!\n", module);
if (!design->selected_module(module))
continue;

View file

@ -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.
of the directory where they are placed.

View file

@ -0,0 +1,3 @@
yosys_backend(edif
edif.cc
)

View file

@ -1,3 +0,0 @@
OBJS += backends/edif/edif.o

View file

@ -30,9 +30,11 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true)
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br)
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false)
#define EDIF_DEF(_id) edif_names(_id.unescape(), true)
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(_id.unescape(), true, _ren, _bl, _br)
#define EDIF_REF(_id) edif_names(_id.unescape(), false)
#define EDIF_DEF_STR(_id) edif_names(RTLIL::unescape_id(_id), true)
#define EDIF_REF_STR(_id) edif_names(RTLIL::unescape_id(_id), false)
struct EdifNames
{
@ -207,9 +209,9 @@ struct EdifBackend : public Backend {
top_module_name = module->name.str();
if (module->processes.size() != 0)
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", log_id(module->name));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", module->name.unescape());
if (module->memories.size() != 0)
log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", log_id(module->name));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", module->name.unescape());
for (auto cell : module->cells())
{
@ -227,7 +229,7 @@ struct EdifBackend : public Backend {
if (top_module_name.empty())
log_error("No module found in design!\n");
*f << stringf("(edif %s\n", EDIF_DEF(top_module_name));
*f << stringf("(edif %s\n", EDIF_DEF_STR(top_module_name));
*f << stringf(" (edifVersion 2 0 0)\n");
*f << stringf(" (edifLevel 0)\n");
*f << stringf(" (keywordMap (keywordLevel 0))\n");
@ -317,12 +319,12 @@ struct EdifBackend : public Backend {
for (auto &dep : it.second)
if (module_deps.count(dep) > 0)
goto not_ready_yet;
// log("Next in topological sort: %s\n", log_id(it.first->name));
// log("Next in topological sort: %s\n", it.first->name.unescape());
sorted_modules.push_back(it.first);
not_ready_yet:;
}
if (sorted_modules_idx == sorted_modules.size())
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->name.unescape());
while (sorted_modules_idx < sorted_modules.size())
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
}
@ -486,7 +488,7 @@ struct EdifBackend : public Backend {
for (int i = 0; i < GetSize(sig); i++)
if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n",
i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i]));
i, module, cell, p.first.unescape(), log_signal(sig[i]));
else {
int member_idx = lsbidx ? i : GetSize(sig)-i-1;
auto m = design->module(cell->type);
@ -534,7 +536,7 @@ struct EdifBackend : public Backend {
if (netname[i] == ' ' || netname[i] == '\\')
netname.erase(netname.begin() + i--);
}
*f << stringf(" (net %s (joined\n", EDIF_DEF(netname));
*f << stringf(" (net %s (joined\n", EDIF_DEF_STR(netname));
for (auto &ref : it.second)
*f << stringf(" %s\n", ref.first);
if (sig.wire == NULL) {
@ -572,7 +574,7 @@ struct EdifBackend : public Backend {
if (keepmode)
{
*f << stringf(" (net %s (joined\n", EDIF_DEF(netname));
*f << stringf(" (net %s (joined\n", EDIF_DEF_STR(netname));
auto &refs = net_join_db.at(mapped_sig);
for (auto &ref : refs)
@ -588,7 +590,7 @@ struct EdifBackend : public Backend {
}
else
{
log_warning("Ignoring conflicting 'keep' property on net %s. Use -keep to generate the extra net nevertheless.\n", EDIF_DEF(netname));
log_warning("Ignoring conflicting 'keep' property on net %s. Use -keep to generate the extra net nevertheless.\n", EDIF_DEF_STR(netname));
}
}
}
@ -599,8 +601,8 @@ struct EdifBackend : public Backend {
}
*f << stringf(" )\n");
*f << stringf(" (design %s\n", EDIF_DEF(top_module_name));
*f << stringf(" (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name));
*f << stringf(" (design %s\n", EDIF_DEF_STR(top_module_name));
*f << stringf(" (cellRef %s (libraryRef DESIGN))\n", EDIF_REF_STR(top_module_name));
*f << stringf(" )\n");
*f << stringf(")\n");

View file

@ -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")

View file

@ -0,0 +1,8 @@
yosys_backend(firrtl
firrtl.cc
REQUIRES
pmuxtree
bmuxmap
demuxmap
bwmuxmap
)

View file

@ -1,3 +0,0 @@
OBJS += backends/firrtl/firrtl.o

View file

@ -82,7 +82,7 @@ const char *make_id(IdString id)
if (namecache.count(id) != 0)
return namecache.at(id).c_str();
string new_id = log_id(id);
string new_id = id.unescape();
for (int i = 0; i < GetSize(new_id); i++)
{
@ -263,7 +263,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
if (wire->port_input && wire->port_output)
{
log_error("Module port %s.%s is inout!\n", log_id(mod_instance), log_id(wire));
log_error("Module port %s.%s is inout!\n", mod_instance, wire);
}
const std::string portDecl = stringf("%s%s %s: UInt<%d> %s\n",
@ -559,12 +559,12 @@ struct FirrtlWorker
if (wire->attributes.count(ID::init)) {
log_warning("Initial value (%s) for (%s.%s) not supported\n",
wire->attributes.at(ID::init).as_string().c_str(),
log_id(module), log_id(wire));
module, wire);
}
if (wire->port_id)
{
if (wire->port_input && wire->port_output)
log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire));
log_error("Module port %s.%s is inout!\n", module, wire);
port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent, wire->port_input ? "input" : "output",
wireName, wire->width, wireFileinfo.c_str()));
}
@ -833,7 +833,7 @@ struct FirrtlWorker
primop = "shl";
int shiftAmount = b_sig.as_int();
if (shiftAmount < 0) {
log_error("Negative power exponent - %d: %s.%s\n", shiftAmount, log_id(module), log_id(cell));
log_error("Negative power exponent - %d: %s.%s\n", shiftAmount, module, cell);
}
b_expr = std::to_string(shiftAmount);
firrtl_width = a_width + shiftAmount;
@ -844,7 +844,7 @@ struct FirrtlWorker
firrtl_width = a_width + (1 << b_width) - 1;
}
} else {
log_error("Non power 2: %s.%s\n", log_id(module), log_id(cell));
log_error("Non power 2: %s.%s\n", module, cell);
}
}
@ -905,7 +905,7 @@ struct FirrtlWorker
{
bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool();
if (clkpol == false)
log_error("Negative edge clock on FF %s.%s.\n", log_id(module), log_id(cell));
log_error("Negative edge clock on FF %s.%s.\n", module, cell);
int width = cell->parameters.at(ID::WIDTH).as_int();
string expr = make_expr(cell->getPort(ID::D));
@ -983,7 +983,7 @@ struct FirrtlWorker
if (cell->type == ID($scopeinfo))
continue;
log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell));
log_error("Cell type not supported: %s (%s.%s)\n", cell->type.unescape(), module, cell);
}
for (auto &mem : memories) {
@ -991,10 +991,10 @@ struct FirrtlWorker
Const init_data = mem.get_init_data();
if (!init_data.is_fully_undef())
log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(mem.memid));
log_error("Memory with initialization data: %s.%s\n", module, mem.memid.unescape());
if (mem.start_offset != 0)
log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(mem.memid));
log_error("Memory with nonzero offset: %s.%s\n", module, mem.memid.unescape());
for (int i = 0; i < GetSize(mem.rd_ports); i++)
{
@ -1002,7 +1002,7 @@ struct FirrtlWorker
string port_name(stringf("%s.r%d", mem_id, i));
if (port.clk_enable)
log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
log_error("Clocked read port %d on memory %s.%s.\n", i, module, mem.memid.unescape());
std::ostringstream rpe;
@ -1023,12 +1023,12 @@ struct FirrtlWorker
string port_name(stringf("%s.w%d", mem_id, i));
if (!port.clk_enable)
log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
log_error("Unclocked write port %d on memory %s.%s.\n", i, module, mem.memid.unescape());
if (!port.clk_polarity)
log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
log_error("Negedge write port %d on memory %s.%s.\n", i, module, mem.memid.unescape());
for (int i = 1; i < GetSize(port.en); i++)
if (port.en[0] != port.en[i])
log_error("Complex write enable on port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
log_error("Complex write enable on port %d on memory %s.%s.\n", i, module, mem.memid.unescape());
std::ostringstream wpe;

View file

@ -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
)

View file

@ -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

View file

@ -89,7 +89,7 @@ struct CxxStruct {
}
f.print("\n\t\ttemplate <typename T> void visit(T &&fn) {{\n");
for (auto p : types) {
f.print("\t\t\tfn(\"{}\", {});\n", RTLIL::unescape_id(p.first), scope(p.first, p.first));
f.print("\t\t\tfn(\"{}\", {});\n", p.first.unescape(), scope(p.first, p.first));
}
f.print("\t\t}}\n");
f.print("\t}};\n\n");

View file

@ -80,7 +80,7 @@ public:
SmtStruct(std::string name, SmtScope &scope) : scope(scope), name(name) {}
void insert(IdString field_name, SmtSort sort) {
field_names(field_name);
auto accessor = scope.unique_name("\\" + name + "_" + RTLIL::unescape_id(field_name));
auto accessor = scope.unique_name("\\" + name + "_" + field_name.unescape());
fields.emplace_back(Field{sort, accessor});
}
void write_definition(SExprWriter &w) {
@ -99,7 +99,7 @@ public:
w.open(list(name));
for(auto field_name : field_names) {
w << fn(field_name);
w.comment(RTLIL::unescape_id(field_name), true);
w.comment(field_name.unescape(), true);
}
w.close();
}
@ -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);
}

View file

@ -106,7 +106,7 @@ public:
w.open(list(name));
for(auto field_name : field_names) {
w << fn(field_name);
w.comment(RTLIL::unescape_id(field_name), true);
w.comment(field_name.unescape(), true);
}
w.close();
}
@ -281,7 +281,7 @@ struct SmtrModule {
w.push();
w.open(list());
w.open(list("assoc-result"));
w << list("assoc", "\"" + RTLIL::unescape_id(input->name) + "\"", inputs_name);
w << list("assoc", "\"" + input->name.unescape() + "\"", inputs_name);
w.pop();
w.open(list("if", "assoc-result"));
w << list("cdr", "assoc-result");
@ -298,13 +298,13 @@ struct SmtrModule {
w << list(*output_helper_name, outputs_name);
w.open(list("list"));
for (auto output : ir.outputs()) {
w << list("cons", "\"" + RTLIL::unescape_id(output->name) + "\"", output_struct.access("outputs", output->name));
w << list("cons", "\"" + output->name.unescape() + "\"", output_struct.access("outputs", output->name));
}
w.pop();
}
void write(std::ostream &out)
{
{
SExprWriter w(out);
input_struct.write_definition(w);

View file

@ -46,7 +46,7 @@ struct MemContentsTest {
error:
printf("FAIL\n");
int digits = (data_width + 3) / 4;
for(auto addr = 0; addr < (1<<addr_width); addr++) {
if(addr % 8 == 0) printf("%.8x ", addr);
auto it = reference.find(addr);
@ -146,11 +146,11 @@ struct FunctionalTestGeneric : public Pass
log("Dumping module `%s'.\n", module->name);
auto fir = Functional::IR::from_module(module);
for(auto node : fir)
std::cout << RTLIL::unescape_id(node.name()) << " = " << node.to_string([](auto n) { return RTLIL::unescape_id(n.name()); }) << "\n";
std::cout << node.name().unescape() << " = " << node.to_string([](auto n) { return n.name().unescape(); }) << "\n";
for(auto output : fir.all_outputs())
std::cout << RTLIL::unescape_id(output->kind) << " " << RTLIL::unescape_id(output->name) << " = " << RTLIL::unescape_id(output->value().name()) << "\n";
std::cout << output->kind.unescape() << " " << output->name.unescape() << " = " << output->value().name().unescape() << "\n";
for(auto state : fir.all_states())
std::cout << RTLIL::unescape_id(state->kind) << " " << RTLIL::unescape_id(state->name) << " = " << RTLIL::unescape_id(state->next_value().name()) << "\n";
std::cout << state->kind.unescape() << " " << state->name.unescape() << " = " << state->next_value().name().unescape() << "\n";
}
}
} FunctionalCxxBackend;

View file

@ -0,0 +1,3 @@
yosys_backend(intersynth
intersynth.cc
)

View file

@ -1,3 +0,0 @@
OBJS += backends/intersynth/intersynth.o

View file

@ -41,7 +41,7 @@ static std::string netname(std::set<std::string> &conntypes_code, std::set<std::
return stringf("CONST_%d_0x%x", sig.size(), sig.as_int());
}
return RTLIL::unescape_id(sig.as_wire()->name);
return sig.as_wire()->name.unescape();
}
struct IntersynthBackend : public Backend {
@ -133,26 +133,26 @@ struct IntersynthBackend : public Backend {
if (selected && !design->selected_whole_module(module->name)) {
if (design->selected_module(module->name))
log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name));
log_cmd_error("Can't handle partially selected module %s!\n", module->name.unescape());
continue;
}
log("Generating netlist %s.\n", log_id(module->name));
log("Generating netlist %s.\n", module->name.unescape());
if (module->memories.size() != 0 || module->processes.size() != 0)
log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n");
std::set<std::string> constcells_code;
netlists_code += stringf("# Netlist of module %s\n", log_id(module->name));
netlists_code += stringf("netlist %s\n", log_id(module->name));
netlists_code += stringf("# Netlist of module %s\n", module->name.unescape());
netlists_code += stringf("netlist %s\n", module->name.unescape());
// Module Ports: "std::set<string> celltypes_code" prevents duplicate top level ports
for (auto wire : module->wires()) {
if (wire->port_input || wire->port_output) {
celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n",
log_id(wire->name), wire->width, wire->port_input ? "*" : "",
wire->port_input ? "input" : "output", log_id(wire->name), wire->width, log_id(wire->name)));
netlists_code += stringf("node %s %s PORT %s\n", log_id(wire->name), log_id(wire->name),
wire->name.unescape(), wire->width, wire->port_input ? "*" : "",
wire->port_input ? "input" : "output", wire->name.unescape(), wire->width, wire->name.unescape()));
netlists_code += stringf("node %s %s PORT %s\n", wire->name.unescape(), wire->name.unescape(),
netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str());
}
}
@ -163,26 +163,26 @@ struct IntersynthBackend : public Backend {
std::string celltype_code, node_code;
if (!ct.cell_known(cell->type))
log_error("Found unknown cell type %s in module!\n", log_id(cell->type));
log_error("Found unknown cell type %s in module!\n", cell->type.unescape());
celltype_code = stringf("celltype %s", log_id(cell->type));
node_code = stringf("node %s %s", log_id(cell->name), log_id(cell->type));
celltype_code = stringf("celltype %s", cell->type.unescape());
node_code = stringf("node %s %s", cell->name.unescape(), cell->type.unescape());
for (auto &port : cell->connections()) {
RTLIL::SigSpec sig = sigmap(port.second);
if (sig.size() != 0) {
conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first));
node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig));
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", port.first.unescape());
node_code += stringf(" %s %s", port.first.unescape(), netname(conntypes_code, celltypes_code, constcells_code, sig));
}
}
for (auto &param : cell->parameters) {
celltype_code += stringf(" cfg:%d %s", int(param.second.size()), log_id(param.first));
celltype_code += stringf(" cfg:%d %s", int(param.second.size()), param.first.unescape());
if (param.second.size() != 32) {
node_code += stringf(" %s '", log_id(param.first));
node_code += stringf(" %s '", param.first.unescape());
for (int i = param.second.size()-1; i >= 0; i--)
node_code += param.second[i] == State::S1 ? "1" : "0";
} else
node_code += stringf(" %s 0x%x", log_id(param.first), param.second.as_int());
node_code += stringf(" %s 0x%x", param.first.unescape(), param.second.as_int());
}
celltypes_code.insert(celltype_code + "\n");

View file

@ -0,0 +1,5 @@
yosys_backend(jny
jny.cc
PROVIDES
jny
)

View file

@ -1,2 +0,0 @@
OBJS += backends/jny/jny.o

View file

@ -91,7 +91,7 @@ struct JnyWriter
{
_cells.clear();
for (auto cell : mod->cells()) {
const auto cell_type = escape_string(RTLIL::unescape_id(cell->type));
const auto cell_type = escape_string(cell->type.unescape());
if (_cells.find(cell_type) == _cells.end())
_cells.emplace(cell_type, std::vector<Cell*>());
@ -214,7 +214,7 @@ struct JnyWriter
void write_cell_conn(const std::pair<RTLIL::IdString, RTLIL::SigSpec>& sig, uint16_t indent_level = 0) {
const auto _indent = gen_indent(indent_level);
f << _indent << " {\n";
f << _indent << " \"name\": \"" << escape_string(RTLIL::unescape_id(sig.first)) << "\",\n";
f << _indent << " \"name\": \"" << escape_string(sig.first.unescape()) << "\",\n";
f << _indent << " \"signals\": [\n";
write_sigspec(sig.second, indent_level + 2);
@ -232,7 +232,7 @@ struct JnyWriter
const auto _indent = gen_indent(indent_level);
f << _indent << "{\n";
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(mod->name)));
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(mod->name.unescape()));
f << _indent << " \"cell_sorts\": [\n";
bool first_sort{true};
@ -275,12 +275,12 @@ struct JnyWriter
const auto _indent = gen_indent(indent_level);
bool first_port{true};
for (auto con : port_cell->connections()) {
for (auto& con : port_cell->connections()) {
if (!first_port)
f << ",\n";
f << _indent << " {\n";
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(con.first)));
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(con.first.unescape()));
f << _indent << " \"direction\": \"";
if (port_cell->input(con.first))
f << "i";
@ -351,10 +351,10 @@ struct JnyWriter
f << stringf(",\n");
const auto param_val = param.second;
if (!param_val.empty()) {
f << stringf(" %s\"%s\": ", _indent, escape_string(RTLIL::unescape_id(param.first)));
f << stringf(" %s\"%s\": ", _indent, escape_string(param.first.unescape()));
write_param_val(param_val);
} else {
f << stringf(" %s\"%s\": true", _indent, escape_string(RTLIL::unescape_id(param.first)));
f << stringf(" %s\"%s\": true", _indent, escape_string(param.first.unescape()));
}
first_param = false;
@ -366,7 +366,7 @@ struct JnyWriter
log_assert(cell != nullptr);
f << _indent << " {\n";
f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(RTLIL::unescape_id(cell->name)));
f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(cell->name.unescape()));
if (_include_connections) {
f << ",\n" << _indent << " \"connections\": [\n";

View file

@ -0,0 +1,5 @@
yosys_backend(json
json.cc
PROVIDES
json
)

View file

@ -1,3 +0,0 @@
OBJS += backends/json/json.o

View file

@ -76,7 +76,7 @@ struct JsonWriter
string get_name(IdString name)
{
return get_string(RTLIL::unescape_id(name));
return get_string(name.unescape());
}
string get_bits(SigSpec sig)
@ -152,7 +152,7 @@ struct JsonWriter
sigidcounter = 2;
if (module->has_processes()) {
log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", log_id(module));
log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", module);
}
f << stringf(" %s: {\n", get_name(module->name));
@ -316,13 +316,13 @@ struct JsonWriter
f << stringf(" /* %3d */ [ ", node_idx);
if (node.portbit >= 0)
f << stringf("\"%sport\", \"%s\", %d", node.inverter ? "n" : "",
log_id(node.portname), node.portbit);
node.portname.unescape(), node.portbit);
else if (node.left_parent < 0 && node.right_parent < 0)
f << stringf("\"%s\"", node.inverter ? "true" : "false");
else
f << stringf("\"%s\", %d, %d", node.inverter ? "nand" : "and", node.left_parent, node.right_parent);
for (auto &op : node.outports)
f << stringf(", \"%s\", %d", log_id(op.first), op.second);
f << stringf(", \"%s\", %d", op.first.unescape(), op.second);
f << stringf(" ]");
node_idx++;
}

View file

@ -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
)

View file

@ -1,3 +0,0 @@
OBJS += backends/rtlil/rtlil_backend.o

View file

@ -0,0 +1,3 @@
yosys_backend(simplec
simplec.cc
)

View file

@ -1,3 +0,0 @@
OBJS += backends/simplec/simplec.o

View file

@ -78,7 +78,7 @@ struct HierDirtyFlags
for (Cell *cell : module->cells()) {
Module *mod = module->design->module(cell->type);
if (mod) children[cell->name] = new HierDirtyFlags(mod, cell->name, this,
prefix + cid(cell->name) + ".", log_prefix + "." + prefix + log_id(cell->name));
prefix + cid(cell->name) + ".", log_prefix + "." + prefix + cell->name.unescape());
}
}
@ -354,23 +354,23 @@ struct SimplecWorker
struct_declarations.push_back(" // Input Ports");
for (Wire *w : mod->wires())
if (w->port_input)
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), w));
struct_declarations.push_back("");
struct_declarations.push_back(" // Output Ports");
for (Wire *w : mod->wires())
if (!w->port_input && w->port_output)
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), w));
struct_declarations.push_back("");
struct_declarations.push_back(" // Internal Wires");
for (Wire *w : mod->wires())
if (!w->port_input && !w->port_output)
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), w));
for (Cell *c : mod->cells())
if (design->module(c->type))
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type), cid(c->name), log_id(c)));
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type), cid(c->name), c));
struct_declarations.push_back(stringf("};"));
struct_declarations.push_back("#endif");
@ -391,7 +391,7 @@ struct SimplecWorker
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", log_id(cell), log_id(cell->type)));
stringf(" // %s (%s)", cell, cell->type.unescape()));
work->set_dirty(y);
return;
@ -418,7 +418,7 @@ struct SimplecWorker
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", log_id(cell), log_id(cell->type)));
stringf(" // %s (%s)", cell, cell->type.unescape()));
work->set_dirty(y);
return;
@ -441,7 +441,7 @@ struct SimplecWorker
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", log_id(cell), log_id(cell->type)));
stringf(" // %s (%s)", cell, cell->type.unescape()));
work->set_dirty(y);
return;
@ -466,7 +466,7 @@ struct SimplecWorker
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", log_id(cell), log_id(cell->type)));
stringf(" // %s (%s)", cell, cell->type.unescape()));
work->set_dirty(y);
return;
@ -490,13 +490,13 @@ struct SimplecWorker
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
stringf(" // %s (%s)", log_id(cell), log_id(cell->type)));
stringf(" // %s (%s)", cell, cell->type.unescape()));
work->set_dirty(y);
return;
}
log_error("No C model for %s available at the moment (FIXME).\n", log_id(cell->type));
log_error("No C model for %s available at the moment (FIXME).\n", cell->type.unescape());
}
void eval_dirty(HierDirtyFlags *work)
@ -517,7 +517,7 @@ struct SimplecWorker
if (chunk.wire == nullptr)
continue;
if (verbose)
log(" Propagating %s.%s[%d:%d].\n", work->log_prefix, log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
log(" Propagating %s.%s[%d:%d].\n", work->log_prefix, chunk.wire, chunk.offset+chunk.width-1, chunk.offset);
funct_declarations.push_back(stringf(" // Updated signal in %s: %s", work->log_prefix, log_signal(chunk)));
}
@ -539,8 +539,8 @@ struct SimplecWorker
work->parent->set_dirty(parent_bit);
if (verbose)
log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset,
work->parent->log_prefix.c_str(), log_id(parent_bit.wire), parent_bit.offset);
log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix, bit.wire, bit.offset,
work->parent->log_prefix.c_str(), parent_bit.wire, parent_bit.offset);
}
for (auto &port : bit2cell[work->module][bit])
@ -556,12 +556,12 @@ struct SimplecWorker
child->set_dirty(child_bit);
if (verbose)
log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset,
work->log_prefix.c_str(), log_id(std::get<0>(port)), log_id(child_bit.wire), child_bit.offset);
log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix, bit.wire, bit.offset,
work->log_prefix.c_str(), std::get<0>(port), child_bit.wire, child_bit.offset);
} else {
if (verbose)
log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix, log_id(std::get<0>(port)),
work->log_prefix.c_str(), log_id(bit.wire), bit.offset);
log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix, std::get<0>(port),
work->log_prefix.c_str(), bit.wire, bit.offset);
work->set_dirty(std::get<0>(port));
}
}
@ -576,10 +576,10 @@ struct SimplecWorker
if (cell == nullptr || topoidx.at(cell) < topoidx.at(c))
cell = c;
string hiername = work->log_prefix + "." + log_id(cell);
string hiername = work->log_prefix + "." + cell->name.unescape();
if (verbose)
log(" Evaluating %s (%s, best of %d).\n", hiername, log_id(cell->type), GetSize(work->dirty_cells));
log(" Evaluating %s (%s, best of %d).\n", hiername, cell->type.unescape(), GetSize(work->dirty_cells));
if (activated_cells.count(hiername))
reactivated_cells.insert(hiername);
@ -618,8 +618,8 @@ struct SimplecWorker
if (verbose)
log(" Propagating alias %s.%s[%d] -> %s.%s[%d].\n",
work->log_prefix.c_str(), log_id(canonical_bit.wire), canonical_bit.offset,
work->log_prefix.c_str(), log_id(bit.wire), bit.offset);
work->log_prefix.c_str(), canonical_bit.wire, canonical_bit.offset,
work->log_prefix.c_str(), bit.wire, bit.offset);
}
work->sticky_dirty_bits.clear();
@ -716,7 +716,7 @@ struct SimplecWorker
{
create_module_struct(mod);
HierDirtyFlags work(mod, IdString(), nullptr, "state->", log_id(mod->name));
HierDirtyFlags work(mod, IdString(), nullptr, "state->", mod->name.unescape());
make_init_func(&work);
make_eval_func(&work);

View file

@ -11,4 +11,3 @@ endmodule
module unit_y(input [31:0] a, b, c, output [31:0] y);
assign y = a & (b | c);
endmodule

View file

@ -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
)

View file

@ -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

View file

@ -60,7 +60,7 @@ struct Smt2Worker
const char *get_id(IdString n)
{
if (ids.count(n) == 0) {
std::string str = log_id(n);
std::string str = n.unescape();
for (int i = 0; i < GetSize(str); i++) {
if (str[i] == '\\')
str[i] = '/';
@ -207,7 +207,7 @@ struct Smt2Worker
}
else if (is_output || !is_input)
log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n",
log_id(conn.first), log_id(module), log_id(cell), log_id(cell->type));
conn.first.unescape(), module, cell, cell->type.unescape());
if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && conn.first.in(ID::CLK, ID::C))
{
@ -448,7 +448,7 @@ struct Smt2Worker
}
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell);
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool %s) ; %s\n",
get_id(module), idcounter, get_id(module), processed_expr.c_str(), log_signal(bit)));
@ -498,7 +498,7 @@ struct Smt2Worker
processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr);
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell);
if (type == 'b') {
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool %s) ; %s\n",
@ -529,7 +529,7 @@ struct Smt2Worker
processed_expr += ch;
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell);
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool %s) ; %s\n",
get_id(module), idcounter, get_id(module), processed_expr.c_str(), log_signal(sig_y)));
@ -541,7 +541,7 @@ struct Smt2Worker
{
if (verbose)
log("%*s=> export_cell %s (%s) [%s]\n", 2+2*GetSize(recursive_cells), "",
log_id(cell), log_id(cell->type), exported_cells.count(cell) ? "old" : "new");
cell, cell->type.unescape(), exported_cells.count(cell) ? "old" : "new");
if (recursive_cells.count(cell))
log_error("Found logic loop in module %s! See cell %s.\n", get_id(module), get_id(cell));
@ -750,7 +750,7 @@ struct Smt2Worker
get_bv(sig_b.extract(i*width, width)).c_str(), processed_expr.c_str());
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", cell);
RTLIL::SigSpec sig = sigmap(cell->getPort(ID::Y));
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
@ -786,7 +786,7 @@ struct Smt2Worker
has_async_wr = true;
}
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", log_id(cell), log_id(module));
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", 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));
@ -813,7 +813,7 @@ struct Smt2Worker
if (port.clk_enable)
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), log_id(mem->memid), log_id(module));
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), mem->memid.unescape(), module);
decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig)));
@ -857,7 +857,7 @@ struct Smt2Worker
if (port.clk_enable)
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), log_id(mem->memid), log_id(module));
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), mem->memid.unescape(), module);
decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig)));
@ -928,30 +928,30 @@ struct Smt2Worker
if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smt2`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type, module, cell);
}
log_error("Unsupported cell type %s for cell %s.%s.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type, module, cell);
}
void verify_smtlib2_module()
{
if (!module->get_blackbox_attribute())
log_error("Module %s with smtlib2_module attribute must also have blackbox attribute.\n", log_id(module));
log_error("Module %s with smtlib2_module attribute must also have blackbox attribute.\n", module);
if (module->cells().size() > 0)
log_error("Module %s with smtlib2_module attribute must not have any cells inside it.\n", log_id(module));
log_error("Module %s with smtlib2_module attribute must not have any cells inside it.\n", module);
for (auto wire : module->wires())
if (!wire->port_id)
log_error("Wire %s.%s must be input or output since module has smtlib2_module attribute.\n", log_id(module),
log_id(wire));
log_error("Wire %s.%s must be input or output since module has smtlib2_module attribute.\n", module,
wire);
}
void run()
@ -991,8 +991,8 @@ struct Smt2Worker
}
bool is_smtlib2_comb_expr = wire->has_attribute(ID::smtlib2_comb_expr);
if (is_smtlib2_comb_expr && !is_smtlib2_module)
log_error("smtlib2_comb_expr is only valid in a module with the smtlib2_module attribute: wire %s.%s", log_id(module),
log_id(wire));
log_error("smtlib2_comb_expr is only valid in a module with the smtlib2_module attribute: wire %s.%s", module,
wire);
if (wire->port_id || is_register || contains_clock || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) {
RTLIL::SigSpec sig = sigmap(wire);
std::vector<std::string> comments;
@ -1023,10 +1023,10 @@ struct Smt2Worker
smtlib2_comb_expr =
"(let (\n" + smtlib2_inputs + ")\n" + wire->get_string_attribute(ID::smtlib2_comb_expr) + "\n)";
if (wire->port_input || !wire->port_output)
log_error("smtlib2_comb_expr is only valid on output: wire %s.%s", log_id(module), log_id(wire));
log_error("smtlib2_comb_expr is only valid on output: wire %s.%s", module, wire);
if (!bvmode && GetSize(sig) > 1)
log_error("smtlib2_comb_expr is unsupported on multi-bit wires when -nobv is specified: wire %s.%s",
log_id(module), log_id(wire));
module, wire);
comments.push_back(witness_signal("blackbox", wire->width, 0, get_id(wire), -1, wire));
}
@ -1075,7 +1075,7 @@ struct Smt2Worker
if (wire->attributes.count(ID::init)) {
if (is_smtlib2_module)
log_error("init attribute not allowed on wires in module with smtlib2_module attribute: wire %s.%s",
log_id(module), log_id(wire));
module, wire);
RTLIL::SigSpec sig = sigmap(wire);
Const val = wire->attributes.at(ID::init);
@ -1381,7 +1381,7 @@ struct Smt2Worker
}
}
if (verbose) log("=> finalizing SMT2 representation of %s.\n", log_id(module));
if (verbose) log("=> finalizing SMT2 representation of %s.\n", module);
for (auto c : hiercells) {
assert_list.push_back(stringf("(|%s_a| (|%s_h %s| state))", get_id(c->type), get_id(module), get_id(c->name)));
@ -1867,12 +1867,12 @@ struct Smt2Backend : public Backend {
for (auto &dep : it.second)
if (module_deps.count(dep) > 0)
goto not_ready_yet;
// log("Next in topological sort: %s\n", log_id(it.first->name));
// log("Next in topological sort: %s\n", it.first->name.unescape());
sorted_modules.push_back(it.first);
not_ready_yet:;
}
if (sorted_modules_idx == sorted_modules.size())
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", module_deps.begin()->first->name.unescape());
while (sorted_modules_idx < sorted_modules.size())
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
}
@ -1902,7 +1902,7 @@ struct Smt2Backend : public Backend {
if (module->has_processes_warn())
continue;
log("Creating SMT-LIBv2 representation of module %s.\n", log_id(module));
log("Creating SMT-LIBv2 representation of module %s.\n", module);
Smt2Worker worker(module, bvmode, memmode, wiresmode, verbose, statebv, statedt, forallmode, mod_stbv_width, mod_clk_cache);
worker.run();

4
backends/smt2/smtbmc.py Normal file → Executable file
View file

@ -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

View file

@ -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)]

View file

@ -52,4 +52,3 @@ echo ""
echo " All tests passed."
echo ""
exit 0

8
backends/smt2/witness.py Normal file → Executable file
View file

@ -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":

View file

@ -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

View file

@ -0,0 +1,7 @@
yosys_backend(smv
smv.cc
REQUIRES
bmuxmap
demuxmap
bwmuxmap
)

View file

@ -1,3 +0,0 @@
OBJS += backends/smv/smv.o

View file

@ -217,7 +217,7 @@ struct SmvWorker
partial_assignment_wires.insert(wire);
if (wire->port_input)
inputvars.push_back(stringf("%s : unsigned word[%d]; -- %s", cid(wire->name), wire->width, log_id(wire)));
inputvars.push_back(stringf("%s : unsigned word[%d]; -- %s", cid(wire->name), wire->width, wire));
if (wire->attributes.count(ID::init))
assignments.push_back(stringf("init(%s) := %s;", lvalue(wire), rvalue(wire->attributes.at(ID::init))));
@ -579,18 +579,18 @@ struct SmvWorker
if (cell->type[0] == '$') {
if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
if (cell->type.in(ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF" || cell->type.str().substr(0, 7) == "$_ALDFF") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smv`.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
log_error("Unsupported cell type %s for cell %s.%s.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
}
// f << stringf(" %s : %s;\n", cid(cell->name), cid(cell->type));
@ -799,7 +799,7 @@ struct SmvBackend : public Backend {
*f << stringf("-- SMV description generated by %s\n", yosys_maybe_version());
log("Creating SMV representation of module %s.\n", log_id(module));
log("Creating SMV representation of module %s.\n", module);
SmvWorker worker(module, verbose, *f);
worker.run();
@ -819,7 +819,7 @@ struct SmvBackend : public Backend {
*f << stringf("-- SMV description generated by %s\n", yosys_maybe_version());
for (auto module : modules) {
log("Creating SMV representation of module %s.\n", log_id(module));
log("Creating SMV representation of module %s.\n", module);
SmvWorker worker(module, verbose, *f);
worker.run();
}

View file

@ -30,4 +30,3 @@ for fn in test_*.il; do
done
grep '^-- invariant .* is false' *.out || echo 'All OK.'

View file

@ -0,0 +1,3 @@
yosys_backend(spice
spice.cc
)

View file

@ -1,3 +0,0 @@
OBJS += backends/spice/spice.o

View file

@ -30,7 +30,7 @@ PRIVATE_NAMESPACE_BEGIN
static string spice_id2str(IdString id)
{
static const char *escape_chars = "$\\[]()<>=";
string s = RTLIL::unescape_id(id);
string s = id.unescape();
for (auto &ch : s)
if (strchr(escape_chars, ch) != nullptr) ch = '_';
@ -82,7 +82,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
if (design->module(cell->type) == nullptr)
{
log_warning("no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n",
log_id(cell->type), log_id(module), log_id(cell));
cell->type.unescape(), module, cell);
for (auto &conn : cell->connections()) {
RTLIL::SigSpec sig = sigmap(conn.second);
port_sigs.push_back(sig);
@ -224,9 +224,9 @@ struct SpiceBackend : public Backend {
continue;
if (module->processes.size() != 0)
log_error("Found unmapped processes in module %s: unmapped processes are not supported in SPICE backend!\n", log_id(module));
log_error("Found unmapped processes in module %s: unmapped processes are not supported in SPICE backend!\n", module);
if (module->memories.size() != 0)
log_error("Found unmapped memories in module %s: unmapped memories are not supported in SPICE backend!\n", log_id(module));
log_error("Found unmapped memories in module %s: unmapped memories are not supported in SPICE backend!\n", module);
if (module->name == RTLIL::escape_id(top_module_name)) {
top_module = module;

View file

@ -0,0 +1,3 @@
yosys_backend(table
table.cc
)

View file

@ -1,3 +0,0 @@
OBJS += backends/table/table.o

View file

@ -77,8 +77,8 @@ struct TableBackend : public Backend {
if (wire->port_id == 0)
continue;
*f << log_id(module) << "\t";
*f << log_id(wire) << "\t";
*f << module->name.unescape() << "\t";
*f << wire->name.unescape() << "\t";
*f << "-" << "\t";
*f << "-" << "\t";
@ -97,10 +97,10 @@ struct TableBackend : public Backend {
for (auto cell : module->cells())
for (auto conn : cell->connections())
{
*f << log_id(module) << "\t";
*f << log_id(cell) << "\t";
*f << log_id(cell->type) << "\t";
*f << log_id(conn.first) << "\t";
*f << module->name.unescape() << "\t";
*f << cell->name.unescape() << "\t";
*f << cell->type.unescape() << "\t";
*f << conn.first.unescape() << "\t";
if (cell->input(conn.first) && cell->output(conn.first))
*f << "inout" << "\t";

View file

@ -0,0 +1,8 @@
yosys_backend(verilog
verilog_backend.cc
verilog_backend.h
REQUIRES
bmuxmap
demuxmap
clean_zerowidth
)

View file

@ -1,3 +0,0 @@
OBJS += backends/verilog/verilog_backend.o

View file

@ -38,7 +38,7 @@ USING_YOSYS_NAMESPACE
using namespace VERILOG_BACKEND;
const pool<string> VERILOG_BACKEND::verilog_keywords() {
const pool<string> &VERILOG_BACKEND::verilog_keywords() {
static const pool<string> 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 &reg_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
}
@ -2388,7 +2397,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
log_warning("Module %s contains RTLIL processes with sync rules. Such RTLIL "
"processes can't always be mapped directly to Verilog always blocks. "
"unintended changes in simulation behavior are possible! Use \"proc\" "
"to convert processes to logic networks and registers.\n", log_id(module));
"to convert processes to logic networks and registers.\n", module);
f << stringf("\n");
for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
@ -2714,7 +2723,7 @@ struct VerilogBackend : public Backend {
continue;
if (selected && !design->selected_whole_module(module->name)) {
if (design->selected_module(module->name))
log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name));
log_cmd_error("Can't handle partially selected module %s!\n", module->name.unescape());
continue;
}
log("Dumping module `%s'.\n", module->name);

View file

@ -29,7 +29,7 @@
YOSYS_NAMESPACE_BEGIN
namespace VERILOG_BACKEND {
const pool<string> verilog_keywords();
const pool<string> &verilog_keywords();
bool char_is_verilog_escaped(char c);
bool id_is_verilog_escaped(const std::string &str);

View file

@ -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 <pthread.h>
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()

Some files were not shown because too many files have changed in this diff Show more