Merge branch 'main' into nella/latch-toggle

This commit is contained in:
nella 2026-07-08 11:41:08 +02:00 committed by GitHub
commit f5809a7c2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
675 changed files with 10003 additions and 8149 deletions

View File

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

View File

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

View File

@ -33,21 +33,21 @@ runs:
# and docs/source/getting_started/installation.rst to match. # and docs/source/getting_started/installation.rst to match.
- name: Linux common dependencies - name: Linux common dependencies
if: runner.os == 'Linux' if: runner.os == 'Linux'
uses: awalsh128/cache-apt-pkgs-action@v1.6.0 uses: awalsh128/cache-apt-pkgs-action@v1.6.1
with: with:
packages: gawk git make python3 packages: gawk git make python3
version: ${{ inputs.runs-on }}-commonys version: ${{ inputs.runs-on }}-commonys
- name: Linux build dependencies - name: Linux build dependencies
if: runner.os == 'Linux' && inputs.get-build-deps == 'true' 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: with:
packages: bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libgtest-dev libgmock-dev packages: bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libgtest-dev libgmock-dev
version: ${{ inputs.runs-on }}-buildys version: ${{ inputs.runs-on }}-buildys
- name: Linux docs dependencies - name: Linux docs dependencies
if: runner.os == 'Linux' && inputs.get-docs-deps == 'true' 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: with:
packages: graphviz xdot packages: graphviz xdot
version: ${{ inputs.runs-on }}-docsys version: ${{ inputs.runs-on }}-docsys
@ -56,7 +56,7 @@ runs:
if: runner.os == 'macOS' if: runner.os == 'macOS'
shell: bash shell: bash
run: | run: |
brew bundle brew install bison flex gawk libffi git pkg-config python3 bash googletest tcl-tk llvm
- name: Linux runtime environment - name: Linux runtime environment
if: runner.os == 'Linux' if: runner.os == 'Linux'
@ -70,7 +70,7 @@ runs:
shell: bash shell: bash
run: | run: |
echo "${{ github.workspace }}/.local/bin" >> $GITHUB_PATH 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 bison)/bin" >> $GITHUB_PATH
echo "$(brew --prefix flex)/bin" >> $GITHUB_PATH echo "$(brew --prefix flex)/bin" >> $GITHUB_PATH
echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV

View File

@ -11,7 +11,7 @@ runs:
steps: steps:
- name: iverilog Linux deps - name: iverilog Linux deps
if: steps.restore-iverilog.outputs.cache-hit != 'true' && runner.os == 'Linux' 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: with:
packages: autoconf gperf make gcc g++ bison flex libbz2-dev packages: autoconf gperf make gcc g++ bison flex libbz2-dev
version: ${{ inputs.runs-on }}-iverilog version: ${{ inputs.runs-on }}-iverilog
@ -40,7 +40,7 @@ runs:
make -j$procs make -j$procs
make install make install
- uses: actions/cache/restore@v4 - uses: actions/cache/restore@v6
id: restore-iverilog id: restore-iverilog
with: with:
path: .local/ path: .local/
@ -62,7 +62,7 @@ runs:
run: | run: |
iverilog -V iverilog -V
- uses: actions/cache/save@v4 - uses: actions/cache/save@v6
id: save-iverilog id: save-iverilog
if: steps.restore-iverilog.outputs.cache-hit != 'true' if: steps.restore-iverilog.outputs.cache-hit != 'true'
with: with:

View File

@ -3,7 +3,7 @@ name: "CodeQL"
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 3 * * *' - cron: '0 3 * * 6'
jobs: jobs:
analyze: analyze:
@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false

View File

@ -3,8 +3,8 @@ name: Test extra build flows
on: on:
pull_request: pull_request:
merge_group: merge_group:
#push: push:
# branches: [ main ] branches: [ main ]
workflow_dispatch: workflow_dispatch:
jobs: jobs:
@ -15,7 +15,7 @@ jobs:
steps: steps:
- id: skip_check - id: skip_check
if: ${{ github.event_name != 'merge_group' }} if: ${{ github.event_name != 'merge_group' }}
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
# don't run on documentation changes # don't run on documentation changes
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
@ -27,6 +27,8 @@ jobs:
run: | run: |
if [ "${{ github.event_name }}" = "merge_group" ]; then if [ "${{ github.event_name }}" = "merge_group" ]; then
echo "should_skip=false" >> $GITHUB_OUTPUT echo "should_skip=false" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" = "push" ]; then
should_skip=false
else else
echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT
fi fi
@ -35,15 +37,25 @@ jobs:
name: Visual Studio build name: Visual Studio build
runs-on: windows-latest runs-on: windows-latest
needs: [pre_job] 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'
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false
- name: Setup MSVC - name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1 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 - name: Install flex/bison
shell: pwsh shell: pwsh
@ -57,8 +69,9 @@ jobs:
- name: Configure CMake - name: Configure CMake
run: > run: >
cmake -S . -B build cmake -S . -B build
-A x64 -G Ninja
-DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=Release
-DYOSYS_COMPILER_LAUNCHER=ccache
- name: Build - name: Build
run: > run: >
@ -66,16 +79,77 @@ jobs:
--config Release --config Release
--parallel --parallel
wasi-build: mingw-build:
name: WASI build name: MINGW64 build
needs: pre_job runs-on: windows-latest
if: (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true' needs: [pre_job]
runs-on: ubuntu-latest if: (github.event_name == 'push' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true'
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false 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 == '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@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 - name: Build
run: | run: |
WASI_VER=33 WASI_VER=33
@ -95,34 +169,15 @@ jobs:
make install) make install)
export PATH=${WASI_SDK_PATH}/bin:$(pwd)/flex-prefix/bin:${PATH} 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 . 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) cmake --build build -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
extra-builds-result: extra-builds-result:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- vs-build - vs-build
- mingw-build
- wasi-build - wasi-build
- nix-build
if: always() if: always()
steps: steps:
- name: Check results - 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/') }} docs_export: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/docs-preview') || startsWith(github.ref, 'refs/tags/') }}
steps: steps:
- id: skip_check - id: skip_check
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
paths_ignore: '["**/README.md"]' paths_ignore: '["**/README.md"]'
# don't cancel in case we're updating docs # don't cancel in case we're updating docs
@ -46,7 +46,7 @@ jobs:
runs-on: [self-hosted, linux, x64, fast] runs-on: [self-hosted, linux, x64, fast]
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v4 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
submodules: true submodules: true
@ -72,7 +72,7 @@ jobs:
cmake --build build --target docs-prepare -j$procs cmake --build build --target docs-prepare -j$procs
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: cmd-ref-${{ github.sha }} name: cmd-ref-${{ github.sha }}
path: | path: |

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository with submodules - name: Checkout repository with submodules
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
submodules: 'recursive' submodules: 'recursive'
persist-credentials: false persist-credentials: false

View File

@ -3,8 +3,8 @@ name: Build and run tests
on: on:
pull_request: pull_request:
merge_group: merge_group:
#push: push:
# branches: [ main ] branches: [ main ]
workflow_dispatch: workflow_dispatch:
jobs: jobs:
@ -15,7 +15,7 @@ jobs:
steps: steps:
- id: skip_check - id: skip_check
if: ${{ github.event_name != 'merge_group' }} if: ${{ github.event_name != 'merge_group' }}
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
# don't run on documentation changes # don't run on documentation changes
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
@ -26,7 +26,7 @@ jobs:
- id: set_output - id: set_output
run: | run: |
if [ "${{ github.event_name }}" = "merge_group" ]; then if [ "${{ github.event_name }}" = "merge_group" ]; then
echo "should_skip=false" >> $GITHUB_OUTPUT echo "should_skip=true" >> $GITHUB_OUTPUT
else else
echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT
fi fi
@ -38,7 +38,7 @@ jobs:
steps: steps:
- id: skip_check - id: skip_check
if: ${{ github.event_name != 'merge_group' }} if: ${{ github.event_name != 'merge_group' }}
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
# don't run on readme changes # don't run on readme changes
paths_ignore: '["**/README.md"]' paths_ignore: '["**/README.md"]'
@ -49,7 +49,9 @@ jobs:
- id: set_output - id: set_output
run: | run: |
if [ "${{ github.event_name }}" = "merge_group" ]; then 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 else
echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT
fi fi
@ -68,7 +70,7 @@ jobs:
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false
@ -79,11 +81,19 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
get-build-deps: true 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 - name: Build
shell: bash shell: bash
run: | run: |
rm -rf build rm -rf build
cmake -B build . -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release cmake -B build . -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DYOSYS_COMPILER_LAUNCHER=ccache
cmake --build build -j$procs cmake --build build -j$procs
ctest --test-dir build/tests/unit ctest --test-dir build/tests/unit
@ -108,7 +118,7 @@ jobs:
name: Run tests name: Run tests
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [build-yosys, pre_job] 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: env:
CC: clang CC: clang
strategy: strategy:
@ -117,7 +127,7 @@ jobs:
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
@ -158,7 +168,7 @@ jobs:
name: Run test_cell name: Run test_cell
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [build-yosys, pre_job] 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: env:
CC: clang CC: clang
strategy: strategy:
@ -166,7 +176,7 @@ jobs:
os: [ubuntu-latest] os: [ubuntu-latest]
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
@ -197,14 +207,14 @@ jobs:
name: Run docs tests name: Run docs tests
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [build-yosys, pre_docs_job] needs: [build-yosys, pre_docs_job]
if: needs.pre_docs_job.outputs.should_skip != 'true' if: github.event_name != 'push' && needs.pre_job.outputs.should_skip != 'true'
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest] os: [ubuntu-latest]
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
@ -239,14 +249,14 @@ jobs:
name: Try build docs name: Try build docs
runs-on: [self-hosted, linux, x64, fast] runs-on: [self-hosted, linux, x64, fast]
needs: [pre_docs_job] 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: strategy:
matrix: matrix:
docs-target: [html, latexpdf] docs-target: [html, latexpdf]
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v4 uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false
@ -276,7 +286,7 @@ jobs:
cmake --build build --target docs-${{ matrix.docs-target }} -j$procs cmake --build build --target docs-${{ matrix.docs-target }} -j$procs
- name: Store docs build artifact - name: Store docs build artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: docs-build-${{ matrix.docs-target }} name: docs-build-${{ matrix.docs-target }}
path: docs/build/ path: docs/build/

View File

@ -3,8 +3,8 @@ name: Compiler testing
on: on:
pull_request: pull_request:
merge_group: merge_group:
#push: push:
# branches: [ main ] branches: [ main ]
workflow_dispatch: workflow_dispatch:
jobs: jobs:
@ -15,7 +15,7 @@ jobs:
steps: steps:
- id: skip_check - id: skip_check
if: ${{ github.event_name != 'merge_group' }} if: ${{ github.event_name != 'merge_group' }}
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
# don't run on documentation changes # don't run on documentation changes
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
@ -27,6 +27,8 @@ jobs:
run: | run: |
if [ "${{ github.event_name }}" = "merge_group" ]; then if [ "${{ github.event_name }}" = "merge_group" ]; then
echo "should_skip=false" >> $GITHUB_OUTPUT echo "should_skip=false" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" = "push" ]; then
should_skip=false
else else
echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT
fi fi
@ -34,7 +36,7 @@ jobs:
test-compile: test-compile:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: pre_job 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: env:
CXXFLAGS: ${{ startsWith(matrix.compiler, 'gcc') && '-Wp,-D_GLIBCXX_ASSERTIONS' || ''}} CXXFLAGS: ${{ startsWith(matrix.compiler, 'gcc') && '-Wp,-D_GLIBCXX_ASSERTIONS' || ''}}
strategy: strategy:
@ -43,22 +45,19 @@ jobs:
- ubuntu-latest - ubuntu-latest
compiler: compiler:
# oldest supported # oldest supported
- 'clang-14' - 'clang-16'
- 'gcc-11' - 'gcc-11'
# newest, make sure to update maximum standard step to match # newest, make sure to update maximum standard step to match
- 'clang-22' - 'clang-22'
- 'gcc-16' - 'gcc-16'
include: include:
# macOS x86
- os: macos-15-intel
compiler: 'clang-22'
# macOS arm # macOS arm
- os: macos-latest - os: macos-latest
compiler: 'clang-22' compiler: 'clang-22'
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false
@ -69,11 +68,18 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
get-build-deps: true 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 - name: Setup Cpp
uses: aminya/setup-cpp@v1 uses: aminya/setup-cpp@v1
with: with:
compiler: ${{ matrix.compiler }} compiler: ${{ matrix.compiler }}
gcc: ${{ (matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-14') && '12' || '' }}
- name: Tool versions - name: Tool versions
shell: bash shell: bash
@ -81,17 +87,12 @@ jobs:
$CC --version $CC --version
$CXX --version $CXX --version
- name: Fix clang-14 toolchain
if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang-14'
run: |
echo 'CXXFLAGS=--gcc-toolchain=/usr -isystem /usr/include/c++/12 -isystem /usr/include/x86_64-linux-gnu/c++/12' >> $GITHUB_ENV
# minimum standard # minimum standard
- name: Build C++20 - name: Build C++20
shell: bash shell: bash
run: | run: |
rm -rf build rm -rf build
cmake -B build -DCMAKE_CXX_STANDARD=20 . --fresh cmake -B build -DCMAKE_CXX_STANDARD=20 -DYOSYS_COMPILER_LAUNCHER=ccache . --fresh
cmake --build build --target yosys -j$procs cmake --build build --target yosys -j$procs
# maximum standard, only on newest compilers # maximum standard, only on newest compilers
@ -100,7 +101,7 @@ jobs:
shell: bash shell: bash
run: | run: |
rm -rf build rm -rf build
cmake -B build -DCMAKE_CXX_STANDARD=26 . --fresh cmake -B build -DCMAKE_CXX_STANDARD=26 -DYOSYS_COMPILER_LAUNCHER=ccache . --fresh
cmake --build build --target yosys -j$procs cmake --build build --target yosys -j$procs
test-compile-result: test-compile-result:

View File

@ -15,7 +15,7 @@ jobs:
steps: steps:
- id: skip_check - id: skip_check
if: ${{ github.event_name != 'merge_group' }} if: ${{ github.event_name != 'merge_group' }}
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
# don't run on documentation changes # don't run on documentation changes
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
@ -27,38 +27,30 @@ jobs:
run: | run: |
if [ "${{ github.event_name }}" = "merge_group" ]; then if [ "${{ github.event_name }}" = "merge_group" ]; then
echo "should_skip=false" >> $GITHUB_OUTPUT echo "should_skip=false" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" = "push" ]; then
should_skip=false
else else
echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT echo "should_skip=${{ steps.skip_check.outputs.should_skip }}" >> $GITHUB_OUTPUT
fi fi
run_san: test-sanitizers:
name: Build and run tests runs-on: [self-hosted, linux, x64, fast]
runs-on: ${{ matrix.os }}
needs: pre_job 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 == 'merge_group' || github.event_name == 'workflow_dispatch') && needs.pre_job.outputs.should_skip != 'true'
env: env:
CC: clang CC: clang
ASAN_OPTIONS: halt_on_error=1 detect_container_overflow=0 ASAN_OPTIONS: halt_on_error=1 detect_container_overflow=0
UBSAN_OPTIONS: halt_on_error=1 UBSAN_OPTIONS: halt_on_error=1
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
sanitizer: ['undefined,address']
fail-fast: false
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false
- name: Setup environment - name: Runtime environment
uses: ./.github/actions/setup-build-env run: |
with: echo "procs=$(nproc)" >> $GITHUB_ENV
runs-on: ${{ matrix.os }}
get-build-deps: true
get-test-deps: true
get-iverilog: true
- name: Build - name: Build
shell: bash shell: bash
@ -66,7 +58,8 @@ jobs:
rm -rf build rm -rf build
cmake -B build . \ cmake -B build . \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_BUILD_TYPE=Sanitize -DSANITIZE=${{ matrix.sanitizer }} -DCMAKE_BUILD_TYPE=Sanitize -DSANITIZE='undefined,address' \
-DYOSYS_COMPILER_LAUNCHER=ccache
cmake --build build -j$procs cmake --build build -j$procs
- name: Log yosys-config output - name: Log yosys-config output
@ -87,7 +80,7 @@ jobs:
test-sanitizers-result: test-sanitizers-result:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- run_san - test-sanitizers
if: always() if: always()
steps: steps:
- name: Check results - name: Check results

View File

@ -9,7 +9,7 @@ jobs:
runs-on: [self-hosted, linux, x64, fast] runs-on: [self-hosted, linux, x64, fast]
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v4 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
submodules: true submodules: true

View File

@ -15,7 +15,7 @@ jobs:
steps: steps:
- id: skip_check - id: skip_check
if: ${{ github.event_name != 'merge_group' }} if: ${{ github.event_name != 'merge_group' }}
uses: fkirc/skip-duplicate-actions@v5 uses: mmicko/skip-duplicate-actions@master
with: with:
# don't run on documentation changes # don't run on documentation changes
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]' paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
@ -37,7 +37,7 @@ jobs:
runs-on: [self-hosted, linux, x64, fast] runs-on: [self-hosted, linux, x64, fast]
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v4 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
submodules: true submodules: true
@ -70,7 +70,7 @@ jobs:
cmake --build build --target install cmake --build build --target install
- name: Checkout SBY - name: Checkout SBY
uses: actions/checkout@v4 uses: actions/checkout@v7
with: with:
repository: 'YosysHQ/sby' repository: 'YosysHQ/sby'
path: 'sby' path: 'sby'
@ -125,7 +125,7 @@ jobs:
runs-on: [self-hosted, linux, x64, fast] runs-on: [self-hosted, linux, x64, fast]
steps: steps:
- name: Checkout Yosys - name: Checkout Yosys
uses: actions/checkout@v4 uses: actions/checkout@v7
with: with:
persist-credentials: false persist-credentials: false
submodules: true submodules: true

View File

@ -47,7 +47,7 @@ jobs:
name: Build Wheels | ${{ matrix.os.name }} | ${{ matrix.os.archs }} name: Build Wheels | ${{ matrix.os.name }} | ${{ matrix.os.archs }}
runs-on: ${{ matrix.os.runner }} runs-on: ${{ matrix.os.runner }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true

15
.gitmodules vendored
View File

@ -5,3 +5,18 @@
[submodule "cxxopts"] [submodule "cxxopts"]
path = libs/cxxopts path = libs/cxxopts
url = https://github.com/jarro2783/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

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

@ -1802,4 +1802,3 @@ Yosys 0.1.0 .. Yosys 0.2.0
- Added "design -stash/-copy-from/-copy-to" - Added "design -stash/-copy-from/-copy-to"
- Added "copy" command - Added "copy" command
- Added "splice" command - Added "splice" command

View File

@ -39,6 +39,7 @@ set(CMAKE_CXX_SCAN_FOR_MODULES NO)
set(YOSYS_COMPILER_LAUNCHER "" CACHE STRING "Compiler launcher (ccache, sccache)") set(YOSYS_COMPILER_LAUNCHER "" CACHE STRING "Compiler launcher (ccache, sccache)")
option(YOSYS_ENABLE_COVERAGE "Enable code coverage" OFF) option(YOSYS_ENABLE_COVERAGE "Enable code coverage" OFF)
option(YOSYS_ENABLE_PROFILING "Enable instruction profiling" 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_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)") set(YOSYS_COMPONENTS "everything" CACHE STRING "List of components to build (use pass names)")
@ -52,6 +53,7 @@ option(YOSYS_WITHOUT_ZLIB "Disable zlib integration" OFF)
option(YOSYS_WITHOUT_LIBFFI "Disable libffi integration" OFF) option(YOSYS_WITHOUT_LIBFFI "Disable libffi integration" OFF)
option(YOSYS_WITHOUT_READLINE "Disable readline integration" OFF) option(YOSYS_WITHOUT_READLINE "Disable readline integration" OFF)
option(YOSYS_WITHOUT_EDITLINE "Disable editline 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_WITHOUT_TCL "Disable Tcl integration" OFF)
option(YOSYS_WITH_PYTHON "Enable Python integration" OFF) option(YOSYS_WITH_PYTHON "Enable Python integration" OFF)
@ -307,6 +309,7 @@ condition(YOSYS_ENABLE_EDITLINE editline_FOUND AND NOT YOSYS_WITHOUT_EDITLINE AN
condition(YOSYS_ENABLE_TCL tcl_FOUND AND libtommath_FOUND AND NOT YOSYS_WITHOUT_TCL) 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_PYTHON Python3Devel_FOUND AND PyosysEnv_FOUND AND YOSYS_WITH_PYTHON)
condition(YOSYS_ENABLE_VERIFIC YOSYS_VERIFIC_DIR AND zlib_FOUND) condition(YOSYS_ENABLE_VERIFIC YOSYS_VERIFIC_DIR AND zlib_FOUND)
condition(YOSYS_ENABLE_SLANG NOT YOSYS_WITHOUT_SLANG)
# Describe dependencies and features # Describe dependencies and features
# CMake 4.0 would let us use proper conditions, but that's too new for now. # CMake 4.0 would let us use proper conditions, but that's too new for now.
@ -534,8 +537,19 @@ if (NOT YOSYS_BUILD_PYTHON_ONLY)
add_custom_target(test-vanilla add_custom_target(test-vanilla
COMMAND make vanilla-test ${makefile_vars} COMMAND make vanilla-test ${makefile_vars}
ENABLE_FUNCTIONAL_TESTS=$<IF:$<BOOL:${YOSYS_ENABLE_FUNCTIONAL_TESTS}>,1,0>
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
DEPENDS ${makefile_depends} 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 JOB_SERVER_AWARE TRUE
) )

View File

@ -36,6 +36,7 @@ frontends/ast/ @widlarizer
techlibs/intel_alm/ @Ravenslofty techlibs/intel_alm/ @Ravenslofty
techlibs/gowin/ @pepijndevos techlibs/gowin/ @pepijndevos
techlibs/gatemate/ @pu-cc techlibs/gatemate/ @pu-cc
techlibs/fabulous/ fpga.research.group@gmail.com
# pyosys # pyosys
pyosys/* @donn pyosys/* @donn

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 extensive Verilog-2005 support and provides a basic set of
synthesis algorithms for various application domains. 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 Yosys can be adapted to perform any synthesis job by combining
the existing passes (algorithms) using synthesis scripts and the existing passes (algorithms) using synthesis scripts and
adding additional passes as needed by extending the yosys C++ adding additional passes as needed by extending the yosys C++
@ -67,13 +70,9 @@ on Read the Docs.
When cloning Yosys, some required libraries are included as git submodules. Make When cloning Yosys, some required libraries are included as git submodules. Make
sure to call e.g. sure to call e.g.
$ git clone --recurse-submodules https://github.com/YosysHQ/yosys.git
or
$ git clone https://github.com/YosysHQ/yosys.git $ git clone https://github.com/YosysHQ/yosys.git
$ cd yosys $ cd yosys
$ git submodule update --init --recursive $ git submodule update --init
A C++ compiler with C++20 support is required as well as some standard tools 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 such as GNU Flex, GNU Bison (>=3.8), CMake (>=3.28), Make (or other CMake
@ -303,4 +302,3 @@ DOCS (e.g.)
This will build/rebuild yosys as necessary before generating the website This will build/rebuild yosys as necessary before generating the website
documentation from the yosys help commands. To build for pdf instead of html, documentation from the yosys help commands. To build for pdf instead of html,
use the `docs-latexpdf` target. use the `docs-latexpdf` target.

2
abc

@ -1 +1 @@
Subproject commit 1e85fff18db313b29584dc1ff7c2074d2275a381 Subproject commit e026ed5380f3bdc3beea2ff9ffc23236fc549d5b

View File

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

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; ./test_gate > test_gate.out")
os.system("set -x; md5sum test_gold.out test_gate.out") os.system("set -x; md5sum test_gold.out test_gate.out")

View File

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

View File

@ -226,7 +226,30 @@ class SmtIo:
print('timeout option is not supported for mathsat.') print('timeout option is not supported for mathsat.')
sys.exit(1) 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:
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 == "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: if self.noincr:
self.popen_vargs = [self.solver, '--smt2'] + self.solver_opts self.popen_vargs = [self.solver, '--smt2'] + self.solver_opts
else: else:

View File

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

View File

@ -192,8 +192,10 @@ def aiw2yw(input, mapfile, output, skip_x, present_only):
header_lines = list(itertools.islice(input, 0, 2)) 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() 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": if status == "0":
raise click.ClickException(f"{input_name}: file contains no trace, the AIGER status is unsat") raise click.ClickException(f"{input_name}: file contains no trace, the AIGER status is unsat")
elif status == "2": elif status == "2":

View File

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

View File

@ -197,14 +197,22 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string &reg_name)
reg_name = id(chunk.wire->name); reg_name = id(chunk.wire->name);
if (sig.size() != chunk.wire->width) { if (sig.size() != chunk.wire->width) {
if (sig.size() == 1) int idx;
reg_name += stringf("[%d]", chunk.wire->start_offset + chunk.offset); if (chunk.wire->upto)
else if (chunk.wire->upto) idx = (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset;
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);
else else
reg_name += stringf("[%d:%d]", chunk.wire->start_offset + chunk.offset + chunk.width - 1, idx = chunk.wire->start_offset + chunk.offset;
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; 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)) if (wire->attributes.count(ID::single_bit_vector))
range = stringf(" [%d:%d]", wire->start_offset, wire->start_offset); range = stringf(" [%d:%d]", wire->start_offset, wire->start_offset);
} }
std::string sign = wire->is_signed ? " signed" : "";
if (wire->port_input && !wire->port_output) 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) 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) 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)) { 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)) { if (wire->attributes.count(ID::init)) {
f << stringf(" = "); f << stringf(" = ");
dump_const(f, wire->attributes.at(ID::init)); dump_const(f, wire->attributes.at(ID::init));
} }
f << stringf(";\n"); f << stringf(";\n");
} else } 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 #endif
} }

View File

@ -42,7 +42,9 @@ function(yosys_abc_target arg_LIBNAME arg_EXENAME)
list(TRANSFORM all_sources PREPEND abc/) list(TRANSFORM all_sources PREPEND abc/)
# Required to get `-DABC_NAMESPACE` below to work consistently. # Required to get `-DABC_NAMESPACE` below to work consistently.
if(NOT MSVC)
set_source_files_properties(${all_sources} PROPERTIES LANGUAGE CXX) set_source_files_properties(${all_sources} PROPERTIES LANGUAGE CXX)
endif()
set(main_source abc/src/base/main/main.c) set(main_source abc/src/base/main/main.c)
list(REMOVE_ITEM all_sources ${main_source}) list(REMOVE_ITEM all_sources ${main_source})
@ -55,9 +57,10 @@ function(yosys_abc_target arg_LIBNAME arg_EXENAME)
target_include_directories(${arg_LIBNAME} PRIVATE abc/src) target_include_directories(${arg_LIBNAME} PRIVATE abc/src)
target_compile_definitions(${arg_LIBNAME} PUBLIC target_compile_definitions(${arg_LIBNAME} PUBLIC
WIN32_NO_DLL WIN32_NO_DLL
ABC_NAMESPACE=abc $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:ABC_NAMESPACE=abc>
ABC_USE_STDINT_H=1 ABC_USE_STDINT_H=1
ABC_USE_CUDD=1 ABC_USE_CUDD=1
ABC_NO_HISTORY=1
ABC_NO_DYNAMIC_LINKING ABC_NO_DYNAMIC_LINKING
$<${YOSYS_ENABLE_THREADS}:ABC_USE_PTHREADS> $<${YOSYS_ENABLE_THREADS}:ABC_USE_PTHREADS>
$<${YOSYS_ENABLE_READLINE}:ABC_USE_READLINE> $<${YOSYS_ENABLE_READLINE}:ABC_USE_READLINE>
@ -81,6 +84,7 @@ function(yosys_abc_target arg_LIBNAME arg_EXENAME)
-Wno-deprecated-comma-subscript -Wno-deprecated-comma-subscript
-Wno-format -Wno-format
-Wno-constant-logical-operand -Wno-constant-logical-operand
-Wno-sizeof-pointer-memaccess
) )
target_link_libraries(${arg_LIBNAME} PUBLIC target_link_libraries(${arg_LIBNAME} PUBLIC
$<${YOSYS_ENABLE_THREADS}:Threads::Threads> $<${YOSYS_ENABLE_THREADS}:Threads::Threads>

View File

@ -29,4 +29,3 @@ Yosys environment variables
``YOSYS_ABORT_ON_LOG_ERROR`` ``YOSYS_ABORT_ON_LOG_ERROR``
Can be used for debugging Yosys internals. Setting it to 1 causes abort() to Can be used for debugging Yosys internals. Setting it to 1 causes abort() to
be called when Yosys terminates with an error message. be called when Yosys terminates with an error message.

View File

@ -20,4 +20,3 @@ output reg Q;
always @(posedge C) always @(posedge C)
Q <= D; Q <= D;
endmodule endmodule

View File

@ -16,4 +16,3 @@ macc_xilinx_xmap.dot: macc_xilinx_*.v macc_xilinx_test.ys
.PHONY: clean .PHONY: clean
clean: clean:
@rm -f *.dot @rm -f *.dot

View File

@ -50,4 +50,3 @@ show -prefix macc_xilinx_test2e -format dot -notitle test2
design -load __macc_xilinx_xmap design -load __macc_xilinx_xmap
show -prefix macc_xilinx_xmap -format dot -notitle show -prefix macc_xilinx_xmap -format dot -notitle

View File

@ -89,4 +89,3 @@ check:
stat stat
check -noinit check -noinit
blackbox =A:whitebox blackbox =A:whitebox

View File

@ -15,4 +15,3 @@ opt_merge after
clean clean
show -format dot -prefix opt_merge_full -notitle -color cornflowerblue uut show -format dot -prefix opt_merge_full -notitle -color cornflowerblue uut

View File

@ -14,4 +14,3 @@ opt_muxtree after
clean clean
show -format dot -prefix opt_muxtree_full -notitle -color cornflowerblue uut show -format dot -prefix opt_muxtree_full -notitle -color cornflowerblue uut

View File

@ -19,4 +19,3 @@ eval -set in 1 -show out
eval -set in 270369 -show out eval -set in 270369 -show out
sat -set out 632435482 sat -set out 632435482

View File

@ -17,4 +17,3 @@ examples:
.PHONY: clean .PHONY: clean
clean: clean:
@rm -f *.dot @rm -f *.dot

View File

@ -178,4 +178,3 @@ of carry chains and DSPs, it avoids optimising for a path that isn't the actual
critical path, while the generally-longer paths result in ABC9 being able to critical path, while the generally-longer paths result in ABC9 being able to
reduce design area by mapping other logic to slower cells with greater logic reduce design area by mapping other logic to slower cells with greater logic
density. density.

View File

@ -31,4 +31,3 @@ for commands such as `abc`\ /`abc9`, `simplemap`, `dfflegalize`, and
extract extract
abc abc
cell_libs cell_libs

View File

@ -787,4 +787,3 @@ Asynchronous writes
end end
assign read_data = mem[read_addr]; assign read_data = mem[read_addr];

View File

@ -14,4 +14,3 @@ of interest for developers looking to customise Yosys builds.
advanced_bugpoint advanced_bugpoint
contributing contributing
test_suites test_suites

View File

@ -16,6 +16,20 @@ tests.
cmake -B build . cmake -B build .
cmake --build build --target test --parallel $(nproc) cmake --build build --target test --parallel $(nproc)
.. warning::
There are limitations when using `Ninja` as generator, so we suggest using
`Unix Makefiles` to make running tests in parallel possible. However, it is
possible to use it directly by running:
.. code:: console
cd tests
make -j9
Please note that in this case default build directory is `build` but can be
overwritten by providing `BUILD_DIR` variable.
Vanilla tests Vanilla tests
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -76,15 +90,19 @@ If you don't have one of the :ref:`getting_started/installation:CAD suite(s)`
installed, you should also install Z3 `following their installed, you should also install Z3 `following their
instructions <https://github.com/Z3Prover/z3>`_. instructions <https://github.com/Z3Prover/z3>`_.
.. TODO:: CMAKE_TODO Functional tests are disabled by default, to enable them use next code snippet
and run tests as usual:
How does this work under CMake? Is it only via ``make -C tests .. code:: console
ENABLE_FUNCTIONAL_TESTS=1`` and then manually setting ``BUILD_DIR`` and
``PROGRAM_PREFIX``? And possibly also setting ``YOSYS`` et al if there is a
``.exe``. Previous instructions:
Then, set the :makevar:`ENABLE_FUNCTIONAL_TESTS` make variable when calling cmake -B build . -DYOSYS_ENABLE_FUNCTIONAL_TESTS=ON
``make test`` and the functional tests will be run as well. cmake --build build --target test --parallel $(nproc)
Or run just functional tests with:
.. code:: console
cmake --build build --target test-functional
Docs tests Docs tests
~~~~~~~~~~ ~~~~~~~~~~
@ -164,6 +182,9 @@ compiler versions. For up to date information, including OS versions, refer to
test for ``kernel/celledges.cc``, you will need to create a file like this: test for ``kernel/celledges.cc``, you will need to create a file like this:
``tests/unit/kernel/celledgesTest.cc``; ``tests/unit/kernel/celledgesTest.cc``;
* Implement your unit test * Implement your unit test
* Add unit test to file list in `CMakeLists.txt`
In case unit tests are added to new directory, note that you need also to
create new `CmakeList.txt` file and add ``yosys_gtest(dir-name unit-test.cc)```
Run unit tests Run unit tests
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -172,10 +193,4 @@ compiler versions. For up to date information, including OS versions, refer to
.. code-block:: console .. code-block:: console
make unit-test cmake --build build --target test-unit
If you want to remove all unit test files, type:
.. code-block:: console
make clean-unit-test

View File

@ -16,4 +16,3 @@ These scripts contain three types of commands:
overview overview
control_and_data control_and_data
verilog_frontend verilog_frontend

View File

@ -56,4 +56,3 @@ constructs must be called from the synthesis script first.
.. [1] .. [1]
In Yosys the term pass is only used to refer to commands that operate on the In Yosys the term pass is only used to refer to commands that operate on the
RTLIL data structure. RTLIL data structure.

View File

@ -158,8 +158,8 @@ An ``RTLIL::Wire`` object has the following properties:
- The wire name - The wire name
- A list of attributes - A list of attributes
- A width (buses are just wires with a width more than 1) - A width (buses are just wires with a width more than 1)
- Bus direction (MSB to LSB or vice versa) - Bus direction (MSb to LSb or vice versa)
- Lowest valid bit index (LSB or MSB depending on bus direction) - Lowest valid bit index (LSb or MSb depending on bus direction)
- If the wire is a port: port number and direction (input/output/inout) - If the wire is a port: port number and direction (input/output/inout)
As with modules, the attributes can be Verilog attributes imported by the As with modules, the attributes can be Verilog attributes imported by the
@ -171,8 +171,8 @@ signals. This makes some aspects of RTLIL more complex but enables Yosys to be
used for coarse grain synthesis where the cells of the target architecture used for coarse grain synthesis where the cells of the target architecture
operate on entire signal vectors instead of single bit wires. operate on entire signal vectors instead of single bit wires.
In Verilog and VHDL, busses may have arbitrary bounds, and LSB can have either In Verilog and VHDL, busses may have arbitrary bounds, and LSb can have either
the lowest or the highest bit index. In RTLIL, bit 0 always corresponds to LSB; the lowest or the highest bit index. In RTLIL, bit 0 always corresponds to LSb;
however, information from the HDL frontend is preserved so that the bus will be however, information from the HDL frontend is preserved so that the bus will be
correctly indexed in error messages, backend output, constraint files, etc. correctly indexed in error messages, backend output, constraint files, etc.

View File

@ -16,4 +16,3 @@ Programming board:
All of the above: All of the above:
bash run.sh bash run.sh

View File

@ -21,4 +21,3 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports CLK
set_property CONFIG_VOLTAGE 3.3 [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design] set_property CFGBVS VCCO [current_design]

View File

@ -10,4 +10,3 @@ Each test bench can be run separately by either running:
The later case also includes pure verilog simulation using the iverilog The later case also includes pure verilog simulation using the iverilog
and gtkwave for comparison. and gtkwave for comparison.

View File

@ -36,4 +36,3 @@ X1 nC D t DLATCH
X2 C t Q DLATCH X2 C t Q DLATCH
X3 C nC NOT X3 C nC NOT
.ENDS DFF .ENDS DFF

View File

@ -41,4 +41,3 @@ always @(posedge C, posedge S, posedge R)
else else
Q <= D; Q <= D;
endmodule endmodule

View File

@ -28,4 +28,3 @@ Alatch D E null null Q nQ latch1
.model dff1 d_dff .model dff1 d_dff
Adff D C null null Q nQ dff1 Adff D C null null Q nQ dff1
.ENDS DFF .ENDS DFF

View File

@ -13,4 +13,3 @@ abc -liberty cmos_cells.lib;;
write_verilog synth.v write_verilog synth.v
write_spice -neg 0s -pos 1s synth.sp write_spice -neg 0s -pos 1s synth.sp

View File

@ -4,4 +4,3 @@ set -ex
../../yosys counter.ys ../../yosys counter.ys
ngspice testbench.sp ngspice testbench.sp

View File

@ -12,4 +12,3 @@ iverilog -o counter_tb counter.v counter_tb.v
# requires ngspice with xspice support enabled: # requires ngspice with xspice support enabled:
ngspice testbench_digital.sp ngspice testbench_digital.sp

View File

@ -19,4 +19,3 @@ int main()
Yosys::yosys_shutdown(); Yosys::yosys_shutdown();
return 0; return 0;
} }

View File

@ -14,4 +14,3 @@ gowinTool_linux directory
3.) edit gowinTool_linux/bin/gwlicense.ini. Set lic="..." to 3.) edit gowinTool_linux/bin/gwlicense.ini. Set lic="..." to
the full path to the license file. the full path to the license file.

View File

@ -2,4 +2,3 @@
iverilog -D POST_IMPL -o verif_post -s tb_top tb_top.v top.vqm $(yosys-config --datdir/altera_intel/max10/cells_comb_max10.v) iverilog -D POST_IMPL -o verif_post -s tb_top tb_top.v top.vqm $(yosys-config --datdir/altera_intel/max10/cells_comb_max10.v)
vvp -N verif_post vvp -N verif_post

View File

@ -2,4 +2,3 @@
iverilog -D POST_IMPL -o verif_post -s tb lfsr_updown_tb.v top.vqm $(yosys-config --datdir/altera_intel/max10/cells_comb_max10.v) iverilog -D POST_IMPL -o verif_post -s tb lfsr_updown_tb.v top.vqm $(yosys-config --datdir/altera_intel/max10/cells_comb_max10.v)
vvp -N verif_post vvp -N verif_post

View File

@ -10,4 +10,3 @@ osu035_stdcells.lib:
clean: clean:
rm -f osu035_stdcells.lib rm -f osu035_stdcells.lib
rm -f example.yslog example.edif rm -f example.yslog example.edif

View File

@ -74,4 +74,3 @@ clean:
rm -f glift_mux.ys rm -f glift_mux.ys
.PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 clean .PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 clean

View File

@ -10,4 +10,3 @@ module demo9;
cover(1); cover(1);
end end
endmodule endmodule

0
examples/smtbmc/glift/C7552.v Executable file → Normal file
View File

0
examples/smtbmc/glift/C880.v Executable file → Normal file
View File

0
examples/smtbmc/glift/alu2.v Executable file → Normal file
View File

0
examples/smtbmc/glift/alu4.v Executable file → Normal file
View File

0
examples/smtbmc/glift/t481.v Executable file → Normal file
View File

0
examples/smtbmc/glift/too_large.v Executable file → Normal file
View File

0
examples/smtbmc/glift/ttt2.v Executable file → Normal file
View File

0
examples/smtbmc/glift/x1.v Executable file → Normal file
View File

View File

@ -6,5 +6,6 @@ add_subdirectory(json)
add_subdirectory(liberty) add_subdirectory(liberty)
add_subdirectory(rpc) add_subdirectory(rpc)
add_subdirectory(rtlil) add_subdirectory(rtlil)
add_subdirectory(slang)
add_subdirectory(verific) add_subdirectory(verific)
add_subdirectory(verilog) add_subdirectory(verilog)

View File

@ -161,4 +161,3 @@ std::unique_ptr<AST::AstNode> AST::dpi_call(AstSrcLocType, const std::string&, c
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END
#endif /* YOSYS_ENABLE_LIBFFI */ #endif /* YOSYS_ENABLE_LIBFFI */

View File

@ -2619,21 +2619,27 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
input_error("Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str); input_error("Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str);
auto resolved = current_scope.at(init_ast->children[0]->str); auto resolved = current_scope.at(init_ast->children[0]->str);
auto apply_loop_var_type = [&resolved](std::unique_ptr<AstNode> &value) {
if (resolved->range_valid) { if (resolved->range_valid) {
int const_size = varbuf->range_left - varbuf->range_right; int const_size = value->range_left - value->range_right;
int resolved_size = resolved->range_left - resolved->range_right; int resolved_size = resolved->range_left - resolved->range_right;
if (const_size < resolved_size) { if (const_size < resolved_size) {
for (int i = const_size; i < resolved_size; i++) for (int i = const_size; i < resolved_size; i++)
varbuf->bits.push_back(resolved->is_signed ? varbuf->bits.back() : State::S0); value->bits.push_back(resolved->is_signed ? value->bits.back() : State::S0);
varbuf->range_left = resolved->range_left; value->range_left = resolved->range_left;
varbuf->range_right = resolved->range_right; value->range_right = resolved->range_right;
varbuf->range_swapped = resolved->range_swapped; value->range_swapped = resolved->range_swapped;
varbuf->range_valid = resolved->range_valid; value->range_valid = resolved->range_valid;
} }
} }
value->is_signed = resolved->is_signed;
};
apply_loop_var_type(varbuf);
varbuf = std::make_unique<AstNode>(location, AST_LOCALPARAM, std::move(varbuf)); varbuf = std::make_unique<AstNode>(location, AST_LOCALPARAM, std::move(varbuf));
varbuf->str = init_ast->children[0]->str; varbuf->str = init_ast->children[0]->str;
varbuf->is_signed = resolved->is_signed;
AstNode *backup_scope_varbuf = current_scope[varbuf->str]; AstNode *backup_scope_varbuf = current_scope[varbuf->str];
current_scope[varbuf->str] = varbuf.get(); current_scope[varbuf->str] = varbuf.get();
@ -2708,6 +2714,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
if (buf->type != AST_CONSTANT) if (buf->type != AST_CONSTANT)
input_error("Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type)); input_error("Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type));
apply_loop_var_type(buf);
varbuf->children[0] = std::move(buf); varbuf->children[0] = std::move(buf);
} }

View File

@ -691,4 +691,3 @@ struct BlifFrontend : public Frontend {
} BlifFrontend; } BlifFrontend;
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

View File

@ -836,5 +836,3 @@ skip_cell:;
} LibertyFrontend; } LibertyFrontend;
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

View File

@ -0,0 +1,39 @@
include(lib/cmake/GitRevision.cmake)
git_rev_parse(YOSYS_SLANG_REVISION ${CMAKE_CURRENT_SOURCE_DIR}/lib)
git_rev_parse(SLANG_REVISION ${PROJECT_SOURCE_DIR}/libs/slang)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/lib/src/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
yosys_frontend(slang
lib/src/abort_helpers.cc
lib/src/addressing.cc
lib/src/async_pattern.cc
lib/src/async_pattern.h
lib/src/blackboxes.cc
lib/src/builder.cc
lib/src/cases.cc
lib/src/cases.h
lib/src/diag.cc
lib/src/diag.h
lib/src/initialization.cc
lib/src/lvalue.cc
lib/src/memory.h
lib/src/naming.cc
lib/src/procedural.cc
lib/src/slang_frontend.cc
lib/src/slang_frontend.h
lib/src/statements.h
lib/src/sva.cc
lib/src/variables.cc
lib/src/variables.h
${CMAKE_CURRENT_BINARY_DIR}/version.h
DEFINITIONS
YOSYS_MAJOR=${YOSYS_VERSION_MAJOR}
YOSYS_MINOR=${YOSYS_VERSION_MINOR}
ENABLE_IF
YOSYS_ENABLE_SLANG
INCLUDE_DIRS
${CMAKE_CURRENT_BINARY_DIR}
LIBRARIES
$<${YOSYS_ENABLE_SLANG}:slang::slang>
fmt::fmt
)

1
frontends/slang/lib Submodule

@ -0,0 +1 @@
Subproject commit 2caaaefa831a1d548a681268ccf3eea925ca1312

View File

@ -34,4 +34,3 @@ should be something like this:
SBY [example] summary: engine_0 (smtbmc yices) returned PASS for induction SBY [example] summary: engine_0 (smtbmc yices) returned PASS for induction
SBY [example] summary: successful proof by k-induction. SBY [example] summary: successful proof by k-induction.
SBY [example] DONE (PASS, rc=0) SBY [example] DONE (PASS, rc=0)

View File

@ -713,4 +713,3 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
<*>. { BEGIN(0); return char_tok(*YYText(), out_loc); } <*>. { BEGIN(0); return char_tok(*YYText(), out_loc); }
%% %%

View File

@ -156,7 +156,7 @@ yosys_core(kernel
set(yosys_cc_definitions set(yosys_cc_definitions
"$<$<BOOL:${YOSYS_ABC_EXECUTABLE}>:ABCEXTERNAL=\"${YOSYS_ABC_EXECUTABLE}\">" "$<$<BOOL:${YOSYS_ABC_EXECUTABLE}>:ABCEXTERNAL=\"${YOSYS_ABC_EXECUTABLE}\">"
$<$<BOOL:${MSYS}>:YOSYS_WIN32_UNIX_DIR> $<$<BOOL:${MINGW}>:YOSYS_WIN32_UNIX_DIR>
) )
set_source_files_properties(yosys.cc PROPERTIES set_source_files_properties(yosys.cc PROPERTIES
COMPILE_DEFINITIONS "${yosys_cc_definitions}" COMPILE_DEFINITIONS "${yosys_cc_definitions}"

View File

@ -107,6 +107,18 @@ struct BitPatternPool
return bits; return bits;
} }
/**
* A literal x/z bit can never match a 2-valued selector, so a pattern containing
* one covers nothing.
*/
static bool covers_nothing(RTLIL::SigSpec sig)
{
for (auto bit : sig)
if (bit.wire == NULL && (bit.data == RTLIL::State::Sx || bit.data == RTLIL::State::Sz))
return true;
return false;
}
/** /**
* Two cubes match if their intersection is non-empty. * Two cubes match if their intersection is non-empty.
*/ */
@ -131,6 +143,8 @@ struct BitPatternPool
*/ */
bool has_any(RTLIL::SigSpec sig) bool has_any(RTLIL::SigSpec sig)
{ {
if (covers_nothing(sig))
return false;
bits_t bits = sig2bits(sig); bits_t bits = sig2bits(sig);
for (auto &it : database) for (auto &it : database)
if (match(it, bits)) if (match(it, bits))
@ -149,6 +163,8 @@ struct BitPatternPool
*/ */
bool has_all(RTLIL::SigSpec sig) bool has_all(RTLIL::SigSpec sig)
{ {
if (covers_nothing(sig))
return true;
bits_t bits = sig2bits(sig); bits_t bits = sig2bits(sig);
for (auto &it : database) for (auto &it : database)
if (match(it, bits)) { if (match(it, bits)) {
@ -170,6 +186,8 @@ struct BitPatternPool
bool take(RTLIL::SigSpec sig) bool take(RTLIL::SigSpec sig)
{ {
bool status = false; bool status = false;
if (covers_nothing(sig))
return false;
bits_t bits = sig2bits(sig); bits_t bits = sig2bits(sig);
for (auto it = database.begin(); it != database.end();) for (auto it = database.begin(); it != database.end();)
if (match(*it, bits)) { if (match(*it, bits)) {

View File

@ -712,4 +712,3 @@ RTLIL::Const RTLIL::const_bwmux(const RTLIL::Const &arg1, const RTLIL::Const &ar
} }
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

View File

@ -97,4 +97,3 @@ for line in fileinput.input():
print(simHelper) print(simHelper)
# new # new
simHelper = SimHelper() simHelper = SimHelper()

View File

@ -169,4 +169,3 @@ void PrettyJson::entry_json(const char *name, const Json &value)
this->name(name); this->name(name);
this->value(value); this->value(value);
} }

View File

@ -388,12 +388,6 @@ void log_formatted_file_error(std::string_view filename, int lineno, std::string
log_error_with_prefix(prefix, str); log_error_with_prefix(prefix, str);
} }
void logv_file_error(const string &filename, int lineno,
const char *format, va_list ap)
{
log_formatted_file_error(filename, lineno, vstringf(format, ap));
}
void log_experimental(const std::string &str) void log_experimental(const std::string &str)
{ {
if (log_experimentals_ignored.count(str) == 0 && log_experimentals.count(str) == 0) { if (log_experimentals_ignored.count(str) == 0 && log_experimentals.count(str) == 0) {

View File

@ -24,7 +24,6 @@
#include <time.h> #include <time.h>
#include <atomic>
#include <regex> #include <regex>
#define YS_REGEX_COMPILE(param) std::regex(param, \ #define YS_REGEX_COMPILE(param) std::regex(param, \
std::regex_constants::nosubs | \ std::regex_constants::nosubs | \
@ -44,20 +43,11 @@
# endif # endif
#endif #endif
#if defined(_MSC_VER)
// At least this is not in MSVC++ 2013.
# define __PRETTY_FUNCTION__ __FUNCTION__
#endif
// from libs/sha1/sha1.h // from libs/sha1/sha1.h
class SHA1; class SHA1;
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
#define S__LINE__sub2(x) #x
#define S__LINE__sub1(x) S__LINE__sub2(x)
#define S__LINE__ S__LINE__sub1(__LINE__)
// YS_DEBUGTRAP is a macro that is functionally equivalent to a breakpoint // YS_DEBUGTRAP is a macro that is functionally equivalent to a breakpoint
// if the platform provides such functionality, and does nothing otherwise. // if the platform provides such functionality, and does nothing otherwise.
// If no debugger is attached, it starts a just-in-time debugger if available, // If no debugger is attached, it starts a just-in-time debugger if available,
@ -120,9 +110,6 @@ extern int log_make_debug;
extern int log_force_debug; extern int log_force_debug;
extern int log_debug_suppressed; extern int log_debug_suppressed;
[[deprecated]]
[[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap);
void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg)); void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg));
extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg); extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg);

View File

@ -615,6 +615,15 @@ int RTLIL::Const::as_int_saturating(bool is_signed) const
return as_int(is_signed); return as_int(is_signed);
} }
void RTLIL::Const::tag_bare_integer_const(const std::string &value)
{
if (value.empty() || value.find('\'') != std::string::npos)
return;
size_t start = (value[0] == '-' || value[0] == '+') ? 1 : 0;
if (start < value.size() && std::all_of(value.begin() + start, value.end(), ::isdigit))
flags |= RTLIL::CONST_FLAG_SIGNED;
}
int RTLIL::Const::get_min_size(bool is_signed) const int RTLIL::Const::get_min_size(bool is_signed) const
{ {
if (empty()) return 0; if (empty()) return 0;

View File

@ -1091,6 +1091,8 @@ public:
// over/underflow, otherwise the max/min value for int depending on the sign. // over/underflow, otherwise the max/min value for int depending on the sign.
int as_int_saturating(bool is_signed = false) const; int as_int_saturating(bool is_signed = false) const;
void tag_bare_integer_const(const std::string &value);
std::string as_string(const char* any = "-") const; std::string as_string(const char* any = "-") const;
static Const from_string(const std::string &str); static Const from_string(const std::string &str);
std::vector<RTLIL::State> to_bits() const; std::vector<RTLIL::State> to_bits() const;

View File

@ -77,7 +77,6 @@
# define strtok_r strtok_s # define strtok_r strtok_s
# define strdup _strdup # define strdup _strdup
# define snprintf _snprintf
# define getcwd _getcwd # define getcwd _getcwd
# define mkdir _mkdir # define mkdir _mkdir
# define popen _popen # define popen _popen

View File

@ -7,3 +7,50 @@ add_subdirectory(json11)
add_subdirectory(minisat) add_subdirectory(minisat)
add_subdirectory(sha1) add_subdirectory(sha1)
add_subdirectory(subcircuit) add_subdirectory(subcircuit)
block()
set(BUILD_SHARED_LIBS OFF)
include(FetchContent)
set(FETCHCONTENT_FULLY_DISCONNECTED ON)
option(FMT_INSTALL OFF)
FetchContent_Declare(
fmt
EXCLUDE_FROM_ALL
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/fmt
)
FetchContent_MakeAvailable(fmt)
FetchContent_Declare(
tomlplusplus
EXCLUDE_FROM_ALL
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tomlplusplus
)
FetchContent_MakeAvailable(tomlplusplus)
FetchContent_Declare(
boost_regex
EXCLUDE_FROM_ALL
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boost_regex
SOURCE_SUBDIR _no_build_
)
FetchContent_MakeAvailable(boost_regex)
if (NOT YOSYS_WITHOUT_SLANG)
set(SLANG_USE_MIMALLOC OFF)
add_subdirectory(slang)
# Headers autodetect based on <boost/config.hpp> but when version
# does exist but does not match requirements it becomes problematic
if(NOT Boost_FOUND)
target_compile_definitions(slang_slang PRIVATE BOOST_REGEX_STANDALONE)
endif()
if (SLANG_INCLUDE_TOOLS)
# Temporary to prevent build issues
set_target_properties(slang_tidy_obj_lib PROPERTIES YOSYS_IS_ABC ON)
install(TARGETS slang_driver RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS slang_hier RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS slang_reflect RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS slang_tidy RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
endif()
endblock()

1
libs/boost_regex Submodule

@ -0,0 +1 @@
Subproject commit 2b3ac0834f31086c6e3c0e0ceb8516e427d5c39d

1
libs/fmt Submodule

@ -0,0 +1 @@
Subproject commit 1be298e1bd68957e4cd352e1f676f00e07dcfb57

View File

@ -1,6 +1,6 @@
/* /*
LZ4 - Fast LZ compression algorithm LZ4 - Fast LZ compression algorithm
Copyright (C) 2011-2023, Yann Collet. Copyright (c) Yann Collet. All rights reserved.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@ -77,7 +77,8 @@
#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ #ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */
# if defined(__GNUC__) && \ # if defined(__GNUC__) && \
( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \ ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \
|| defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|| (defined(__riscv) && defined(__riscv_zicclsm)) )
# define LZ4_FORCE_MEMORY_ACCESS 2 # define LZ4_FORCE_MEMORY_ACCESS 2
# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__) || defined(_MSC_VER) # elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__) || defined(_MSC_VER)
# define LZ4_FORCE_MEMORY_ACCESS 1 # define LZ4_FORCE_MEMORY_ACCESS 1
@ -124,14 +125,17 @@
# include <intrin.h> /* only present in VS2005+ */ # include <intrin.h> /* only present in VS2005+ */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
# pragma warning(disable : 6237) /* disable: C6237: conditional expression is always 0 */ # pragma warning(disable : 6237) /* disable: C6237: conditional expression is always 0 */
# pragma warning(disable : 6239) /* disable: C6239: (<non-zero constant> && <expression>) always evaluates to the result of <expression> */
# pragma warning(disable : 6240) /* disable: C6240: (<expression> && <non-zero constant>) always evaluates to the result of <expression> */
# pragma warning(disable : 6326) /* disable: C6326: Potential comparison of a constant with another constant */
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#ifndef LZ4_FORCE_INLINE #ifndef LZ4_FORCE_INLINE
# ifdef _MSC_VER /* Visual Studio */ # if defined (_MSC_VER) && !defined (__clang__) /* MSVC */
# define LZ4_FORCE_INLINE static __forceinline # define LZ4_FORCE_INLINE static __forceinline
# else # else
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# ifdef __GNUC__ # if defined (__GNUC__) || defined (__clang__)
# define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) # define LZ4_FORCE_INLINE static inline __attribute__((always_inline))
# else # else
# define LZ4_FORCE_INLINE static inline # define LZ4_FORCE_INLINE static inline
@ -298,7 +302,7 @@ static int LZ4_isAligned(const void* ptr, size_t alignment)
#include <limits.h> #include <limits.h>
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# include <stdint.h> # include <stdint.h>
typedef uint8_t BYTE; typedef unsigned char BYTE; /*uint8_t not necessarily blessed to alias arbitrary type*/
typedef uint16_t U16; typedef uint16_t U16;
typedef uint32_t U32; typedef uint32_t U32;
typedef int32_t S32; typedef int32_t S32;
@ -430,7 +434,7 @@ static U16 LZ4_readLE16(const void* memPtr)
return LZ4_read16(memPtr); return LZ4_read16(memPtr);
} else { } else {
const BYTE* p = (const BYTE*)memPtr; const BYTE* p = (const BYTE*)memPtr;
return (U16)((U16)p[0] + (p[1]<<8)); return (U16)((U16)p[0] | (p[1]<<8));
} }
} }
@ -441,7 +445,7 @@ static U32 LZ4_readLE32(const void* memPtr)
return LZ4_read32(memPtr); return LZ4_read32(memPtr);
} else { } else {
const BYTE* p = (const BYTE*)memPtr; const BYTE* p = (const BYTE*)memPtr;
return (U32)p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24); return (U32)p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
} }
} }
#endif #endif
@ -475,12 +479,7 @@ static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
#ifndef LZ4_FAST_DEC_LOOP #ifndef LZ4_FAST_DEC_LOOP
# if defined __i386__ || defined _M_IX86 || defined __x86_64__ || defined _M_X64 # if defined __i386__ || defined _M_IX86 || defined __x86_64__ || defined _M_X64
# define LZ4_FAST_DEC_LOOP 1 # define LZ4_FAST_DEC_LOOP 1
# elif defined(__aarch64__) && defined(__APPLE__) # elif defined(__aarch64__)
# define LZ4_FAST_DEC_LOOP 1
# elif defined(__aarch64__) && !defined(__clang__)
/* On non-Apple aarch64, we disable this optimization for clang because
* on certain mobile chipsets, performance is reduced with clang. For
* more information refer to https://github.com/lz4/lz4/pull/707 */
# define LZ4_FAST_DEC_LOOP 1 # define LZ4_FAST_DEC_LOOP 1
# else # else
# define LZ4_FAST_DEC_LOOP 0 # define LZ4_FAST_DEC_LOOP 0
@ -495,10 +494,9 @@ LZ4_memcpy_using_offset_base(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, con
assert(srcPtr + offset == dstPtr); assert(srcPtr + offset == dstPtr);
if (offset < 8) { if (offset < 8) {
LZ4_write32(dstPtr, 0); /* silence an msan warning when offset==0 */ LZ4_write32(dstPtr, 0); /* silence an msan warning when offset==0 */
dstPtr[0] = srcPtr[0]; assert(offset != 1); /* offset==0 happens on testing */
dstPtr[1] = srcPtr[1]; LZ4_memcpy(dstPtr, srcPtr, 2);
dstPtr[2] = srcPtr[2]; LZ4_memcpy(dstPtr + 2, srcPtr + 2, 2);
dstPtr[3] = srcPtr[3];
srcPtr += inc32table[offset]; srcPtr += inc32table[offset];
LZ4_memcpy(dstPtr+4, srcPtr, 4); LZ4_memcpy(dstPtr+4, srcPtr, 4);
srcPtr -= dec64table[offset]; srcPtr -= dec64table[offset];
@ -512,6 +510,20 @@ LZ4_memcpy_using_offset_base(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, con
LZ4_wildCopy8(dstPtr, srcPtr, dstEnd); LZ4_wildCopy8(dstPtr, srcPtr, dstEnd);
} }
#ifdef __aarch64__
/* customized variant of memcpy, which can overwrite up to 64 bytes beyond dstEnd */
LZ4_FORCE_INLINE void
LZ4_wildCopy64(void* dstPtr, const void* srcPtr, void* dstEnd)
{
BYTE* d = (BYTE*)dstPtr;
const BYTE* s = (const BYTE*)srcPtr;
BYTE* const e = (BYTE*)dstEnd;
do { LZ4_memcpy(d,s,64); d+=64; s+=64; } while (d<e);
}
#endif
/* customized variant of memcpy, which can overwrite up to 32 bytes beyond dstEnd /* customized variant of memcpy, which can overwrite up to 32 bytes beyond dstEnd
* this version copies two times 16 bytes (instead of one time 32 bytes) * this version copies two times 16 bytes (instead of one time 32 bytes)
* because it must be compatible with offsets >= 16. */ * because it must be compatible with offsets >= 16. */
@ -527,7 +539,7 @@ LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd)
/* LZ4_memcpy_using_offset() presumes : /* LZ4_memcpy_using_offset() presumes :
* - dstEnd >= dstPtr + MINMATCH * - dstEnd >= dstPtr + MINMATCH
* - there is at least 8 bytes available to write after dstEnd */ * - there is at least 12 bytes available to write after dstEnd */
LZ4_FORCE_INLINE void LZ4_FORCE_INLINE void
LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset) LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset)
{ {
@ -893,7 +905,7 @@ LZ4_prepareTable(LZ4_stream_t_internal* const cctx,
|| tableType == byPtr || tableType == byPtr
|| inputSize >= 4 KB) || inputSize >= 4 KB)
{ {
DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", cctx); DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", (void*)cctx);
MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE); MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE);
cctx->currentOffset = 0; cctx->currentOffset = 0;
cctx->tableType = (U32)clearedTable; cctx->tableType = (U32)clearedTable;
@ -1118,7 +1130,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic_validated(
goto _last_literals; goto _last_literals;
} }
if (litLength >= RUN_MASK) { if (litLength >= RUN_MASK) {
int len = (int)(litLength - RUN_MASK); unsigned len = litLength - RUN_MASK;
*token = (RUN_MASK<<ML_BITS); *token = (RUN_MASK<<ML_BITS);
for(; len >= 255 ; len-=255) *op++ = 255; for(; len >= 255 ; len-=255) *op++ = 255;
*op++ = (BYTE)len; *op++ = (BYTE)len;
@ -1529,7 +1541,7 @@ LZ4_stream_t* LZ4_createStream(void)
{ {
LZ4_stream_t* const lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); LZ4_stream_t* const lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
LZ4_STATIC_ASSERT(sizeof(LZ4_stream_t) >= sizeof(LZ4_stream_t_internal)); LZ4_STATIC_ASSERT(sizeof(LZ4_stream_t) >= sizeof(LZ4_stream_t_internal));
DEBUGLOG(4, "LZ4_createStream %p", lz4s); DEBUGLOG(4, "LZ4_createStream %p", (void*)lz4s);
if (lz4s == NULL) return NULL; if (lz4s == NULL) return NULL;
LZ4_initStream(lz4s, sizeof(*lz4s)); LZ4_initStream(lz4s, sizeof(*lz4s));
return lz4s; return lz4s;
@ -1560,7 +1572,7 @@ LZ4_stream_t* LZ4_initStream (void* buffer, size_t size)
* prefer initStream() which is more general */ * prefer initStream() which is more general */
void LZ4_resetStream (LZ4_stream_t* LZ4_stream) void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
{ {
DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", LZ4_stream); DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", (void*)LZ4_stream);
MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t_internal)); MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t_internal));
} }
@ -1572,15 +1584,18 @@ void LZ4_resetStream_fast(LZ4_stream_t* ctx) {
int LZ4_freeStream (LZ4_stream_t* LZ4_stream) int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
{ {
if (!LZ4_stream) return 0; /* support free on NULL */ if (!LZ4_stream) return 0; /* support free on NULL */
DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream); DEBUGLOG(5, "LZ4_freeStream %p", (void*)LZ4_stream);
FREEMEM(LZ4_stream); FREEMEM(LZ4_stream);
return (0); return (0);
} }
#endif #endif
typedef enum { _ld_fast, _ld_slow } LoadDict_mode_e;
#define HASH_UNIT sizeof(reg_t) #define HASH_UNIT sizeof(reg_t)
int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) static int LZ4_loadDict_internal(LZ4_stream_t* LZ4_dict,
const char* dictionary, int dictSize,
LoadDict_mode_e _ld)
{ {
LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse;
const tableType_t tableType = byU32; const tableType_t tableType = byU32;
@ -1588,7 +1603,7 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
const BYTE* const dictEnd = p + dictSize; const BYTE* const dictEnd = p + dictSize;
U32 idx32; U32 idx32;
DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, dictionary, LZ4_dict); DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, (void*)dictionary, (void*)LZ4_dict);
/* It's necessary to reset the context, /* It's necessary to reset the context,
* and not just continue it with prepareTable() * and not just continue it with prepareTable()
@ -1616,20 +1631,46 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
while (p <= dictEnd-HASH_UNIT) { while (p <= dictEnd-HASH_UNIT) {
U32 const h = LZ4_hashPosition(p, tableType); U32 const h = LZ4_hashPosition(p, tableType);
/* Note: overwriting => favors positions end of dictionary */
LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType); LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType);
p+=3; idx32+=3; p+=3; idx32+=3;
} }
if (_ld == _ld_slow) {
/* Fill hash table with additional references, to improve compression capability */
p = dict->dictionary;
idx32 = dict->currentOffset - dict->dictSize;
while (p <= dictEnd-HASH_UNIT) {
U32 const h = LZ4_hashPosition(p, tableType);
U32 const limit = dict->currentOffset - 64 KB;
if (LZ4_getIndexOnHash(h, dict->hashTable, tableType) <= limit) {
/* Note: not overwriting => favors positions beginning of dictionary */
LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType);
}
p++; idx32++;
}
}
return (int)dict->dictSize; return (int)dict->dictSize;
} }
int LZ4_loadDict(LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
{
return LZ4_loadDict_internal(LZ4_dict, dictionary, dictSize, _ld_fast);
}
int LZ4_loadDictSlow(LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
{
return LZ4_loadDict_internal(LZ4_dict, dictionary, dictSize, _ld_slow);
}
void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream) void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream)
{ {
const LZ4_stream_t_internal* dictCtx = (dictionaryStream == NULL) ? NULL : const LZ4_stream_t_internal* dictCtx = (dictionaryStream == NULL) ? NULL :
&(dictionaryStream->internal_donotuse); &(dictionaryStream->internal_donotuse);
DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)", DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)",
workingStream, dictionaryStream, (void*)workingStream, (void*)dictionaryStream,
dictCtx != NULL ? dictCtx->dictSize : 0); dictCtx != NULL ? dictCtx->dictSize : 0);
if (dictCtx != NULL) { if (dictCtx != NULL) {
@ -1693,7 +1734,7 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream,
&& (inputSize > 0) /* tolerance : don't lose history, in case next invocation would use prefix mode */ && (inputSize > 0) /* tolerance : don't lose history, in case next invocation would use prefix mode */
&& (streamPtr->dictCtx == NULL) /* usingDictCtx */ && (streamPtr->dictCtx == NULL) /* usingDictCtx */
) { ) {
DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary); DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, (void*)streamPtr->dictionary);
/* remove dictionary existence from history, to employ faster prefix mode */ /* remove dictionary existence from history, to employ faster prefix mode */
streamPtr->dictSize = 0; streamPtr->dictSize = 0;
streamPtr->dictionary = (const BYTE*)source; streamPtr->dictionary = (const BYTE*)source;
@ -1783,7 +1824,7 @@ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
{ {
LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse;
DEBUGLOG(5, "LZ4_saveDict : dictSize=%i, safeBuffer=%p", dictSize, safeBuffer); DEBUGLOG(5, "LZ4_saveDict : dictSize=%i, safeBuffer=%p", dictSize, (void*)safeBuffer);
if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */ if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */
if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; } if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; }
@ -1936,42 +1977,32 @@ LZ4_decompress_unsafe_generic(
/* Read the variable-length literal or match length. /* Read the variable-length literal or match length.
* *
* @ip : input pointer * @ipPtr : pointer to input pointer, will be advanced
* @ilimit : position after which if length is not decoded, the input is necessarily corrupted. * @ilimit : read is forbidden beyond this position (must be within input buffer)
* @initial_check - check ip >= ipmax before start of loop. Returns initial_error if so.
* @error (output) - error code. Must be set to 0 before call.
**/ **/
typedef size_t Rvl_t; typedef size_t Rvl_t;
static const Rvl_t rvl_error = (Rvl_t)(-1); static const Rvl_t rvl_error = (Rvl_t)(-1);
LZ4_FORCE_INLINE Rvl_t LZ4_FORCE_INLINE Rvl_t
read_variable_length(const BYTE** ip, const BYTE* ilimit, read_variable_length(const BYTE** ipPtr, const BYTE* ilimit)
int initial_check)
{ {
Rvl_t s, length = 0; Rvl_t s, length = 0;
assert(ip != NULL); assert(ipPtr != NULL);
assert(*ip != NULL); assert(*ipPtr != NULL);
assert(ilimit != NULL); assert(ilimit != NULL);
if (initial_check && unlikely((*ip) >= ilimit)) { /* read limit reached */ if (unlikely((*ipPtr) >= ilimit)) { /* read limit reached */
return rvl_error; return rvl_error;
} }
s = **ip; s = **ipPtr;
(*ip)++; (*ipPtr)++;
length += s; length += s;
if (unlikely((*ip) > ilimit)) { /* read limit reached */
return rvl_error;
}
/* accumulator overflow detection (32-bit mode only) */
if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) {
return rvl_error;
}
if (likely(s != 255)) return length; if (likely(s != 255)) return length;
do { do {
s = **ip; if (unlikely((*ipPtr) >= ilimit)) { /* read limit reached */
(*ip)++;
length += s;
if (unlikely((*ip) > ilimit)) { /* read limit reached */
return rvl_error; return rvl_error;
} }
s = **ipPtr;
(*ipPtr)++;
length += s;
/* accumulator overflow detection (32-bit mode only) */ /* accumulator overflow detection (32-bit mode only) */
if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) {
return rvl_error; return rvl_error;
@ -2042,7 +2073,7 @@ LZ4_decompress_generic(
* note : fast loop may show a regression for some client arm chips. */ * note : fast loop may show a regression for some client arm chips. */
#if LZ4_FAST_DEC_LOOP #if LZ4_FAST_DEC_LOOP
if ((oend - op) < FASTLOOP_SAFE_DISTANCE) { if ((oend - op) < FASTLOOP_SAFE_DISTANCE) {
DEBUGLOG(6, "skip fast decode loop"); DEBUGLOG(6, "move to safe decode loop");
goto safe_decode; goto safe_decode;
} }
@ -2054,50 +2085,61 @@ LZ4_decompress_generic(
assert(ip < iend); assert(ip < iend);
token = *ip++; token = *ip++;
length = token >> ML_BITS; /* literal length */ length = token >> ML_BITS; /* literal length */
DEBUGLOG(7, "blockPos%6u: litLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length);
if (ip > iend-(16 + 1/*max lit + offset + nextToken*/)) { goto safe_literal_copy_early; }
/* decode literal length */ /* decode literal length */
if (length == RUN_MASK) { if (length == RUN_MASK) {
size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); /* literal length >= RUN_MASK means >= RUN_MASK literal bytes follow the extension bytes,
* so extension bytes cannot reach the last RUN_MASK bytes of input */
size_t const addl = read_variable_length(&ip, iend - RUN_MASK);
if (addl == rvl_error) { if (addl == rvl_error) {
DEBUGLOG(6, "error reading long literal length"); DEBUGLOG(6, "error reading long literal length");
goto _output_error; goto _output_error;
} }
length += addl; length += addl;
if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ cpy = op+length;
if (unlikely((uptrval)(cpy)<(uptrval)(op))) { goto _output_error; } /* overflow detection */
if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */
/* copy literals */ /* copy literals */
LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
if ((op+length>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; } #ifdef __aarch64__
LZ4_wildCopy32(op, ip, op+length); if ((cpy>oend-64) || (ip+length>iend-64)) { goto safe_literal_copy; }
ip += length; op += length; LZ4_wildCopy64(op, ip, cpy);
} else if (ip <= iend-(16 + 1/*max lit + offset + nextToken*/)) { #else
/* We don't need to check oend, since we check it once for each loop below */ if ((cpy>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; }
LZ4_wildCopy32(op, ip, cpy);
#endif
ip += length; op = cpy;
} else {
DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length); DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length);
/* Literals can only be <= 14, but hope compilers optimize better when copy by a register size */ /* Literals can only be <= 14, but hope compilers optimize better when copy by a register size */
LZ4_memcpy(op, ip, 16); LZ4_memcpy(op, ip, 16);
ip += length; op += length; ip += length; op += length;
} else {
goto safe_literal_copy;
} }
/* get offset */ /* get offset */
offset = LZ4_readLE16(ip); ip+=2; offset = LZ4_readLE16(ip); ip+=2;
DEBUGLOG(6, " offset = %zu", offset); DEBUGLOG(6, "blockPos%6u: offset = %u", (unsigned)(op-(BYTE*)dst), (unsigned)offset);
match = op - offset; match = op - offset;
assert(match <= op); /* overflow check */ assert(match <= op); /* overflow check */
/* get matchlength */ /* get matchlength */
length = token & ML_MASK; length = token & ML_MASK;
DEBUGLOG(7, " match length token = %u (len==%u)", (unsigned)length, (unsigned)length+MINMATCH);
if (length == ML_MASK) { if (length == ML_MASK) {
size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); /* after match length extension bytes, at least 1 token + LASTLITERALS literals must remain */
size_t const addl = read_variable_length(&ip, iend - (1 + LASTLITERALS));
if (addl == rvl_error) { if (addl == rvl_error) {
DEBUGLOG(6, "error reading long match length"); DEBUGLOG(5, "error reading long match length");
goto _output_error; goto _output_error;
} }
length += addl; length += addl;
length += MINMATCH; length += MINMATCH;
DEBUGLOG(7, " long match length == %u", (unsigned)length);
if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */
if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
goto safe_match_copy; goto safe_match_copy;
@ -2105,6 +2147,7 @@ LZ4_decompress_generic(
} else { } else {
length += MINMATCH; length += MINMATCH;
if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
DEBUGLOG(7, "moving to safe_match_copy (ml==%u)", (unsigned)length);
goto safe_match_copy; goto safe_match_copy;
} }
@ -2123,7 +2166,7 @@ LZ4_decompress_generic(
} } } } } }
if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) { if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) {
DEBUGLOG(6, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match); DEBUGLOG(5, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match);
goto _output_error; goto _output_error;
} }
/* match starting within external dictionary */ /* match starting within external dictionary */
@ -2162,9 +2205,13 @@ LZ4_decompress_generic(
/* copy match within block */ /* copy match within block */
cpy = op + length; cpy = op + length;
assert((op <= oend) && (oend-op >= 32)); assert((op <= oend) && (oend-op >= 64));
if (unlikely(offset<16)) { if (unlikely(offset<16)) {
LZ4_memcpy_using_offset(op, match, cpy, offset); LZ4_memcpy_using_offset(op, match, cpy, offset);
#ifdef __aarch64__
} else if (offset >= 64) {
LZ4_wildCopy64(op, match, cpy);
#endif
} else { } else {
LZ4_wildCopy32(op, match, cpy); LZ4_wildCopy32(op, match, cpy);
} }
@ -2180,6 +2227,7 @@ LZ4_decompress_generic(
assert(ip < iend); assert(ip < iend);
token = *ip++; token = *ip++;
length = token >> ML_BITS; /* literal length */ length = token >> ML_BITS; /* literal length */
DEBUGLOG(7, "blockPos%6u: litLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length);
/* A two-stage shortcut for the most common case: /* A two-stage shortcut for the most common case:
* 1) If the literal length is 0..14, and there is enough space, * 1) If the literal length is 0..14, and there is enough space,
@ -2200,6 +2248,7 @@ LZ4_decompress_generic(
/* The second stage: prepare for match copying, decode full info. /* The second stage: prepare for match copying, decode full info.
* If it doesn't work out, the info won't be wasted. */ * If it doesn't work out, the info won't be wasted. */
length = token & ML_MASK; /* match length */ length = token & ML_MASK; /* match length */
DEBUGLOG(7, "blockPos%6u: matchLength token = %u (len=%u)", (unsigned)(op-(BYTE*)dst), (unsigned)length, (unsigned)length + 4);
offset = LZ4_readLE16(ip); ip += 2; offset = LZ4_readLE16(ip); ip += 2;
match = op - offset; match = op - offset;
assert(match <= op); /* check overflow */ assert(match <= op); /* check overflow */
@ -2222,20 +2271,27 @@ LZ4_decompress_generic(
goto _copy_match; goto _copy_match;
} }
#if LZ4_FAST_DEC_LOOP
safe_literal_copy_early:
#endif
/* decode literal length */ /* decode literal length */
if (length == RUN_MASK) { if (length == RUN_MASK) {
size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); /* literal length >= RUN_MASK means >= RUN_MASK literal bytes follow the extension bytes,
* so extension bytes cannot reach the last RUN_MASK bytes of input */
size_t const addl = read_variable_length(&ip, iend-RUN_MASK);
if (addl == rvl_error) { goto _output_error; } if (addl == rvl_error) { goto _output_error; }
length += addl; length += addl;
if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */
if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */
} }
/* copy literals */
cpy = op+length;
#if LZ4_FAST_DEC_LOOP #if LZ4_FAST_DEC_LOOP
safe_literal_copy: safe_literal_copy:
#endif #endif
/* copy literals */
cpy = op+length;
LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) { if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) {
@ -2272,9 +2328,10 @@ LZ4_decompress_generic(
* so check that we exactly consume the input and don't overrun the output buffer. * so check that we exactly consume the input and don't overrun the output buffer.
*/ */
if ((ip+length != iend) || (cpy > oend)) { if ((ip+length != iend) || (cpy > oend)) {
DEBUGLOG(6, "should have been last run of literals") DEBUGLOG(5, "should have been last run of literals")
DEBUGLOG(6, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend); DEBUGLOG(5, "ip(%p) + length(%i) = %p != iend (%p)", (void*)ip, (int)length, (void*)(ip+length), (void*)iend);
DEBUGLOG(6, "or cpy(%p) > oend(%p)", cpy, oend); DEBUGLOG(5, "or cpy(%p) > (oend-MFLIMIT)(%p)", (void*)cpy, (void*)(oend-MFLIMIT));
DEBUGLOG(5, "after writing %u bytes / %i bytes available", (unsigned)(op-(BYTE*)dst), outputSize);
goto _output_error; goto _output_error;
} }
} }
@ -2300,10 +2357,12 @@ LZ4_decompress_generic(
/* get matchlength */ /* get matchlength */
length = token & ML_MASK; length = token & ML_MASK;
DEBUGLOG(7, "blockPos%6u: matchLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length);
_copy_match: _copy_match:
if (length == ML_MASK) { if (length == ML_MASK) {
size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); /* after match length extension bytes, at least 1 token + LASTLITERALS literals must remain */
size_t const addl = read_variable_length(&ip, iend - (1 + LASTLITERALS));
if (addl == rvl_error) { goto _output_error; } if (addl == rvl_error) { goto _output_error; }
length += addl; length += addl;
if (unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ if (unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */

View File

@ -1,7 +1,7 @@
/* /*
* LZ4 - Fast LZ compression algorithm * LZ4 - Fast LZ compression algorithm
* Header File * Header File
* Copyright (C) 2011-2023, Yann Collet. * Copyright (c) Yann Collet. All rights reserved.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@ -129,8 +129,8 @@ extern "C" {
/*------ Version ------*/ /*------ Version ------*/
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */ #define LZ4_VERSION_MINOR 10 /* for new (non-breaking) interface capabilities */
#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
@ -148,6 +148,7 @@ LZ4LIB_API const char* LZ4_versionString (void); /**< library version string;
**************************************/ **************************************/
/*! /*!
* LZ4_MEMORY_USAGE : * LZ4_MEMORY_USAGE :
* Can be selected at compile time, by setting LZ4_MEMORY_USAGE.
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB) * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB)
* Increasing memory usage improves compression ratio, generally at the cost of speed. * Increasing memory usage improves compression ratio, generally at the cost of speed.
* Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality. * Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality.
@ -157,6 +158,7 @@ LZ4LIB_API const char* LZ4_versionString (void); /**< library version string;
# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT # define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT
#endif #endif
/* These are absolute limits, they should not be changed by users */
#define LZ4_MEMORY_USAGE_MIN 10 #define LZ4_MEMORY_USAGE_MIN 10
#define LZ4_MEMORY_USAGE_DEFAULT 14 #define LZ4_MEMORY_USAGE_DEFAULT 14
#define LZ4_MEMORY_USAGE_MAX 20 #define LZ4_MEMORY_USAGE_MAX 20
@ -256,10 +258,12 @@ LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* d
* @return : Nb bytes written into 'dst' (necessarily <= dstCapacity) * @return : Nb bytes written into 'dst' (necessarily <= dstCapacity)
* or 0 if compression fails. * or 0 if compression fails.
* *
* Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+): * Note : 'targetDstSize' must be >= 1, because it's the smallest valid lz4 payload.
* the produced compressed content could, in specific circumstances, *
* require to be decompressed into a destination buffer larger * Note 2:from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+):
* by at least 1 byte than the content to decompress. * the produced compressed content could, in rare circumstances,
* require to be decompressed into a destination buffer
* larger by at least 1 byte than decompressesSize.
* If an application uses `LZ4_compress_destSize()`, * If an application uses `LZ4_compress_destSize()`,
* it's highly recommended to update liblz4 to v1.9.2 or better. * it's highly recommended to update liblz4 to v1.9.2 or better.
* If this can't be done or ensured, * If this can't be done or ensured,
@ -368,6 +372,51 @@ LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
*/ */
LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
/*! LZ4_loadDictSlow() : v1.10.0+
* Same as LZ4_loadDict(),
* but uses a bit more cpu to reference the dictionary content more thoroughly.
* This is expected to slightly improve compression ratio.
* The extra-cpu cost is likely worth it if the dictionary is re-used across multiple sessions.
* @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded)
*/
LZ4LIB_API int LZ4_loadDictSlow(LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
/*! LZ4_attach_dictionary() : stable since v1.10.0
*
* This allows efficient re-use of a static dictionary multiple times.
*
* Rather than re-loading the dictionary buffer into a working context before
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
* in which the working stream references @dictionaryStream in-place.
*
* Several assumptions are made about the state of @dictionaryStream.
* Currently, only states which have been prepared by LZ4_loadDict() or
* LZ4_loadDictSlow() should be expected to work.
*
* Alternatively, the provided @dictionaryStream may be NULL,
* in which case any existing dictionary stream is unset.
*
* If a dictionary is provided, it replaces any pre-existing stream history.
* The dictionary contents are the only history that can be referenced and
* logically immediately precede the data compressed in the first subsequent
* compression call.
*
* The dictionary will only remain attached to the working stream through the
* first compression call, at the end of which it is cleared.
* @dictionaryStream stream (and source buffer) must remain in-place / accessible / unchanged
* through the completion of the compression session.
*
* Note: there is no equivalent LZ4_attach_*() method on the decompression side
* because there is no initialization cost, hence no need to share the cost across multiple sessions.
* To decompress LZ4 blocks using dictionary, attached or not,
* just employ the regular LZ4_setStreamDecode() for streaming,
* or the stateless LZ4_decompress_safe_usingDict() for one-shot decompression.
*/
LZ4LIB_API void
LZ4_attach_dictionary(LZ4_stream_t* workingStream,
const LZ4_stream_t* dictionaryStream);
/*! LZ4_compress_fast_continue() : /*! LZ4_compress_fast_continue() :
* Compress 'src' content using data from previously compressed blocks, for better compression ratio. * Compress 'src' content using data from previously compressed blocks, for better compression ratio.
* 'dst' buffer must be already allocated. * 'dst' buffer must be already allocated.
@ -563,43 +612,12 @@ LZ4_decompress_safe_partial_usingDict(const char* src, char* dst,
*/ */
LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
/*! LZ4_compress_destSize_extState() : /*! LZ4_compress_destSize_extState() : introduced in v1.10.0
* Same as LZ4_compress_destSize(), but using an externally allocated state. * Same as LZ4_compress_destSize(), but using an externally allocated state.
* Also: exposes @acceleration * Also: exposes @acceleration
*/ */
int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration); int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration);
/*! LZ4_attach_dictionary() :
* This is an experimental API that allows
* efficient use of a static dictionary many times.
*
* Rather than re-loading the dictionary buffer into a working context before
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
* in which the working stream references the dictionary stream in-place.
*
* Several assumptions are made about the state of the dictionary stream.
* Currently, only streams which have been prepared by LZ4_loadDict() should
* be expected to work.
*
* Alternatively, the provided dictionaryStream may be NULL,
* in which case any existing dictionary stream is unset.
*
* If a dictionary is provided, it replaces any pre-existing stream history.
* The dictionary contents are the only history that can be referenced and
* logically immediately precede the data compressed in the first subsequent
* compression call.
*
* The dictionary will only remain attached to the working stream through the
* first compression call, at the end of which it is cleared. The dictionary
* stream (and source buffer) must remain in-place / accessible / unchanged
* through the completion of the first compression call on the stream.
*/
LZ4LIB_STATIC_API void
LZ4_attach_dictionary(LZ4_stream_t* workingStream,
const LZ4_stream_t* dictionaryStream);
/*! In-place compression and decompression /*! In-place compression and decompression
* *
* It's possible to have input and output sharing the same buffer, * It's possible to have input and output sharing the same buffer,
@ -683,7 +701,7 @@ LZ4_attach_dictionary(LZ4_stream_t* workingStream,
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# include <stdint.h> # include <stdint.h>
typedef int8_t LZ4_i8; typedef int8_t LZ4_i8;
typedef uint8_t LZ4_byte; typedef unsigned char LZ4_byte;
typedef uint16_t LZ4_u16; typedef uint16_t LZ4_u16;
typedef uint32_t LZ4_u32; typedef uint32_t LZ4_u32;
#else #else

1
libs/slang Submodule

@ -0,0 +1 @@
Subproject commit 6175750969f17289695f94be5105f6006c82eb61

1
libs/tomlplusplus Submodule

@ -0,0 +1 @@
Subproject commit a43ad3787293f4a46b1d70c0924b5a25d10e79fc

View File

@ -543,12 +543,12 @@ struct CheckMemPass : public Pass {
for (auto &init : mem.inits) { for (auto &init : mem.inits) {
int start = init.addr.as_int(); int start = init.addr.as_int();
if (start < min_addr) { if (start < min_addr) {
log_warning("Mem %s.%s starts at %d but initializes address %d.\n", log_id(module), log_id(mem.mem), min_addr, start); log_warning("Mem %s.%s starts at %d but initializes address %d.\n", module, mem.mem, min_addr, start);
counter++; counter++;
} }
int end = start + (GetSize(init.data) / mem.width) - 1; int end = start + (GetSize(init.data) / mem.width) - 1;
if (end > max_addr) { if (end > max_addr) {
log_warning("Mem %s.%s ends at %d but initializes address %d.\n", log_id(module), log_id(mem.mem), max_addr, end); log_warning("Mem %s.%s ends at %d but initializes address %d.\n", module, mem.mem, max_addr, end);
counter++; counter++;
} }
} }
@ -557,7 +557,7 @@ struct CheckMemPass : public Pass {
if (addr_sig.is_fully_const()) { if (addr_sig.is_fully_const()) {
auto addr = addr_sig.as_int(); auto addr = addr_sig.as_int();
if (addr < min_addr || addr > max_addr) { if (addr < min_addr || addr > max_addr) {
log_warning("Mem %s.%s contains entries for addresses %d..%d but %s address %d.\n", log_id(module), log_id(mem.mem), min_addr, max_addr, access, addr); log_warning("Mem %s.%s contains entries for addresses %d..%d but %s address %d.\n", module, mem.mem, min_addr, max_addr, access, addr);
counter++; counter++;
} }
} else if (nonconst_mode) { } else if (nonconst_mode) {
@ -566,7 +566,7 @@ struct CheckMemPass : public Pass {
int addr_sig_min = 0; int addr_sig_min = 0;
int addr_sig_max = (1 << addr_sig.size()) - 1; int addr_sig_max = (1 << addr_sig.size()) - 1;
if (min_addr > addr_sig_min || max_addr < addr_sig_max) { if (min_addr > addr_sig_min || max_addr < addr_sig_max) {
log_warning("Mem %s.%s contains entries for addresses %d..%d but has a potentially dangerous non-const input %s\n", log_id(module), log_id(mem.mem), min_addr, max_addr, log_signal(addr_sig)); log_warning("Mem %s.%s contains entries for addresses %d..%d but has a potentially dangerous non-const input %s\n", module, mem.mem, min_addr, max_addr, log_signal(addr_sig));
counter++; counter++;
} }
} }

View File

@ -401,4 +401,3 @@ struct DesignPass : public Pass {
} DesignPass; } DesignPass;
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

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