mirror of
https://github.com/YosysHQ/yosys
synced 2026-06-27 19:18:49 +00:00
Merge branch 'YosysHQ:main' into main
This commit is contained in:
commit
f07ed6d588
846 changed files with 46500 additions and 27046 deletions
|
|
@ -11,6 +11,10 @@ indent_style = space
|
|||
indent_size = 2
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.rst]
|
||||
indent_style = space
|
||||
indent_size = 3
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
|
|
|||
5
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
5
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -6,15 +6,14 @@ body:
|
|||
attributes:
|
||||
value: >
|
||||
|
||||
If you have a general question, please ask it in the [Discussions](https://github.com/YosysHQ/yosys/discussions) area
|
||||
or join our [IRC Channel](https://web.libera.chat/#yosys) or [Community Slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA).
|
||||
If you have a general question, please ask it on the [Discourse forum](https://yosyshq.discourse.group/).
|
||||
|
||||
|
||||
If you have a feature request, please fill out the appropriate issue form, this form is for bugs and/or regressions.
|
||||
|
||||
|
||||
Please contact [YosysHQ GmbH](https://www.yosyshq.com/) if you need
|
||||
commercial support for Yosys.
|
||||
commercial support or work done for Yosys.
|
||||
|
||||
- type: input
|
||||
id: yosys_version
|
||||
|
|
|
|||
11
.github/ISSUE_TEMPLATE/config.yml
vendored
11
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -1,11 +1,8 @@
|
|||
contact_links:
|
||||
- name: Discussions
|
||||
url: https://github.com/YosysHQ/yosys/discussions
|
||||
about: "Have a question? Ask it on our discussions page!"
|
||||
- name: Community Slack
|
||||
url: https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA
|
||||
about: "Yosys Community Slack"
|
||||
- name: Discourse
|
||||
url: https://yosyshq.discourse.group
|
||||
about: "Have a question? Ask it on our Discourse group!"
|
||||
- name: IRC Channel
|
||||
url: https://web.libera.chat/#yosys
|
||||
about: "#yosys on irc.libera.chat"
|
||||
|
||||
|
||||
|
|
|
|||
3
.github/ISSUE_TEMPLATE/docs_report.yml
vendored
3
.github/ISSUE_TEMPLATE/docs_report.yml
vendored
|
|
@ -6,8 +6,7 @@ body:
|
|||
attributes:
|
||||
value: >
|
||||
|
||||
If you have a general question, please ask it in the [Discussions](https://github.com/YosysHQ/yosys/discussions) area
|
||||
or join our [IRC Channel](https://web.libera.chat/#yosys) or [Community Slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA).
|
||||
If you have a general question, please ask it on the [Discourse forum](https://yosyshq.discourse.group/).
|
||||
|
||||
|
||||
If you have found a bug in Yosys, or in building the documentation,
|
||||
|
|
|
|||
9
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
9
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
|
|
@ -1,18 +1,17 @@
|
|||
name: Feature Request
|
||||
description: "Submit a feature request for Yosys"
|
||||
description: "Submit a feature request for Yosys"
|
||||
labels: ["feature-request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
|
||||
If you have a general question, please ask it in the [Discussions](https://github.com/YosysHQ/yosys/discussions) area
|
||||
or join our [IRC Channel](https://web.libera.chat/#yosys) or [Community Slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA).
|
||||
|
||||
If you have a general question, please ask it on the [Discourse forum](https://yosyshq.discourse.group/).
|
||||
|
||||
|
||||
If you have a bug report, please fill out the appropriate issue form, this form is for feature requests.
|
||||
|
||||
|
||||
|
||||
Please contact [YosysHQ GmbH](https://www.yosyshq.com/) if you need
|
||||
commercial support or work done for Yosys.
|
||||
|
||||
|
|
|
|||
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -1,5 +1,9 @@
|
|||
_If your work is part of a larger effort, please discuss your general plans on [Discourse](https://yosyshq.discourse.group/) first to align your vision with maintainers._
|
||||
|
||||
_What are the reasons/motivation for this change?_
|
||||
|
||||
_Explain how this is achieved._
|
||||
|
||||
_If applicable, please suggest to reviewers how they can test the change._
|
||||
_Make sure your change comes with tests. If not possible, share how a reviewer might evaluate it._
|
||||
|
||||
_These template prompts can be deleted when you're done responding to them._
|
||||
72
.github/actions/setup-build-env/action.yml
vendored
72
.github/actions/setup-build-env/action.yml
vendored
|
|
@ -1,21 +1,71 @@
|
|||
name: Build environment setup
|
||||
description: Configure build env for Yosys builds
|
||||
|
||||
inputs:
|
||||
runs-on:
|
||||
required: true
|
||||
type: string
|
||||
get-build-deps:
|
||||
description: 'Install Yosys build dependencies'
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
get-docs-deps:
|
||||
description: 'Install Yosys docs dependencies'
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
get-test-deps:
|
||||
description: 'Install Yosys test dependencies'
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
get-iverilog:
|
||||
description: 'Install iverilog'
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install Linux Dependencies
|
||||
# if updating common/build/docs dependencies, make sure to update README.md
|
||||
# and docs/source/getting_started/installation.rst to match.
|
||||
- name: Linux common dependencies
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install gperf build-essential bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libbz2-dev
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: gawk git make python3
|
||||
version: ${{ inputs.runs-on }}-commonys
|
||||
|
||||
- name: Linux build dependencies
|
||||
if: runner.os == 'Linux' && inputs.get-build-deps == 'true'
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev
|
||||
version: ${{ inputs.runs-on }}-buildys
|
||||
|
||||
- name: Linux docs dependencies
|
||||
if: runner.os == 'Linux' && inputs.get-docs-deps == 'true'
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: graphviz xdot
|
||||
version: ${{ inputs.runs-on }}-docsys
|
||||
|
||||
# if updating test dependencies, make sure to update
|
||||
# docs/source/yosys_internals/extending_yosys/test_suites.rst to match.
|
||||
- name: Linux test dependencies
|
||||
if: runner.os == 'Linux' && inputs.get-test-deps == 'true'
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: libgtest-dev
|
||||
version: ${{ inputs.runs-on }}-testys
|
||||
|
||||
- name: Install macOS Dependencies
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew update
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install bison flex gawk libffi pkg-config bash autoconf llvm lld || true
|
||||
brew bundle
|
||||
|
||||
- name: Linux runtime environment
|
||||
if: runner.os == 'Linux'
|
||||
|
|
@ -29,7 +79,13 @@ runs:
|
|||
shell: bash
|
||||
run: |
|
||||
echo "${{ github.workspace }}/.local/bin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix llvm@20)/bin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix flex)/bin" >> $GITHUB_PATH
|
||||
echo "procs=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup iverilog
|
||||
if: inputs.get-iverilog == 'true'
|
||||
uses: ./.github/actions/setup-iverilog
|
||||
with:
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
|
|
|
|||
70
.github/actions/setup-iverilog/action.yml
vendored
Normal file
70
.github/actions/setup-iverilog/action.yml
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
name: iverilog setup
|
||||
description: Cached build and install of iverilog
|
||||
|
||||
inputs:
|
||||
runs-on:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: iverilog Linux deps
|
||||
if: steps.restore-iverilog.outputs.cache-hit != 'true' && runner.os == 'Linux'
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: autoconf gperf make gcc g++ bison flex libbz2-dev
|
||||
version: ${{ inputs.runs-on }}-iverilog
|
||||
|
||||
- name: iverilog macOS deps
|
||||
if: steps.restore-iverilog.outputs.cache-hit != 'true' && runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
brew install autoconf
|
||||
|
||||
- name: Get iverilog
|
||||
id: get-iverilog
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/steveicarus/iverilog.git
|
||||
cd iverilog
|
||||
echo "IVERILOG_GIT=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get vcd2fst
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/mmicko/libwave.git
|
||||
mkdir -p ${{ github.workspace }}/.local/
|
||||
cd libwave
|
||||
cmake . -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/.local
|
||||
make -j$procs
|
||||
make install
|
||||
|
||||
- uses: actions/cache/restore@v4
|
||||
id: restore-iverilog
|
||||
with:
|
||||
path: .local/
|
||||
key: ${{ inputs.runs-on }}-${{ steps.get-iverilog.outputs.IVERILOG_GIT }}
|
||||
|
||||
- name: Build iverilog
|
||||
if: steps.restore-iverilog.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.local/
|
||||
cd iverilog
|
||||
autoconf
|
||||
CC=gcc CXX=g++ ./configure --prefix=${{ github.workspace }}/.local
|
||||
make -j$procs
|
||||
make install
|
||||
|
||||
- name: Check iverilog
|
||||
shell: bash
|
||||
run: |
|
||||
iverilog -V
|
||||
|
||||
- uses: actions/cache/save@v4
|
||||
id: save-iverilog
|
||||
if: steps.restore-iverilog.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: .local/
|
||||
key: ${{ steps.restore-iverilog.outputs.cache-primary-key }}
|
||||
13
.github/workflows/codeql.yml
vendored
13
.github/workflows/codeql.yml
vendored
|
|
@ -10,13 +10,18 @@ jobs:
|
|||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install deps
|
||||
run: sudo apt-get install bison flex libreadline-dev tcl-dev libffi-dev
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ubuntu-latest
|
||||
get-build-deps: true
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
|
|
|
|||
57
.github/workflows/extra-builds.yml
vendored
57
.github/workflows/extra-builds.yml
vendored
|
|
@ -1,6 +1,14 @@
|
|||
name: Test extra build flows
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
# always test main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# test PRs
|
||||
pull_request:
|
||||
# allow triggering tests, ignores skip check
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
|
|
@ -11,11 +19,11 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
# don't run on documentation changes
|
||||
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
|
||||
# cancel previous builds if a new commit is pushed
|
||||
cancel_others: 'true'
|
||||
# only run on push *or* pull_request, not both
|
||||
concurrent_skipping: 'same_content_newer'
|
||||
# but never cancel main
|
||||
cancel_others: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
vs-prep:
|
||||
name: Prepare Visual Studio build
|
||||
|
|
@ -25,20 +33,22 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
- run: sudo apt-get install libfl-dev
|
||||
- name: Build
|
||||
run: make vcxsrc YOSYS_VER=latest
|
||||
run: make vcxsrc YOSYS_COMPILER="Visual Studio" VCX_DIR_NAME=yosys-win32-vcxsrc-latest
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vcxsrc
|
||||
path: yosys-win32-vcxsrc-latest.zip
|
||||
|
||||
|
||||
vs-build:
|
||||
name: Visual Studio build
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-latest
|
||||
needs: [vs-prep, pre_job]
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
steps:
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: vcxsrc
|
||||
|
|
@ -49,7 +59,7 @@ jobs:
|
|||
uses: microsoft/setup-msbuild@v2
|
||||
- name: MSBuild
|
||||
working-directory: yosys-win32-vcxsrc-latest
|
||||
run: msbuild YosysVS.sln /p:PlatformToolset=v142 /p:Configuration=Release /p:WindowsTargetPlatformVersion=10.0.17763.0
|
||||
run: msbuild YosysVS.sln /p:PlatformToolset=v142 /p:Configuration=Release /p:WindowsTargetPlatformVersion=10.0.26100.0
|
||||
|
||||
wasi-build:
|
||||
name: WASI build
|
||||
|
|
@ -59,16 +69,28 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
- name: Build
|
||||
run: |
|
||||
WASI_SDK=wasi-sdk-19.0
|
||||
WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz
|
||||
WASI_SDK=wasi-sdk-27.0-x86_64-linux
|
||||
WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz
|
||||
if ! [ -d ${WASI_SDK} ]; then curl -L ${WASI_SDK_URL} | tar xzf -; fi
|
||||
|
||||
FLEX_VER=2.6.4
|
||||
FLEX=flex-${FLEX_VER}
|
||||
FLEX_URL=https://github.com/westes/flex/releases/download/v${FLEX_VER}/${FLEX}.tar.gz
|
||||
if ! [ -d ${FLEX} ]; then curl -L ${FLEX_URL} | tar xzf -; fi
|
||||
|
||||
mkdir -p flex-build
|
||||
(cd flex-build &&
|
||||
../${FLEX}/configure --prefix=$(pwd)/../flex-prefix &&
|
||||
make &&
|
||||
make install)
|
||||
|
||||
mkdir -p build
|
||||
cat > build/Makefile.conf <<END
|
||||
export PATH := $(pwd)/${WASI_SDK}/bin:${PATH}
|
||||
export PATH := $(pwd)/${WASI_SDK}/bin:$(pwd)/flex-prefix/bin:${PATH}
|
||||
WASI_SYSROOT := $(pwd)/${WASI_SDK}/share/wasi-sysroot
|
||||
|
||||
CONFIG := wasi
|
||||
|
|
@ -78,6 +100,8 @@ jobs:
|
|||
ENABLE_READLINE := 0
|
||||
ENABLE_PLUGINS := 0
|
||||
ENABLE_ZLIB := 0
|
||||
|
||||
CXXFLAGS += -I$(pwd)/flex-prefix/include
|
||||
END
|
||||
|
||||
make -C build -f ../Makefile CXX=clang -j$(nproc)
|
||||
|
|
@ -95,7 +119,8 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: cachix/install-nix-action@v26
|
||||
persist-credentials: false
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.18.1/install
|
||||
install_url: https://releases.nixos.org/nix/nix-2.30.0/install
|
||||
- run: nix build .?submodules=1 -L
|
||||
|
|
|
|||
12
.github/workflows/prepare-docs.yml
vendored
12
.github/workflows/prepare-docs.yml
vendored
|
|
@ -20,13 +20,13 @@ jobs:
|
|||
# only run on push *or* pull_request, not both
|
||||
concurrent_skipping: ${{ env.docs_export && 'never' || 'same_content_newer'}}
|
||||
- id: docs_var
|
||||
run: echo "docs_export=${{ env.docs_export }}" >> $GITHUB_OUTPUT
|
||||
run: echo "docs_export=${docs_export}" >> $GITHUB_OUTPUT
|
||||
|
||||
prepare-docs:
|
||||
# docs builds are needed for anything on main, any tagged versions, and any tag
|
||||
# or branch starting with docs-preview
|
||||
needs: check_docs_rebuild
|
||||
if: ${{ needs.check_docs_rebuild.outputs.should_skip != 'true' }}
|
||||
if: ${{ needs.check_docs_rebuild.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }}
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
|
|
@ -47,19 +47,19 @@ jobs:
|
|||
echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
make -j${{ env.procs }} ENABLE_LTO=1
|
||||
echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf
|
||||
make -j$procs
|
||||
|
||||
- name: Prepare docs
|
||||
shell: bash
|
||||
run:
|
||||
make docs/prep -j${{ env.procs }} TARGETS= EXTRA_TARGETS=
|
||||
make docs/prep -j$procs TARGETS= EXTRA_TARGETS=
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cmd-ref-${{ github.sha }}
|
||||
path: |
|
||||
docs/source/cmd
|
||||
docs/source/generated
|
||||
docs/source/_images
|
||||
docs/source/code_examples
|
||||
|
|
@ -72,7 +72,7 @@ jobs:
|
|||
- name: Test build docs
|
||||
shell: bash
|
||||
run: |
|
||||
make -C docs html -j${{ env.procs }} TARGETS= EXTRA_TARGETS=
|
||||
make -C docs html -j$procs TARGETS= EXTRA_TARGETS=
|
||||
|
||||
- name: Trigger RTDs build
|
||||
if: ${{ needs.check_docs_rebuild.outputs.docs_export == 'true' }}
|
||||
|
|
|
|||
1
.github/workflows/source-vendor.yml
vendored
1
.github/workflows/source-vendor.yml
vendored
|
|
@ -10,6 +10,7 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
persist-credentials: false
|
||||
|
||||
- name: Create clean tarball
|
||||
run: |
|
||||
|
|
|
|||
126
.github/workflows/test-build.yml
vendored
126
.github/workflows/test-build.yml
vendored
|
|
@ -1,6 +1,14 @@
|
|||
name: Build and run tests
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
# always test main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# test PRs
|
||||
pull_request:
|
||||
# allow triggering tests, ignores skip check
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
|
|
@ -11,11 +19,12 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
# don't run on documentation changes
|
||||
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
|
||||
# cancel previous builds if a new commit is pushed
|
||||
cancel_others: 'true'
|
||||
# only run on push *or* pull_request, not both
|
||||
concurrent_skipping: 'same_content_newer'
|
||||
# but never cancel main
|
||||
cancel_others: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
pre_docs_job:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
|
|
@ -24,15 +33,16 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
# don't run on readme changes
|
||||
paths_ignore: '["**/README.md"]'
|
||||
# cancel previous builds if a new commit is pushed
|
||||
cancel_others: 'true'
|
||||
# only run on push *or* pull_request, not both
|
||||
concurrent_skipping: 'same_content_newer'
|
||||
# but never cancel main
|
||||
cancel_others: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
build-yosys:
|
||||
name: Reusable build
|
||||
runs-on: ${{ matrix.os }}
|
||||
# pre_job is a subset of pre_docs_job, so we can always build for pre_docs_job
|
||||
needs: pre_docs_job
|
||||
if: needs.pre_docs_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
|
|
@ -46,9 +56,13 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-build-deps: true
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
|
|
@ -56,8 +70,7 @@ jobs:
|
|||
mkdir build
|
||||
cd build
|
||||
make -f ../Makefile config-$CC
|
||||
echo 'SANITIZER = undefined' >> Makefile.conf
|
||||
make -f ../Makefile -j$procs ENABLE_LTO=1
|
||||
make -f ../Makefile -j$procs
|
||||
|
||||
- name: Log yosys-config output
|
||||
run: |
|
||||
|
|
@ -83,7 +96,6 @@ jobs:
|
|||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
CC: clang
|
||||
UBSAN_OPTIONS: halt_on_error=1
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
|
|
@ -91,44 +103,15 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
|
||||
- name: Get iverilog
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/steveicarus/iverilog.git
|
||||
cd iverilog
|
||||
echo "IVERILOG_GIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: Get vcd2fst
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/mmicko/libwave.git
|
||||
mkdir -p ${{ github.workspace }}/.local/
|
||||
cd libwave
|
||||
cmake . -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/.local
|
||||
make -j$procs
|
||||
make install
|
||||
|
||||
- name: Cache iverilog
|
||||
id: cache-iverilog
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .local/
|
||||
key: ${{ matrix.os }}-${{ env.IVERILOG_GIT }}
|
||||
|
||||
- name: Build iverilog
|
||||
if: steps.cache-iverilog.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.local/
|
||||
cd iverilog
|
||||
autoconf
|
||||
CC=gcc CXX=g++ ./configure --prefix=${{ github.workspace }}/.local
|
||||
make -j$procs
|
||||
make install
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-test-deps: true
|
||||
get-iverilog: true
|
||||
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
|
|
@ -155,6 +138,45 @@ jobs:
|
|||
run: |
|
||||
find tests/**/*.err -print -exec cat {} \;
|
||||
|
||||
test-cells:
|
||||
name: Run test_cell
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [build-yosys, pre_job]
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
CC: clang
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-${{ matrix.os }}
|
||||
|
||||
- name: Uncompress build
|
||||
shell: bash
|
||||
run:
|
||||
tar -xvf build.tar
|
||||
|
||||
- name: test_cell
|
||||
shell: bash
|
||||
run: |
|
||||
./yosys -p 'test_cell -n 20 -s 1 all'
|
||||
./yosys -p 'test_cell -n 20 -s 1 -nosat -aigmap $pow $pmux'
|
||||
./yosys -p 'test_cell -n 20 -s 1 -nosat -aigmap $eqx $nex $bweqx'
|
||||
./yosys -p 'test_cell -n 20 -s 1 -aigmap $buf'
|
||||
|
||||
test-docs:
|
||||
name: Run docs tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
|
@ -169,9 +191,15 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-build-deps: true
|
||||
get-docs-deps: true
|
||||
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
|
|
@ -190,13 +218,13 @@ jobs:
|
|||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -C docs test -j${{ env.procs }}
|
||||
make -C docs test -j$procs
|
||||
|
||||
test-docs-build:
|
||||
name: Try build docs
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
needs: [pre_docs_job]
|
||||
if: needs.pre_docs_job.outputs.should_skip != 'true'
|
||||
if: ${{ needs.pre_docs_job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }}
|
||||
strategy:
|
||||
matrix:
|
||||
docs-target: [html, latexpdf]
|
||||
|
|
@ -206,6 +234,7 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
|
||||
- name: Runtime environment
|
||||
run: |
|
||||
|
|
@ -215,7 +244,8 @@ jobs:
|
|||
run: |
|
||||
make config-clang
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
make -j${{ env.procs }}
|
||||
echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf
|
||||
make -j$procs
|
||||
|
||||
- name: Install doc prereqs
|
||||
shell: bash
|
||||
|
|
@ -225,7 +255,7 @@ jobs:
|
|||
- name: Build docs
|
||||
shell: bash
|
||||
run: |
|
||||
make docs DOC_TARGET=${{ matrix.docs-target }} -j${{ env.procs }}
|
||||
make docs DOC_TARGET=${{ matrix.docs-target }} -j$procs
|
||||
|
||||
- name: Store docs build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
|
|||
33
.github/workflows/test-compile.yml
vendored
33
.github/workflows/test-compile.yml
vendored
|
|
@ -1,6 +1,14 @@
|
|||
name: Compiler testing
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
# always test main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# test PRs
|
||||
pull_request:
|
||||
# allow triggering tests, ignores skip check
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
|
|
@ -11,11 +19,11 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
# don't run on documentation changes
|
||||
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
|
||||
# cancel previous builds if a new commit is pushed
|
||||
cancel_others: 'true'
|
||||
# only run on push *or* pull_request, not both
|
||||
concurrent_skipping: 'same_content_newer'
|
||||
# but never cancel main
|
||||
cancel_others: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
test-compile:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
|
@ -34,20 +42,27 @@ jobs:
|
|||
- 'gcc-10'
|
||||
# newest, make sure to update maximum standard step to match
|
||||
- 'clang-19'
|
||||
- 'gcc-13'
|
||||
- 'gcc-14'
|
||||
include:
|
||||
# macOS
|
||||
- os: macos-13
|
||||
compiler: 'clang'
|
||||
# macOS x86
|
||||
- os: macos-15-intel
|
||||
compiler: 'clang-19'
|
||||
# macOS arm
|
||||
- os: macos-latest
|
||||
compiler: 'clang-19'
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-build-deps: true
|
||||
|
||||
- name: Setup Cpp
|
||||
uses: aminya/setup-cpp@v1
|
||||
|
|
@ -69,7 +84,7 @@ jobs:
|
|||
|
||||
# maximum standard, only on newest compilers
|
||||
- name: Build C++20
|
||||
if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-13' }}
|
||||
if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }}
|
||||
shell: bash
|
||||
run: |
|
||||
make config-$CC_SHORT
|
||||
|
|
|
|||
78
.github/workflows/test-sanitizers.yml
vendored
Normal file
78
.github/workflows/test-sanitizers.yml
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
name: Check clang sanitizers
|
||||
|
||||
on:
|
||||
# always test main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# ignore PRs due to time needed
|
||||
# allow triggering tests, ignores skip check
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
||||
steps:
|
||||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
# don't run on documentation changes
|
||||
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
|
||||
|
||||
run_san:
|
||||
name: Build and run tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
CC: clang
|
||||
ASAN_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:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-build-deps: true
|
||||
get-test-deps: true
|
||||
get-iverilog: true
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
make config-$CC
|
||||
echo 'SANITIZER = ${{ matrix.sanitizer }}' >> Makefile.conf
|
||||
make -j$procs
|
||||
|
||||
- name: Log yosys-config output
|
||||
run: |
|
||||
./yosys-config || true
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs test TARGETS= EXTRA_TARGETS=
|
||||
|
||||
- name: Report errors
|
||||
if: ${{ failure() }}
|
||||
shell: bash
|
||||
run: |
|
||||
find tests/**/*.err -print -exec cat {} \;
|
||||
|
||||
- name: Run unit tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs unit-test ENABLE_LIBYOSYS=1
|
||||
67
.github/workflows/test-verific.yml
vendored
67
.github/workflows/test-verific.yml
vendored
|
|
@ -1,6 +1,14 @@
|
|||
name: Build and run tests with Verific (Linux)
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
# always test main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# test PRs
|
||||
pull_request:
|
||||
# allow triggering tests, ignores skip check
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
pre-job:
|
||||
|
|
@ -11,15 +19,15 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
# don't run on documentation changes
|
||||
paths_ignore: '["**/README.md", "docs/**", "guidelines/**"]'
|
||||
# cancel previous builds if a new commit is pushed
|
||||
cancel_others: 'true'
|
||||
# only run on push *or* pull_request, not both
|
||||
concurrent_skipping: 'same_content_newer'
|
||||
# but never cancel main
|
||||
cancel_others: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
test-verific:
|
||||
needs: pre-job
|
||||
if: needs.pre-job.outputs.should_skip != 'true'
|
||||
if: ${{ needs.pre-job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }}
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
|
|
@ -40,7 +48,7 @@ jobs:
|
|||
echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
echo "ENABLE_FUNCTIONAL_TESTS := 1" >> Makefile.conf
|
||||
make -j${{ env.procs }} ENABLE_LTO=1
|
||||
make -j$procs ENABLE_LTO=1
|
||||
|
||||
- name: Install Yosys
|
||||
run: |
|
||||
|
|
@ -51,6 +59,7 @@ jobs:
|
|||
with:
|
||||
repository: 'YosysHQ/sby'
|
||||
path: 'sby'
|
||||
persist-credentials: false
|
||||
|
||||
- name: Build SBY
|
||||
run: |
|
||||
|
|
@ -58,7 +67,7 @@ jobs:
|
|||
|
||||
- name: Run Yosys tests
|
||||
run: |
|
||||
make -j${{ env.procs }} test
|
||||
make -j$procs test
|
||||
|
||||
- name: Run Verific specific Yosys tests
|
||||
run: |
|
||||
|
|
@ -69,3 +78,47 @@ jobs:
|
|||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
run: |
|
||||
make -C sby run_ci
|
||||
|
||||
- name: Run unit tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs unit-test ENABLE_LTO=1 ENABLE_LIBYOSYS=1
|
||||
|
||||
test-pyosys:
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }}
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: true
|
||||
- name: Install UV
|
||||
run: |
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
- name: Runtime environment
|
||||
run: |
|
||||
echo "procs=$(nproc)" >> $GITHUB_ENV
|
||||
echo "${{ github.workspace }}/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Build pyosys
|
||||
run: |
|
||||
make config-clang
|
||||
echo "ENABLE_VERIFIC := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
echo "ENABLE_PYOSYS := 1" >> Makefile.conf
|
||||
echo "PYTHON_DESTDIR := /usr/lib/python3/site-packages" >> Makefile.conf
|
||||
make -j$procs
|
||||
|
||||
- name: Install pyosys
|
||||
run: |
|
||||
make install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX=
|
||||
|
||||
- name: Run pyosys tests
|
||||
run: |
|
||||
export PYTHONPATH=${GITHUB_WORKSPACE}/.local/usr/lib/python3/site-packages:$PYTHONPATH
|
||||
python3 tests/pyosys/run_tests.py
|
||||
|
|
|
|||
3
.github/workflows/update-flake-lock.yml
vendored
3
.github/workflows/update-flake-lock.yml
vendored
|
|
@ -6,10 +6,13 @@ on:
|
|||
|
||||
jobs:
|
||||
lockfile:
|
||||
if: github.repository == 'YosysHQ/Yosys'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
- name: Update flake.lock
|
||||
|
|
|
|||
9
.github/workflows/version.yml
vendored
9
.github/workflows/version.yml
vendored
|
|
@ -7,6 +7,7 @@ on:
|
|||
|
||||
jobs:
|
||||
bump-version:
|
||||
if: github.repository == 'YosysHQ/Yosys'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -14,14 +15,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
- name: Take last commit
|
||||
id: log
|
||||
run: echo "message=$(git log --no-merges -1 --oneline)" >> $GITHUB_OUTPUT
|
||||
- name: Take repository
|
||||
id: repo
|
||||
run: echo "message=$GITHUB_REPOSITORY" >> $GITHUB_OUTPUT
|
||||
- name: Bump version
|
||||
if: "!contains(steps.log.outputs.message, 'Bump version') && contains(steps.repo.outputs.message, 'YosysHQ/yosys')"
|
||||
if: ${{ !contains(steps.log.outputs.message, 'Bump version') }}
|
||||
run: |
|
||||
make bumpversion
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
|
@ -29,7 +28,7 @@ jobs:
|
|||
git add Makefile
|
||||
git commit -m "Bump version"
|
||||
- name: Push changes # push the output folder to your repo
|
||||
if: "!contains(steps.log.outputs.message, 'Bump version') && contains(steps.repo.outputs.message, 'YosysHQ/yosys')"
|
||||
if: ${{ !contains(steps.log.outputs.message, 'Bump version') }}
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
70
.github/workflows/wheels.yml
vendored
70
.github/workflows/wheels.yml
vendored
|
|
@ -1,6 +1,10 @@
|
|||
name: Build Wheels for PyPI
|
||||
|
||||
# run every Sunday at 10 AM
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 10 * * 0"
|
||||
|
||||
jobs:
|
||||
build_wheels:
|
||||
|
|
@ -14,26 +18,22 @@ jobs:
|
|||
runner: "ubuntu-22.04",
|
||||
archs: "x86_64",
|
||||
},
|
||||
## Aarch64 is disabled for now: GitHub is committing to EOY
|
||||
## for free aarch64 runners for open-source projects and
|
||||
## emulation times out:
|
||||
## https://github.com/orgs/community/discussions/19197#discussioncomment-10550689
|
||||
# {
|
||||
# name: "Ubuntu 22.04",
|
||||
# family: "linux",
|
||||
# runner: "ubuntu-22.04",
|
||||
# archs: "aarch64",
|
||||
# },
|
||||
{
|
||||
name: "macOS 13",
|
||||
name: "Ubuntu 22.04",
|
||||
family: "linux",
|
||||
runner: "ubuntu-22.04-arm",
|
||||
archs: "aarch64",
|
||||
},
|
||||
{
|
||||
name: "macOS 15 x64",
|
||||
family: "macos",
|
||||
runner: "macos-13",
|
||||
runner: "macos-15-intel",
|
||||
archs: "x86_64",
|
||||
},
|
||||
{
|
||||
name: "macOS 14",
|
||||
name: "macOS 15 arm64",
|
||||
family: "macos",
|
||||
runner: "macos-14",
|
||||
runner: "macos-15",
|
||||
archs: "arm64",
|
||||
},
|
||||
## Windows is disabled because of an issue with compiling FFI as
|
||||
|
|
@ -53,28 +53,26 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- if: ${{ matrix.os.family == 'linux' }}
|
||||
name: "[Linux] Set up QEMU"
|
||||
uses: docker/setup-qemu-action@v3
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Get Boost Source
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p boost
|
||||
curl -L https://github.com/boostorg/boost/releases/download/boost-1.86.0/boost-1.86.0-b2-nodocs.tar.gz | tar --strip-components=1 -xzC boost
|
||||
- name: Get FFI
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ffi
|
||||
curl -L https://github.com/libffi/libffi/releases/download/v3.4.6/libffi-3.4.6.tar.gz | tar --strip-components=1 -xzC ffi
|
||||
curl -L https://github.com/libffi/libffi/releases/download/v3.4.8/libffi-3.4.8.tar.gz | tar --strip-components=1 -xzC ffi
|
||||
- if: ${{ matrix.os.family == 'linux' }}
|
||||
name: "[Linux] Bison 3.8.2"
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p bison
|
||||
curl -L https://ftpmirror.gnu.org/gnu/bison/bison-3.8.2.tar.gz | tar --strip-components=1 -xzC bison
|
||||
## Software installed by default in GitHub Action Runner VMs:
|
||||
## https://github.com/actions/runner-images
|
||||
- if: ${{ matrix.os.family == 'macos' }}
|
||||
name: "[macOS] Flex/Bison"
|
||||
run: |
|
||||
brew install flex bison
|
||||
echo "PATH=$(brew --prefix flex)/bin:$PATH" >> $GITHUB_ENV
|
||||
echo "PATH=$(brew --prefix bison)/bin:$PATH" >> $GITHUB_ENV
|
||||
echo "PATH=$(brew --prefix flex)/bin:$(brew --prefix bison)/bin:$PATH" >> $GITHUB_ENV
|
||||
- if: ${{ matrix.os.family == 'windows' }}
|
||||
name: "[Windows] Flex/Bison"
|
||||
run: |
|
||||
|
|
@ -99,25 +97,30 @@ jobs:
|
|||
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
|
||||
CIBW_BEFORE_ALL: bash ./.github/workflows/wheels/cibw_before_all.sh
|
||||
CIBW_ENVIRONMENT: >
|
||||
CXXFLAGS=-I./boost/pfx/include
|
||||
LINKFLAGS=-L./boost/pfx/lib
|
||||
OPTFLAGS=-O3
|
||||
PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig
|
||||
makeFlags='BOOST_PYTHON_LIB=./boost/pfx/lib/libboost_python*.a'
|
||||
PATH="$PWD/bison/src:$PATH"
|
||||
CIBW_ENVIRONMENT_MACOS: >
|
||||
CXXFLAGS=-I./boost/pfx/include
|
||||
LINKFLAGS=-L./boost/pfx/lib
|
||||
OPTFLAGS=-O3
|
||||
PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig
|
||||
MACOSX_DEPLOYMENT_TARGET=11
|
||||
makeFlags='BOOST_PYTHON_LIB=./boost/pfx/lib/libboost_python*.a CONFIG=clang'
|
||||
makeFlags='CONFIG=clang'
|
||||
PATH="$PWD/bison/src:$PATH"
|
||||
CIBW_BEFORE_BUILD: bash ./.github/workflows/wheels/cibw_before_build.sh
|
||||
CIBW_TEST_COMMAND: python3 {project}/tests/arch/ecp5/add_sub.py
|
||||
CIBW_TEST_COMMAND: python3 {project}/tests/pyosys/run_tests.py
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: python-wheels-${{ matrix.os.runner }}
|
||||
path: ./wheelhouse/*.whl
|
||||
upload_wheels:
|
||||
name: Upload Wheels
|
||||
if: (github.repository == 'YosysHQ/Yosys') && (github.event_name == 'workflow_dispatch')
|
||||
runs-on: ubuntu-latest
|
||||
# Specifying a GitHub environment is optional, but strongly encouraged
|
||||
environment: pypi
|
||||
permissions:
|
||||
# IMPORTANT: this permission is mandatory for Trusted Publishing
|
||||
id-token: write
|
||||
needs: build_wheels
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
|
|
@ -131,6 +134,3 @@ jobs:
|
|||
mv *.whl ./dist
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.PYPI_TOKEN }}
|
||||
repository-url: ${{ vars.PYPI_INDEX || 'https://upload.pypi.org/legacy/' }}
|
||||
|
|
|
|||
14
.github/workflows/wheels/_run_cibw_linux.py
vendored
14
.github/workflows/wheels/_run_cibw_linux.py
vendored
|
|
@ -20,11 +20,19 @@ import os
|
|||
import yaml
|
||||
import platform
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
__dir__ = os.path.dirname(os.path.abspath(__file__))
|
||||
__yosys_root__ = Path(__file__).absolute().parents[3]
|
||||
|
||||
for source in ["ffi", "bison"]:
|
||||
if not (__yosys_root__ / source).is_dir():
|
||||
print(
|
||||
"You need to download ffi and bison in a similar manner to wheels.yml first."
|
||||
)
|
||||
exit(-1)
|
||||
|
||||
workflow = yaml.safe_load(open(os.path.join(os.path.dirname(__dir__), "wheels.yml")))
|
||||
with open(__yosys_root__ / ".github" / "workflows" / "wheels.yml") as f:
|
||||
workflow = yaml.safe_load(f)
|
||||
|
||||
env = os.environ.copy()
|
||||
|
||||
|
|
@ -40,5 +48,5 @@ for key, value in cibw_step["env"].items():
|
|||
continue
|
||||
env[key] = value
|
||||
|
||||
env["CIBW_ARCHS"] = os.getenv("CIBW_ARCHS") or platform.machine()
|
||||
env["CIBW_ARCHS"] = os.getenv("CIBW_ARCHS", platform.machine())
|
||||
subprocess.check_call(["cibuildwheel"], env=env)
|
||||
|
|
|
|||
36
.github/workflows/wheels/cibw_before_all.sh
vendored
36
.github/workflows/wheels/cibw_before_all.sh
vendored
|
|
@ -1,23 +1,37 @@
|
|||
set -e
|
||||
set -x
|
||||
#!/bin/bash
|
||||
set -e -x
|
||||
|
||||
# Build-time dependencies
|
||||
## Linux Docker Images
|
||||
if command -v yum &> /dev/null; then
|
||||
yum install -y flex bison
|
||||
yum install -y flex # manylinux's bison versions are hopelessly out of date
|
||||
fi
|
||||
|
||||
if command -v apk &> /dev/null; then
|
||||
apk add flex bison
|
||||
fi
|
||||
|
||||
if ! printf '%s\n' '%require "3.8"' '%%' 'start: ;' | bison -o /dev/null /dev/stdin ; then
|
||||
(
|
||||
set -e -x
|
||||
cd bison
|
||||
./configure
|
||||
make clean
|
||||
make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu)
|
||||
)
|
||||
fi
|
||||
|
||||
## macOS/Windows -- installed in GitHub Action itself, not container
|
||||
|
||||
# Build Static FFI (platform-dependent but not Python version dependent)
|
||||
cd ffi
|
||||
## Ultimate libyosys.so will be shared, so we need fPIC for the static libraries
|
||||
CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PWD/pfx
|
||||
## Without this, SHELL has a space in its path which breaks the makefile
|
||||
make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu)
|
||||
## Forces static library to be used in all situations
|
||||
sed -i.bak 's@-L${toolexeclibdir} -lffi@${toolexeclibdir}/libffi.a@' ./pfx/lib/pkgconfig/libffi.pc
|
||||
# Runtime Dependencies
|
||||
## Build Static FFI (platform-dependent but not Python version dependent)
|
||||
(
|
||||
set -e -x
|
||||
cd ffi
|
||||
## Ultimate libyosys.so will be shared, so we need fPIC for the static libraries
|
||||
CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PWD/pfx
|
||||
make clean
|
||||
make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu)
|
||||
## Forces static library to be used in all situations
|
||||
sed -i.bak 's@-L${toolexeclibdir} -lffi@${toolexeclibdir}/libffi.a@' ./pfx/lib/pkgconfig/libffi.pc
|
||||
)
|
||||
|
|
|
|||
25
.github/workflows/wheels/cibw_before_build.sh
vendored
25
.github/workflows/wheels/cibw_before_build.sh
vendored
|
|
@ -1,8 +1,8 @@
|
|||
set -e
|
||||
set -x
|
||||
|
||||
# Don't use objects from previous compiles on Windows/macOS
|
||||
make clean
|
||||
# Don't use Python objects from previous compiles
|
||||
make clean-py
|
||||
|
||||
# DEBUG: show python3 and python3-config outputs
|
||||
if [ "$(uname)" != "Linux" ]; then
|
||||
|
|
@ -11,24 +11,3 @@ if [ "$(uname)" != "Linux" ]; then
|
|||
fi
|
||||
python3 --version
|
||||
python3-config --includes
|
||||
|
||||
# Build boost
|
||||
cd ./boost
|
||||
## Delete the artefacts from previous builds (if any)
|
||||
rm -rf ./pfx
|
||||
## Bootstrap bjam
|
||||
./bootstrap.sh --prefix=./pfx
|
||||
## Build Boost against current version of Python, only for
|
||||
## static linkage (Boost is statically linked because system boost packages
|
||||
## wildly vary in versions, including the libboost_python3 version)
|
||||
./b2\
|
||||
-j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu)\
|
||||
--prefix=./pfx\
|
||||
--with-filesystem\
|
||||
--with-system\
|
||||
--with-python\
|
||||
cxxflags="$(python3-config --includes) -std=c++17 -fPIC"\
|
||||
cflags="$(python3-config --includes) -fPIC"\
|
||||
link=static\
|
||||
variant=release\
|
||||
install
|
||||
|
|
|
|||
80
.gitignore
vendored
80
.gitignore
vendored
|
|
@ -1,24 +1,29 @@
|
|||
## user config
|
||||
/Makefile.conf
|
||||
|
||||
## homebrew
|
||||
/Brewfile.lock.json
|
||||
|
||||
## build artifacts
|
||||
/.git-abc-submodule-hash
|
||||
# compiler intermediate files
|
||||
*.o
|
||||
*.d
|
||||
*.dwo
|
||||
.*.swp
|
||||
*.gch
|
||||
*.gcda
|
||||
*.gcno
|
||||
*~
|
||||
__pycache__
|
||||
/.cproject
|
||||
/.project
|
||||
/.settings
|
||||
/qtcreator.files
|
||||
/qtcreator.includes
|
||||
/qtcreator.config
|
||||
/qtcreator.creator
|
||||
/qtcreator.creator.user
|
||||
/coverage.info
|
||||
/coverage_html
|
||||
/Makefile.conf
|
||||
/viz.js
|
||||
*.so.dSYM/
|
||||
|
||||
## test artifacts
|
||||
**/run-test.mk
|
||||
*.err
|
||||
*.log
|
||||
*.tmp
|
||||
|
||||
# compiler output files
|
||||
/kernel/version_*.cc
|
||||
/share
|
||||
/yosys
|
||||
/yosys.exe
|
||||
/yosys.js
|
||||
|
|
@ -34,21 +39,50 @@ __pycache__
|
|||
/yosys-witness-script.py
|
||||
/yosys-filterlib
|
||||
/yosys-filterlib.exe
|
||||
/kernel/*.pyh
|
||||
/kernel/python_wrappers.cc
|
||||
/kernel/version_*.cc
|
||||
/share
|
||||
/yosys-win32-mxebin-*
|
||||
/yosys-win32-vcxsrc-*
|
||||
/yosysjs-*
|
||||
/libyosys.so
|
||||
|
||||
# build directories
|
||||
/tests/unit/bintest/
|
||||
/tests/unit/objtest/
|
||||
/tests/ystests
|
||||
/build
|
||||
/result
|
||||
/dist
|
||||
/*.egg-info
|
||||
/build
|
||||
/venv
|
||||
/boost
|
||||
|
||||
# pyosys
|
||||
/kernel/*.pyh
|
||||
/kernel/python_wrappers.cc
|
||||
/ffi
|
||||
/bison
|
||||
/venv
|
||||
/*.whl
|
||||
/*.egg-info
|
||||
|
||||
# yosysjs dependency
|
||||
/viz.js
|
||||
|
||||
# other
|
||||
/coverage.info
|
||||
/coverage_html
|
||||
|
||||
|
||||
# these really belong in global gitignore since they're not specific to this project but rather to user tool choice
|
||||
# but too many people don't have a global gitignore configured:
|
||||
# https://docs.github.com/en/get-started/git-basics/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer
|
||||
__pycache__
|
||||
*~
|
||||
.*.swp
|
||||
/.cache
|
||||
/.vscode
|
||||
/.cproject
|
||||
/.project
|
||||
/.settings
|
||||
/qtcreator.files
|
||||
/qtcreator.includes
|
||||
/qtcreator.config
|
||||
/qtcreator.creator
|
||||
/qtcreator.creator.user
|
||||
/compile_commands.json
|
||||
|
|
|
|||
6
Brewfile
6
Brewfile
|
|
@ -6,9 +6,9 @@ brew "git"
|
|||
brew "graphviz"
|
||||
brew "pkg-config"
|
||||
brew "python3"
|
||||
brew "tcl-tk"
|
||||
brew "uv"
|
||||
brew "xdot"
|
||||
brew "bash"
|
||||
brew "boost-python3"
|
||||
brew "llvm"
|
||||
brew "llvm@20"
|
||||
brew "lld"
|
||||
brew "googletest"
|
||||
|
|
|
|||
139
CHANGELOG
139
CHANGELOG
|
|
@ -2,9 +2,146 @@
|
|||
List of major changes and improvements between releases
|
||||
=======================================================
|
||||
|
||||
Yosys 0.51 .. Yosys 0.52-dev
|
||||
Yosys 0.60 .. Yosys 0.61-dev
|
||||
--------------------------
|
||||
|
||||
Yosys 0.59 .. Yosys 0.60
|
||||
--------------------------
|
||||
* Various
|
||||
- read_verilog: suport unsized parameters.
|
||||
- Added static library compile option.
|
||||
|
||||
* New commands and options
|
||||
- Added "sdc" pass for reading SDC files.
|
||||
- Added experimental "sdc_expand" and "opensta" for OpenSTA integration.
|
||||
- Added "icell_liberty" pass for used internal cells.
|
||||
|
||||
Yosys 0.58 .. Yosys 0.59
|
||||
--------------------------
|
||||
* Various
|
||||
- Pyosys is rewritten using pybind11.
|
||||
- alumacc: merge independent of sign.
|
||||
- write_btor: Include $assert and $assume cells in -ywmap output.
|
||||
- RTLIL parser rewritten for efficiency.
|
||||
- Wildcards enabled for Liberty file consuming.
|
||||
- timeest: Add top ports launching/sampling.
|
||||
|
||||
* New commands and options
|
||||
- Added "-apply_derived_type" option to "box_derive" pass.
|
||||
- Added "-publish_icells" option to "chtype" pass.
|
||||
- Added "-width" option to "sim" pass.
|
||||
- Added "sort" pass for sorting the design objects.
|
||||
- Merged "synth_ecp5" and "synth_nexus" into "synth_lattice" pass.
|
||||
- Added "-strict-gw5a-dffs" and "-setundef" options to "synth_gowin" pass.
|
||||
|
||||
Yosys 0.57 .. Yosys 0.58
|
||||
--------------------------
|
||||
* Various
|
||||
- Run ABC passes in parallel.
|
||||
- Extending support for buffer normalization.
|
||||
- Overhaul of logging APIs.
|
||||
- read_blif: Represent sequential elements with gate cells.
|
||||
- Support multiple lib files in abc9_exe.
|
||||
|
||||
* New commands and options
|
||||
- Added "-wireshape" option to "show" command to allow
|
||||
control the shape of wire nodes.
|
||||
- Added "-relativeshare" option to "read_verilog", "synth"
|
||||
and "techmap" pass for synthesis reproducibility testing.
|
||||
- "write_rtlil" pass no longer sorts design, added "-sort"
|
||||
option to match old behavior
|
||||
- Added "-sva-continue-on-err" to "verific" pass to allow
|
||||
processing designs that includes unsupported SVA.
|
||||
|
||||
Yosys 0.56 .. Yosys 0.57
|
||||
--------------------------
|
||||
* New commands and options
|
||||
- Added "-initstates" option to "abstract" pass.
|
||||
- Added "-set-assumes" option to "equiv_induct"
|
||||
and "equiv_simple" passes.
|
||||
- Added "-always" option to "raise_error" pass.
|
||||
- Added "-hierarchy" option to "stat" pass.
|
||||
- Added "-noflatten" option to "synth_quicklogic" pass.
|
||||
|
||||
* Various
|
||||
- smtbmc: Support skipping steps in cover mode.
|
||||
- write_btor: support $buf.
|
||||
- read_verilog: support package import.
|
||||
|
||||
Yosys 0.55 .. Yosys 0.56
|
||||
--------------------------
|
||||
* New commands and options
|
||||
- Added "-unescape" option to "rename" pass.
|
||||
- Added "-assert2cover" option to "chformal" pass.
|
||||
- Added "linecoverage" pass to generate lcov report from selection.
|
||||
- Added "opt_hier" pass to enable hierarchical optimization.
|
||||
- Added "-hieropt" option to "synth" pass.
|
||||
- Added "-expect-return", "-err-grep" and "-suffix" options
|
||||
to "bugpoint" pass.
|
||||
- Added "raise_error" dev pass.
|
||||
|
||||
* Various
|
||||
- Added groups to command reference documentation.
|
||||
- Added bugpoint guide to documentation.
|
||||
- verific: correctly reset Verific flags after import.
|
||||
|
||||
Yosys 0.54 .. Yosys 0.55
|
||||
--------------------------
|
||||
* Various
|
||||
- read_verilog: Implemented SystemVerilog unique/priority if.
|
||||
- "attrmap" pass is able to alter memory attributes.
|
||||
- verific: Support SVA followed-by operator in cover mode.
|
||||
|
||||
Yosys 0.53 .. Yosys 0.54
|
||||
--------------------------
|
||||
* New commands and options
|
||||
- Added "-genlib" option to "abc_new" and "abc9_exe" passes.
|
||||
- Added "-verbose" and "-quiet" options to "libcache" pass.
|
||||
- Added "-no-sort" option to "write_aiger" pass.
|
||||
|
||||
* Various
|
||||
- Added "muldiv_c" peepopt.
|
||||
- Accept (and ignore) SystemVerilog unique/priority if.
|
||||
- "read_verilog" copy inout ports in and out of functions/tasks.
|
||||
- Enable single-bit vector wires in RTLIL.
|
||||
|
||||
* Xilinx support
|
||||
- Single-port URAM mapping to support memories 2048 x 144b
|
||||
|
||||
Yosys 0.52 .. Yosys 0.53
|
||||
--------------------------
|
||||
* New commands and options
|
||||
- Added "constmap" pass for technology mapping of coarse constant value.
|
||||
- Added "timeest" pass to estimate the critical path in clock domain.
|
||||
- Added "-blackbox" option to "cutpoint" pass to cut all instances of
|
||||
blackboxes.
|
||||
- Added "-noscopeinfo" option to "cutpoint" pass.
|
||||
- Added "-nocleanup" option to "flatten" pass to prevent removal of
|
||||
unused submodules.
|
||||
- Added "-declockgate" option to "formalff" pass that turns clock
|
||||
gating into clock enables.
|
||||
|
||||
* Various
|
||||
- Added "$scopeinfo" cells to preserve information during "cutpoint" pass.
|
||||
- Added dataflow tracking documentation.
|
||||
- share: Restrict activation patterns to potentially relevant signal.
|
||||
- liberty: More robust parsing.
|
||||
- verific: bit blast RAM if using mem2reg attribute.
|
||||
|
||||
Yosys 0.51 .. Yosys 0.52
|
||||
--------------------------
|
||||
* New commands and options
|
||||
- Added "-pattern-limit" option to "share" pass to limit analysis effort.
|
||||
- Added "libcache" pass to control caching of technology library
|
||||
data parsed from liberty files.
|
||||
- Added "read_verilog_file_list" to parse verilog file list.
|
||||
|
||||
* Various
|
||||
- Added $macc_v2 cell.
|
||||
- Improve lexer performance and zlib support for "read_liberty".
|
||||
- opt_expr: optimize pow of 2 cells.
|
||||
|
||||
|
||||
Yosys 0.50 .. Yosys 0.51
|
||||
--------------------------
|
||||
* New commands and options
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ passes/opt/opt_lut.cc @whitequark
|
|||
passes/techmap/abc9*.cc @eddiehung @Ravenslofty
|
||||
backends/aiger/xaiger.cc @eddiehung
|
||||
docs/ @KrystalDelusion
|
||||
docs/source/using_yosys/synthesis/abc.rst @KrystalDelusion @Ravenslofty
|
||||
.github/workflows/*.yml @mmicko
|
||||
|
||||
## External Contributors
|
||||
|
|
@ -29,15 +30,16 @@ docs/ @KrystalDelusion
|
|||
# These still override previous lines, so be careful not to
|
||||
# accidentally disable any of the above rules.
|
||||
|
||||
frontends/verilog/ @zachjs
|
||||
frontends/ast/ @zachjs
|
||||
frontends/verilog/ @widlarizer
|
||||
frontends/ast/ @widlarizer
|
||||
|
||||
techlibs/intel_alm/ @Ravenslofty
|
||||
techlibs/gowin/ @pepijndevos
|
||||
techlibs/gatemate/ @pu-cc
|
||||
|
||||
# pyosys
|
||||
misc/*.py @btut
|
||||
pyosys/* @donn
|
||||
setup.py @donn
|
||||
|
||||
backends/firrtl @ucbjrl @azidar
|
||||
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ much easier for someone to respond and help.
|
|||
|
||||
### Bug reports
|
||||
|
||||
Before you submit an issue, please have a search of the existing issues in case
|
||||
one already exists. Making sure that you have a minimal, complete and
|
||||
verifiable example (MVCE) is a great way to quickly check an existing issue
|
||||
against a new one. Stack overflow has a guide on [how to create an
|
||||
MVCE](https://stackoverflow.com/help/minimal-reproducible-example). The
|
||||
[`bugpoint`
|
||||
command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/bugpoint.html)
|
||||
in Yosys can be helpful for this process.
|
||||
Before you submit an issue, please check out the [how-to guide for
|
||||
`bugpoint`](https://yosys.readthedocs.io/en/latest/using_yosys/bugpoint.html).
|
||||
This guide will take you through the process of using the [`bugpoint`
|
||||
command](https://yosys.readthedocs.io/en/latest/cmd/bugpoint.html) in Yosys to
|
||||
produce a [minimal, complete and verifiable
|
||||
example](https://stackoverflow.com/help/minimal-reproducible-example) (MVCE).
|
||||
Providing an MVCE with your bug report drastically increases the likelihood that
|
||||
someone will be able to help resolve your issue.
|
||||
|
||||
|
||||
# Using pull requests
|
||||
|
|
@ -60,14 +60,11 @@ merge; please do not use these labels if you are not a maintainer.
|
|||
|
||||
# Asking questions
|
||||
|
||||
If you have a question about how to use Yosys, please ask on our [discussions
|
||||
page](https://github.com/YosysHQ/yosys/discussions) or in our [community
|
||||
slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA).
|
||||
The slack is also a great place to ask questions about developing or
|
||||
If you have a question about how to use Yosys, please ask on our [Discourse forum](https://yosyshq.discourse.group/) or in our [discussions
|
||||
page](https://github.com/YosysHQ/yosys/discussions).
|
||||
The Discourse is also a great place to ask questions about developing or
|
||||
contributing to Yosys.
|
||||
|
||||
We have open dev 'jour fixe' (JF) meetings where developers from YosysHQ and the
|
||||
We have open [dev 'jour fixe' (JF) meetings](https://docs.google.com/document/d/1SapA6QAsJcsgwsdKJDgnGR2mr97pJjV4eeXg_TVJhRU/edit?usp=sharing) where developers from YosysHQ and the
|
||||
community come together to discuss open issues and PRs. This is also a good
|
||||
place to talk to us about how to implement larger PRs. Please join the
|
||||
community slack if you would like to join the next meeting, the link is
|
||||
available in the description of the #devel-discuss channel.
|
||||
place to talk to us about how to implement larger PRs.
|
||||
|
|
|
|||
287
Makefile
287
Makefile
|
|
@ -21,12 +21,14 @@ ENABLE_VERIFIC_HIER_TREE := 1
|
|||
ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 0
|
||||
ENABLE_VERIFIC_EDIF := 0
|
||||
ENABLE_VERIFIC_LIBERTY := 0
|
||||
ENABLE_COVER := 1
|
||||
ENABLE_LIBYOSYS := 0
|
||||
ENABLE_LIBYOSYS_STATIC := 0
|
||||
ENABLE_ZLIB := 1
|
||||
ENABLE_HELP_SOURCE := 0
|
||||
|
||||
# python wrappers
|
||||
ENABLE_PYOSYS := 0
|
||||
PYOSYS_USE_UV := 1
|
||||
|
||||
# other configuration flags
|
||||
ENABLE_GCOV := 0
|
||||
|
|
@ -43,7 +45,12 @@ LINK_ABC := 0
|
|||
# Needed for environments that can't run executables (i.e. emscripten, wasm)
|
||||
DISABLE_SPAWN := 0
|
||||
# Needed for environments that don't have proper thread support (i.e. emscripten, wasm--for now)
|
||||
ENABLE_THREADS := 1
|
||||
ifeq ($(ENABLE_THREADS),1)
|
||||
DISABLE_ABC_THREADS := 0
|
||||
else
|
||||
DISABLE_ABC_THREADS := 1
|
||||
endif
|
||||
|
||||
# clang sanitizers
|
||||
SANITIZER =
|
||||
|
|
@ -88,26 +95,31 @@ TARGETS = $(PROGRAM_PREFIX)yosys$(EXE) $(PROGRAM_PREFIX)yosys-config
|
|||
PRETTY = 1
|
||||
SMALL = 0
|
||||
|
||||
# Unit test
|
||||
UNITESTPATH := tests/unit
|
||||
|
||||
all: top-all
|
||||
|
||||
YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST)))
|
||||
VPATH := $(YOSYS_SRC)
|
||||
|
||||
CXXSTD ?= c++17
|
||||
# Unit test
|
||||
UNITESTPATH := $(YOSYS_SRC)/tests/unit
|
||||
|
||||
export CXXSTD ?= c++17
|
||||
CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include
|
||||
LIBS := $(LIBS) -lstdc++ -lm
|
||||
PLUGIN_LINKFLAGS :=
|
||||
PLUGIN_LIBS :=
|
||||
EXE_LINKFLAGS :=
|
||||
EXE_LIBS :=
|
||||
ifeq ($(OS), MINGW)
|
||||
EXE_LINKFLAGS := -Wl,--export-all-symbols -Wl,--out-implib,libyosys_exe.a
|
||||
PLUGIN_LINKFLAGS += -L"$(LIBDIR)"
|
||||
PLUGIN_LIBS := -lyosys_exe
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_HELP_SOURCE),1)
|
||||
CXXFLAGS += -DYOSYS_ENABLE_HELP_SOURCE
|
||||
endif
|
||||
|
||||
PKG_CONFIG ?= pkg-config
|
||||
SED ?= sed
|
||||
BISON ?= bison
|
||||
|
|
@ -122,12 +134,8 @@ LINKFLAGS += -rdynamic
|
|||
ifneq ($(shell :; command -v brew),)
|
||||
BREW_PREFIX := $(shell brew --prefix)/opt
|
||||
$(info $$BREW_PREFIX is [${BREW_PREFIX}])
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
CXXFLAGS += -I$(BREW_PREFIX)/boost/include
|
||||
LINKFLAGS += -L$(BREW_PREFIX)/boost/lib -L$(BREW_PREFIX)/boost-python3/lib
|
||||
endif
|
||||
CXXFLAGS += -I$(BREW_PREFIX)/readline/include
|
||||
LINKFLAGS += -L$(BREW_PREFIX)/readline/lib
|
||||
CXXFLAGS += -I$(BREW_PREFIX)/readline/include -I$(BREW_PREFIX)/flex/include
|
||||
LINKFLAGS += -L$(BREW_PREFIX)/readline/lib -L$(BREW_PREFIX)/flex/lib
|
||||
PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH)
|
||||
PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH)
|
||||
export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH)
|
||||
|
|
@ -153,7 +161,7 @@ ifeq ($(OS), Haiku)
|
|||
CXXFLAGS += -D_DEFAULT_SOURCE
|
||||
endif
|
||||
|
||||
YOSYS_VER := 0.51+17
|
||||
YOSYS_VER := 0.60+64
|
||||
YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1)
|
||||
YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1)
|
||||
YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2)
|
||||
|
|
@ -169,14 +177,16 @@ CXXFLAGS += -DYOSYS_VER=\\"$(YOSYS_VER)\\" \
|
|||
TARBALL_GIT_REV := $(shell cat $(YOSYS_SRC)/.gitcommit)
|
||||
ifneq ($(findstring Format:,$(TARBALL_GIT_REV)),)
|
||||
GIT_REV := $(shell GIT_DIR=$(YOSYS_SRC)/.git git rev-parse --short=9 HEAD || echo UNKNOWN)
|
||||
GIT_DIRTY := $(shell GIT_DIR=$(YOSYS_SRC)/.git git diff --exit-code --quiet 2>/dev/null; if [ $$? -ne 0 ]; then echo "-dirty"; fi)
|
||||
else
|
||||
GIT_REV := $(TARBALL_GIT_REV)
|
||||
GIT_DIRTY := ""
|
||||
endif
|
||||
|
||||
OBJS = kernel/version_$(GIT_REV).o
|
||||
|
||||
bumpversion:
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline c4b5190.. | wc -l`/;" Makefile
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 5bafeb7.. | wc -l`/;" Makefile
|
||||
|
||||
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
|
||||
|
||||
|
|
@ -197,17 +207,17 @@ endif
|
|||
include Makefile.conf
|
||||
endif
|
||||
|
||||
PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
|
||||
PYTHON_EXECUTABLE ?= $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)"
|
||||
PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"")
|
||||
PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.)
|
||||
|
||||
ENABLE_PYTHON_CONFIG_EMBED ?= $(shell $(PYTHON_EXECUTABLE)-config --embed --libs > /dev/null && echo 1)
|
||||
ifeq ($(ENABLE_PYTHON_CONFIG_EMBED),1)
|
||||
PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config --embed
|
||||
else
|
||||
PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config
|
||||
PYTHON_CONFIG_FOR_EXE := $(PYTHON_CONFIG)
|
||||
PYTHON_CONFIG_EMBED_AVAILABLE ?= $(shell $(PYTHON_EXECUTABLE)-config --embed --libs > /dev/null && echo 1)
|
||||
ifeq ($(PYTHON_CONFIG_EMBED_AVAILABLE),1)
|
||||
PYTHON_CONFIG_FOR_EXE := $(PYTHON_CONFIG) --embed
|
||||
endif
|
||||
|
||||
PYTHON_DESTDIR := $(shell $(PYTHON_EXECUTABLE) -c "import site; print(site.getsitepackages()[-1]);")
|
||||
|
|
@ -240,9 +250,6 @@ ifneq ($(SANITIZER),)
|
|||
$(info [Clang Sanitizer] $(SANITIZER))
|
||||
CXXFLAGS += -g -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=$(SANITIZER)
|
||||
LINKFLAGS += -g -fsanitize=$(SANITIZER)
|
||||
ifneq ($(findstring address,$(SANITIZER)),)
|
||||
ENABLE_COVER := 0
|
||||
endif
|
||||
ifneq ($(findstring memory,$(SANITIZER)),)
|
||||
CXXFLAGS += -fPIE -fsanitize-memory-track-origins
|
||||
LINKFLAGS += -fPIE -fsanitize-memory-track-origins
|
||||
|
|
@ -275,12 +282,11 @@ ifeq ($(WASI_SDK),)
|
|||
CXX = clang++
|
||||
AR = llvm-ar
|
||||
RANLIB = llvm-ranlib
|
||||
WASIFLAGS := -target wasm32-wasi --sysroot $(WASI_SYSROOT) $(WASIFLAGS)
|
||||
WASIFLAGS := -target wasm32-wasi $(WASIFLAGS)
|
||||
else
|
||||
CXX = $(WASI_SDK)/bin/clang++
|
||||
AR = $(WASI_SDK)/bin/ar
|
||||
RANLIB = $(WASI_SDK)/bin/ranlib
|
||||
WASIFLAGS := --sysroot $(WASI_SDK)/share/wasi-sysroot $(WASIFLAGS)
|
||||
endif
|
||||
CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) $(OPT_LEVEL) -D_WASI_EMULATED_PROCESS_CLOCKS $(filter-out -fPIC,$(CXXFLAGS))
|
||||
LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS))
|
||||
|
|
@ -294,6 +300,7 @@ DISABLE_SPAWN := 1
|
|||
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
LINK_ABC := 1
|
||||
ENABLE_THREADS := 0
|
||||
DISABLE_ABC_THREADS := 1
|
||||
endif
|
||||
|
||||
|
|
@ -303,7 +310,7 @@ CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR
|
|||
CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS))
|
||||
LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s
|
||||
LIBS := $(filter-out -lrt,$(LIBS))
|
||||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC -fpermissive -w"
|
||||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w"
|
||||
ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="i686-w64-mingw32-gcc" CXX="$(CXX)"
|
||||
EXE = .exe
|
||||
|
||||
|
|
@ -313,7 +320,7 @@ CXXFLAGS += -std=$(CXXSTD) $(OPT_LEVEL) -D_POSIX_SOURCE -DYOSYS_WIN32_UNIX_DIR
|
|||
CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS))
|
||||
LINKFLAGS := $(filter-out -rdynamic,$(LINKFLAGS)) -s
|
||||
LIBS := $(filter-out -lrt,$(LIBS))
|
||||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC -fpermissive -w"
|
||||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DWIN32_NO_DLL -DWIN32 -DHAVE_STRUCT_TIMESPEC -fpermissive -w"
|
||||
ABCMKARGS += LIBS="-lpthread -lshlwapi -s" ABC_USE_NO_READLINE=0 CC="x86_64-w64-mingw32-gcc" CXX="$(CXX)"
|
||||
EXE = .exe
|
||||
|
||||
|
|
@ -334,32 +341,35 @@ endif
|
|||
|
||||
ifeq ($(ENABLE_LIBYOSYS),1)
|
||||
TARGETS += libyosys.so
|
||||
ifeq ($(ENABLE_LIBYOSYS_STATIC),1)
|
||||
TARGETS += libyosys.a
|
||||
endif
|
||||
endif
|
||||
|
||||
PY_WRAPPER_FILE = pyosys/wrappers
|
||||
|
||||
# running make clean on just those and then recompiling saves a lot of
|
||||
# time when running cibuildwheel
|
||||
PYTHON_OBJECTS = pyosys/wrappers.o kernel/drivers.o kernel/yosys.o passes/cmds/plugin.o
|
||||
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
# python-config --ldflags includes -l and -L, but LINKFLAGS is only -L
|
||||
LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags))
|
||||
LIBS += $(shell $(PYTHON_CONFIG) --libs)
|
||||
CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON
|
||||
|
||||
# Detect name of boost_python library. Some distros use boost_python-py<version>, other boost_python<version>, some only use the major version number, some a concatenation of major and minor version numbers
|
||||
CHECK_BOOST_PYTHON = (echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(LINKFLAGS) $(LIBS) -l$(1) - > /dev/null 2>&1 && echo "-l$(1)")
|
||||
BOOST_PYTHON_LIB ?= $(shell \
|
||||
$(call CHECK_BOOST_PYTHON,boost_python-py$(subst .,,$(PYTHON_VERSION))) || \
|
||||
$(call CHECK_BOOST_PYTHON,boost_python-py$(PYTHON_MAJOR_VERSION)) || \
|
||||
$(call CHECK_BOOST_PYTHON,boost_python$(subst .,,$(PYTHON_VERSION))) || \
|
||||
$(call CHECK_BOOST_PYTHON,boost_python$(PYTHON_MAJOR_VERSION)) \
|
||||
)
|
||||
|
||||
ifeq ($(BOOST_PYTHON_LIB),)
|
||||
$(error BOOST_PYTHON_LIB could not be detected. Please define manually)
|
||||
UV_ENV :=
|
||||
ifeq ($(PYOSYS_USE_UV),1)
|
||||
UV_ENV := uv run --no-project --with 'pybind11>3,<4' --with 'cxxheaderparser'
|
||||
endif
|
||||
|
||||
LIBS += $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem
|
||||
PY_WRAPPER_FILE = kernel/python_wrappers
|
||||
LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags))
|
||||
LIBS += $(shell $(PYTHON_CONFIG) --libs)
|
||||
EXE_LIBS += $(filter-out $(LIBS),$(shell $(PYTHON_CONFIG_FOR_EXE) --libs))
|
||||
PYBIND11_INCLUDE ?= $(shell $(UV_ENV) $(PYTHON_EXECUTABLE) -m pybind11 --includes)
|
||||
CXXFLAGS += -I$(PYBIND11_INCLUDE) -DYOSYS_ENABLE_PYTHON
|
||||
CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DYOSYS_ENABLE_PYTHON
|
||||
|
||||
OBJS += $(PY_WRAPPER_FILE).o
|
||||
PY_GEN_SCRIPT= py_wrap_generator
|
||||
PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()")
|
||||
PY_GEN_SCRIPT = $(YOSYS_SRC)/pyosys/generator.py
|
||||
PY_WRAP_INCLUDES := $(shell $(UV_ENV) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) --print-includes)
|
||||
endif # ENABLE_PYOSYS
|
||||
|
||||
ifeq ($(ENABLE_READLINE),1)
|
||||
|
|
@ -388,6 +398,10 @@ ifeq ($(DISABLE_ABC_THREADS),1)
|
|||
ABCMKARGS += "ABC_USE_NO_PTHREADS=1"
|
||||
endif
|
||||
|
||||
ifeq ($(LINK_ABC),1)
|
||||
ABCMKARGS += "ABC_USE_PIC=1"
|
||||
endif
|
||||
|
||||
ifeq ($(DISABLE_SPAWN),1)
|
||||
CXXFLAGS += -DYOSYS_DISABLE_SPAWN
|
||||
endif
|
||||
|
|
@ -443,6 +457,12 @@ endif
|
|||
|
||||
ifeq ($(ENABLE_DEBUG),1)
|
||||
CXXFLAGS := -Og -DDEBUG $(filter-out $(OPT_LEVEL),$(CXXFLAGS))
|
||||
STRIP :=
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_THREADS),1)
|
||||
CXXFLAGS += -DYOSYS_ENABLE_THREADS
|
||||
LIBS += -lpthread
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
|
|
@ -456,6 +476,9 @@ else
|
|||
ifeq ($(ABCEXTERNAL),)
|
||||
TARGETS := $(PROGRAM_PREFIX)yosys-abc$(EXE) $(TARGETS)
|
||||
endif
|
||||
ifeq ($(DISABLE_SPAWN),1)
|
||||
$(error ENABLE_ABC=1 requires either LINK_ABC=1 or DISABLE_SPAWN=0)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
@ -507,8 +530,12 @@ ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1)
|
|||
VERIFIC_COMPONENTS += extensions
|
||||
CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS
|
||||
else
|
||||
# YosysHQ flavor of Verific always needs extensions linked
|
||||
# if disabled it will just not be invoked but parts
|
||||
# are required for it to initialize properly
|
||||
ifneq ($(wildcard $(VERIFIC_DIR)/extensions),)
|
||||
VERIFIC_COMPONENTS += extensions
|
||||
OBJS += kernel/log_compat.o
|
||||
endif
|
||||
endif
|
||||
CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC
|
||||
|
|
@ -519,11 +546,6 @@ LIBS_VERIFIC += -Wl,--whole-archive $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VE
|
|||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(ENABLE_COVER),1)
|
||||
CXXFLAGS += -DYOSYS_ENABLE_COVER
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_CCACHE),1)
|
||||
CXX := ccache $(CXX)
|
||||
else
|
||||
|
|
@ -539,6 +561,13 @@ $(subst //,/,$(1)/$(notdir $(2))): $(2)
|
|||
$$(Q) cp "$(YOSYS_SRC)"/$(2) $(subst //,/,$(1)/$(notdir $(2)))
|
||||
endef
|
||||
|
||||
define add_share_file_and_rename
|
||||
EXTRA_TARGETS += $(subst //,/,$(1)/$(3))
|
||||
$(subst //,/,$(1)/$(3)): $(2)
|
||||
$$(P) mkdir -p $(1)
|
||||
$$(Q) cp "$(YOSYS_SRC)"/$(2) $(subst //,/,$(1)/$(3))
|
||||
endef
|
||||
|
||||
define add_gen_share_file
|
||||
EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2)))
|
||||
$(subst //,/,$(1)/$(notdir $(2))): $(2)
|
||||
|
|
@ -586,7 +615,9 @@ $(eval $(call add_include_file,kernel/fmt.h))
|
|||
ifeq ($(ENABLE_ZLIB),1)
|
||||
$(eval $(call add_include_file,kernel/fstdata.h))
|
||||
endif
|
||||
$(eval $(call add_include_file,kernel/gzip.h))
|
||||
$(eval $(call add_include_file,kernel/hashlib.h))
|
||||
$(eval $(call add_include_file,kernel/io.h))
|
||||
$(eval $(call add_include_file,kernel/json.h))
|
||||
$(eval $(call add_include_file,kernel/log.h))
|
||||
$(eval $(call add_include_file,kernel/macc.h))
|
||||
|
|
@ -599,6 +630,7 @@ $(eval $(call add_include_file,kernel/satgen.h))
|
|||
$(eval $(call add_include_file,kernel/scopeinfo.h))
|
||||
$(eval $(call add_include_file,kernel/sexpr.h))
|
||||
$(eval $(call add_include_file,kernel/sigtools.h))
|
||||
$(eval $(call add_include_file,kernel/threading.h))
|
||||
$(eval $(call add_include_file,kernel/timinginfo.h))
|
||||
$(eval $(call add_include_file,kernel/utils.h))
|
||||
$(eval $(call add_include_file,kernel/yosys.h))
|
||||
|
|
@ -612,15 +644,21 @@ endif
|
|||
$(eval $(call add_include_file,libs/sha1/sha1.h))
|
||||
$(eval $(call add_include_file,libs/json11/json11.hpp))
|
||||
$(eval $(call add_include_file,passes/fsm/fsmdata.h))
|
||||
$(eval $(call add_include_file,passes/techmap/libparse.h))
|
||||
$(eval $(call add_include_file,frontends/ast/ast.h))
|
||||
$(eval $(call add_include_file,frontends/ast/ast_binding.h))
|
||||
$(eval $(call add_include_file,frontends/blif/blifparse.h))
|
||||
$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h))
|
||||
|
||||
OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o
|
||||
OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o
|
||||
OBJS += kernel/rtlil_bufnorm.o
|
||||
OBJS += kernel/log_help.o
|
||||
ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1)
|
||||
OBJS += kernel/log_compat.o
|
||||
endif
|
||||
OBJS += kernel/binding.o kernel/tclapi.o
|
||||
OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o
|
||||
OBJS += kernel/drivertools.o kernel/functional.o
|
||||
OBJS += kernel/drivertools.o kernel/functional.o kernel/threading.o
|
||||
ifeq ($(ENABLE_ZLIB),1)
|
||||
OBJS += kernel/fstdata.o
|
||||
endif
|
||||
|
|
@ -685,7 +723,6 @@ OBJS += passes/hierarchy/hierarchy.o
|
|||
OBJS += passes/cmds/select.o
|
||||
OBJS += passes/cmds/show.o
|
||||
OBJS += passes/cmds/stat.o
|
||||
OBJS += passes/cmds/cover.o
|
||||
OBJS += passes/cmds/design.o
|
||||
OBJS += passes/cmds/plugin.o
|
||||
|
||||
|
|
@ -726,15 +763,18 @@ share: $(EXTRA_TARGETS)
|
|||
@echo ""
|
||||
|
||||
$(PROGRAM_PREFIX)yosys$(EXE): $(OBJS)
|
||||
$(P) $(CXX) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LINKFLAGS) $(LINKFLAGS) $(OBJS) $(LIBS) $(LIBS_VERIFIC)
|
||||
$(P) $(CXX) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LINKFLAGS) $(LINKFLAGS) $(OBJS) $(EXE_LIBS) $(LIBS) $(LIBS_VERIFIC)
|
||||
|
||||
libyosys.so: $(filter-out kernel/driver.o,$(OBJS))
|
||||
ifeq ($(OS), Darwin)
|
||||
$(P) $(CXX) -o libyosys.so -shared -undefined dynamic_lookup -Wl,-install_name,$(LIBDIR)/libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC)
|
||||
$(P) $(CXX) -o libyosys.so -shared -undefined dynamic_lookup -Wl,-install_name,libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC)
|
||||
else
|
||||
$(P) $(CXX) -o libyosys.so -shared -Wl,-soname,$(LIBDIR)/libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC)
|
||||
$(P) $(CXX) -o libyosys.so -shared -Wl,-soname,libyosys.so $(LINKFLAGS) $^ $(LIBS) $(LIBS_VERIFIC)
|
||||
endif
|
||||
|
||||
libyosys.a: $(filter-out kernel/driver.o,$(OBJS))
|
||||
$(P) $(AR) rcs $@ $^
|
||||
|
||||
%.o: %.cc
|
||||
$(Q) mkdir -p $(dir $@)
|
||||
$(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $<
|
||||
|
|
@ -744,21 +784,22 @@ endif
|
|||
$(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(CXX) $(CXXFLAGS) -x c++ -o $@ -E -P -
|
||||
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
$(PY_WRAPPER_FILE).cc: misc/$(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES)
|
||||
$(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT) pyosys/wrappers_tpl.cc $(PY_WRAP_INCLUDES) pyosys/hashlib.h
|
||||
$(Q) mkdir -p $(dir $@)
|
||||
$(P) python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")"
|
||||
$(P) $(UV_ENV) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) $(PY_WRAPPER_FILE).cc
|
||||
endif
|
||||
|
||||
%.o: %.cpp
|
||||
$(Q) mkdir -p $(dir $@)
|
||||
$(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $<
|
||||
|
||||
YOSYS_VER_STR := Yosys $(YOSYS_VER) (git sha1 $(GIT_REV), $(notdir $(CXX)) $(shell \
|
||||
$(CXX) --version | tr ' ()' '\n' | grep '^[0-9]' | head -n1) $(filter -f% -m% -O% -DNDEBUG,$(CXXFLAGS)))
|
||||
YOSYS_GIT_STR := $(GIT_REV)$(GIT_DIRTY)
|
||||
YOSYS_COMPILER := $(notdir $(CXX)) $(shell $(CXX) --version | tr ' ()' '\n' | grep '^[0-9]' | head -n1) $(filter -f% -m% -O% -DNDEBUG,$(CXXFLAGS))
|
||||
YOSYS_VER_STR := Yosys $(YOSYS_VER) (git sha1 $(YOSYS_GIT_STR), $(YOSYS_COMPILER))
|
||||
|
||||
kernel/version_$(GIT_REV).cc: $(YOSYS_SRC)/Makefile
|
||||
$(P) rm -f kernel/version_*.o kernel/version_*.d kernel/version_*.cc
|
||||
$(Q) mkdir -p kernel && echo "namespace Yosys { extern const char *yosys_version_str; const char *yosys_version_str=\"$(YOSYS_VER_STR)\"; }" > kernel/version_$(GIT_REV).cc
|
||||
$(Q) mkdir -p kernel && echo "namespace Yosys { extern const char *yosys_version_str; const char *yosys_version_str=\"$(YOSYS_VER_STR)\"; const char *yosys_git_hash_str=\"$(YOSYS_GIT_STR)\"; }" > kernel/version_$(GIT_REV).cc
|
||||
|
||||
ifeq ($(ENABLE_VERIFIC),1)
|
||||
CXXFLAGS_NOVERIFIC = $(foreach v,$(CXXFLAGS),$(if $(findstring $(VERIFIC_DIR),$(v)),,$(v)))
|
||||
|
|
@ -777,7 +818,7 @@ $(PROGRAM_PREFIX)yosys-config: misc/yosys-config.in $(YOSYS_SRC)/Makefile
|
|||
.PHONY: check-git-abc
|
||||
|
||||
check-git-abc:
|
||||
@if [ ! -d "$(YOSYS_SRC)/abc" ]; then \
|
||||
@if [ ! -d "$(YOSYS_SRC)/abc" ] && git -C "$(YOSYS_SRC)" status >/dev/null 2>&1; then \
|
||||
echo "Error: The 'abc' directory does not exist."; \
|
||||
echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \
|
||||
exit 1; \
|
||||
|
|
@ -803,12 +844,28 @@ check-git-abc:
|
|||
echo "3. Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \
|
||||
echo "4. Reapply your changes: Move your saved changes back to the 'abc' directory, if necessary."; \
|
||||
exit 1; \
|
||||
elif ! git -C "$(YOSYS_SRC)" status >/dev/null 2>&1; then \
|
||||
echo "$(realpath $(YOSYS_SRC)) is not configured as a git repository, and 'abc' folder is missing."; \
|
||||
echo "If you already have ABC, set 'ABCEXTERNAL' make variable to point to ABC executable."; \
|
||||
echo "Otherwise, download release archive 'yosys.tar.gz' from https://github.com/YosysHQ/yosys/releases."; \
|
||||
echo " ('Source code' archive does not contain submodules.)"; \
|
||||
exit 1; \
|
||||
else \
|
||||
echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
abc/abc$(EXE) abc/libabc.a: | check-git-abc
|
||||
.git-abc-submodule-hash: FORCE
|
||||
@new=$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null || echo none); \
|
||||
old=$$(cat .git-abc-submodule-hash 2>/dev/null || echo none); \
|
||||
if [ "$$new" != "$$old" ]; then \
|
||||
echo "$$new" > .git-abc-submodule-hash; \
|
||||
fi
|
||||
|
||||
abc/abc$(EXE) abc/libabc.a: .git-abc-submodule-hash | check-git-abc
|
||||
@if [ "$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null)" != "$$(cat ../.git-abc-submodule-hash 2>/dev/null || echo none)" ]; then \
|
||||
rm -f abc/abc$(EXE); \
|
||||
fi
|
||||
$(P)
|
||||
$(Q) mkdir -p abc && $(MAKE) -C $(PROGRAM_PREFIX)abc -f "$(realpath $(YOSYS_SRC)/abc/Makefile)" ABCSRC="$(realpath $(YOSYS_SRC)/abc/)" $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc",PROG="abc$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc.a)
|
||||
|
||||
|
|
@ -846,12 +903,15 @@ MK_TEST_DIRS += tests/arch/nexus
|
|||
MK_TEST_DIRS += tests/arch/quicklogic/pp3
|
||||
MK_TEST_DIRS += tests/arch/quicklogic/qlf_k6n10f
|
||||
MK_TEST_DIRS += tests/arch/xilinx
|
||||
MK_TEST_DIRS += tests/bugpoint
|
||||
MK_TEST_DIRS += tests/opt
|
||||
MK_TEST_DIRS += tests/sat
|
||||
MK_TEST_DIRS += tests/sdc
|
||||
MK_TEST_DIRS += tests/sim
|
||||
MK_TEST_DIRS += tests/svtypes
|
||||
MK_TEST_DIRS += tests/techmap
|
||||
MK_TEST_DIRS += tests/various
|
||||
MK_TEST_DIRS += tests/rtlil
|
||||
ifeq ($(ENABLE_VERIFIC),1)
|
||||
ifneq ($(YOSYS_NOVERIFIC),1)
|
||||
MK_TEST_DIRS += tests/verific
|
||||
|
|
@ -874,6 +934,7 @@ SH_TEST_DIRS += tests/bram
|
|||
SH_TEST_DIRS += tests/svinterfaces
|
||||
SH_TEST_DIRS += tests/xprop
|
||||
SH_TEST_DIRS += tests/select
|
||||
SH_TEST_DIRS += tests/peepopt
|
||||
SH_TEST_DIRS += tests/proc
|
||||
SH_TEST_DIRS += tests/blif
|
||||
SH_TEST_DIRS += tests/arch
|
||||
|
|
@ -881,6 +942,7 @@ SH_TEST_DIRS += tests/rpc
|
|||
SH_TEST_DIRS += tests/memfile
|
||||
SH_TEST_DIRS += tests/fmt
|
||||
SH_TEST_DIRS += tests/cxxrtl
|
||||
SH_TEST_DIRS += tests/liberty
|
||||
ifeq ($(ENABLE_FUNCTIONAL_TESTS),1)
|
||||
SH_TEST_DIRS += tests/functional
|
||||
endif
|
||||
|
|
@ -957,28 +1019,43 @@ unit-test: libyosys.so
|
|||
clean-unit-test:
|
||||
@$(MAKE) -C $(UNITESTPATH) clean
|
||||
|
||||
install-dev: $(PROGRAM_PREFIX)yosys-config share
|
||||
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_SUDO) cp $(PROGRAM_PREFIX)yosys-config $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR)
|
||||
$(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/.
|
||||
|
||||
install: $(TARGETS) $(EXTRA_TARGETS)
|
||||
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_SUDO) cp $(filter-out libyosys.so,$(TARGETS)) $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_SUDO) cp $(filter-out libyosys.so libyosys.a,$(TARGETS)) $(DESTDIR)$(BINDIR)
|
||||
ifneq ($(filter $(PROGRAM_PREFIX)yosys,$(TARGETS)),)
|
||||
$(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys
|
||||
if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys; fi
|
||||
endif
|
||||
ifneq ($(filter $(PROGRAM_PREFIX)yosys-abc,$(TARGETS)),)
|
||||
$(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-abc
|
||||
if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-abc; fi
|
||||
endif
|
||||
ifneq ($(filter $(PROGRAM_PREFIX)yosys-filterlib,$(TARGETS)),)
|
||||
$(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-filterlib
|
||||
if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-filterlib; fi
|
||||
endif
|
||||
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR)
|
||||
$(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/.
|
||||
ifeq ($(ENABLE_LIBYOSYS),1)
|
||||
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(LIBDIR)
|
||||
$(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)/
|
||||
$(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so
|
||||
if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so; fi
|
||||
ifeq ($(ENABLE_LIBYOSYS_STATIC),1)
|
||||
$(INSTALL_SUDO) cp libyosys.a $(DESTDIR)$(LIBDIR)/
|
||||
endif
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys
|
||||
$(INSTALL_SUDO) cp $(YOSYS_SRC)/pyosys/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py
|
||||
$(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so
|
||||
$(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/
|
||||
$(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
ifeq ($(ABCEXTERNAL),)
|
||||
$(INSTALL_SUDO) cp $(PROGRAM_PREFIX)yosys-abc$(EXE) $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc$(EXE)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ENABLE_PLUGINS),1)
|
||||
|
|
@ -993,6 +1070,9 @@ uninstall:
|
|||
$(INSTALL_SUDO) rm -rvf $(DESTDIR)$(DATDIR)
|
||||
ifeq ($(ENABLE_LIBYOSYS),1)
|
||||
$(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so
|
||||
ifeq ($(ENABLE_LIBYOSYS_STATIC),1)
|
||||
$(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.a
|
||||
endif
|
||||
ifeq ($(ENABLE_PYOSYS),1)
|
||||
$(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so
|
||||
$(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py
|
||||
|
|
@ -1000,19 +1080,8 @@ ifeq ($(ENABLE_PYOSYS),1)
|
|||
endif
|
||||
endif
|
||||
|
||||
# also others, but so long as it doesn't fail this is enough to know we tried
|
||||
docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS)
|
||||
$(Q) mkdir -p docs/source/cmd
|
||||
$(Q) mkdir -p temp/docs/source/cmd
|
||||
$(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual'
|
||||
$(Q) rsync -rc temp/docs/source/cmd docs/source
|
||||
$(Q) rm -rf temp
|
||||
docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS)
|
||||
$(Q) mkdir -p docs/source/cell
|
||||
$(Q) mkdir -p temp/docs/source/cell
|
||||
$(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-cells-manual'
|
||||
$(Q) rsync -rc temp/docs/source/cell docs/source
|
||||
$(Q) rm -rf temp
|
||||
docs/source/generated/cmds.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
||||
$(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cmds-json $@'
|
||||
|
||||
docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
||||
$(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@'
|
||||
|
|
@ -1029,6 +1098,15 @@ docs/source/generated/functional/rosette.diff: backends/functional/smtlib.cc bac
|
|||
PHONY: docs/gen/functional_ir
|
||||
docs/gen/functional_ir: docs/source/generated/functional/smtlib.cc docs/source/generated/functional/rosette.diff
|
||||
|
||||
docs/source/generated/%.log: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
||||
$(Q) ./$(PROGRAM_PREFIX)yosys -qQT -h '$*' -l $@
|
||||
|
||||
docs/source/generated/chformal.cc: passes/cmds/chformal.cc docs/source/generated
|
||||
$(Q) cp $< $@
|
||||
|
||||
PHONY: docs/gen/chformal
|
||||
docs/gen/chformal: docs/source/generated/chformal.log docs/source/generated/chformal.cc
|
||||
|
||||
PHONY: docs/gen docs/usage docs/reqs
|
||||
docs/gen: $(TARGETS)
|
||||
$(Q) $(MAKE) -C docs gen
|
||||
|
|
@ -1038,10 +1116,10 @@ docs/source/generated:
|
|||
|
||||
# some commands return an error and print the usage text to stderr
|
||||
define DOC_USAGE_STDERR
|
||||
docs/source/generated/$(1): $(TARGETS) docs/source/generated
|
||||
docs/source/generated/$(1): $(TARGETS) docs/source/generated FORCE
|
||||
-$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@
|
||||
endef
|
||||
DOCS_USAGE_STDERR := yosys-config yosys-filterlib
|
||||
DOCS_USAGE_STDERR := yosys-filterlib
|
||||
|
||||
# The in-tree ABC (yosys-abc) is only built when ABCEXTERNAL is not set.
|
||||
ifeq ($(ABCEXTERNAL),)
|
||||
|
|
@ -1053,9 +1131,9 @@ $(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage))))
|
|||
# others print to stdout
|
||||
define DOC_USAGE_STDOUT
|
||||
docs/source/generated/$(1): $(TARGETS) docs/source/generated
|
||||
$(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@
|
||||
$(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@ || rm $$@
|
||||
endef
|
||||
DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness
|
||||
DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness yosys-config
|
||||
$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage))))
|
||||
|
||||
docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR))
|
||||
|
|
@ -1064,16 +1142,15 @@ docs/reqs:
|
|||
$(Q) $(MAKE) -C docs reqs
|
||||
|
||||
.PHONY: docs/prep
|
||||
docs/prep: docs/source/cmd/abc.rst docs/source/generated/cells.json docs/gen docs/usage docs/gen/functional_ir
|
||||
docs/prep: docs/source/generated/cells.json docs/source/generated/cmds.json docs/gen docs/usage docs/gen/functional_ir docs/gen/chformal
|
||||
|
||||
DOC_TARGET ?= html
|
||||
docs: docs/prep
|
||||
$(Q) $(MAKE) -C docs $(DOC_TARGET)
|
||||
|
||||
clean:
|
||||
clean: clean-py clean-unit-test
|
||||
rm -rf share
|
||||
rm -rf kernel/*.pyh
|
||||
rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc
|
||||
rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS)
|
||||
rm -f kernel/version_*.o kernel/version_*.cc
|
||||
rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d
|
||||
rm -rf tests/asicworld/*.out tests/asicworld/*.log
|
||||
|
|
@ -1086,12 +1163,20 @@ clean:
|
|||
rm -f tests/svinterfaces/*.log_stdout tests/svinterfaces/*.log_stderr tests/svinterfaces/dut_result.txt tests/svinterfaces/reference_result.txt tests/svinterfaces/a.out tests/svinterfaces/*_syn.v tests/svinterfaces/*.diff
|
||||
rm -f tests/tools/cmp_tbdata
|
||||
rm -f $(addsuffix /run-test.mk,$(MK_TEST_DIRS))
|
||||
-$(MAKE) -C docs clean
|
||||
rm -rf docs/source/cmd docs/util/__pycache__
|
||||
-$(MAKE) -C $(YOSYS_SRC)/docs clean
|
||||
rm -rf docs/util/__pycache__
|
||||
rm -f libyosys.so
|
||||
|
||||
clean-py:
|
||||
rm -f $(PY_WRAPPER_FILE).inc.cc $(PY_WRAPPER_FILE).cc
|
||||
rm -f $(PYTHON_OBJECTS)
|
||||
rm -f *.whl
|
||||
rm -f libyosys.so libyosys.a
|
||||
rm -rf kernel/*.pyh
|
||||
|
||||
clean-abc:
|
||||
$(MAKE) -C abc DEP= clean
|
||||
rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a
|
||||
$(MAKE) -C $(YOSYS_SRC)/abc DEP= clean
|
||||
rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a .git-abc-submodule-hash
|
||||
|
||||
mrproper: clean
|
||||
git clean -xdf
|
||||
|
|
@ -1120,15 +1205,17 @@ qtcreator:
|
|||
{ echo .; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \) -printf '%h\n' | sort -u; } > qtcreator.includes
|
||||
touch qtcreator.creator
|
||||
|
||||
vcxsrc: $(GENFILES) $(EXTRA_TARGETS)
|
||||
rm -rf yosys-win32-vcxsrc-$(YOSYS_VER){,.zip}
|
||||
VCX_DIR_NAME := yosys-win32-vcxsrc-$(YOSYS_VER)
|
||||
vcxsrc: $(GENFILES) $(EXTRA_TARGETS) kernel/version_$(GIT_REV).cc
|
||||
rm -rf $(VCX_DIR_NAME){,.zip}
|
||||
cp -f kernel/version_$(GIT_REV).cc kernel/version.cc
|
||||
set -e; for f in `ls $(filter %.cc %.cpp,$(GENFILES)) $(addsuffix .cc,$(basename $(OBJS))) $(addsuffix .cpp,$(basename $(OBJS))) 2> /dev/null`; do \
|
||||
echo "Analyse: $$f" >&2; cpp -std=c++17 -MM -I. -D_YOSYS_ $$f; done | sed 's,.*:,,; s,//*,/,g; s,/[^/]*/\.\./,/,g; y, \\,\n\n,;' | grep '^[^/]' | sort -u | grep -v kernel/version_ > srcfiles.txt
|
||||
echo "libs/fst/fst_win_unistd.h" >> srcfiles.txt
|
||||
bash misc/create_vcxsrc.sh yosys-win32-vcxsrc $(YOSYS_VER) $(GIT_REV)
|
||||
echo "namespace Yosys { extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys (Version Information Unavailable)\"; }" > kernel/version.cc
|
||||
zip yosys-win32-vcxsrc-$(YOSYS_VER)/genfiles.zip $(GENFILES) kernel/version.cc
|
||||
zip -r yosys-win32-vcxsrc-$(YOSYS_VER).zip yosys-win32-vcxsrc-$(YOSYS_VER)/
|
||||
echo "kernel/version.cc" >> srcfiles.txt
|
||||
bash misc/create_vcxsrc.sh $(VCX_DIR_NAME) $(YOSYS_VER)
|
||||
zip $(VCX_DIR_NAME)/genfiles.zip $(GENFILES) kernel/version.cc
|
||||
zip -r $(VCX_DIR_NAME).zip $(VCX_DIR_NAME)/
|
||||
rm -f srcfiles.txt kernel/version.cc
|
||||
|
||||
config-clean: clean
|
||||
|
|
@ -1190,5 +1277,7 @@ echo-cxx:
|
|||
-include kernel/*.d
|
||||
-include techlibs/*/*.d
|
||||
|
||||
.PHONY: all top-all abc test install install-abc docs clean mrproper qtcreator coverage vcxsrc
|
||||
FORCE:
|
||||
|
||||
.PHONY: all top-all abc test install-dev install install-abc docs clean mrproper qtcreator coverage vcxsrc
|
||||
.PHONY: config-clean config-clang config-gcc config-gcc-static config-gprof config-sudo
|
||||
|
|
|
|||
30
README.md
30
README.md
|
|
@ -25,6 +25,9 @@ Web Site and Other Resources
|
|||
More information and documentation can be found on the Yosys web site:
|
||||
- https://yosyshq.net/yosys/
|
||||
|
||||
If you have any Yosys-related questions, please post them on the Discourse group:
|
||||
- https://yosyshq.discourse.group
|
||||
|
||||
Documentation from this repository is automatically built and available on Read
|
||||
the Docs:
|
||||
- https://yosyshq.readthedocs.io/projects/yosys
|
||||
|
|
@ -34,6 +37,9 @@ verification front-end for Yosys, SBY:
|
|||
- https://yosyshq.readthedocs.io/projects/sby/
|
||||
- https://github.com/YosysHQ/sby
|
||||
|
||||
The Yosys blog has news and articles from users:
|
||||
- https://blog.yosyshq.com
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
|
@ -74,13 +80,13 @@ recommended) and some standard tools such as GNU Flex, GNU Bison, and GNU Make.
|
|||
TCL, readline and libffi are optional (see ``ENABLE_*`` settings in Makefile).
|
||||
Xdot (graphviz) is used by the ``show`` command in yosys to display schematics.
|
||||
|
||||
For example on Ubuntu Linux 16.04 LTS the following commands will install all
|
||||
For example on Ubuntu Linux 22.04 LTS the following commands will install all
|
||||
prerequisites for building yosys:
|
||||
|
||||
$ sudo apt-get install build-essential clang lld bison flex \
|
||||
libreadline-dev gawk tcl-dev libffi-dev git \
|
||||
graphviz xdot pkg-config python3 libboost-system-dev \
|
||||
libboost-python-dev libboost-filesystem-dev zlib1g-dev
|
||||
$ sudo apt-get install gawk git make python3 lld bison clang flex \
|
||||
libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev \
|
||||
graphviz xdot
|
||||
$ curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
The environment variable `CXX` can be used to control the C++ compiler used, or
|
||||
run one of the following to override it:
|
||||
|
|
@ -242,7 +248,7 @@ Note that there is no need to build the manual if you just want to read it.
|
|||
Simply visit https://yosys.readthedocs.io/en/latest/ instead.
|
||||
|
||||
In addition to those packages listed above for building Yosys from source, the
|
||||
following are used for building the website:
|
||||
following are used for building the website:
|
||||
|
||||
$ sudo apt install pdf2svg faketime
|
||||
|
||||
|
|
@ -258,7 +264,7 @@ build process for the website. Or, run the following:
|
|||
Or for MacOS, using homebrew:
|
||||
|
||||
$ brew install basictex
|
||||
$ sudo tlmgr update --self
|
||||
$ sudo tlmgr update --self
|
||||
$ sudo tlmgr install collection-latexextra latexmk tex-gyre
|
||||
|
||||
The Python package, Sphinx, is needed along with those listed in
|
||||
|
|
@ -268,5 +274,13 @@ The Python package, Sphinx, is needed along with those listed in
|
|||
|
||||
From the root of the repository, run `make docs`. This will build/rebuild yosys
|
||||
as necessary before generating the website documentation from the yosys help
|
||||
commands. To build for pdf instead of html, call
|
||||
commands. To build for pdf instead of html, call
|
||||
`make docs DOC_TARGET=latexpdf`.
|
||||
|
||||
It is recommended to use the `ENABLE_HELP_SOURCE` make option for Yosys builds
|
||||
that will be used to build the documentation. This option enables source
|
||||
location tracking for passes and improves the command reference through grouping
|
||||
related commands and allowing for the documentation to link to the corresponding
|
||||
source files. Without this, a warning will be raised during the Sphinx build
|
||||
about `Found commands assigned to group unknown` and `make docs` is configured
|
||||
to fail on warnings by default.
|
||||
|
|
|
|||
2
abc
2
abc
|
|
@ -1 +1 @@
|
|||
Subproject commit f2d68d590fa6f8fc32295a2edd79afc0d14a1414
|
||||
Subproject commit 9182a8048d0bc86b39a6cb6b0488a7e1d10b2607
|
||||
|
|
@ -132,7 +132,7 @@ struct AigerWriter
|
|||
return a;
|
||||
}
|
||||
|
||||
AigerWriter(Module *module, bool zinit_mode, bool imode, bool omode, bool bmode, bool lmode) : module(module), zinit_mode(zinit_mode), sigmap(module)
|
||||
AigerWriter(Module *module, bool no_sort, bool zinit_mode, bool imode, bool omode, bool bmode, bool lmode) : module(module), zinit_mode(zinit_mode), sigmap(module)
|
||||
{
|
||||
pool<SigBit> undriven_bits;
|
||||
pool<SigBit> unused_bits;
|
||||
|
|
@ -152,6 +152,37 @@ struct AigerWriter
|
|||
if (wire->port_input)
|
||||
sigmap.add(wire);
|
||||
|
||||
// handle ports
|
||||
// provided the input_bits and output_bits don't get sorted they
|
||||
// will be returned in reverse order, so add them in reverse to
|
||||
// match
|
||||
for (auto riter = module->ports.rbegin(); riter != module->ports.rend(); ++riter) {
|
||||
auto *wire = module->wire(*riter);
|
||||
for (int i = 0; i < GetSize(wire); i++)
|
||||
{
|
||||
SigBit wirebit(wire, i);
|
||||
SigBit bit = sigmap(wirebit);
|
||||
|
||||
if (bit.wire == nullptr) {
|
||||
if (wire->port_output) {
|
||||
aig_map[wirebit] = (bit == State::S1) ? 1 : 0;
|
||||
output_bits.insert(wirebit);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wire->port_input)
|
||||
input_bits.insert(bit);
|
||||
|
||||
if (wire->port_output) {
|
||||
if (bit != wirebit)
|
||||
alias_map[wirebit] = bit;
|
||||
output_bits.insert(wirebit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle wires
|
||||
for (auto wire : module->wires())
|
||||
{
|
||||
if (wire->attributes.count(ID::init)) {
|
||||
|
|
@ -167,25 +198,13 @@ struct AigerWriter
|
|||
SigBit wirebit(wire, i);
|
||||
SigBit bit = sigmap(wirebit);
|
||||
|
||||
if (bit.wire == nullptr) {
|
||||
if (wire->port_output) {
|
||||
aig_map[wirebit] = (bit == State::S1) ? 1 : 0;
|
||||
output_bits.insert(wirebit);
|
||||
}
|
||||
if (bit.wire == nullptr)
|
||||
continue;
|
||||
if (wire->port_input || wire->port_output)
|
||||
continue;
|
||||
}
|
||||
|
||||
undriven_bits.insert(bit);
|
||||
unused_bits.insert(bit);
|
||||
|
||||
if (wire->port_input)
|
||||
input_bits.insert(bit);
|
||||
|
||||
if (wire->port_output) {
|
||||
if (bit != wirebit)
|
||||
alias_map[wirebit] = bit;
|
||||
output_bits.insert(wirebit);
|
||||
}
|
||||
}
|
||||
|
||||
if (wire->width == 1) {
|
||||
|
|
@ -200,12 +219,6 @@ struct AigerWriter
|
|||
}
|
||||
}
|
||||
|
||||
for (auto bit : input_bits)
|
||||
undriven_bits.erase(bit);
|
||||
|
||||
for (auto bit : output_bits)
|
||||
unused_bits.erase(bit);
|
||||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID($_NOT_))
|
||||
|
|
@ -343,8 +356,11 @@ struct AigerWriter
|
|||
}
|
||||
|
||||
init_map.sort();
|
||||
input_bits.sort();
|
||||
output_bits.sort();
|
||||
// we are relying here on unsorted pools iterating last-in-first-out
|
||||
if (!no_sort) {
|
||||
input_bits.sort();
|
||||
output_bits.sort();
|
||||
}
|
||||
not_map.sort();
|
||||
ff_map.sort();
|
||||
and_map.sort();
|
||||
|
|
@ -662,8 +678,7 @@ struct AigerWriter
|
|||
f << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
f << stringf("c\nGenerated by %s\n", yosys_version_str);
|
||||
f << stringf("c\nGenerated by %s\n", yosys_maybe_version());
|
||||
}
|
||||
|
||||
void write_map(std::ostream &f, bool verbose_map, bool no_startoffset)
|
||||
|
|
@ -698,7 +713,7 @@ struct AigerWriter
|
|||
}
|
||||
|
||||
if (wire->port_output) {
|
||||
int o = ordered_outputs.at(sig[i]);
|
||||
int o = ordered_outputs.at(SigSpec(wire, i));
|
||||
output_lines[o] += stringf("output %d %d %s\n", o, index, log_id(wire));
|
||||
}
|
||||
|
||||
|
|
@ -746,7 +761,7 @@ struct AigerWriter
|
|||
{
|
||||
json.begin_object();
|
||||
json.entry("version", "Yosys Witness Aiger map");
|
||||
json.entry("gennerator", yosys_version_str);
|
||||
json.entry("gennerator", yosys_maybe_version());
|
||||
|
||||
json.entry("latch_count", aig_l);
|
||||
json.entry("input_count", aig_i);
|
||||
|
|
@ -902,6 +917,9 @@ struct AigerBackend : public Backend {
|
|||
log(" -symbols\n");
|
||||
log(" include a symbol table in the generated AIGER file\n");
|
||||
log("\n");
|
||||
log(" -no-sort\n");
|
||||
log(" don't sort input/output ports\n");
|
||||
log("\n");
|
||||
log(" -map <filename>\n");
|
||||
log(" write an extra file with port and latch symbols\n");
|
||||
log("\n");
|
||||
|
|
@ -926,6 +944,7 @@ struct AigerBackend : public Backend {
|
|||
bool zinit_mode = false;
|
||||
bool miter_mode = false;
|
||||
bool symbols_mode = false;
|
||||
bool no_sort = false;
|
||||
bool verbose_map = false;
|
||||
bool imode = false;
|
||||
bool omode = false;
|
||||
|
|
@ -956,6 +975,10 @@ struct AigerBackend : public Backend {
|
|||
symbols_mode = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-no-sort") {
|
||||
no_sort = true;
|
||||
continue;
|
||||
}
|
||||
if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) {
|
||||
map_filename = args[++argidx];
|
||||
continue;
|
||||
|
|
@ -1009,7 +1032,7 @@ struct AigerBackend : public Backend {
|
|||
if (!top_module->memories.empty())
|
||||
log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", log_id(top_module));
|
||||
|
||||
AigerWriter writer(top_module, zinit_mode, imode, omode, bmode, lmode);
|
||||
AigerWriter writer(top_module, no_sort, zinit_mode, imode, omode, bmode, lmode);
|
||||
writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode);
|
||||
|
||||
if (!map_filename.empty()) {
|
||||
|
|
@ -1017,7 +1040,7 @@ struct AigerBackend : public Backend {
|
|||
std::ofstream mapf;
|
||||
mapf.open(map_filename.c_str(), std::ofstream::trunc);
|
||||
if (mapf.fail())
|
||||
log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", map_filename, strerror(errno));
|
||||
writer.write_map(mapf, verbose_map, no_startoffset);
|
||||
}
|
||||
|
||||
|
|
@ -1028,7 +1051,7 @@ struct AigerBackend : public Backend {
|
|||
PrettyJson json;
|
||||
|
||||
if (!json.write_to_file(yw_map_filename))
|
||||
log_error("Can't open file `%s' for writing: %s\n", yw_map_filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", yw_map_filename, strerror(errno));
|
||||
writer.write_ywmap(json);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -671,7 +671,7 @@ struct XAigerWriter
|
|||
//f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
|
||||
//f.write(buffer_str.data(), buffer_str.size());
|
||||
|
||||
f << stringf("Generated by %s\n", yosys_version_str);
|
||||
f << stringf("Generated by %s\n", yosys_maybe_version());
|
||||
|
||||
design->scratchpad_set_int("write_xaiger.num_ands", and_map.size());
|
||||
design->scratchpad_set_int("write_xaiger.num_wires", aig_map.size());
|
||||
|
|
@ -788,7 +788,7 @@ struct XAigerBackend : public Backend {
|
|||
std::ofstream mapf;
|
||||
mapf.open(map_filename.c_str(), std::ofstream::trunc);
|
||||
if (mapf.fail())
|
||||
log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", map_filename, strerror(errno));
|
||||
writer.write_map(mapf);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "kernel/register.h"
|
||||
#include "kernel/celltypes.h"
|
||||
#include "kernel/rtlil.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
|
@ -91,7 +92,7 @@ struct Index {
|
|||
int pos = index_wires(info, m);
|
||||
|
||||
for (auto cell : m->cells()) {
|
||||
if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3)))
|
||||
if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port)))
|
||||
continue;
|
||||
|
||||
Module *submodule = m->design->module(cell->type);
|
||||
|
|
@ -105,6 +106,13 @@ struct Index {
|
|||
if (allow_blackboxes) {
|
||||
info.found_blackboxes.insert(cell);
|
||||
} else {
|
||||
// Even if we don't allow blackboxes these might still be
|
||||
// present outside of any traversed input cones, so we
|
||||
// can't bail at this point. If they are hit by a traversal
|
||||
// (which can only really happen with $tribuf not
|
||||
// $connect), we can still detect this as an error later.
|
||||
if (cell->type == ID($connect) || (cell->type == ID($tribuf) && cell->has_attribute(ID(aiger2_zbuf))))
|
||||
continue;
|
||||
if (!submodule || submodule->get_blackbox_attribute())
|
||||
log_error("Unsupported cell type: %s (%s in %s)\n",
|
||||
log_id(cell->type), log_id(cell), log_id(m));
|
||||
|
|
@ -483,7 +491,8 @@ struct Index {
|
|||
{
|
||||
Design *design = index.design;
|
||||
auto &minfo = leaf_minfo(index);
|
||||
log_assert(minfo.suboffsets.count(cell));
|
||||
if (!minfo.suboffsets.count(cell))
|
||||
log_error("Reached unsupport cell %s (%s in %s)\n", log_id(cell->type), log_id(cell), log_id(cell->module));
|
||||
Module *def = design->module(cell->type);
|
||||
log_assert(def);
|
||||
levels.push_back(Level(index.modules.at(def), cell));
|
||||
|
|
@ -566,7 +575,7 @@ struct Index {
|
|||
}
|
||||
|
||||
Lit ret;
|
||||
if (!bit.wire->port_input) {
|
||||
if (!bit.wire->port_input || bit.wire->port_output) {
|
||||
// an output of a cell
|
||||
Cell *driver = bit.wire->driverCell();
|
||||
|
||||
|
|
@ -618,7 +627,7 @@ struct Index {
|
|||
|
||||
if (!cursor) {
|
||||
log_assert(bit.wire->module == top);
|
||||
log_assert(bit.wire->port_input);
|
||||
log_assert(bit.wire->port_input && !bit.wire->port_output);
|
||||
return lits[top_minfo->windices[bit.wire] + bit.offset];
|
||||
} else {
|
||||
log_assert(bit.wire->module == cursor->leaf_module(*this));
|
||||
|
|
@ -723,7 +732,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
|
|||
for (auto id : top->ports) {
|
||||
Wire *w = top->wire(id);
|
||||
log_assert(w);
|
||||
if (w->port_input)
|
||||
if (w->port_input && !w->port_output)
|
||||
for (int i = 0; i < w->width; i++) {
|
||||
pi_literal(SigBit(w, i)) = lit_counter;
|
||||
inputs.push_back(SigBit(w, i));
|
||||
|
|
@ -828,7 +837,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
{
|
||||
log_assert(cursor.is_top()); // TOOD: fix analyzer to work with hierarchy
|
||||
|
||||
if (bit.wire->port_input)
|
||||
if (bit.wire->port_input && !bit.wire->port_output)
|
||||
return false;
|
||||
|
||||
Cell *driver = bit.wire->driverCell();
|
||||
|
|
@ -837,11 +846,14 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
return false;
|
||||
|
||||
int max = 1;
|
||||
for (auto wire : mod->wires())
|
||||
if (wire->port_input)
|
||||
for (int i = 0; i < wire->width; i++) {
|
||||
int ilevel = visit(cursor, driver->getPort(wire->name)[i]);
|
||||
max = std::max(max, ilevel + 1);
|
||||
for (auto wire : mod->wires()) {
|
||||
if (wire->port_input && !wire->port_output) {
|
||||
SigSpec port = driver->getPort(wire->name);
|
||||
for (int i = 0; i < std::min(wire->width, port.size()); i++) {
|
||||
int ilevel = visit(cursor, port[i]);
|
||||
max = std::max(max, ilevel + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
lits[idx] = max;
|
||||
|
||||
|
|
@ -858,7 +870,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
for (auto id : top->ports) {
|
||||
Wire *w = top->wire(id);
|
||||
log_assert(w);
|
||||
if (w->port_input)
|
||||
if (w->port_input && !w->port_output)
|
||||
for (int i = 0; i < w->width; i++)
|
||||
pi_literal(SigBit(w, i)) = 0;
|
||||
}
|
||||
|
|
@ -868,7 +880,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
Module *def = design->module(box->type);
|
||||
if (!(def && def->has_attribute(ID::abc9_box_id)))
|
||||
for (auto &conn : box->connections_)
|
||||
if (box->output(conn.first))
|
||||
if (box->port_dir(conn.first) != RTLIL::PD_INPUT)
|
||||
for (auto bit : conn.second)
|
||||
pi_literal(bit, &cursor) = 0;
|
||||
}
|
||||
|
|
@ -883,7 +895,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
Module *def = design->module(box->type);
|
||||
if (!(def && def->has_attribute(ID::abc9_box_id)))
|
||||
for (auto &conn : box->connections_)
|
||||
if (box->input(conn.first))
|
||||
if (box->port_dir(conn.first) == RTLIL::PD_INPUT)
|
||||
for (auto bit : conn.second)
|
||||
(void) eval_po(bit);
|
||||
}
|
||||
|
|
@ -903,6 +915,16 @@ struct XAigerWriter : AigerWriter {
|
|||
typedef std::pair<SigBit, HierCursor> HierBit;
|
||||
std::vector<HierBit> pos;
|
||||
std::vector<HierBit> pis;
|
||||
|
||||
// * The aiger output port sequence is COs (inputs to modeled boxes),
|
||||
// inputs to opaque boxes, then module outputs. COs going first is
|
||||
// required by abc.
|
||||
// * proper_pos_counter counts ports which follow after COs
|
||||
// * The mapping file `pseudopo` and `po` statements use indexing relative
|
||||
// to the first port following COs.
|
||||
// * If a module output is directly driven by an opaque box, the emission
|
||||
// of the po statement in the mapping file is skipped. This is done to
|
||||
// aid re-integration of the mapped result.
|
||||
int proper_pos_counter = 0;
|
||||
|
||||
pool<SigBit> driven_by_opaque_box;
|
||||
|
|
@ -937,15 +959,10 @@ struct XAigerWriter : AigerWriter {
|
|||
lit_counter += 2;
|
||||
}
|
||||
|
||||
void append_box_ports(Cell *box, HierCursor &cursor, bool inputs)
|
||||
void append_opaque_box_ports(Cell *box, HierCursor &cursor, bool inputs)
|
||||
{
|
||||
for (auto &conn : box->connections_) {
|
||||
bool is_input = box->input(conn.first);
|
||||
bool is_output = box->output(conn.first);
|
||||
|
||||
if (!(is_input || is_output) || (is_input && is_output))
|
||||
log_error("Ambiguous port direction on %s/%s\n",
|
||||
log_id(box->type), log_id(conn.first));
|
||||
bool is_input = box->port_dir(conn.first) == RTLIL::PD_INPUT;
|
||||
|
||||
if (is_input && inputs) {
|
||||
int bitp = 0;
|
||||
|
|
@ -955,13 +972,14 @@ struct XAigerWriter : AigerWriter {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Inputs to opaque boxes are proper POs as far as abc is concerned
|
||||
if (map_file.is_open()) {
|
||||
log_assert(cursor.is_top());
|
||||
map_file << "pseudopo " << proper_pos_counter++ << " " << bitp
|
||||
map_file << "pseudopo " << proper_pos_counter << " " << bitp
|
||||
<< " " << box->name.c_str()
|
||||
<< " " << conn.first.c_str() << "\n";
|
||||
}
|
||||
|
||||
proper_pos_counter++;
|
||||
pos.push_back(std::make_pair(bit, cursor));
|
||||
|
||||
if (mapping_prep)
|
||||
|
|
@ -969,10 +987,10 @@ struct XAigerWriter : AigerWriter {
|
|||
|
||||
bitp++;
|
||||
}
|
||||
} else if (is_output && !inputs) {
|
||||
} else if (!is_input && !inputs) {
|
||||
for (auto &bit : conn.second) {
|
||||
if (!bit.wire || bit.wire->port_input)
|
||||
log_error("Bad connection");
|
||||
if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output))
|
||||
log_error("Bad connection %s/%s ~ %s\n", log_id(box), log_id(conn.first), log_signal(conn.second));
|
||||
|
||||
|
||||
ensure_pi(bit, cursor);
|
||||
|
|
@ -1011,8 +1029,8 @@ struct XAigerWriter : AigerWriter {
|
|||
auto &minfo = cursor.leaf_minfo(*this);
|
||||
|
||||
for (auto box : minfo.found_blackboxes) {
|
||||
log_debug(" - %s.%s (type %s): ", cursor.path().c_str(),
|
||||
RTLIL::unescape_id(box->name).c_str(),
|
||||
log_debug(" - %s.%s (type %s): ", cursor.path(),
|
||||
RTLIL::unescape_id(box->name),
|
||||
log_id(box->type));
|
||||
|
||||
Module *box_module = design->module(box->type), *box_derived;
|
||||
|
|
@ -1038,7 +1056,7 @@ struct XAigerWriter : AigerWriter {
|
|||
});
|
||||
|
||||
for (auto [cursor, box, def] : opaque_boxes)
|
||||
append_box_ports(box, cursor, false);
|
||||
append_opaque_box_ports(box, cursor, false);
|
||||
|
||||
holes_module = design->addModule(NEW_ID);
|
||||
std::vector<RTLIL::Wire *> holes_pis;
|
||||
|
|
@ -1086,6 +1104,8 @@ struct XAigerWriter : AigerWriter {
|
|||
bit = RTLIL::Sx;
|
||||
}
|
||||
|
||||
// Nonopaque box inputs come first and are not part of
|
||||
// the PO numbering used by the mapping file.
|
||||
pos.push_back(std::make_pair(bit, cursor));
|
||||
}
|
||||
boxes_co_num += port->width;
|
||||
|
|
@ -1106,7 +1126,7 @@ struct XAigerWriter : AigerWriter {
|
|||
holes_pi_idx++;
|
||||
}
|
||||
holes_wb->setPort(port_id, in_conn);
|
||||
} else if (port->port_output && !port->port_input) {
|
||||
} else if (port->port_output) {
|
||||
// primary
|
||||
for (int i = 0; i < port->width; i++) {
|
||||
SigBit bit;
|
||||
|
|
@ -1138,7 +1158,7 @@ struct XAigerWriter : AigerWriter {
|
|||
}
|
||||
|
||||
for (auto [cursor, box, def] : opaque_boxes)
|
||||
append_box_ports(box, cursor, true);
|
||||
append_opaque_box_ports(box, cursor, true);
|
||||
|
||||
write_be32(h_buffer, 1);
|
||||
write_be32(h_buffer, pis.size());
|
||||
|
|
@ -1159,7 +1179,7 @@ struct XAigerWriter : AigerWriter {
|
|||
log_assert(port);
|
||||
if (port->port_input && !port->port_output) {
|
||||
box_co_num += port->width;
|
||||
} else if (port->port_output && !port->port_input) {
|
||||
} else if (port->port_output) {
|
||||
box_ci_num += port->width;
|
||||
} else {
|
||||
log_abort();
|
||||
|
|
@ -1182,7 +1202,7 @@ struct XAigerWriter : AigerWriter {
|
|||
reset_counters();
|
||||
|
||||
for (auto w : top->wires())
|
||||
if (w->port_input)
|
||||
if (w->port_input && !w->port_output)
|
||||
for (int i = 0; i < w->width; i++)
|
||||
ensure_pi(SigBit(w, i));
|
||||
|
||||
|
|
@ -1195,10 +1215,14 @@ struct XAigerWriter : AigerWriter {
|
|||
for (auto w : top->wires())
|
||||
if (w->port_output)
|
||||
for (int i = 0; i < w->width; i++) {
|
||||
// When a module output is directly driven by an opaque box, we
|
||||
// don't emit it to the mapping file to aid re-integration, but we
|
||||
// do emit a proper PO.
|
||||
if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) {
|
||||
map_file << "po " << proper_pos_counter++ << " " << i
|
||||
map_file << "po " << proper_pos_counter << " " << i
|
||||
<< " " << w->name.c_str() << "\n";
|
||||
}
|
||||
proper_pos_counter++;
|
||||
pos.push_back(std::make_pair(SigBit(w, i), HierCursor{}));
|
||||
}
|
||||
|
||||
|
|
@ -1446,7 +1470,7 @@ struct XAiger2Backend : Backend {
|
|||
if (!map_filename.empty()) {
|
||||
writer.map_file.open(map_filename);
|
||||
if (!writer.map_file)
|
||||
log_cmd_error("Failed to open '%s' for writing\n", map_filename.c_str());
|
||||
log_cmd_error("Failed to open '%s' for writing\n", map_filename);
|
||||
}
|
||||
|
||||
design->bufNormalize(true);
|
||||
|
|
|
|||
|
|
@ -157,14 +157,14 @@ struct BlifDumper
|
|||
f << stringf("%c", ch);
|
||||
f << stringf("\"\n");
|
||||
} else
|
||||
f << stringf("%s\n", param.second.as_string().c_str());
|
||||
f << stringf("%s\n", param.second.as_string());
|
||||
}
|
||||
}
|
||||
|
||||
void dump()
|
||||
{
|
||||
f << stringf("\n");
|
||||
f << stringf(".model %s\n", str(module->name).c_str());
|
||||
f << stringf(".model %s\n", str(module->name));
|
||||
|
||||
std::map<int, RTLIL::Wire*> inputs, outputs;
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ struct BlifDumper
|
|||
for (auto &it : inputs) {
|
||||
RTLIL::Wire *wire = it.second;
|
||||
for (int i = 0; i < wire->width; i++)
|
||||
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)).c_str());
|
||||
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)));
|
||||
}
|
||||
f << stringf("\n");
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ struct BlifDumper
|
|||
for (auto &it : outputs) {
|
||||
RTLIL::Wire *wire = it.second;
|
||||
for (int i = 0; i < wire->width; i++)
|
||||
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)).c_str());
|
||||
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)));
|
||||
}
|
||||
f << stringf("\n");
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ struct BlifDumper
|
|||
if (!config->impltf_mode) {
|
||||
if (!config->false_type.empty()) {
|
||||
if (config->false_type == "+")
|
||||
f << stringf(".names %s\n", config->false_out.c_str());
|
||||
f << stringf(".names %s\n", config->false_out);
|
||||
else if (config->false_type != "-")
|
||||
f << stringf(".%s %s %s=$false\n", subckt_or_gate(config->false_type),
|
||||
config->false_type.c_str(), config->false_out.c_str());
|
||||
|
|
@ -208,7 +208,7 @@ struct BlifDumper
|
|||
f << stringf(".names $false\n");
|
||||
if (!config->true_type.empty()) {
|
||||
if (config->true_type == "+")
|
||||
f << stringf(".names %s\n1\n", config->true_out.c_str());
|
||||
f << stringf(".names %s\n1\n", config->true_out);
|
||||
else if (config->true_type != "-")
|
||||
f << stringf(".%s %s %s=$true\n", subckt_or_gate(config->true_type),
|
||||
config->true_type.c_str(), config->true_out.c_str());
|
||||
|
|
@ -216,7 +216,7 @@ struct BlifDumper
|
|||
f << stringf(".names $true\n1\n");
|
||||
if (!config->undef_type.empty()) {
|
||||
if (config->undef_type == "+")
|
||||
f << stringf(".names %s\n", config->undef_out.c_str());
|
||||
f << stringf(".names %s\n", config->undef_out);
|
||||
else if (config->undef_type != "-")
|
||||
f << stringf(".%s %s %s=$undef\n", subckt_or_gate(config->undef_type),
|
||||
config->undef_type.c_str(), config->undef_out.c_str());
|
||||
|
|
@ -331,31 +331,31 @@ struct BlifDumper
|
|||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($_FF_)) {
|
||||
f << stringf(".latch %s %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
|
||||
f << stringf(".latch %s %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
|
||||
str_init(cell->getPort(ID::Q)).c_str());
|
||||
goto internal_cell;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($_DFF_N_)) {
|
||||
f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
|
||||
f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
|
||||
str(cell->getPort(ID::C)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
|
||||
goto internal_cell;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($_DFF_P_)) {
|
||||
f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
|
||||
f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
|
||||
str(cell->getPort(ID::C)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
|
||||
goto internal_cell;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($_DLATCH_N_)) {
|
||||
f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
|
||||
f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
|
||||
str(cell->getPort(ID::E)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
|
||||
goto internal_cell;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == ID($_DLATCH_P_)) {
|
||||
f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
|
||||
f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
|
||||
str(cell->getPort(ID::E)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
|
||||
goto internal_cell;
|
||||
}
|
||||
|
|
@ -366,10 +366,10 @@ struct BlifDumper
|
|||
auto width = cell->parameters.at(ID::WIDTH).as_int();
|
||||
log_assert(inputs.size() == width);
|
||||
for (int i = width-1; i >= 0; i--)
|
||||
f << stringf(" %s", str(inputs.extract(i, 1)).c_str());
|
||||
f << stringf(" %s", str(inputs.extract(i, 1)));
|
||||
auto &output = cell->getPort(ID::Y);
|
||||
log_assert(output.size() == 1);
|
||||
f << stringf(" %s", str(output).c_str());
|
||||
f << stringf(" %s", str(output));
|
||||
f << stringf("\n");
|
||||
RTLIL::SigSpec mask = cell->parameters.at(ID::LUT);
|
||||
for (int i = 0; i < (1 << width); i++)
|
||||
|
|
@ -392,10 +392,10 @@ struct BlifDumper
|
|||
table.push_back(State::S0);
|
||||
log_assert(inputs.size() == width);
|
||||
for (int i = 0; i < width; i++)
|
||||
f << stringf(" %s", str(inputs.extract(i, 1)).c_str());
|
||||
f << stringf(" %s", str(inputs.extract(i, 1)));
|
||||
auto &output = cell->getPort(ID::Y);
|
||||
log_assert(output.size() == 1);
|
||||
f << stringf(" %s", str(output).c_str());
|
||||
f << stringf(" %s", str(output));
|
||||
f << stringf("\n");
|
||||
for (int i = 0; i < depth; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
|
|
@ -410,11 +410,11 @@ struct BlifDumper
|
|||
goto internal_cell;
|
||||
}
|
||||
|
||||
f << stringf(".%s %s", subckt_or_gate(cell->type.str()), str(cell->type).c_str());
|
||||
f << stringf(".%s %s", subckt_or_gate(cell->type.str()), str(cell->type));
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
if (conn.second.size() == 1) {
|
||||
f << stringf(" %s=%s", str(conn.first).c_str(), str(conn.second[0]).c_str());
|
||||
f << stringf(" %s=%s", str(conn.first), str(conn.second[0]));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -423,11 +423,11 @@ struct BlifDumper
|
|||
|
||||
if (w == nullptr) {
|
||||
for (int i = 0; i < GetSize(conn.second); i++)
|
||||
f << stringf(" %s[%d]=%s", str(conn.first).c_str(), i, str(conn.second[i]).c_str());
|
||||
f << stringf(" %s[%d]=%s", str(conn.first), i, str(conn.second[i]));
|
||||
} else {
|
||||
for (int i = 0; i < std::min(GetSize(conn.second), GetSize(w)); i++) {
|
||||
SigBit sig(w, i);
|
||||
f << stringf(" %s[%d]=%s", str(conn.first).c_str(), sig.wire->upto ?
|
||||
f << stringf(" %s[%d]=%s", str(conn.first), sig.wire->upto ?
|
||||
sig.wire->start_offset+sig.wire->width-sig.offset-1 :
|
||||
sig.wire->start_offset+sig.offset, str(conn.second[i]).c_str());
|
||||
}
|
||||
|
|
@ -436,7 +436,7 @@ struct BlifDumper
|
|||
f << stringf("\n");
|
||||
|
||||
if (config->cname_mode)
|
||||
f << stringf(".cname %s\n", str(cell->name).c_str());
|
||||
f << stringf(".cname %s\n", str(cell->name));
|
||||
if (config->attr_mode)
|
||||
dump_params(".attr", cell->attributes);
|
||||
if (config->param_mode)
|
||||
|
|
@ -445,7 +445,7 @@ struct BlifDumper
|
|||
if (0) {
|
||||
internal_cell:
|
||||
if (config->iname_mode)
|
||||
f << stringf(".cname %s\n", str(cell->name).c_str());
|
||||
f << stringf(".cname %s\n", str(cell->name));
|
||||
if (config->iattr_mode)
|
||||
dump_params(".attr", cell->attributes);
|
||||
}
|
||||
|
|
@ -461,12 +461,12 @@ struct BlifDumper
|
|||
continue;
|
||||
|
||||
if (config->conn_mode)
|
||||
f << stringf(".conn %s %s\n", str(rhs_bit).c_str(), str(lhs_bit).c_str());
|
||||
f << stringf(".conn %s %s\n", str(rhs_bit), str(lhs_bit));
|
||||
else if (!config->buf_type.empty())
|
||||
f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(),
|
||||
f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type,
|
||||
config->buf_in.c_str(), str(rhs_bit).c_str(), config->buf_out.c_str(), str(lhs_bit).c_str());
|
||||
else
|
||||
f << stringf(".names %s %s\n1 1\n", str(rhs_bit).c_str(), str(lhs_bit).c_str());
|
||||
f << stringf(".names %s %s\n1 1\n", str(rhs_bit), str(lhs_bit));
|
||||
}
|
||||
|
||||
f << stringf(".end\n");
|
||||
|
|
@ -649,7 +649,7 @@ struct BlifBackend : public Backend {
|
|||
if (module->get_bool_attribute(ID::top))
|
||||
top_module_name = module->name.str();
|
||||
|
||||
*f << stringf("# Generated by %s\n", yosys_version_str);
|
||||
*f << stringf("# Generated by %s\n", yosys_maybe_version());
|
||||
|
||||
std::vector<RTLIL::Module*> mod_list;
|
||||
|
||||
|
|
@ -674,7 +674,7 @@ struct BlifBackend : public Backend {
|
|||
}
|
||||
|
||||
if (!top_module_name.empty())
|
||||
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
|
||||
log_error("Can't find top module `%s'!\n", top_module_name);
|
||||
|
||||
for (auto module : mod_list)
|
||||
BlifDumper::dump(*f, module, design, config);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "kernel/mem.h"
|
||||
#include "kernel/json.h"
|
||||
#include "kernel/yw.h"
|
||||
#include "kernel/utils.h"
|
||||
#include <string>
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
|
@ -97,24 +98,22 @@ struct BtorWorker
|
|||
vector<ywmap_btor_sig> ywmap_states;
|
||||
dict<SigBit, int> ywmap_clock_bits;
|
||||
dict<SigBit, int> ywmap_clock_inputs;
|
||||
vector<Cell *> ywmap_asserts;
|
||||
vector<Cell *> ywmap_assumes;
|
||||
|
||||
|
||||
PrettyJson ywmap_json;
|
||||
|
||||
void btorf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3))
|
||||
template <typename... Args>
|
||||
void btorf(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
f << indent << vstringf(fmt, ap);
|
||||
va_end(ap);
|
||||
f << indent << fmt.format(args...);
|
||||
}
|
||||
|
||||
void infof(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3))
|
||||
template <typename... Args>
|
||||
void infof(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
info_lines.push_back(vstringf(fmt, ap));
|
||||
va_end(ap);
|
||||
info_lines.push_back(fmt.format(args...));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -128,7 +127,7 @@ struct BtorWorker
|
|||
std::replace(src.begin(), src.end(), ' ', '_');
|
||||
if (srcsymbols.count(src) || module->count_id("\\" + src)) {
|
||||
for (int i = 1;; i++) {
|
||||
string s = stringf("%s-%d", src.c_str(), i);
|
||||
string s = stringf("%s-%d", src, i);
|
||||
if (!srcsymbols.count(s) && !module->count_id("\\" + s)) {
|
||||
src = s;
|
||||
break;
|
||||
|
|
@ -191,7 +190,7 @@ struct BtorWorker
|
|||
void btorf_push(const string &id)
|
||||
{
|
||||
if (verbose) {
|
||||
f << indent << stringf(" ; begin %s\n", id.c_str());
|
||||
f << indent << stringf(" ; begin %s\n", id);
|
||||
indent += " ";
|
||||
}
|
||||
}
|
||||
|
|
@ -200,7 +199,7 @@ struct BtorWorker
|
|||
{
|
||||
if (verbose) {
|
||||
indent = indent.substr(4);
|
||||
f << indent << stringf(" ; end %s\n", id.c_str());
|
||||
f << indent << stringf(" ; end %s\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +244,7 @@ struct BtorWorker
|
|||
string cell_list;
|
||||
for (auto c : cell_recursion_guard)
|
||||
cell_list += stringf("\n %s", log_id(c));
|
||||
log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list.c_str());
|
||||
log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list);
|
||||
}
|
||||
|
||||
cell_recursion_guard.insert(cell);
|
||||
|
|
@ -321,12 +320,12 @@ struct BtorWorker
|
|||
btorf("%d slt %d %d %d\n", nid_b_ltz, sid_bit, nid_b, nid_zero);
|
||||
|
||||
nid = next_nid++;
|
||||
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str());
|
||||
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell));
|
||||
}
|
||||
else
|
||||
{
|
||||
nid = next_nid++;
|
||||
btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
|
||||
}
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
|
@ -367,7 +366,7 @@ struct BtorWorker
|
|||
|
||||
int sid = get_bv_sid(width);
|
||||
int nid = next_nid++;
|
||||
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
|
||||
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op, sid, nid_a, nid_b, getinfo(cell));
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
||||
|
|
@ -393,12 +392,12 @@ struct BtorWorker
|
|||
|
||||
if (cell->type == ID($_ANDNOT_)) {
|
||||
btorf("%d not %d %d\n", nid1, sid, nid_b);
|
||||
btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
|
||||
btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
|
||||
}
|
||||
|
||||
if (cell->type == ID($_ORNOT_)) {
|
||||
btorf("%d not %d %d\n", nid1, sid, nid_b);
|
||||
btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
|
||||
btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
|
||||
}
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
|
@ -420,13 +419,13 @@ struct BtorWorker
|
|||
if (cell->type == ID($_OAI3_)) {
|
||||
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
|
||||
btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c);
|
||||
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell).c_str());
|
||||
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI3_)) {
|
||||
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
|
||||
btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c);
|
||||
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell).c_str());
|
||||
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
|
||||
}
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
|
@ -451,14 +450,14 @@ struct BtorWorker
|
|||
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
|
||||
btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d);
|
||||
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
|
||||
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell).c_str());
|
||||
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell));
|
||||
}
|
||||
|
||||
if (cell->type == ID($_AOI4_)) {
|
||||
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
|
||||
btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d);
|
||||
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
|
||||
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell).c_str());
|
||||
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell));
|
||||
}
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
|
@ -490,9 +489,9 @@ struct BtorWorker
|
|||
|
||||
int nid = next_nid++;
|
||||
if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) {
|
||||
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
|
||||
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op, sid, nid_a, nid_b, getinfo(cell));
|
||||
} else {
|
||||
btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
|
||||
}
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
|
@ -508,7 +507,7 @@ struct BtorWorker
|
|||
goto okay;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($not), ID($neg), ID($_NOT_), ID($pos)))
|
||||
if (cell->type.in(ID($not), ID($neg), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_)))
|
||||
{
|
||||
string btor_op;
|
||||
if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not";
|
||||
|
|
@ -520,14 +519,14 @@ struct BtorWorker
|
|||
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
||||
// the $pos cell just passes through, all other cells need an actual operation applied
|
||||
// the $pos/$buf cells just pass through, all other cells need an actual operation applied
|
||||
int nid = nid_a;
|
||||
if (cell->type != ID($pos))
|
||||
if (!cell->type.in(ID($pos), ID($buf), ID($_BUF_)))
|
||||
{
|
||||
log_assert(!btor_op.empty());
|
||||
int sid = get_bv_sid(width);
|
||||
nid = next_nid++;
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
|
||||
}
|
||||
|
||||
if (GetSize(sig) < width) {
|
||||
|
|
@ -567,9 +566,9 @@ struct BtorWorker
|
|||
|
||||
int nid = next_nid++;
|
||||
if (btor_op != "not")
|
||||
btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
|
||||
else
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
||||
|
|
@ -600,11 +599,11 @@ struct BtorWorker
|
|||
|
||||
if (cell->type == ID($reduce_xnor)) {
|
||||
int nid2 = next_nid++;
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
|
||||
btorf("%d not %d %d\n", nid2, sid, nid);
|
||||
nid = nid2;
|
||||
} else {
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
|
||||
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
|
||||
}
|
||||
|
||||
SigSpec sig = sigmap(cell->getPort(ID::Y));
|
||||
|
|
@ -639,9 +638,9 @@ struct BtorWorker
|
|||
int tmp = nid;
|
||||
nid = next_nid++;
|
||||
btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
|
||||
btorf("%d not %d %d%s\n", nid, sid, tmp, getinfo(cell).c_str());
|
||||
btorf("%d not %d %d%s\n", nid, sid, tmp, getinfo(cell));
|
||||
} else {
|
||||
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str());
|
||||
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell));
|
||||
}
|
||||
|
||||
add_nid_sig(nid, sig_y);
|
||||
|
|
@ -664,7 +663,7 @@ struct BtorWorker
|
|||
int nid_s = get_sig_nid(sig_s.extract(i));
|
||||
int nid2 = next_nid++;
|
||||
if (i == GetSize(sig_s)-1)
|
||||
btorf("%d ite %d %d %d %d%s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str());
|
||||
btorf("%d ite %d %d %d %d%s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell));
|
||||
else
|
||||
btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
|
||||
nid = nid2;
|
||||
|
|
@ -708,12 +707,13 @@ struct BtorWorker
|
|||
}
|
||||
}
|
||||
|
||||
Const initval;
|
||||
Const::Builder initval_bits(GetSize(sig_q));
|
||||
for (int i = 0; i < GetSize(sig_q); i++)
|
||||
if (initbits.count(sig_q[i]))
|
||||
initval.bits().push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0);
|
||||
initval_bits.push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0);
|
||||
else
|
||||
initval.bits().push_back(State::Sx);
|
||||
initval_bits.push_back(State::Sx);
|
||||
Const initval = initval_bits.build();
|
||||
|
||||
int nid_init_val = -1;
|
||||
|
||||
|
|
@ -752,7 +752,7 @@ struct BtorWorker
|
|||
int sid = get_bv_sid(GetSize(sig_y));
|
||||
int nid = next_nid++;
|
||||
|
||||
btorf("%d state %d%s\n", nid, sid, getinfo(cell).c_str());
|
||||
btorf("%d state %d%s\n", nid, sid, getinfo(cell));
|
||||
|
||||
ywmap_state(sig_y);
|
||||
|
||||
|
|
@ -775,7 +775,7 @@ struct BtorWorker
|
|||
int one_nid = get_sig_nid(State::S1);
|
||||
int zero_nid = get_sig_nid(State::S0);
|
||||
initstate_nid = next_nid++;
|
||||
btorf("%d state %d%s\n", initstate_nid, sid, getinfo(cell).c_str());
|
||||
btorf("%d state %d%s\n", initstate_nid, sid, getinfo(cell));
|
||||
btorf("%d init %d %d %d\n", next_nid++, sid, initstate_nid, one_nid);
|
||||
btorf("%d next %d %d %d\n", next_nid++, sid, initstate_nid, zero_nid);
|
||||
|
||||
|
|
@ -1042,15 +1042,16 @@ struct BtorWorker
|
|||
{
|
||||
if (bit.wire == nullptr)
|
||||
{
|
||||
Const c(bit.data);
|
||||
|
||||
while (i+GetSize(c) < GetSize(sig) && sig[i+GetSize(c)].wire == nullptr)
|
||||
c.bits().push_back(sig[i+GetSize(c)].data);
|
||||
Const::Builder c_bits;
|
||||
c_bits.push_back(bit.data);
|
||||
while (i + GetSize(c_bits) < GetSize(sig) && sig[i + GetSize(c_bits)].wire == nullptr)
|
||||
c_bits.push_back(sig[i + GetSize(c_bits)].data);
|
||||
Const c = c_bits.build();
|
||||
|
||||
if (consts.count(c) == 0) {
|
||||
int sid = get_bv_sid(GetSize(c));
|
||||
int nid = next_nid++;
|
||||
btorf("%d const %d %s\n", nid, sid, c.as_string().c_str());
|
||||
btorf("%d const %d %s\n", nid, sid, c.as_string());
|
||||
consts[c] = nid;
|
||||
nid_width[nid] = GetSize(c);
|
||||
}
|
||||
|
|
@ -1214,7 +1215,7 @@ struct BtorWorker
|
|||
int sid = get_bv_sid(GetSize(sig));
|
||||
int nid = next_nid++;
|
||||
|
||||
btorf("%d input %d%s\n", nid, sid, getinfo(wire).c_str());
|
||||
btorf("%d input %d%s\n", nid, sid, getinfo(wire));
|
||||
ywmap_input(wire);
|
||||
add_nid_sig(nid, sig);
|
||||
|
||||
|
|
@ -1259,7 +1260,7 @@ struct BtorWorker
|
|||
btorf_push(stringf("output %s", log_id(wire)));
|
||||
|
||||
int nid = get_sig_nid(wire);
|
||||
btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire).c_str());
|
||||
btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire));
|
||||
|
||||
btorf_pop(stringf("output %s", log_id(wire)));
|
||||
}
|
||||
|
|
@ -1281,6 +1282,8 @@ struct BtorWorker
|
|||
btorf("%d or %d %d %d\n", nid_a_or_not_en, sid, nid_a, nid_not_en);
|
||||
btorf("%d constraint %d\n", nid, nid_a_or_not_en);
|
||||
|
||||
if (ywmap_json.active()) ywmap_assumes.emplace_back(cell);
|
||||
|
||||
btorf_pop(log_id(cell));
|
||||
}
|
||||
|
||||
|
|
@ -1301,10 +1304,12 @@ struct BtorWorker
|
|||
bad_properties.push_back(nid_en_and_not_a);
|
||||
} else {
|
||||
if (cover_mode) {
|
||||
infof("bad %d%s\n", nid_en_and_not_a, getinfo(cell, true).c_str());
|
||||
infof("bad %d%s\n", nid_en_and_not_a, getinfo(cell, true));
|
||||
} else {
|
||||
int nid = next_nid++;
|
||||
btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str());
|
||||
btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true));
|
||||
|
||||
if (ywmap_json.active()) ywmap_asserts.emplace_back(cell);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1326,7 +1331,7 @@ struct BtorWorker
|
|||
bad_properties.push_back(nid_en_and_a);
|
||||
} else {
|
||||
int nid = next_nid++;
|
||||
btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true).c_str());
|
||||
btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true));
|
||||
}
|
||||
|
||||
btorf_pop(log_id(cell));
|
||||
|
|
@ -1347,7 +1352,7 @@ struct BtorWorker
|
|||
continue;
|
||||
|
||||
int this_nid = next_nid++;
|
||||
btorf("%d uext %d %d %d%s\n", this_nid, sid, nid, 0, getinfo(wire).c_str());
|
||||
btorf("%d uext %d %d %d%s\n", this_nid, sid, nid, 0, getinfo(wire));
|
||||
if (info_clocks.count(nid))
|
||||
info_clocks[this_nid] |= info_clocks[nid];
|
||||
|
||||
|
|
@ -1370,7 +1375,7 @@ struct BtorWorker
|
|||
SigSpec sig = sigmap(cell->getPort(ID::D));
|
||||
int nid_q = get_sig_nid(sig);
|
||||
int sid = get_bv_sid(GetSize(sig));
|
||||
btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str());
|
||||
btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell));
|
||||
|
||||
btorf_pop(stringf("next %s", log_id(cell)));
|
||||
}
|
||||
|
|
@ -1429,7 +1434,7 @@ struct BtorWorker
|
|||
}
|
||||
|
||||
int nid2 = next_nid++;
|
||||
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)).c_str());
|
||||
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)));
|
||||
|
||||
btorf_pop(stringf("next %s", log_id(mem->memid)));
|
||||
}
|
||||
|
|
@ -1462,6 +1467,7 @@ struct BtorWorker
|
|||
log_assert(cursor == 0);
|
||||
log_assert(GetSize(todo) == 1);
|
||||
btorf("%d bad %d\n", nid, todo[cursor]);
|
||||
// What do we do with ywmap_asserts when using single_bad?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1488,7 +1494,7 @@ struct BtorWorker
|
|||
std::ofstream f;
|
||||
f.open(info_filename.c_str(), std::ofstream::trunc);
|
||||
if (f.fail())
|
||||
log_error("Can't open file `%s' for writing: %s\n", info_filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", info_filename, strerror(errno));
|
||||
for (auto &it : info_lines)
|
||||
f << it;
|
||||
f.close();
|
||||
|
|
@ -1498,7 +1504,7 @@ struct BtorWorker
|
|||
{
|
||||
ywmap_json.begin_object();
|
||||
ywmap_json.entry("version", "Yosys Witness BTOR map");
|
||||
ywmap_json.entry("generator", yosys_version_str);
|
||||
ywmap_json.entry("generator", yosys_maybe_version());
|
||||
|
||||
ywmap_json.name("clocks");
|
||||
ywmap_json.begin_array();
|
||||
|
|
@ -1527,6 +1533,18 @@ struct BtorWorker
|
|||
emit_ywmap_btor_sig(entry);
|
||||
ywmap_json.end_array();
|
||||
|
||||
ywmap_json.name("asserts");
|
||||
ywmap_json.begin_array();
|
||||
for (Cell *cell : ywmap_asserts)
|
||||
ywmap_json.value(witness_path(cell));
|
||||
ywmap_json.end_array();
|
||||
|
||||
ywmap_json.name("assumes");
|
||||
ywmap_json.begin_array();
|
||||
for (Cell *cell : ywmap_assumes)
|
||||
ywmap_json.value(witness_path(cell));
|
||||
ywmap_json.end_array();
|
||||
|
||||
ywmap_json.end_object();
|
||||
}
|
||||
}
|
||||
|
|
@ -1612,7 +1630,7 @@ struct BtorBackend : public Backend {
|
|||
log_cmd_error("No top module found.\n");
|
||||
|
||||
*f << stringf("; BTOR description generated by %s for module %s.\n",
|
||||
yosys_version_str, log_id(topmod));
|
||||
yosys_maybe_version(), log_id(topmod));
|
||||
|
||||
BtorWorker(*f, topmod, verbose, single_bad, cover_mode, print_internal_names, info_filename, ywmap_filename);
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ bool is_extending_cell(RTLIL::IdString type)
|
|||
bool is_inlinable_cell(RTLIL::IdString type)
|
||||
{
|
||||
return is_unary_cell(type) || is_binary_cell(type) || type.in(
|
||||
ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux));
|
||||
ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux), ID($bwmux));
|
||||
}
|
||||
|
||||
bool is_ff_cell(RTLIL::IdString type)
|
||||
|
|
@ -616,7 +616,7 @@ std::string escape_c_string(const std::string &input)
|
|||
output.push_back('\\');
|
||||
output.push_back(c);
|
||||
} else {
|
||||
char l = c & 0x3, m = (c >> 3) & 0x3, h = (c >> 6) & 0x3;
|
||||
char l = c & 0x7, m = (c >> 3) & 0x7, h = (c >> 6) & 0x3;
|
||||
output.append("\\");
|
||||
output.push_back('0' + h);
|
||||
output.push_back('0' + m);
|
||||
|
|
@ -637,20 +637,6 @@ std::string escape_cxx_string(const std::string &input)
|
|||
return output;
|
||||
}
|
||||
|
||||
std::string basename(const std::string &filepath)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const std::string dir_seps = "\\/";
|
||||
#else
|
||||
const std::string dir_seps = "/";
|
||||
#endif
|
||||
size_t sep_pos = filepath.find_last_of(dir_seps);
|
||||
if (sep_pos != std::string::npos)
|
||||
return filepath.substr(sep_pos + 1);
|
||||
else
|
||||
return filepath;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::string get_hdl_name(T *object)
|
||||
{
|
||||
|
|
@ -770,7 +756,7 @@ struct CxxrtlWorker {
|
|||
// 1b. Generated identifiers for internal names (beginning with `$`) start with `i_`.
|
||||
// 2. An underscore is escaped with another underscore, i.e. `__`.
|
||||
// 3. Any other non-alnum character is escaped with underscores around its lowercase hex code, e.g. `@` as `_40_`.
|
||||
std::string mangle_name(const RTLIL::IdString &name)
|
||||
std::string mangle_name(RTLIL::IdString name)
|
||||
{
|
||||
std::string mangled;
|
||||
bool first = true;
|
||||
|
|
@ -800,7 +786,7 @@ struct CxxrtlWorker {
|
|||
return mangled;
|
||||
}
|
||||
|
||||
std::string mangle_module_name(const RTLIL::IdString &name, bool is_blackbox = false)
|
||||
std::string mangle_module_name(RTLIL::IdString name, bool is_blackbox = false)
|
||||
{
|
||||
// Class namespace.
|
||||
if (is_blackbox)
|
||||
|
|
@ -808,19 +794,19 @@ struct CxxrtlWorker {
|
|||
return mangle_name(name);
|
||||
}
|
||||
|
||||
std::string mangle_memory_name(const RTLIL::IdString &name)
|
||||
std::string mangle_memory_name(RTLIL::IdString name)
|
||||
{
|
||||
// Class member namespace.
|
||||
return "memory_" + mangle_name(name);
|
||||
}
|
||||
|
||||
std::string mangle_cell_name(const RTLIL::IdString &name)
|
||||
std::string mangle_cell_name(RTLIL::IdString name)
|
||||
{
|
||||
// Class member namespace.
|
||||
return "cell_" + mangle_name(name);
|
||||
}
|
||||
|
||||
std::string mangle_wire_name(const RTLIL::IdString &name)
|
||||
std::string mangle_wire_name(RTLIL::IdString name)
|
||||
{
|
||||
// Class member namespace.
|
||||
return mangle_name(name);
|
||||
|
|
@ -1198,6 +1184,14 @@ struct CxxrtlWorker {
|
|||
f << ">(";
|
||||
dump_sigspec_rhs(cell->getPort(ID::S), for_debug);
|
||||
f << ").val()";
|
||||
// Bitwise muxes
|
||||
} else if (cell->type == ID($bwmux)) {
|
||||
dump_sigspec_rhs(cell->getPort(ID::A), for_debug);
|
||||
f << ".bwmux(";
|
||||
dump_sigspec_rhs(cell->getPort(ID::B), for_debug);
|
||||
f << ",";
|
||||
dump_sigspec_rhs(cell->getPort(ID::S), for_debug);
|
||||
f << ").val()";
|
||||
// Demuxes
|
||||
} else if (cell->type == ID($demux)) {
|
||||
dump_sigspec_rhs(cell->getPort(ID::A), for_debug);
|
||||
|
|
@ -1525,7 +1519,7 @@ struct CxxrtlWorker {
|
|||
}
|
||||
// Internal cells
|
||||
} else if (is_internal_cell(cell->type)) {
|
||||
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str());
|
||||
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type);
|
||||
// User cells
|
||||
} else if (for_debug) {
|
||||
// Outlines are called on demand when computing the value of a debug item. Nothing to do here.
|
||||
|
|
@ -1660,26 +1654,29 @@ struct CxxrtlWorker {
|
|||
f << signal_temp << " == ";
|
||||
dump_sigspec(compare, /*is_lhs=*/false, for_debug);
|
||||
} else if (compare.is_fully_const()) {
|
||||
RTLIL::Const compare_mask, compare_value;
|
||||
RTLIL::Const::Builder compare_mask_builder(compare.size());
|
||||
RTLIL::Const::Builder compare_value_builder(compare.size());
|
||||
for (auto bit : compare.as_const()) {
|
||||
switch (bit) {
|
||||
case RTLIL::S0:
|
||||
case RTLIL::S1:
|
||||
compare_mask.bits().push_back(RTLIL::S1);
|
||||
compare_value.bits().push_back(bit);
|
||||
compare_mask_builder.push_back(RTLIL::S1);
|
||||
compare_value_builder.push_back(bit);
|
||||
break;
|
||||
|
||||
case RTLIL::Sx:
|
||||
case RTLIL::Sz:
|
||||
case RTLIL::Sa:
|
||||
compare_mask.bits().push_back(RTLIL::S0);
|
||||
compare_value.bits().push_back(RTLIL::S0);
|
||||
compare_mask_builder.push_back(RTLIL::S0);
|
||||
compare_value_builder.push_back(RTLIL::S0);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_assert(false);
|
||||
}
|
||||
}
|
||||
RTLIL::Const compare_mask = compare_mask_builder.build();
|
||||
RTLIL::Const compare_value = compare_value_builder.build();
|
||||
f << "and_uu<" << compare.size() << ">(" << signal_temp << ", ";
|
||||
dump_const(compare_mask);
|
||||
f << ") == ";
|
||||
|
|
@ -2402,7 +2399,12 @@ struct CxxrtlWorker {
|
|||
auto cell_attrs = scopeinfo_attributes(cell, ScopeinfoAttrs::Cell);
|
||||
cell_attrs.erase(ID::module_not_derived);
|
||||
f << indent << "scopes->add(path, " << escape_cxx_string(get_hdl_name(cell)) << ", ";
|
||||
f << escape_cxx_string(cell->get_string_attribute(ID(module))) << ", ";
|
||||
if (module_attrs.count(ID(hdlname))) {
|
||||
f << escape_cxx_string(module_attrs.at(ID(hdlname)).decode_string());
|
||||
} else {
|
||||
f << escape_cxx_string(cell->get_string_attribute(ID(module)));
|
||||
}
|
||||
f << ", ";
|
||||
dump_serialized_metadata(module_attrs);
|
||||
f << ", ";
|
||||
dump_serialized_metadata(cell_attrs);
|
||||
|
|
@ -2416,8 +2418,6 @@ struct CxxrtlWorker {
|
|||
inc_indent();
|
||||
for (auto wire : module->wires()) {
|
||||
const auto &debug_wire_type = debug_wire_types[wire];
|
||||
if (!wire->name.isPublic())
|
||||
continue;
|
||||
count_public_wires++;
|
||||
switch (debug_wire_type.type) {
|
||||
case WireType::BUFFERED:
|
||||
|
|
@ -2425,6 +2425,9 @@ struct CxxrtlWorker {
|
|||
// Member wire
|
||||
std::vector<std::string> flags;
|
||||
|
||||
if (!wire->name.isPublic())
|
||||
flags.push_back("GENERATED");
|
||||
|
||||
if (wire->port_input && wire->port_output)
|
||||
flags.push_back("INOUT");
|
||||
else if (wire->port_output)
|
||||
|
|
@ -2841,7 +2844,7 @@ struct CxxrtlWorker {
|
|||
}
|
||||
|
||||
if (split_intf)
|
||||
f << "#include \"" << basename(intf_filename) << "\"\n";
|
||||
f << "#include \"" << name_from_file_path(intf_filename) << "\"\n";
|
||||
else
|
||||
f << "#include <cxxrtl/cxxrtl.h>\n";
|
||||
f << "\n";
|
||||
|
|
@ -3028,7 +3031,7 @@ struct CxxrtlWorker {
|
|||
if (init == RTLIL::Const()) {
|
||||
init = RTLIL::Const(State::Sx, GetSize(bit.wire));
|
||||
}
|
||||
init.bits()[bit.offset] = port.init_value[i];
|
||||
init.set(bit.offset, port.init_value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3464,8 +3467,8 @@ struct CxxrtlWorker {
|
|||
};
|
||||
|
||||
struct CxxrtlBackend : public Backend {
|
||||
static const int DEFAULT_OPT_LEVEL = 6;
|
||||
static const int DEFAULT_DEBUG_LEVEL = 4;
|
||||
static constexpr int DEFAULT_OPT_LEVEL = 6;
|
||||
static constexpr int DEFAULT_DEBUG_LEVEL = 4;
|
||||
|
||||
CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { }
|
||||
void help() override
|
||||
|
|
@ -3786,7 +3789,7 @@ struct CxxrtlBackend : public Backend {
|
|||
if (args[argidx] == "-print-output" && argidx+1 < args.size()) {
|
||||
worker.print_output = args[++argidx];
|
||||
if (!(worker.print_output == "std::cout" || worker.print_output == "std::cerr")) {
|
||||
log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output.c_str());
|
||||
log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output);
|
||||
worker.print_output = "std::cout";
|
||||
}
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -200,6 +200,10 @@ enum cxxrtl_flag {
|
|||
// node, such as inputs and dangling wires.
|
||||
CXXRTL_UNDRIVEN = 1 << 4,
|
||||
|
||||
// Generated correspond to netlist nodes that correspond to state with an internal name, that
|
||||
// need to be saved, but wouldn't otherwise have a debug item generated.
|
||||
CXXRTL_GENERATED = 1 << 5,
|
||||
|
||||
// More object flags may be added in the future, but the existing ones will never change.
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -498,6 +498,11 @@ struct value : public expr_base<value<Bits>> {
|
|||
return result;
|
||||
}
|
||||
|
||||
CXXRTL_ALWAYS_INLINE
|
||||
value<Bits> bwmux(const value<Bits> &b, const value<Bits> &s) const {
|
||||
return (bit_and(s.bit_not())).bit_or(b.bit_and(s));
|
||||
}
|
||||
|
||||
template<size_t ResultBits, size_t SelBits>
|
||||
value<ResultBits> demux(const value<SelBits> &sel) const {
|
||||
static_assert(Bits << SelBits == ResultBits, "invalid sizes used in demux()");
|
||||
|
|
@ -1289,6 +1294,7 @@ struct debug_item : ::cxxrtl_object {
|
|||
DRIVEN_SYNC = CXXRTL_DRIVEN_SYNC,
|
||||
DRIVEN_COMB = CXXRTL_DRIVEN_COMB,
|
||||
UNDRIVEN = CXXRTL_UNDRIVEN,
|
||||
GENERATED = CXXRTL_GENERATED,
|
||||
};
|
||||
|
||||
debug_item(const ::cxxrtl_object &object) : cxxrtl_object(object) {}
|
||||
|
|
@ -1764,7 +1770,7 @@ value<BitsY> shr_uu(const value<BitsA> &a, const value<BitsB> &b) {
|
|||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
CXXRTL_ALWAYS_INLINE
|
||||
value<BitsY> shr_su(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return a.shr(b).template scast<BitsY>();
|
||||
return a.template scast<BitsY>().shr(b);
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
|
|
@ -2005,7 +2011,7 @@ std::pair<value<BitsY>, value<BitsY>> divmod_uu(const value<BitsA> &a, const val
|
|||
value<Bits> quotient;
|
||||
value<Bits> remainder;
|
||||
value<Bits> dividend = a.template zext<Bits>();
|
||||
value<Bits> divisor = b.template zext<Bits>();
|
||||
value<Bits> divisor = b.template trunc<BitsB>().template zext<Bits>();
|
||||
std::tie(quotient, remainder) = dividend.udivmod(divisor);
|
||||
return {quotient.template trunc<BitsY>(), remainder.template trunc<BitsY>()};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str()
|
||||
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br).c_str()
|
||||
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str()
|
||||
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true)
|
||||
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br)
|
||||
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false)
|
||||
|
||||
struct EdifNames
|
||||
{
|
||||
|
|
@ -48,8 +48,8 @@ struct EdifNames
|
|||
if (define) {
|
||||
std::string new_id = operator()(id, false);
|
||||
if (port_rename)
|
||||
return stringf("(rename %s \"%s%c%d:%d%c\")", new_id.c_str(), id.c_str(), delim_left, range_left, range_right, delim_right);
|
||||
return new_id != id ? stringf("(rename %s \"%s\")", new_id.c_str(), id.c_str()) : id;
|
||||
return stringf("(rename %s \"%s%c%d:%d%c\")", new_id, id, delim_left, range_left, range_right, delim_right);
|
||||
return new_id != id ? stringf("(rename %s \"%s\")", new_id, id) : id;
|
||||
}
|
||||
|
||||
if (name_map.count(id) > 0)
|
||||
|
|
@ -231,7 +231,8 @@ struct EdifBackend : public Backend {
|
|||
*f << stringf(" (edifVersion 2 0 0)\n");
|
||||
*f << stringf(" (edifLevel 0)\n");
|
||||
*f << stringf(" (keywordMap (keywordLevel 0))\n");
|
||||
*f << stringf(" (comment \"Generated by %s\")\n", yosys_version_str);
|
||||
|
||||
*f << stringf(" (comment \"Generated by %s\")\n", yosys_maybe_version());
|
||||
|
||||
*f << stringf(" (external LIB\n");
|
||||
*f << stringf(" (edifLevel 0)\n");
|
||||
|
|
@ -333,7 +334,7 @@ struct EdifBackend : public Backend {
|
|||
|
||||
auto add_prop = [&](IdString name, Const val) {
|
||||
if ((val.flags & RTLIL::CONST_FLAG_STRING) != 0)
|
||||
*f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string().c_str());
|
||||
*f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string());
|
||||
else if (val.size() <= 32 && RTLIL::SigSpec(val).is_fully_def())
|
||||
*f << stringf("\n (property %s (integer %u))", EDIF_DEF(name), val.as_int());
|
||||
else {
|
||||
|
|
@ -347,7 +348,7 @@ struct EdifBackend : public Backend {
|
|||
char digit_str[2] = { "0123456789abcdef"[digit_value], 0 };
|
||||
hex_string = std::string(digit_str) + hex_string;
|
||||
}
|
||||
*f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val), hex_string.c_str());
|
||||
*f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val), hex_string);
|
||||
}
|
||||
};
|
||||
for (auto module : sorted_modules)
|
||||
|
|
@ -512,13 +513,13 @@ struct EdifBackend : public Backend {
|
|||
if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) {
|
||||
if (sig == RTLIL::State::Sx) {
|
||||
for (auto &ref : it.second)
|
||||
log_warning("Exporting x-bit on %s as zero bit.\n", ref.first.c_str());
|
||||
log_warning("Exporting x-bit on %s as zero bit.\n", ref.first);
|
||||
sig = RTLIL::State::S0;
|
||||
} else if (sig == RTLIL::State::Sz) {
|
||||
continue;
|
||||
} else {
|
||||
for (auto &ref : it.second)
|
||||
log_error("Don't know how to handle %s on %s.\n", log_signal(sig), ref.first.c_str());
|
||||
log_error("Don't know how to handle %s on %s.\n", log_signal(sig), ref.first);
|
||||
log_abort();
|
||||
}
|
||||
}
|
||||
|
|
@ -535,7 +536,7 @@ struct EdifBackend : public Backend {
|
|||
}
|
||||
*f << stringf(" (net %s (joined\n", EDIF_DEF(netname));
|
||||
for (auto &ref : it.second)
|
||||
*f << stringf(" %s\n", ref.first.c_str());
|
||||
*f << stringf(" %s\n", ref.first);
|
||||
if (sig.wire == NULL) {
|
||||
if (nogndvcc)
|
||||
log_error("Design contains constant nodes (map with \"hilomap\" first).\n");
|
||||
|
|
@ -576,7 +577,7 @@ struct EdifBackend : public Backend {
|
|||
auto &refs = net_join_db.at(mapped_sig);
|
||||
for (auto &ref : refs)
|
||||
if (ref.second)
|
||||
*f << stringf(" %s\n", ref.first.c_str());
|
||||
*f << stringf(" %s\n", ref.first);
|
||||
*f << stringf(" )");
|
||||
|
||||
if (attr_properties && raw_sig.wire != NULL)
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
|
|||
const std::string extmoduleFileinfo = getFileinfo(cell);
|
||||
|
||||
// Emit extmodule header.
|
||||
f << stringf(" extmodule %s: %s\n", exported_name.c_str(), extmoduleFileinfo.c_str());
|
||||
f << stringf(" extmodule %s: %s\n", exported_name, extmoduleFileinfo);
|
||||
|
||||
// Emit extmodule ports.
|
||||
for (auto wire : mod_instance->wires())
|
||||
|
|
@ -280,7 +280,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
|
|||
// Emit extmodule "defname" field. This is the name of the verilog blackbox
|
||||
// that is used when verilog is emitted, so we use the name of mod_instance
|
||||
// here.
|
||||
f << stringf("%sdefname = %s\n", indent.c_str(), blackbox_name.c_str());
|
||||
f << stringf("%sdefname = %s\n", indent, blackbox_name);
|
||||
|
||||
// Emit extmodule generic parameters.
|
||||
for (const auto &p : cell->parameters)
|
||||
|
|
@ -301,7 +301,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
|
|||
param_name.end()
|
||||
);
|
||||
|
||||
f << stringf("%sparameter %s = %s\n", indent.c_str(), param_name.c_str(), param_value.c_str());
|
||||
f << stringf("%sparameter %s = %s\n", indent, param_name, param_value);
|
||||
}
|
||||
|
||||
f << "\n";
|
||||
|
|
@ -347,7 +347,7 @@ void emit_elaborated_extmodules(RTLIL::Design *design, std::ostream &f)
|
|||
auto modInstance = design->module(cell->type);
|
||||
// Ensure that we actually have a module instance
|
||||
if (modInstance == nullptr) {
|
||||
log_error("Unknown cell type %s\n", cell->type.c_str());
|
||||
log_error("Unknown cell type %s\n", cell->type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ struct FirrtlWorker
|
|||
else
|
||||
{
|
||||
string wire_id = make_id(chunk.wire->name);
|
||||
new_expr = stringf("bits(%s, %d, %d)", wire_id.c_str(), chunk.offset + chunk.width - 1, chunk.offset);
|
||||
new_expr = stringf("bits(%s, %d, %d)", wire_id, chunk.offset + chunk.width - 1, chunk.offset);
|
||||
}
|
||||
|
||||
if (expr.empty())
|
||||
|
|
@ -465,7 +465,7 @@ struct FirrtlWorker
|
|||
// If there is no instance for this, just return.
|
||||
if (instModule == NULL)
|
||||
{
|
||||
log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str());
|
||||
log_warning("No instance for %s.%s\n", cell_type, cell_name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -477,7 +477,7 @@ struct FirrtlWorker
|
|||
instanceOf;
|
||||
|
||||
std::string cellFileinfo = getFileinfo(cell);
|
||||
wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceName.c_str(), cellFileinfo.c_str()));
|
||||
wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent, cell_name, cell_name_comment, instanceName, cellFileinfo));
|
||||
|
||||
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
|
||||
if (it->second.size() > 0) {
|
||||
|
|
@ -490,7 +490,7 @@ struct FirrtlWorker
|
|||
const SigSpec *sinkSig = nullptr;
|
||||
switch (dir) {
|
||||
case FD_INOUT:
|
||||
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
|
||||
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type, log_signal(it->second));
|
||||
YS_FALLTHROUGH
|
||||
case FD_OUT:
|
||||
sourceExpr = firstName;
|
||||
|
|
@ -498,27 +498,27 @@ struct FirrtlWorker
|
|||
sinkSig = &secondSig;
|
||||
break;
|
||||
case FD_NODIRECTION:
|
||||
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
|
||||
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type, log_signal(it->second));
|
||||
YS_FALLTHROUGH
|
||||
case FD_IN:
|
||||
sourceExpr = secondExpr;
|
||||
sinkExpr = firstName;
|
||||
break;
|
||||
default:
|
||||
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
|
||||
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type, log_signal(it->second), dir);
|
||||
break;
|
||||
}
|
||||
// Check for subfield assignment.
|
||||
std::string bitsString = "bits(";
|
||||
if (sinkExpr.compare(0, bitsString.length(), bitsString) == 0) {
|
||||
if (sinkSig == nullptr)
|
||||
log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str());
|
||||
log_error("Unknown subfield %s.%s\n", cell_type, sinkExpr);
|
||||
// Don't generate the assignment here.
|
||||
// Add the source and sink to the "reverse_wire_map" and we'll output the assignment
|
||||
// as part of the coalesced subfield assignments for this wire.
|
||||
register_reverse_wire_map(sourceExpr, *sinkSig);
|
||||
} else {
|
||||
wire_exprs.push_back(stringf("\n%s%s <= %s %s", indent.c_str(), sinkExpr.c_str(), sourceExpr.c_str(), cellFileinfo.c_str()));
|
||||
wire_exprs.push_back(stringf("\n%s%s <= %s %s", indent, sinkExpr, sourceExpr, cellFileinfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -535,7 +535,7 @@ struct FirrtlWorker
|
|||
int max_shift_width_bits = FIRRTL_MAX_DSH_WIDTH_ERROR - 1;
|
||||
string max_shift_string = stringf("UInt<%d>(%d)", max_shift_width_bits, (1<<max_shift_width_bits) - 1);
|
||||
// Deal with the difference in semantics between FIRRTL and verilog
|
||||
result = stringf("mux(gt(%s, %s), %s, bits(%s, %d, 0))", b_expr.c_str(), max_shift_string.c_str(), max_shift_string.c_str(), b_expr.c_str(), max_shift_width_bits - 1);
|
||||
result = stringf("mux(gt(%s, %s), %s, bits(%s, %d, 0))", b_expr, max_shift_string, max_shift_string, b_expr, max_shift_width_bits - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -543,7 +543,7 @@ struct FirrtlWorker
|
|||
void emit_module()
|
||||
{
|
||||
std::string moduleFileinfo = getFileinfo(module);
|
||||
f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo.c_str());
|
||||
f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo);
|
||||
vector<string> port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs;
|
||||
|
||||
std::vector<Mem> memories = Mem::get_all_memories(module);
|
||||
|
|
@ -565,12 +565,12 @@ struct FirrtlWorker
|
|||
{
|
||||
if (wire->port_input && wire->port_output)
|
||||
log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire));
|
||||
port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent.c_str(), wire->port_input ? "input" : "output",
|
||||
port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent, wire->port_input ? "input" : "output",
|
||||
wireName, wire->width, wireFileinfo.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), wireName, wire->width, wireFileinfo.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, wireName, wire->width, wireFileinfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -602,7 +602,7 @@ struct FirrtlWorker
|
|||
if (cell->type.in(ID($not), ID($logic_not), ID($_NOT_), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor)))
|
||||
{
|
||||
string a_expr = make_expr(cell->getPort(ID::A));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, y_width, cellFileinfo));
|
||||
|
||||
if (a_signed) {
|
||||
a_expr = "asSInt(" + a_expr + ")";
|
||||
|
|
@ -610,7 +610,7 @@ struct FirrtlWorker
|
|||
|
||||
// Don't use the results of logical operations (a single bit) to control padding
|
||||
if (!(cell->type.in(ID($eq), ID($eqx), ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($reduce_bool), ID($logic_not)) && y_width == 1) ) {
|
||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
||||
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
|
||||
}
|
||||
|
||||
// Assume the FIRRTL width is a single bit.
|
||||
|
|
@ -622,27 +622,27 @@ struct FirrtlWorker
|
|||
firrtl_width = a_width;
|
||||
} else if (cell->type == ID($logic_not)) {
|
||||
primop = "eq";
|
||||
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
|
||||
a_expr = stringf("%s, UInt(0)", a_expr);
|
||||
}
|
||||
else if (cell->type == ID($reduce_and)) primop = "andr";
|
||||
else if (cell->type == ID($reduce_or)) primop = "orr";
|
||||
else if (cell->type == ID($reduce_xor)) primop = "xorr";
|
||||
else if (cell->type == ID($reduce_xnor)) {
|
||||
primop = "not";
|
||||
a_expr = stringf("xorr(%s)", a_expr.c_str());
|
||||
a_expr = stringf("xorr(%s)", a_expr);
|
||||
}
|
||||
else if (cell->type == ID($reduce_bool)) {
|
||||
primop = "neq";
|
||||
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
|
||||
a_expr = stringf("%s, %cInt<%d>(0)", a_expr.c_str(), a_signed ? 'S' : 'U', a_width);
|
||||
a_expr = stringf("%s, %cInt<%d>(0)", a_expr, a_signed ? 'S' : 'U', a_width);
|
||||
}
|
||||
|
||||
string expr = stringf("%s(%s)", primop.c_str(), a_expr.c_str());
|
||||
string expr = stringf("%s(%s)", primop, a_expr);
|
||||
|
||||
if ((firrtl_is_signed && !always_uint))
|
||||
expr = stringf("asUInt(%s)", expr.c_str());
|
||||
expr = stringf("asUInt(%s)", expr);
|
||||
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
|
||||
|
||||
continue;
|
||||
|
|
@ -654,13 +654,13 @@ struct FirrtlWorker
|
|||
string a_expr = make_expr(cell->getPort(ID::A));
|
||||
string b_expr = make_expr(cell->getPort(ID::B));
|
||||
std::string cellFileinfo = getFileinfo(cell);
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, y_width, cellFileinfo));
|
||||
|
||||
if (a_signed) {
|
||||
a_expr = "asSInt(" + a_expr + ")";
|
||||
// Expand the "A" operand to the result width
|
||||
if (a_width < y_width) {
|
||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
||||
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
|
||||
a_width = y_width;
|
||||
}
|
||||
}
|
||||
|
|
@ -670,7 +670,7 @@ struct FirrtlWorker
|
|||
b_expr = "asSInt(" + b_expr + ")";
|
||||
// Expand the "B" operand to the result width
|
||||
if (b_width < y_width) {
|
||||
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
|
||||
b_expr = stringf("pad(%s, %d)", b_expr, y_width);
|
||||
b_width = y_width;
|
||||
}
|
||||
}
|
||||
|
|
@ -680,11 +680,11 @@ struct FirrtlWorker
|
|||
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($_XOR_), ID($xnor), ID($and), ID($_AND_), ID($or), ID($_OR_)))
|
||||
{
|
||||
if (a_width < y_width) {
|
||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
||||
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
|
||||
a_width = y_width;
|
||||
}
|
||||
if (b_width < y_width) {
|
||||
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
|
||||
b_expr = stringf("pad(%s, %d)", b_expr, y_width);
|
||||
b_width = y_width;
|
||||
}
|
||||
}
|
||||
|
|
@ -856,23 +856,23 @@ struct FirrtlWorker
|
|||
string expr;
|
||||
// Deal with $xnor == ~^ (not xor)
|
||||
if (primop == "xnor") {
|
||||
expr = stringf("not(xor(%s, %s))", a_expr.c_str(), b_expr.c_str());
|
||||
expr = stringf("not(xor(%s, %s))", a_expr, b_expr);
|
||||
} else {
|
||||
expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str());
|
||||
expr = stringf("%s(%s, %s)", primop, a_expr, b_expr);
|
||||
}
|
||||
|
||||
// Deal with FIRRTL's "shift widens" semantics, or the need to widen the FIRRTL result.
|
||||
// If the operation is signed, the FIRRTL width will be 1 one bit larger.
|
||||
if (extract_y_bits) {
|
||||
expr = stringf("bits(%s, %d, 0)", expr.c_str(), y_width - 1);
|
||||
expr = stringf("bits(%s, %d, 0)", expr, y_width - 1);
|
||||
} else if (firrtl_is_signed && (firrtl_width + 1) < y_width) {
|
||||
expr = stringf("pad(%s, %d)", expr.c_str(), y_width);
|
||||
expr = stringf("pad(%s, %d)", expr, y_width);
|
||||
}
|
||||
|
||||
if ((firrtl_is_signed && !always_uint))
|
||||
expr = stringf("asUInt(%s)", expr.c_str());
|
||||
expr = stringf("asUInt(%s)", expr);
|
||||
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
|
||||
|
||||
continue;
|
||||
|
|
@ -885,11 +885,11 @@ struct FirrtlWorker
|
|||
string a_expr = make_expr(cell->getPort(ID::A));
|
||||
string b_expr = make_expr(cell->getPort(ID::B));
|
||||
string s_expr = make_expr(cell->getPort(ID::S));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), width, cellFileinfo.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, width, cellFileinfo));
|
||||
|
||||
string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str());
|
||||
string expr = stringf("mux(%s, %s, %s)", s_expr, b_expr, a_expr);
|
||||
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
|
||||
|
||||
continue;
|
||||
|
|
@ -911,9 +911,9 @@ struct FirrtlWorker
|
|||
string expr = make_expr(cell->getPort(ID::D));
|
||||
string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")";
|
||||
|
||||
wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent.c_str(), y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str()));
|
||||
wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent, y_id, width, clk_expr, cellFileinfo));
|
||||
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Q));
|
||||
|
||||
continue;
|
||||
|
|
@ -926,7 +926,7 @@ struct FirrtlWorker
|
|||
string a_expr = make_expr(cell->getPort(ID::A));
|
||||
// Get the initial bit selector
|
||||
string b_expr = make_expr(cell->getPort(ID::B));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
|
||||
|
||||
if (cell->getParam(ID::B_SIGNED).as_bool()) {
|
||||
// Use validif to constrain the selection (test the sign bit)
|
||||
|
|
@ -934,9 +934,9 @@ struct FirrtlWorker
|
|||
int b_sign = cell->parameters.at(ID::B_WIDTH).as_int() - 1;
|
||||
b_expr = stringf("validif(not(bits(%s, %d, %d)), %s)", b_string, b_sign, b_sign, b_string);
|
||||
}
|
||||
string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str());
|
||||
string expr = stringf("dshr(%s, %s)", a_expr, b_expr);
|
||||
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, expr));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -948,21 +948,21 @@ struct FirrtlWorker
|
|||
string b_expr = make_expr(cell->getPort(ID::B));
|
||||
auto b_string = b_expr.c_str();
|
||||
string expr;
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
|
||||
|
||||
if (cell->getParam(ID::B_SIGNED).as_bool()) {
|
||||
// We generate a left or right shift based on the sign of b.
|
||||
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_width).c_str(), y_width);
|
||||
std::string dshr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
|
||||
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr, gen_dshl(b_expr, b_width), y_width);
|
||||
std::string dshr = stringf("dshr(%s, %s)", a_expr, b_string);
|
||||
expr = stringf("mux(%s < 0, %s, %s)",
|
||||
b_string,
|
||||
dshl.c_str(),
|
||||
dshr.c_str()
|
||||
);
|
||||
} else {
|
||||
expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
|
||||
expr = stringf("dshr(%s, %s)", a_expr, b_string);
|
||||
}
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, expr));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -973,10 +973,10 @@ struct FirrtlWorker
|
|||
// Verilog appears to treat the result as signed, so if the result is wider than "A",
|
||||
// we need to pad.
|
||||
if (a_width < y_width) {
|
||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
||||
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
|
||||
}
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), a_expr.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, a_expr));
|
||||
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -999,7 +999,7 @@ struct FirrtlWorker
|
|||
for (int i = 0; i < GetSize(mem.rd_ports); i++)
|
||||
{
|
||||
auto &port = mem.rd_ports[i];
|
||||
string port_name(stringf("%s.r%d", mem_id.c_str(), i));
|
||||
string port_name(stringf("%s.r%d", mem_id, i));
|
||||
|
||||
if (port.clk_enable)
|
||||
log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
|
||||
|
|
@ -1010,17 +1010,17 @@ struct FirrtlWorker
|
|||
string ena_expr = make_expr(State::S1);
|
||||
string clk_expr = make_expr(State::S0);
|
||||
|
||||
rpe << stringf("%s%s.addr <= %s\n", indent.c_str(), port_name.c_str(), addr_expr.c_str());
|
||||
rpe << stringf("%s%s.en <= %s\n", indent.c_str(), port_name.c_str(), ena_expr.c_str());
|
||||
rpe << stringf("%s%s.clk <= asClock(%s)\n", indent.c_str(), port_name.c_str(), clk_expr.c_str());
|
||||
rpe << stringf("%s%s.addr <= %s\n", indent, port_name, addr_expr);
|
||||
rpe << stringf("%s%s.en <= %s\n", indent, port_name, ena_expr);
|
||||
rpe << stringf("%s%s.clk <= asClock(%s)\n", indent, port_name, clk_expr);
|
||||
cell_exprs.push_back(rpe.str());
|
||||
register_reverse_wire_map(stringf("%s.data", port_name.c_str()), port.data);
|
||||
register_reverse_wire_map(stringf("%s.data", port_name), port.data);
|
||||
}
|
||||
|
||||
for (int i = 0; i < GetSize(mem.wr_ports); i++)
|
||||
{
|
||||
auto &port = mem.wr_ports[i];
|
||||
string port_name(stringf("%s.w%d", mem_id.c_str(), i));
|
||||
string port_name(stringf("%s.w%d", mem_id, i));
|
||||
|
||||
if (!port.clk_enable)
|
||||
log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
|
||||
|
|
@ -1037,18 +1037,18 @@ struct FirrtlWorker
|
|||
string ena_expr = make_expr(port.en[0]);
|
||||
string clk_expr = make_expr(port.clk);
|
||||
string mask_expr = make_expr(State::S1);
|
||||
wpe << stringf("%s%s.data <= %s\n", indent.c_str(), port_name.c_str(), data_expr.c_str());
|
||||
wpe << stringf("%s%s.addr <= %s\n", indent.c_str(), port_name.c_str(), addr_expr.c_str());
|
||||
wpe << stringf("%s%s.en <= %s\n", indent.c_str(), port_name.c_str(), ena_expr.c_str());
|
||||
wpe << stringf("%s%s.clk <= asClock(%s)\n", indent.c_str(), port_name.c_str(), clk_expr.c_str());
|
||||
wpe << stringf("%s%s.mask <= %s\n", indent.c_str(), port_name.c_str(), mask_expr.c_str());
|
||||
wpe << stringf("%s%s.data <= %s\n", indent, port_name, data_expr);
|
||||
wpe << stringf("%s%s.addr <= %s\n", indent, port_name, addr_expr);
|
||||
wpe << stringf("%s%s.en <= %s\n", indent, port_name, ena_expr);
|
||||
wpe << stringf("%s%s.clk <= asClock(%s)\n", indent, port_name, clk_expr);
|
||||
wpe << stringf("%s%s.mask <= %s\n", indent, port_name, mask_expr);
|
||||
|
||||
cell_exprs.push_back(wpe.str());
|
||||
}
|
||||
|
||||
std::ostringstream me;
|
||||
|
||||
me << stringf(" mem %s:\n", mem_id.c_str());
|
||||
me << stringf(" mem %s:\n", mem_id);
|
||||
me << stringf(" data-type => UInt<%d>\n", mem.width);
|
||||
me << stringf(" depth => %d\n", mem.size);
|
||||
for (int i = 0; i < GetSize(mem.rd_ports); i++)
|
||||
|
|
@ -1068,8 +1068,8 @@ struct FirrtlWorker
|
|||
int y_width = GetSize(conn.first);
|
||||
string expr = make_expr(conn.second);
|
||||
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
|
||||
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, expr));
|
||||
register_reverse_wire_map(y_id, conn.first);
|
||||
}
|
||||
|
||||
|
|
@ -1112,7 +1112,7 @@ struct FirrtlWorker
|
|||
chunk_width++;
|
||||
}
|
||||
|
||||
new_expr = stringf("bits(%s, %d, %d)", start_map.first.c_str(),
|
||||
new_expr = stringf("bits(%s, %d, %d)", start_map.first,
|
||||
start_map.second + chunk_width - 1, start_map.second);
|
||||
is_valid = true;
|
||||
}
|
||||
|
|
@ -1135,13 +1135,13 @@ struct FirrtlWorker
|
|||
|
||||
if (is_valid) {
|
||||
if (make_unconn_id) {
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent.c_str(), unconn_id.c_str(), wireFileinfo.c_str()));
|
||||
wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent, unconn_id, wireFileinfo));
|
||||
// `invalid` is a firrtl construction for simulation so we will not
|
||||
// tag it with a @[fileinfo] tag as it doesn't directly correspond to
|
||||
// a specific line of verilog code.
|
||||
wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), unconn_id.c_str()));
|
||||
wire_decls.push_back(stringf("%s%s is invalid\n", indent, unconn_id));
|
||||
}
|
||||
wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), make_id(wire->name), expr.c_str(), wireFileinfo.c_str()));
|
||||
wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent, make_id(wire->name), expr, wireFileinfo));
|
||||
} else {
|
||||
if (make_unconn_id) {
|
||||
unconn_id.clear();
|
||||
|
|
@ -1149,7 +1149,7 @@ struct FirrtlWorker
|
|||
// `invalid` is a firrtl construction for simulation so we will not
|
||||
// tag it with a @[fileinfo] tag as it doesn't directly correspond to
|
||||
// a specific line of verilog code.
|
||||
wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), make_id(wire->name)));
|
||||
wire_decls.push_back(stringf("%s%s is invalid\n", indent, make_id(wire->name)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1215,9 +1215,6 @@ struct FirrtlBackend : public Backend {
|
|||
}
|
||||
extra_args(f, filename, args, argidx);
|
||||
|
||||
if (!design->full_selection())
|
||||
log_cmd_error("This command only operates on fully selected designs!\n");
|
||||
|
||||
log_header(design, "Executing FIRRTL backend.\n");
|
||||
log_push();
|
||||
|
||||
|
|
@ -1226,11 +1223,12 @@ struct FirrtlBackend : public Backend {
|
|||
Pass::call(design, "demuxmap");
|
||||
Pass::call(design, "bwmuxmap");
|
||||
|
||||
used_names.clear();
|
||||
namecache.clear();
|
||||
autoid_counter = 0;
|
||||
|
||||
// Get the top module, or a reasonable facsimile - we need something for the circuit name.
|
||||
Module *top = design->top_module();
|
||||
Module *top = nullptr;
|
||||
Module *last = nullptr;
|
||||
// Generate module and wire names.
|
||||
for (auto module : design->modules()) {
|
||||
|
|
@ -1251,7 +1249,7 @@ struct FirrtlBackend : public Backend {
|
|||
log_cmd_error("There is no top module in this design!\n");
|
||||
|
||||
std::string circuitFileinfo = getFileinfo(top);
|
||||
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str());
|
||||
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo);
|
||||
|
||||
emit_elaborated_extmodules(design, *f);
|
||||
|
||||
|
|
@ -1265,6 +1263,7 @@ struct FirrtlBackend : public Backend {
|
|||
}
|
||||
}
|
||||
|
||||
used_names.clear();
|
||||
namecache.clear();
|
||||
autoid_counter = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ struct FunctionalCxxBackend : public Backend
|
|||
extra_args(f, filename, args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
log("Dumping module `%s'.\n", module->name.c_str());
|
||||
log("Dumping module `%s'.\n", module->name);
|
||||
printCxx(*f, filename, module);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ struct FunctionalSmtBackend : public Backend {
|
|||
extra_args(f, filename, args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
log("Processing module `%s`.\n", module->name.c_str());
|
||||
log("Processing module `%s`.\n", module->name);
|
||||
SmtModule smt(module);
|
||||
smt.write(*f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,20 +188,27 @@ struct SmtrModule {
|
|||
Functional::IR ir;
|
||||
SmtrScope scope;
|
||||
std::string name;
|
||||
|
||||
bool use_assoc_list_helpers;
|
||||
std::optional<std::string> input_helper_name;
|
||||
std::optional<std::string> output_helper_name;
|
||||
|
||||
SmtrStruct input_struct;
|
||||
SmtrStruct output_struct;
|
||||
SmtrStruct state_struct;
|
||||
|
||||
SmtrModule(Module *module)
|
||||
: ir(Functional::IR::from_module(module))
|
||||
, scope()
|
||||
, name(scope.unique_name(module->name))
|
||||
, input_struct(scope.unique_name(module->name.str() + "_Inputs"), scope)
|
||||
, output_struct(scope.unique_name(module->name.str() + "_Outputs"), scope)
|
||||
, state_struct(scope.unique_name(module->name.str() + "_State"), scope)
|
||||
SmtrModule(Module *module, bool assoc_list_helpers)
|
||||
: ir(Functional::IR::from_module(module)), scope(), name(scope.unique_name(module->name)), use_assoc_list_helpers(assoc_list_helpers),
|
||||
input_struct(scope.unique_name(module->name.str() + "_Inputs"), scope),
|
||||
output_struct(scope.unique_name(module->name.str() + "_Outputs"), scope),
|
||||
state_struct(scope.unique_name(module->name.str() + "_State"), scope)
|
||||
{
|
||||
scope.reserve(name + "_initial");
|
||||
if (assoc_list_helpers) {
|
||||
input_helper_name = scope.unique_name(module->name.str() + "_inputs_helper");
|
||||
scope.reserve(*input_helper_name);
|
||||
output_helper_name = scope.unique_name(module->name.str() + "_outputs_helper");
|
||||
scope.reserve(*output_helper_name);
|
||||
}
|
||||
for (auto input : ir.inputs())
|
||||
input_struct.insert(input->name, input->sort);
|
||||
for (auto output : ir.outputs())
|
||||
|
|
@ -257,6 +264,45 @@ struct SmtrModule {
|
|||
w.pop();
|
||||
}
|
||||
|
||||
void write_assoc_list_helpers(SExprWriter &w)
|
||||
{
|
||||
log_assert(output_helper_name && input_helper_name);
|
||||
|
||||
// Input struct keyword-based constructor.
|
||||
w.push();
|
||||
w.open(list("define"));
|
||||
const auto inputs_name = "inputs";
|
||||
w.open(list(*input_helper_name, inputs_name));
|
||||
w.close();
|
||||
w.open(list(input_struct.name));
|
||||
for (auto input : ir.inputs()) {
|
||||
w.push();
|
||||
w.open(list("let"));
|
||||
w.push();
|
||||
w.open(list());
|
||||
w.open(list("assoc-result"));
|
||||
w << list("assoc", "\"" + RTLIL::unescape_id(input->name) + "\"", inputs_name);
|
||||
w.pop();
|
||||
w.open(list("if", "assoc-result"));
|
||||
w << list("cdr", "assoc-result");
|
||||
w.open(list("begin"));
|
||||
w << list("fprintf", list("current-error-port"), "\"%s not found in inputs\"");
|
||||
w << "'not-found";
|
||||
w.pop();
|
||||
}
|
||||
w.pop();
|
||||
// Output struct keyword-based destructuring
|
||||
w.push();
|
||||
w.open(list("define"));
|
||||
const auto outputs_name = "outputs";
|
||||
w << list(*output_helper_name, outputs_name);
|
||||
w.open(list("list"));
|
||||
for (auto output : ir.outputs()) {
|
||||
w << list("cons", "\"" + RTLIL::unescape_id(output->name) + "\"", output_struct.access("outputs", output->name));
|
||||
}
|
||||
w.pop();
|
||||
}
|
||||
|
||||
void write(std::ostream &out)
|
||||
{
|
||||
SExprWriter w(out);
|
||||
|
|
@ -265,6 +311,10 @@ struct SmtrModule {
|
|||
output_struct.write_definition(w);
|
||||
state_struct.write_definition(w);
|
||||
|
||||
if (use_assoc_list_helpers) {
|
||||
write_assoc_list_helpers(w);
|
||||
}
|
||||
|
||||
write_eval(w);
|
||||
write_initial(w);
|
||||
}
|
||||
|
|
@ -282,12 +332,16 @@ struct FunctionalSmtrBackend : public Backend {
|
|||
log("\n");
|
||||
log(" -provides\n");
|
||||
log(" include 'provide' statement(s) for loading output as a module\n");
|
||||
log(" -assoc-list-helpers\n");
|
||||
log(" provide helper functions which convert inputs/outputs from/to association lists\n");
|
||||
log(" \n");
|
||||
log("\n");
|
||||
}
|
||||
|
||||
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
auto provides = false;
|
||||
auto assoc_list_helpers = false;
|
||||
|
||||
log_header(design, "Executing Functional Rosette Backend.\n");
|
||||
|
||||
|
|
@ -296,6 +350,8 @@ struct FunctionalSmtrBackend : public Backend {
|
|||
{
|
||||
if (args[argidx] == "-provides")
|
||||
provides = true;
|
||||
else if (args[argidx] == "-assoc-list-helpers")
|
||||
assoc_list_helpers = true;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
|
@ -308,7 +364,7 @@ struct FunctionalSmtrBackend : public Backend {
|
|||
|
||||
for (auto module : design->selected_modules()) {
|
||||
log("Processing module `%s`.\n", module->name.c_str());
|
||||
SmtrModule smtr(module);
|
||||
SmtrModule smtr(module, assoc_list_helpers);
|
||||
smtr.write(*f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ struct MemContentsTest {
|
|||
RTLIL::Const values;
|
||||
for(addr_t addr = low; addr <= high; addr++) {
|
||||
RTLIL::Const word(data_dist(rnd), data_width);
|
||||
values.bits().insert(values.bits().end(), word.begin(), word.end());
|
||||
values.append(word);
|
||||
}
|
||||
insert_concatenated(low, values);
|
||||
}
|
||||
|
|
@ -116,7 +116,9 @@ struct MemContentsTest {
|
|||
|
||||
struct FunctionalTestGeneric : public Pass
|
||||
{
|
||||
FunctionalTestGeneric() : Pass("test_generic", "test the generic compute graph") {}
|
||||
FunctionalTestGeneric() : Pass("test_generic", "test the generic compute graph") {
|
||||
internal();
|
||||
}
|
||||
|
||||
void help() override
|
||||
{
|
||||
|
|
@ -141,7 +143,7 @@ struct FunctionalTestGeneric : public Pass
|
|||
*/
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
log("Dumping module `%s'.\n", module->name.c_str());
|
||||
log("Dumping module `%s'.\n", module->name);
|
||||
auto fir = Functional::IR::from_module(module);
|
||||
for(auto node : fir)
|
||||
std::cout << RTLIL::unescape_id(node.name()) << " = " << node.to_string([](auto n) { return RTLIL::unescape_id(n.name()); }) << "\n";
|
||||
|
|
|
|||
|
|
@ -100,13 +100,13 @@ struct IntersynthBackend : public Backend {
|
|||
}
|
||||
extra_args(f, filename, args, argidx);
|
||||
|
||||
log("Output filename: %s\n", filename.c_str());
|
||||
log("Output filename: %s\n", filename);
|
||||
|
||||
for (auto filename : libfiles) {
|
||||
std::ifstream f;
|
||||
f.open(filename.c_str());
|
||||
if (f.fail())
|
||||
log_error("Can't open lib file `%s'.\n", filename.c_str());
|
||||
log_error("Can't open lib file `%s'.\n", filename);
|
||||
RTLIL::Design *lib = new RTLIL::Design;
|
||||
Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog"));
|
||||
libs.push_back(lib);
|
||||
|
|
@ -172,7 +172,7 @@ struct IntersynthBackend : public Backend {
|
|||
if (sig.size() != 0) {
|
||||
conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
|
||||
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first));
|
||||
node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
|
||||
node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig));
|
||||
}
|
||||
}
|
||||
for (auto ¶m : cell->parameters) {
|
||||
|
|
@ -199,13 +199,13 @@ struct IntersynthBackend : public Backend {
|
|||
if (!flag_notypes) {
|
||||
*f << stringf("### Connection Types\n");
|
||||
for (auto code : conntypes_code)
|
||||
*f << stringf("%s", code.c_str());
|
||||
*f << stringf("%s", code);
|
||||
*f << stringf("\n### Cell Types\n");
|
||||
for (auto code : celltypes_code)
|
||||
*f << stringf("%s", code.c_str());
|
||||
*f << stringf("%s", code);
|
||||
}
|
||||
*f << stringf("\n### Netlists\n");
|
||||
*f << stringf("%s", netlists_code.c_str());
|
||||
*f << stringf("%s", netlists_code);
|
||||
|
||||
for (auto lib : libs)
|
||||
delete lib;
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ struct JnyWriter
|
|||
|
||||
f << "{\n";
|
||||
f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\",\n";
|
||||
f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_version_str).c_str());
|
||||
f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_maybe_version()));
|
||||
f << " \"version\": \"0.0.1\",\n";
|
||||
f << " \"invocation\": \"" << escape_string(invk) << "\",\n";
|
||||
f << " \"features\": [";
|
||||
|
|
@ -232,7 +232,7 @@ struct JnyWriter
|
|||
const auto _indent = gen_indent(indent_level);
|
||||
|
||||
f << _indent << "{\n";
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent.c_str(), escape_string(RTLIL::unescape_id(mod->name)).c_str());
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(mod->name)));
|
||||
f << _indent << " \"cell_sorts\": [\n";
|
||||
|
||||
bool first_sort{true};
|
||||
|
|
@ -280,7 +280,7 @@ struct JnyWriter
|
|||
f << ",\n";
|
||||
|
||||
f << _indent << " {\n";
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent.c_str(), escape_string(RTLIL::unescape_id(con.first)).c_str());
|
||||
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(con.first)));
|
||||
f << _indent << " \"direction\": \"";
|
||||
if (port_cell->input(con.first))
|
||||
f << "i";
|
||||
|
|
@ -290,7 +290,7 @@ struct JnyWriter
|
|||
if (con.second.size() == 1)
|
||||
f << _indent << " \"range\": [0, 0]\n";
|
||||
else
|
||||
f << stringf(" %s\"range\": [%d, %d]\n", _indent.c_str(), con.second.size(), 0);
|
||||
f << stringf(" %s\"range\": [%d, %d]\n", _indent, con.second.size(), 0);
|
||||
f << _indent << " }";
|
||||
|
||||
first_port = false;
|
||||
|
|
@ -304,7 +304,7 @@ struct JnyWriter
|
|||
const auto _indent = gen_indent(indent_level);
|
||||
|
||||
f << _indent << "{\n";
|
||||
f << stringf(" %s\"type\": \"%s\",\n", _indent.c_str(), sort.first.c_str());
|
||||
f << stringf(" %s\"type\": \"%s\",\n", _indent, sort.first);
|
||||
f << _indent << " \"ports\": [\n";
|
||||
|
||||
write_cell_ports(port_cell, indent_level + 2);
|
||||
|
|
@ -351,10 +351,10 @@ struct JnyWriter
|
|||
f << stringf(",\n");
|
||||
const auto param_val = param.second;
|
||||
if (!param_val.empty()) {
|
||||
f << stringf(" %s\"%s\": ", _indent.c_str(), escape_string(RTLIL::unescape_id(param.first)).c_str());
|
||||
f << stringf(" %s\"%s\": ", _indent, escape_string(RTLIL::unescape_id(param.first)));
|
||||
write_param_val(param_val);
|
||||
} else {
|
||||
f << stringf(" %s\"%s\": true", _indent.c_str(), escape_string(RTLIL::unescape_id(param.first)).c_str());
|
||||
f << stringf(" %s\"%s\": true", _indent, escape_string(RTLIL::unescape_id(param.first)));
|
||||
}
|
||||
|
||||
first_param = false;
|
||||
|
|
@ -366,7 +366,7 @@ struct JnyWriter
|
|||
log_assert(cell != nullptr);
|
||||
|
||||
f << _indent << " {\n";
|
||||
f << stringf(" %s\"name\": \"%s\"", _indent.c_str(), escape_string(RTLIL::unescape_id(cell->name)).c_str());
|
||||
f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(RTLIL::unescape_id(cell->name)));
|
||||
|
||||
if (_include_connections) {
|
||||
f << ",\n" << _indent << " \"connections\": [\n";
|
||||
|
|
@ -553,7 +553,7 @@ struct JnyPass : public Pass {
|
|||
ff->open(filename.c_str(), std::ofstream::trunc);
|
||||
if (ff->fail()) {
|
||||
delete ff;
|
||||
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", filename, strerror(errno));
|
||||
}
|
||||
f = ff;
|
||||
invk << filename;
|
||||
|
|
@ -568,7 +568,7 @@ struct JnyPass : public Pass {
|
|||
if (!empty) {
|
||||
delete f;
|
||||
} else {
|
||||
log("%s", buf.str().c_str());
|
||||
log("%s", buf.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ struct JsonWriter
|
|||
bool first = true;
|
||||
for (auto ¶m : parameters) {
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first).c_str());
|
||||
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first));
|
||||
write_parameter_value(param.second);
|
||||
first = false;
|
||||
}
|
||||
|
|
@ -155,7 +155,7 @@ struct JsonWriter
|
|||
log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", log_id(module));
|
||||
}
|
||||
|
||||
f << stringf(" %s: {\n", get_name(module->name).c_str());
|
||||
f << stringf(" %s: {\n", get_name(module->name));
|
||||
|
||||
f << stringf(" \"attributes\": {");
|
||||
write_parameters(module->attributes, /*for_module=*/true);
|
||||
|
|
@ -174,7 +174,7 @@ struct JsonWriter
|
|||
if (use_selection && !module->selected(w))
|
||||
continue;
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s: {\n", get_name(n).c_str());
|
||||
f << stringf(" %s: {\n", get_name(n));
|
||||
f << stringf(" \"direction\": \"%s\",\n", w->port_input ? w->port_output ? "inout" : "input" : "output");
|
||||
if (w->start_offset)
|
||||
f << stringf(" \"offset\": %d,\n", w->start_offset);
|
||||
|
|
@ -182,7 +182,7 @@ struct JsonWriter
|
|||
f << stringf(" \"upto\": 1,\n");
|
||||
if (w->is_signed)
|
||||
f << stringf(" \"signed\": %d,\n", w->is_signed);
|
||||
f << stringf(" \"bits\": %s\n", get_bits(w).c_str());
|
||||
f << stringf(" \"bits\": %s\n", get_bits(w));
|
||||
f << stringf(" }");
|
||||
first = false;
|
||||
}
|
||||
|
|
@ -196,13 +196,13 @@ struct JsonWriter
|
|||
if (!scopeinfo_mode && c->type == ID($scopeinfo))
|
||||
continue;
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s: {\n", get_name(c->name).c_str());
|
||||
f << stringf(" %s: {\n", get_name(c->name));
|
||||
f << stringf(" \"hide_name\": %s,\n", c->name[0] == '$' ? "1" : "0");
|
||||
f << stringf(" \"type\": %s,\n", get_name(c->type).c_str());
|
||||
f << stringf(" \"type\": %s,\n", get_name(c->type));
|
||||
if (aig_mode) {
|
||||
Aig aig(c);
|
||||
if (!aig.name.empty()) {
|
||||
f << stringf(" \"model\": \"%s\",\n", aig.name.c_str());
|
||||
f << stringf(" \"model\": \"%s\",\n", aig.name);
|
||||
aig_models.insert(aig);
|
||||
}
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ struct JsonWriter
|
|||
if (c->input(conn.first))
|
||||
direction = c->output(conn.first) ? "inout" : "input";
|
||||
f << stringf("%s\n", first2 ? "" : ",");
|
||||
f << stringf(" %s: \"%s\"", get_name(conn.first).c_str(), direction.c_str());
|
||||
f << stringf(" %s: \"%s\"", get_name(conn.first), direction);
|
||||
first2 = false;
|
||||
}
|
||||
f << stringf("\n },\n");
|
||||
|
|
@ -229,7 +229,7 @@ struct JsonWriter
|
|||
bool first2 = true;
|
||||
for (auto &conn : c->connections()) {
|
||||
f << stringf("%s\n", first2 ? "" : ",");
|
||||
f << stringf(" %s: %s", get_name(conn.first).c_str(), get_bits(conn.second).c_str());
|
||||
f << stringf(" %s: %s", get_name(conn.first), get_bits(conn.second));
|
||||
first2 = false;
|
||||
}
|
||||
f << stringf("\n }\n");
|
||||
|
|
@ -245,7 +245,7 @@ struct JsonWriter
|
|||
if (use_selection && !module->selected(it.second))
|
||||
continue;
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s: {\n", get_name(it.second->name).c_str());
|
||||
f << stringf(" %s: {\n", get_name(it.second->name));
|
||||
f << stringf(" \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0");
|
||||
f << stringf(" \"attributes\": {");
|
||||
write_parameters(it.second->attributes);
|
||||
|
|
@ -265,9 +265,9 @@ struct JsonWriter
|
|||
if (use_selection && !module->selected(w))
|
||||
continue;
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s: {\n", get_name(w->name).c_str());
|
||||
f << stringf(" %s: {\n", get_name(w->name));
|
||||
f << stringf(" \"hide_name\": %s,\n", w->name[0] == '$' ? "1" : "0");
|
||||
f << stringf(" \"bits\": %s,\n", get_bits(w).c_str());
|
||||
f << stringf(" \"bits\": %s,\n", get_bits(w));
|
||||
if (w->start_offset)
|
||||
f << stringf(" \"offset\": %d,\n", w->start_offset);
|
||||
if (w->upto)
|
||||
|
|
@ -291,7 +291,7 @@ struct JsonWriter
|
|||
design->sort();
|
||||
|
||||
f << stringf("{\n");
|
||||
f << stringf(" \"creator\": %s,\n", get_string(yosys_version_str).c_str());
|
||||
f << stringf(" \"creator\": %s,\n", get_string(yosys_maybe_version()));
|
||||
f << stringf(" \"modules\": {\n");
|
||||
vector<Module*> modules = use_selection ? design->selected_modules() : design->modules();
|
||||
bool first_module = true;
|
||||
|
|
@ -308,7 +308,7 @@ struct JsonWriter
|
|||
for (auto &aig : aig_models) {
|
||||
if (!first_model)
|
||||
f << stringf(",\n");
|
||||
f << stringf(" \"%s\": [\n", aig.name.c_str());
|
||||
f << stringf(" \"%s\": [\n", aig.name);
|
||||
int node_idx = 0;
|
||||
for (auto &node : aig.nodes) {
|
||||
if (node_idx != 0)
|
||||
|
|
@ -701,7 +701,7 @@ struct JsonPass : public Pass {
|
|||
ff->open(filename.c_str(), std::ofstream::trunc);
|
||||
if (ff->fail()) {
|
||||
delete ff;
|
||||
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", filename, strerror(errno));
|
||||
}
|
||||
f = ff;
|
||||
} else {
|
||||
|
|
@ -714,7 +714,7 @@ struct JsonPass : public Pass {
|
|||
if (!empty) {
|
||||
delete f;
|
||||
} else {
|
||||
log("%s", buf.str().c_str());
|
||||
log("%s", buf.str());
|
||||
}
|
||||
}
|
||||
} JsonPass;
|
||||
|
|
|
|||
|
|
@ -24,12 +24,23 @@
|
|||
|
||||
#include "rtlil_backend.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/utils.h"
|
||||
#include <errno.h>
|
||||
#include <iterator>
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
using namespace RTLIL_BACKEND;
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const RTLIL::AttrObject *obj)
|
||||
{
|
||||
for (const auto& [name, value] : reversed(obj->attributes)) {
|
||||
f << stringf("%s" "attribute %s ", indent, name);
|
||||
dump_const(f, value);
|
||||
f << stringf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)
|
||||
{
|
||||
if (width < 0)
|
||||
|
|
@ -50,7 +61,9 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi
|
|||
return;
|
||||
}
|
||||
}
|
||||
f << stringf("%d'", width);
|
||||
if ((data.flags & RTLIL::CONST_FLAG_UNSIZED) == 0) {
|
||||
f << stringf("%d'", width);
|
||||
}
|
||||
if (data.flags & RTLIL::CONST_FLAG_SIGNED) {
|
||||
f << stringf("s");
|
||||
}
|
||||
|
|
@ -96,11 +109,11 @@ void RTLIL_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk,
|
|||
dump_const(f, chunk.data, chunk.width, chunk.offset, autoint);
|
||||
} else {
|
||||
if (chunk.width == chunk.wire->width && chunk.offset == 0)
|
||||
f << stringf("%s", chunk.wire->name.c_str());
|
||||
f << stringf("%s", chunk.wire->name);
|
||||
else if (chunk.width == 1)
|
||||
f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
|
||||
f << stringf("%s [%d]", chunk.wire->name, chunk.offset);
|
||||
else
|
||||
f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
|
||||
f << stringf("%s [%d:%d]", chunk.wire->name, chunk.offset+chunk.width-1, chunk.offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,8 +123,9 @@ void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo
|
|||
dump_sigchunk(f, sig.as_chunk(), autoint);
|
||||
} else {
|
||||
f << stringf("{ ");
|
||||
for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
|
||||
dump_sigchunk(f, *it, false);
|
||||
auto chunks = sig.chunks();
|
||||
for (const auto& chunk : reversed(chunks)) {
|
||||
dump_sigchunk(f, chunk, false);
|
||||
f << stringf(" ");
|
||||
}
|
||||
f << stringf("}");
|
||||
|
|
@ -120,16 +134,12 @@ void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo
|
|||
|
||||
void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
|
||||
{
|
||||
for (auto &it : wire->attributes) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, wire);
|
||||
if (wire->driverCell_) {
|
||||
f << stringf("%s" "# driver %s %s\n", indent.c_str(),
|
||||
wire->driverCell()->name.c_str(), wire->driverPort().c_str());
|
||||
f << stringf("%s" "# driver %s %s\n", indent,
|
||||
wire->driverCell()->name, wire->driverPort());
|
||||
}
|
||||
f << stringf("%s" "wire ", indent.c_str());
|
||||
f << stringf("%s" "wire ", indent);
|
||||
if (wire->width != 1)
|
||||
f << stringf("width %d ", wire->width);
|
||||
if (wire->upto)
|
||||
|
|
@ -144,101 +154,85 @@ void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::
|
|||
f << stringf("inout %d ", wire->port_id);
|
||||
if (wire->is_signed)
|
||||
f << stringf("signed ");
|
||||
f << stringf("%s\n", wire->name.c_str());
|
||||
f << stringf("%s\n", wire->name);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
|
||||
{
|
||||
for (auto &it : memory->attributes) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s" "memory ", indent.c_str());
|
||||
dump_attributes(f, indent, memory);
|
||||
f << stringf("%s" "memory ", indent);
|
||||
if (memory->width != 1)
|
||||
f << stringf("width %d ", memory->width);
|
||||
if (memory->size != 0)
|
||||
f << stringf("size %d ", memory->size);
|
||||
if (memory->start_offset != 0)
|
||||
f << stringf("offset %d ", memory->start_offset);
|
||||
f << stringf("%s\n", memory->name.c_str());
|
||||
f << stringf("%s\n", memory->name);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
|
||||
{
|
||||
for (auto &it : cell->attributes) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
dump_attributes(f, indent, cell);
|
||||
f << stringf("%s" "cell %s %s\n", indent, cell->type, cell->name);
|
||||
for (const auto& [name, param] : reversed(cell->parameters)) {
|
||||
f << stringf("%s parameter%s%s%s %s ", indent,
|
||||
(param.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
|
||||
(param.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
|
||||
(param.flags & RTLIL::CONST_FLAG_UNSIZED) != 0 ? " unsized" : "",
|
||||
name);
|
||||
dump_const(f, param);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
|
||||
for (auto &it : cell->parameters) {
|
||||
f << stringf("%s parameter%s%s %s ", indent.c_str(),
|
||||
(it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
|
||||
(it.second.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
|
||||
it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
for (const auto& [port, sig] : reversed(cell->connections_)) {
|
||||
f << stringf("%s connect %s ", indent, port);
|
||||
dump_sigspec(f, sig);
|
||||
f << stringf("\n");
|
||||
}
|
||||
for (auto &it : cell->connections()) {
|
||||
f << stringf("%s connect %s ", indent.c_str(), it.first.c_str());
|
||||
dump_sigspec(f, it.second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
f << stringf("%s" "end\n", indent);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs)
|
||||
{
|
||||
for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it)
|
||||
{
|
||||
f << stringf("%s" "assign ", indent.c_str());
|
||||
dump_sigspec(f, it->first);
|
||||
for (const auto& [lhs, rhs] : cs->actions) {
|
||||
f << stringf("%s" "assign ", indent);
|
||||
dump_sigspec(f, lhs);
|
||||
f << stringf(" ");
|
||||
dump_sigspec(f, it->second);
|
||||
dump_sigspec(f, rhs);
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
||||
for (auto it = cs->switches.begin(); it != cs->switches.end(); ++it)
|
||||
dump_proc_switch(f, indent, *it);
|
||||
for (const auto& sw : cs->switches)
|
||||
dump_proc_switch(f, indent, sw);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
|
||||
{
|
||||
for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, sw);
|
||||
|
||||
f << stringf("%s" "switch ", indent.c_str());
|
||||
f << stringf("%s" "switch ", indent);
|
||||
dump_sigspec(f, sw->signal);
|
||||
f << stringf("\n");
|
||||
|
||||
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it)
|
||||
for (const auto case_ : sw->cases)
|
||||
{
|
||||
for (auto ait = (*it)->attributes.begin(); ait != (*it)->attributes.end(); ++ait) {
|
||||
f << stringf("%s attribute %s ", indent.c_str(), ait->first.c_str());
|
||||
dump_const(f, ait->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s case ", indent.c_str());
|
||||
for (size_t i = 0; i < (*it)->compare.size(); i++) {
|
||||
dump_attributes(f, indent, case_);
|
||||
f << stringf("%s case ", indent);
|
||||
for (size_t i = 0; i < case_->compare.size(); i++) {
|
||||
if (i > 0)
|
||||
f << stringf(" , ");
|
||||
dump_sigspec(f, (*it)->compare[i]);
|
||||
dump_sigspec(f, case_->compare[i]);
|
||||
}
|
||||
f << stringf("\n");
|
||||
|
||||
dump_proc_case_body(f, indent + " ", *it);
|
||||
dump_proc_case_body(f, indent + " ", case_);
|
||||
}
|
||||
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
f << stringf("%s" "end\n", indent);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
|
||||
{
|
||||
f << stringf("%s" "sync ", indent.c_str());
|
||||
f << stringf("%s" "sync ", indent);
|
||||
switch (sy->type) {
|
||||
case RTLIL::ST0: f << stringf("low ");
|
||||
if (0) case RTLIL::ST1: f << stringf("high ");
|
||||
|
|
@ -253,21 +247,17 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
|
|||
case RTLIL::STi: f << stringf("init\n"); break;
|
||||
}
|
||||
|
||||
for (auto &it: sy->actions) {
|
||||
f << stringf("%s update ", indent.c_str());
|
||||
dump_sigspec(f, it.first);
|
||||
for (const auto& [lhs, rhs] : sy->actions) {
|
||||
f << stringf("%s update ", indent);
|
||||
dump_sigspec(f, lhs);
|
||||
f << stringf(" ");
|
||||
dump_sigspec(f, it.second);
|
||||
dump_sigspec(f, rhs);
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
||||
for (auto &it: sy->mem_write_actions) {
|
||||
for (auto it2 = it.attributes.begin(); it2 != it.attributes.end(); ++it2) {
|
||||
f << stringf("%s attribute %s ", indent.c_str(), it2->first.c_str());
|
||||
dump_const(f, it2->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s memwr %s ", indent.c_str(), it.memid.c_str());
|
||||
dump_attributes(f, indent, &it);
|
||||
f << stringf("%s memwr %s ", indent, it.memid);
|
||||
dump_sigspec(f, it.address);
|
||||
f << stringf(" ");
|
||||
dump_sigspec(f, it.data);
|
||||
|
|
@ -281,21 +271,17 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
|
|||
|
||||
void RTLIL_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)
|
||||
{
|
||||
for (auto it = proc->attributes.begin(); it != proc->attributes.end(); ++it) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
|
||||
dump_attributes(f, indent, proc);
|
||||
f << stringf("%s" "process %s\n", indent, proc->name);
|
||||
dump_proc_case_body(f, indent + " ", &proc->root_case);
|
||||
for (auto it = proc->syncs.begin(); it != proc->syncs.end(); ++it)
|
||||
dump_proc_sync(f, indent + " ", *it);
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
for (auto* sync : proc->syncs)
|
||||
dump_proc_sync(f, indent + " ", sync);
|
||||
f << stringf("%s" "end\n", indent);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
|
||||
{
|
||||
f << stringf("%s" "connect ", indent.c_str());
|
||||
f << stringf("%s" "connect ", indent);
|
||||
dump_sigspec(f, left);
|
||||
f << stringf(" ");
|
||||
dump_sigspec(f, right);
|
||||
|
|
@ -304,18 +290,14 @@ void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::
|
|||
|
||||
void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
|
||||
{
|
||||
bool print_header = flag_m || design->selected_whole_module(module->name);
|
||||
bool print_body = !flag_n || !design->selected_whole_module(module->name);
|
||||
bool print_header = flag_m || module->is_selected_whole();
|
||||
bool print_body = !flag_n || !module->is_selected_whole();
|
||||
|
||||
if (print_header)
|
||||
{
|
||||
for (auto it = module->attributes.begin(); it != module->attributes.end(); ++it) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, module);
|
||||
|
||||
f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
|
||||
f << stringf("%s" "module %s\n", indent, module->name);
|
||||
|
||||
if (!module->avail_parameters.empty()) {
|
||||
if (only_selected)
|
||||
|
|
@ -323,9 +305,9 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
for (const auto &p : module->avail_parameters) {
|
||||
const auto &it = module->parameter_default_values.find(p);
|
||||
if (it == module->parameter_default_values.end()) {
|
||||
f << stringf("%s" " parameter %s\n", indent.c_str(), p.c_str());
|
||||
f << stringf("%s" " parameter %s\n", indent, p);
|
||||
} else {
|
||||
f << stringf("%s" " parameter %s ", indent.c_str(), p.c_str());
|
||||
f << stringf("%s" " parameter %s ", indent, p);
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
|
@ -335,40 +317,40 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
|
||||
if (print_body)
|
||||
{
|
||||
for (auto it : module->wires())
|
||||
if (!only_selected || design->selected(module, it)) {
|
||||
for (const auto& [_, wire] : reversed(module->wires_))
|
||||
if (!only_selected || design->selected(module, wire)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_wire(f, indent + " ", it);
|
||||
dump_wire(f, indent + " ", wire);
|
||||
}
|
||||
|
||||
for (auto it : module->memories)
|
||||
if (!only_selected || design->selected(module, it.second)) {
|
||||
for (const auto& [_, mem] : reversed(module->memories))
|
||||
if (!only_selected || design->selected(module, mem)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_memory(f, indent + " ", it.second);
|
||||
dump_memory(f, indent + " ", mem);
|
||||
}
|
||||
|
||||
for (auto it : module->cells())
|
||||
if (!only_selected || design->selected(module, it)) {
|
||||
for (const auto& [_, cell] : reversed(module->cells_))
|
||||
if (!only_selected || design->selected(module, cell)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_cell(f, indent + " ", it);
|
||||
dump_cell(f, indent + " ", cell);
|
||||
}
|
||||
|
||||
for (auto it : module->processes)
|
||||
if (!only_selected || design->selected(module, it.second)) {
|
||||
for (const auto& [_, process] : reversed(module->processes))
|
||||
if (!only_selected || design->selected(module, process)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_proc(f, indent + " ", it.second);
|
||||
dump_proc(f, indent + " ", process);
|
||||
}
|
||||
|
||||
bool first_conn_line = true;
|
||||
for (auto it = module->connections().begin(); it != module->connections().end(); ++it) {
|
||||
for (const auto& [lhs, rhs] : module->connections()) {
|
||||
bool show_conn = !only_selected || design->selected_whole_module(module->name);
|
||||
if (!show_conn) {
|
||||
RTLIL::SigSpec sigs = it->first;
|
||||
sigs.append(it->second);
|
||||
RTLIL::SigSpec sigs = lhs;
|
||||
sigs.append(rhs);
|
||||
for (auto &c : sigs.chunks()) {
|
||||
if (c.wire == NULL || !design->selected(module, c.wire))
|
||||
continue;
|
||||
|
|
@ -378,14 +360,14 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
if (show_conn) {
|
||||
if (only_selected && first_conn_line)
|
||||
f << stringf("\n");
|
||||
dump_conn(f, indent + " ", it->first, it->second);
|
||||
dump_conn(f, indent + " ", lhs, rhs);
|
||||
first_conn_line = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (print_header)
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
f << stringf("%s" "end\n", indent);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
|
||||
|
|
@ -394,7 +376,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
|
|||
|
||||
if (!flag_m) {
|
||||
int count_selected_mods = 0;
|
||||
for (auto module : design->modules()) {
|
||||
for (auto* module : design->modules()) {
|
||||
if (design->selected_whole_module(module->name))
|
||||
flag_m = true;
|
||||
if (design->selected(module))
|
||||
|
|
@ -410,7 +392,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
|
|||
f << stringf("autoidx %d\n", autoidx);
|
||||
}
|
||||
|
||||
for (auto module : design->modules()) {
|
||||
for (const auto& [_, module] : reversed(design->modules_)) {
|
||||
if (!only_selected || design->selected(module)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
|
|
@ -438,10 +420,14 @@ struct RTLILBackend : public Backend {
|
|||
log(" -selected\n");
|
||||
log(" only write selected parts of the design.\n");
|
||||
log("\n");
|
||||
log(" -sort\n");
|
||||
log(" sort design in-place (used to be default).\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
bool selected = false;
|
||||
bool do_sort = false;
|
||||
|
||||
log_header(design, "Executing RTLIL backend.\n");
|
||||
|
||||
|
|
@ -452,14 +438,20 @@ struct RTLILBackend : public Backend {
|
|||
selected = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-sort") {
|
||||
do_sort = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(f, filename, args, argidx);
|
||||
|
||||
design->sort();
|
||||
log("Output filename: %s\n", filename);
|
||||
|
||||
log("Output filename: %s\n", filename.c_str());
|
||||
*f << stringf("# Generated by %s\n", yosys_version_str);
|
||||
if (do_sort)
|
||||
design->sort();
|
||||
|
||||
*f << stringf("# Generated by %s\n", yosys_maybe_version());
|
||||
RTLIL_BACKEND::dump_design(*f, design, selected, true, false);
|
||||
}
|
||||
} RTLILBackend;
|
||||
|
|
@ -527,10 +519,10 @@ struct DumpPass : public Pass {
|
|||
if (!empty) {
|
||||
rewrite_filename(filename);
|
||||
std::ofstream *ff = new std::ofstream;
|
||||
ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc);
|
||||
ff->open(filename, append ? std::ofstream::app : std::ofstream::trunc);
|
||||
if (ff->fail()) {
|
||||
delete ff;
|
||||
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
|
||||
log_error("Can't open file `%s' for writing: %s\n", filename, strerror(errno));
|
||||
}
|
||||
f = ff;
|
||||
} else {
|
||||
|
|
@ -542,7 +534,7 @@ struct DumpPass : public Pass {
|
|||
if (!empty) {
|
||||
delete f;
|
||||
} else {
|
||||
log("%s", buf.str().c_str());
|
||||
log("%s", buf.str());
|
||||
}
|
||||
}
|
||||
} DumpPass;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
namespace RTLIL_BACKEND {
|
||||
void dump_attributes(std::ostream &f, std::string indent, const RTLIL::AttrObject *obj);
|
||||
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true);
|
||||
void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint = true);
|
||||
void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint = true);
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ struct SimplecWorker
|
|||
s[i] -= 'a' - 'A';
|
||||
|
||||
util_declarations.push_back("");
|
||||
util_declarations.push_back(stringf("#ifndef %s", s.c_str()));
|
||||
util_declarations.push_back(stringf("#define %s", s.c_str()));
|
||||
util_declarations.push_back(stringf("#ifndef %s", s));
|
||||
util_declarations.push_back(stringf("#define %s", s));
|
||||
}
|
||||
|
||||
string util_get_bit(const string &signame, int n, int idx)
|
||||
|
|
@ -232,33 +232,33 @@ struct SimplecWorker
|
|||
if (generated_utils.count(util_name) == 0)
|
||||
{
|
||||
util_ifdef_guard(util_name);
|
||||
util_declarations.push_back(stringf("static inline bool %s(const %s *sig)", util_name.c_str(), sigtype(n).c_str()));
|
||||
util_declarations.push_back(stringf("static inline bool %s(const %s *sig)", util_name, sigtype(n)));
|
||||
util_declarations.push_back(stringf("{"));
|
||||
|
||||
int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize;
|
||||
string value_name = stringf("value_%d_%d", std::min(n-1, (word_idx+1)*max_uintsize-1), word_idx*max_uintsize);
|
||||
|
||||
util_declarations.push_back(stringf(" return (sig->%s >> %d) & 1;", value_name.c_str(), word_offset));
|
||||
util_declarations.push_back(stringf(" return (sig->%s >> %d) & 1;", value_name, word_offset));
|
||||
|
||||
util_declarations.push_back(stringf("}"));
|
||||
util_declarations.push_back(stringf("#endif"));
|
||||
generated_utils.insert(util_name);
|
||||
}
|
||||
|
||||
return stringf("%s(&%s)", util_name.c_str(), signame.c_str());
|
||||
return stringf("%s(&%s)", util_name, signame);
|
||||
}
|
||||
|
||||
string util_set_bit(const string &signame, int n, int idx, const string &expr)
|
||||
{
|
||||
if (n == 1 && idx == 0)
|
||||
return stringf(" %s.value_0_0 = %s;", signame.c_str(), expr.c_str());
|
||||
return stringf(" %s.value_0_0 = %s;", signame, expr);
|
||||
|
||||
string util_name = stringf("yosys_simplec_set_bit_%d_of_%d", idx, n);
|
||||
|
||||
if (generated_utils.count(util_name) == 0)
|
||||
{
|
||||
util_ifdef_guard(util_name);
|
||||
util_declarations.push_back(stringf("static inline void %s(%s *sig, bool value)", util_name.c_str(), sigtype(n).c_str()));
|
||||
util_declarations.push_back(stringf("static inline void %s(%s *sig, bool value)", util_name, sigtype(n)));
|
||||
util_declarations.push_back(stringf("{"));
|
||||
|
||||
int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize;
|
||||
|
|
@ -266,9 +266,9 @@ struct SimplecWorker
|
|||
|
||||
#if 0
|
||||
util_declarations.push_back(stringf(" if (value)"));
|
||||
util_declarations.push_back(stringf(" sig->%s |= 1UL << %d;", value_name.c_str(), word_offset));
|
||||
util_declarations.push_back(stringf(" sig->%s |= 1UL << %d;", value_name, word_offset));
|
||||
util_declarations.push_back(stringf(" else"));
|
||||
util_declarations.push_back(stringf(" sig->%s &= ~(1UL << %d);", value_name.c_str(), word_offset));
|
||||
util_declarations.push_back(stringf(" sig->%s &= ~(1UL << %d);", value_name, word_offset));
|
||||
#else
|
||||
util_declarations.push_back(stringf(" sig->%s = (sig->%s & ~((uint%d_t)1 << %d)) | ((uint%d_t)value << %d);",
|
||||
value_name.c_str(), value_name.c_str(), max_uintsize, word_offset, max_uintsize, word_offset));
|
||||
|
|
@ -279,7 +279,7 @@ struct SimplecWorker
|
|||
generated_utils.insert(util_name);
|
||||
}
|
||||
|
||||
return stringf(" %s(&%s, %s);", util_name.c_str(), signame.c_str(), expr.c_str());
|
||||
return stringf(" %s(&%s, %s);", util_name, signame, expr);
|
||||
}
|
||||
|
||||
void create_module_struct(Module *mod)
|
||||
|
|
@ -339,38 +339,38 @@ struct SimplecWorker
|
|||
for (int i = 0; i < GetSize(topo.sorted); i++)
|
||||
topoidx[mod->cell(topo.sorted[i])] = i;
|
||||
|
||||
string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(mod->name).c_str());
|
||||
string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(mod->name));
|
||||
|
||||
for (int i = 0; i < GetSize(ifdef_name); i++)
|
||||
if ('a' <= ifdef_name[i] && ifdef_name[i] <= 'z')
|
||||
ifdef_name[i] -= 'a' - 'A';
|
||||
|
||||
struct_declarations.push_back("");
|
||||
struct_declarations.push_back(stringf("#ifndef %s", ifdef_name.c_str()));
|
||||
struct_declarations.push_back(stringf("#define %s", ifdef_name.c_str()));
|
||||
struct_declarations.push_back(stringf("struct %s_state_t", cid(mod->name).c_str()));
|
||||
struct_declarations.push_back(stringf("#ifndef %s", ifdef_name));
|
||||
struct_declarations.push_back(stringf("#define %s", ifdef_name));
|
||||
struct_declarations.push_back(stringf("struct %s_state_t", cid(mod->name)));
|
||||
struct_declarations.push_back("{");
|
||||
|
||||
struct_declarations.push_back(" // Input Ports");
|
||||
for (Wire *w : mod->wires())
|
||||
if (w->port_input)
|
||||
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width).c_str(), cid(w->name).c_str(), log_id(w)));
|
||||
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
|
||||
|
||||
struct_declarations.push_back("");
|
||||
struct_declarations.push_back(" // Output Ports");
|
||||
for (Wire *w : mod->wires())
|
||||
if (!w->port_input && w->port_output)
|
||||
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width).c_str(), cid(w->name).c_str(), log_id(w)));
|
||||
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
|
||||
|
||||
struct_declarations.push_back("");
|
||||
struct_declarations.push_back(" // Internal Wires");
|
||||
for (Wire *w : mod->wires())
|
||||
if (!w->port_input && !w->port_output)
|
||||
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width).c_str(), cid(w->name).c_str(), log_id(w)));
|
||||
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
|
||||
|
||||
for (Cell *c : mod->cells())
|
||||
if (design->module(c->type))
|
||||
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type).c_str(), cid(c->name).c_str(), log_id(c)));
|
||||
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type), cid(c->name), log_id(c)));
|
||||
|
||||
struct_declarations.push_back(stringf("};"));
|
||||
struct_declarations.push_back("#endif");
|
||||
|
|
@ -407,14 +407,14 @@ struct SimplecWorker
|
|||
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
|
||||
string expr;
|
||||
|
||||
if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr, b_expr);
|
||||
if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr, b_expr);
|
||||
if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr, b_expr);
|
||||
if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr, b_expr);
|
||||
if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr, b_expr);
|
||||
if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr, b_expr);
|
||||
if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr, b_expr);
|
||||
if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr, b_expr);
|
||||
|
||||
log_assert(y.wire);
|
||||
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
|
||||
|
|
@ -436,8 +436,8 @@ struct SimplecWorker
|
|||
string c_expr = c.wire ? util_get_bit(work->prefix + cid(c.wire->name), c.wire->width, c.offset) : c.data ? "1" : "0";
|
||||
string expr;
|
||||
|
||||
if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
|
||||
if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
|
||||
if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr, b_expr, c_expr);
|
||||
if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr, b_expr, c_expr);
|
||||
|
||||
log_assert(y.wire);
|
||||
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
|
||||
|
|
@ -461,8 +461,8 @@ struct SimplecWorker
|
|||
string d_expr = d.wire ? util_get_bit(work->prefix + cid(d.wire->name), d.wire->width, d.offset) : d.data ? "1" : "0";
|
||||
string expr;
|
||||
|
||||
if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
|
||||
if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
|
||||
if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr, b_expr, c_expr, d_expr);
|
||||
if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr, b_expr, c_expr, d_expr);
|
||||
|
||||
log_assert(y.wire);
|
||||
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
|
||||
|
|
@ -484,9 +484,9 @@ struct SimplecWorker
|
|||
string s_expr = s.wire ? util_get_bit(work->prefix + cid(s.wire->name), s.wire->width, s.offset) : s.data ? "1" : "0";
|
||||
|
||||
// casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933)
|
||||
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr.c_str(),
|
||||
cell->type == ID($_NMUX_) ? "!" : "", b_expr.c_str(),
|
||||
cell->type == ID($_NMUX_) ? "!" : "", a_expr.c_str());
|
||||
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr,
|
||||
cell->type == ID($_NMUX_) ? "!" : "", b_expr,
|
||||
cell->type == ID($_NMUX_) ? "!" : "", a_expr);
|
||||
|
||||
log_assert(y.wire);
|
||||
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
|
||||
|
|
@ -504,7 +504,7 @@ struct SimplecWorker
|
|||
while (work->dirty)
|
||||
{
|
||||
if (verbose && (!work->dirty_bits.empty() || !work->dirty_cells.empty()))
|
||||
log(" In %s:\n", work->log_prefix.c_str());
|
||||
log(" In %s:\n", work->log_prefix);
|
||||
|
||||
while (!work->dirty_bits.empty() || !work->dirty_cells.empty())
|
||||
{
|
||||
|
|
@ -517,8 +517,8 @@ struct SimplecWorker
|
|||
if (chunk.wire == nullptr)
|
||||
continue;
|
||||
if (verbose)
|
||||
log(" Propagating %s.%s[%d:%d].\n", work->log_prefix.c_str(), log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
|
||||
funct_declarations.push_back(stringf(" // Updated signal in %s: %s", work->log_prefix.c_str(), log_signal(chunk)));
|
||||
log(" Propagating %s.%s[%d:%d].\n", work->log_prefix, log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
|
||||
funct_declarations.push_back(stringf(" // Updated signal in %s: %s", work->log_prefix, log_signal(chunk)));
|
||||
}
|
||||
|
||||
for (SigBit bit : dirtysig)
|
||||
|
|
@ -539,7 +539,7 @@ struct SimplecWorker
|
|||
work->parent->set_dirty(parent_bit);
|
||||
|
||||
if (verbose)
|
||||
log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix.c_str(), log_id(bit.wire), bit.offset,
|
||||
log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset,
|
||||
work->parent->log_prefix.c_str(), log_id(parent_bit.wire), parent_bit.offset);
|
||||
}
|
||||
|
||||
|
|
@ -556,11 +556,11 @@ struct SimplecWorker
|
|||
child->set_dirty(child_bit);
|
||||
|
||||
if (verbose)
|
||||
log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix.c_str(), log_id(bit.wire), bit.offset,
|
||||
log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset,
|
||||
work->log_prefix.c_str(), log_id(std::get<0>(port)), log_id(child_bit.wire), child_bit.offset);
|
||||
} else {
|
||||
if (verbose)
|
||||
log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix.c_str(), log_id(std::get<0>(port)),
|
||||
log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix, log_id(std::get<0>(port)),
|
||||
work->log_prefix.c_str(), log_id(bit.wire), bit.offset);
|
||||
work->set_dirty(std::get<0>(port));
|
||||
}
|
||||
|
|
@ -579,7 +579,7 @@ struct SimplecWorker
|
|||
string hiername = work->log_prefix + "." + log_id(cell);
|
||||
|
||||
if (verbose)
|
||||
log(" Evaluating %s (%s, best of %d).\n", hiername.c_str(), log_id(cell->type), GetSize(work->dirty_cells));
|
||||
log(" Evaluating %s (%s, best of %d).\n", hiername, log_id(cell->type), GetSize(work->dirty_cells));
|
||||
|
||||
if (activated_cells.count(hiername))
|
||||
reactivated_cells.insert(hiername);
|
||||
|
|
@ -630,13 +630,13 @@ struct SimplecWorker
|
|||
|
||||
void make_func(HierDirtyFlags *work, const string &func_name, const vector<string> &preamble)
|
||||
{
|
||||
log("Generating function %s():\n", func_name.c_str());
|
||||
log("Generating function %s():\n", func_name);
|
||||
|
||||
activated_cells.clear();
|
||||
reactivated_cells.clear();
|
||||
|
||||
funct_declarations.push_back("");
|
||||
funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name.c_str(), cid(work->module->name).c_str()));
|
||||
funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name, cid(work->module->name)));
|
||||
funct_declarations.push_back("{");
|
||||
for (auto &line : preamble)
|
||||
funct_declarations.push_back(line);
|
||||
|
|
@ -657,7 +657,7 @@ struct SimplecWorker
|
|||
{
|
||||
SigSpec sig = sigmaps.at(module)(w);
|
||||
Const val = w->attributes.at(ID::init);
|
||||
val.bits().resize(GetSize(sig), State::Sx);
|
||||
val.resize(GetSize(sig), State::Sx);
|
||||
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
if (val[i] == State::S0 || val[i] == State::S1) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "kernel/log.h"
|
||||
#include "kernel/mem.h"
|
||||
#include "libs/json11/json11.hpp"
|
||||
#include "kernel/utils.h"
|
||||
#include <string>
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
|
@ -81,27 +82,27 @@ struct Smt2Worker
|
|||
if (statebv)
|
||||
{
|
||||
if (width == 0) {
|
||||
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) Bool (= ((_ extract %d %d) state) #b1))", name.c_str(), get_id(module), statebv_width, statebv_width);
|
||||
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) Bool (= ((_ extract %d %d) state) #b1))", name, get_id(module), statebv_width, statebv_width);
|
||||
statebv_width += 1;
|
||||
} else {
|
||||
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) (_ BitVec %d) ((_ extract %d %d) state))", name.c_str(), get_id(module), width, statebv_width+width-1, statebv_width);
|
||||
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) (_ BitVec %d) ((_ extract %d %d) state))", name, get_id(module), width, statebv_width+width-1, statebv_width);
|
||||
statebv_width += width;
|
||||
}
|
||||
}
|
||||
else if (statedt)
|
||||
{
|
||||
if (width == 0) {
|
||||
decl_str = stringf(" (|%s| Bool)", name.c_str());
|
||||
decl_str = stringf(" (|%s| Bool)", name);
|
||||
} else {
|
||||
decl_str = stringf(" (|%s| (_ BitVec %d))", name.c_str(), width);
|
||||
decl_str = stringf(" (|%s| (_ BitVec %d))", name, width);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (width == 0) {
|
||||
decl_str = stringf("(declare-fun |%s| (|%s_s|) Bool)", name.c_str(), get_id(module));
|
||||
decl_str = stringf("(declare-fun |%s| (|%s_s|) Bool)", name, get_id(module));
|
||||
} else {
|
||||
decl_str = stringf("(declare-fun |%s| (|%s_s|) (_ BitVec %d))", name.c_str(), get_id(module), width);
|
||||
decl_str = stringf("(declare-fun |%s| (|%s_s|) (_ BitVec %d))", name, get_id(module), width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ struct Smt2Worker
|
|||
for (auto &mem : memories)
|
||||
{
|
||||
if (is_smtlib2_module)
|
||||
log_error("Memory %s.%s not allowed in module with smtlib2_module attribute", get_id(module), mem.memid.c_str());
|
||||
log_error("Memory %s.%s not allowed in module with smtlib2_module attribute", get_id(module), mem.memid);
|
||||
|
||||
mem.narrow();
|
||||
mem_dict[mem.memid] = &mem;
|
||||
|
|
@ -382,7 +383,7 @@ struct Smt2Worker
|
|||
}
|
||||
|
||||
if (fcache.count(sig[i]) && fcache.at(sig[i]).second == -1) {
|
||||
subexpr.push_back(stringf("(ite %s #b1 #b0)", get_bool(sig[i], state_name).c_str()));
|
||||
subexpr.push_back(stringf("(ite %s #b1 #b0)", get_bool(sig[i], state_name)));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -494,7 +495,7 @@ struct Smt2Worker
|
|||
}
|
||||
|
||||
if (width != GetSize(sig_y) && type != 'b')
|
||||
processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr.c_str());
|
||||
processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr);
|
||||
|
||||
if (verbose)
|
||||
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
|
||||
|
|
@ -616,14 +617,14 @@ struct Smt2Worker
|
|||
string infostr = cell->attributes.count(ID::src) ? cell->attributes.at(ID::src).decode_string().c_str() : get_id(cell);
|
||||
if (cell->attributes.count(ID::reg))
|
||||
infostr += " " + cell->attributes.at(ID::reg).decode_string();
|
||||
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(QY)), infostr.c_str()));
|
||||
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(QY)), infostr));
|
||||
if (cell->getPort(QY).is_wire() && cell->getPort(QY).as_wire()->get_bool_attribute(ID::maximize)){
|
||||
decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter));
|
||||
log("Wire %s is maximized\n", cell->getPort(QY).as_wire()->name.str().c_str());
|
||||
log("Wire %s is maximized\n", cell->getPort(QY).as_wire()->name.str());
|
||||
}
|
||||
else if (cell->getPort(QY).is_wire() && cell->getPort(QY).as_wire()->get_bool_attribute(ID::minimize)){
|
||||
decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter));
|
||||
log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str().c_str());
|
||||
log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str());
|
||||
}
|
||||
|
||||
bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst));
|
||||
|
|
@ -721,7 +722,7 @@ struct Smt2Worker
|
|||
2*GetSize(cell->getPort(ID::A).chunks()) < GetSize(cell->getPort(ID::A))) {
|
||||
bool is_and = cell->type == ID($reduce_and);
|
||||
string bits(GetSize(cell->getPort(ID::A)), is_and ? '1' : '0');
|
||||
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits.c_str()), 'b');
|
||||
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits), 'b');
|
||||
}
|
||||
|
||||
if (cell->type == ID($reduce_and)) return export_reduce(cell, "(and A)", true);
|
||||
|
|
@ -745,7 +746,7 @@ struct Smt2Worker
|
|||
get_bv(sig_s);
|
||||
|
||||
for (int i = 0; i < GetSize(sig_s); i++)
|
||||
processed_expr = stringf("(ite %s %s %s)", get_bool(sig_s[i]).c_str(),
|
||||
processed_expr = stringf("(ite %s %s %s)", get_bool(sig_s[i]),
|
||||
get_bv(sig_b.extract(i*width, width)).c_str(), processed_expr.c_str());
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -1078,24 +1079,24 @@ struct Smt2Worker
|
|||
|
||||
RTLIL::SigSpec sig = sigmap(wire);
|
||||
Const val = wire->attributes.at(ID::init);
|
||||
val.bits().resize(GetSize(sig), State::Sx);
|
||||
val.resize(GetSize(sig), State::Sx);
|
||||
if (bvmode && GetSize(sig) > 1) {
|
||||
Const mask(State::S1, GetSize(sig));
|
||||
bool use_mask = false;
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
if (val[i] != State::S0 && val[i] != State::S1) {
|
||||
val.bits()[i] = State::S0;
|
||||
mask.bits()[i] = State::S0;
|
||||
val.set(i, State::S0);
|
||||
mask.set(i, State::S0);
|
||||
use_mask = true;
|
||||
}
|
||||
if (use_mask)
|
||||
init_list.push_back(stringf("(= (bvand %s #b%s) #b%s) ; %s", get_bv(sig).c_str(), mask.as_string().c_str(), val.as_string().c_str(), get_id(wire)));
|
||||
init_list.push_back(stringf("(= (bvand %s #b%s) #b%s) ; %s", get_bv(sig), mask.as_string(), val.as_string(), get_id(wire)));
|
||||
else
|
||||
init_list.push_back(stringf("(= %s #b%s) ; %s", get_bv(sig).c_str(), val.as_string().c_str(), get_id(wire)));
|
||||
init_list.push_back(stringf("(= %s #b%s) ; %s", get_bv(sig), val.as_string(), get_id(wire)));
|
||||
} else {
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
if (val[i] == State::S0 || val[i] == State::S1)
|
||||
init_list.push_back(stringf("(= %s %s) ; %s", get_bool(sig[i]).c_str(), val[i] == State::S1 ? "true" : "false", get_id(wire)));
|
||||
init_list.push_back(stringf("(= %s %s) ; %s", get_bool(sig[i]), val[i] == State::S1 ? "true" : "false", get_id(wire)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1130,7 +1131,7 @@ struct Smt2Worker
|
|||
}
|
||||
|
||||
if (private_name && cell->attributes.count(ID::src))
|
||||
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string().c_str()));
|
||||
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string()));
|
||||
else
|
||||
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell)));
|
||||
|
||||
|
|
@ -1179,11 +1180,11 @@ struct Smt2Worker
|
|||
SigSpec sig = sigmap(conn.second);
|
||||
|
||||
if (bvmode || GetSize(w) == 1) {
|
||||
hier.push_back(stringf(" (= %s (|%s_n %s| %s)) ; %s.%s\n", (GetSize(w) > 1 ? get_bv(sig) : get_bool(sig)).c_str(),
|
||||
hier.push_back(stringf(" (= %s (|%s_n %s| %s)) ; %s.%s\n", (GetSize(w) > 1 ? get_bv(sig) : get_bool(sig)),
|
||||
get_id(cell->type), get_id(w), cell_state.c_str(), get_id(cell->type), get_id(w)));
|
||||
} else {
|
||||
for (int i = 0; i < GetSize(w); i++)
|
||||
hier.push_back(stringf(" (= %s (|%s_n %s %d| %s)) ; %s.%s[%d]\n", get_bool(sig[i]).c_str(),
|
||||
hier.push_back(stringf(" (= %s (|%s_n %s %d| %s)) ; %s.%s[%d]\n", get_bool(sig[i]),
|
||||
get_id(cell->type), get_id(w), i, cell_state.c_str(), get_id(cell->type), get_id(w), i));
|
||||
}
|
||||
}
|
||||
|
|
@ -1203,25 +1204,25 @@ struct Smt2Worker
|
|||
{
|
||||
std::string expr_d = get_bool(cell->getPort(ID::D));
|
||||
std::string expr_q = get_bool(cell->getPort(ID::Q), "next_state");
|
||||
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
|
||||
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)).c_str(), get_bool(cell->getPort(ID::Q), "other_state").c_str()));
|
||||
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(ID::Q))));
|
||||
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)), get_bool(cell->getPort(ID::Q), "other_state")));
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($ff), ID($dff), ID($anyinit)))
|
||||
{
|
||||
std::string expr_d = get_bv(cell->getPort(ID::D));
|
||||
std::string expr_q = get_bv(cell->getPort(ID::Q), "next_state");
|
||||
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
|
||||
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Q)).c_str(), get_bv(cell->getPort(ID::Q), "other_state").c_str()));
|
||||
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(ID::Q))));
|
||||
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Q)), get_bv(cell->getPort(ID::Q), "other_state")));
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($anyconst), ID($allconst)))
|
||||
{
|
||||
std::string expr_d = get_bv(cell->getPort(ID::Y));
|
||||
std::string expr_q = get_bv(cell->getPort(ID::Y), "next_state");
|
||||
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Y))));
|
||||
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(ID::Y))));
|
||||
if (cell->type == ID($anyconst))
|
||||
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)).c_str(), get_bv(cell->getPort(ID::Y), "other_state").c_str()));
|
||||
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)), get_bv(cell->getPort(ID::Y), "other_state")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1340,11 +1341,11 @@ struct Smt2Worker
|
|||
|
||||
std::string expr_d = stringf("(|%s#%d#%d| state)", get_id(module), arrayid, GetSize(mem->wr_ports));
|
||||
std::string expr_q = stringf("(|%s#%d#0| next_state)", get_id(module), arrayid);
|
||||
trans.push_back(stringf(" (= %s %s) ; %s\n", expr_d.c_str(), expr_q.c_str(), get_id(mem->memid)));
|
||||
trans.push_back(stringf(" (= %s %s) ; %s\n", expr_d, expr_q, get_id(mem->memid)));
|
||||
ex_state_eq.push_back(stringf("(= (|%s#%d#0| state) (|%s#%d#0| other_state))", get_id(module), arrayid, get_id(module), arrayid));
|
||||
|
||||
if (has_async_wr)
|
||||
hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d.c_str(), final_memstate.c_str(), get_id(mem->memid)));
|
||||
hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d, final_memstate, get_id(mem->memid)));
|
||||
|
||||
Const init_data = mem->get_init_data();
|
||||
|
||||
|
|
@ -1360,10 +1361,10 @@ struct Smt2Worker
|
|||
for (int k = 0; k < GetSize(initword); k++) {
|
||||
if (initword[k] == State::S0 || initword[k] == State::S1) {
|
||||
gen_init_constr = true;
|
||||
initmask.bits()[k] = State::S1;
|
||||
initmask.set(k, State::S1);
|
||||
} else {
|
||||
initmask.bits()[k] = State::S0;
|
||||
initword.bits()[k] = State::S0;
|
||||
initmask.set(k, State::S0);
|
||||
initword.set(k, State::S0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1401,7 +1402,7 @@ struct Smt2Worker
|
|||
expr = "\n " + ex_state_eq.front() + "\n";
|
||||
} else {
|
||||
for (auto &str : ex_state_eq)
|
||||
expr += stringf("\n %s", str.c_str());
|
||||
expr += stringf("\n %s", str);
|
||||
expr += "\n)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1414,7 +1415,7 @@ struct Smt2Worker
|
|||
expr = "\n " + ex_input_eq.front() + "\n";
|
||||
} else {
|
||||
for (auto &str : ex_input_eq)
|
||||
expr += stringf("\n %s", str.c_str());
|
||||
expr += stringf("\n %s", str);
|
||||
expr += "\n)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1428,7 +1429,7 @@ struct Smt2Worker
|
|||
assert_expr = "\n " + assert_list.front() + "\n";
|
||||
} else {
|
||||
for (auto &str : assert_list)
|
||||
assert_expr += stringf("\n %s", str.c_str());
|
||||
assert_expr += stringf("\n %s", str);
|
||||
assert_expr += "\n)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1441,7 +1442,7 @@ struct Smt2Worker
|
|||
assume_expr = "\n " + assume_list.front() + "\n";
|
||||
} else {
|
||||
for (auto &str : assume_list)
|
||||
assume_expr += stringf("\n %s", str.c_str());
|
||||
assume_expr += stringf("\n %s", str);
|
||||
assume_expr += "\n)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1454,7 +1455,7 @@ struct Smt2Worker
|
|||
init_expr = "\n " + init_list.front() + "\n";
|
||||
} else {
|
||||
for (auto &str : init_list)
|
||||
init_expr += stringf("\n %s", str.c_str());
|
||||
init_expr += stringf("\n %s", str);
|
||||
init_expr += "\n)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1775,7 +1776,7 @@ struct Smt2Backend : public Backend {
|
|||
if (args[argidx] == "-tpl" && argidx+1 < args.size()) {
|
||||
template_f.open(args[++argidx]);
|
||||
if (template_f.fail())
|
||||
log_error("Can't open template file `%s'.\n", args[argidx].c_str());
|
||||
log_error("Can't open template file `%s'.\n", args[argidx]);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-bv" || args[argidx] == "-mem") {
|
||||
|
|
@ -1830,7 +1831,7 @@ struct Smt2Backend : public Backend {
|
|||
}
|
||||
}
|
||||
|
||||
*f << stringf("; SMT-LIBv2 description generated by %s\n", yosys_version_str);
|
||||
*f << stringf("; SMT-LIBv2 description generated by %s\n", yosys_maybe_version());
|
||||
|
||||
if (!bvmode)
|
||||
*f << stringf("; yosys-smt2-nobv\n");
|
||||
|
|
@ -1845,7 +1846,7 @@ struct Smt2Backend : public Backend {
|
|||
*f << stringf("; yosys-smt2-stdt\n");
|
||||
|
||||
for (auto &it : solver_options)
|
||||
*f << stringf("; yosys-smt2-solver-option %s %s\n", it.first.c_str(), it.second.c_str());
|
||||
*f << stringf("; yosys-smt2-solver-option %s %s\n", it.first, it.second);
|
||||
|
||||
std::vector<RTLIL::Module*> sorted_modules;
|
||||
|
||||
|
|
@ -1912,7 +1913,7 @@ struct Smt2Backend : public Backend {
|
|||
}
|
||||
|
||||
if (topmod)
|
||||
*f << stringf("; yosys-smt2-topmod %s\n", topmod_id.c_str());
|
||||
*f << stringf("; yosys-smt2-topmod %s\n", topmod_id);
|
||||
|
||||
*f << stringf("; end of yosys output\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -1875,6 +1875,11 @@ elif covermode:
|
|||
smt_assert_antecedent("(|%s_t| s%d s%d)" % (topmod, step-1, step))
|
||||
smt_assert_antecedent("(not (|%s_is| s%d))" % (topmod, step))
|
||||
|
||||
if step < skip_steps:
|
||||
print_msg("Skipping step %d.." % (step))
|
||||
step += 1
|
||||
continue
|
||||
|
||||
while "1" in cover_mask:
|
||||
print_msg("Checking cover reachability in step %d.." % (step))
|
||||
smt_push()
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ struct SmvWorker
|
|||
{
|
||||
if (!idcache.count(id))
|
||||
{
|
||||
string name = stringf("_%s", id.c_str());
|
||||
string name = stringf("_%s", id);
|
||||
|
||||
if (name.compare(0, 2, "_\\") == 0)
|
||||
name = "_" + name.substr(2);
|
||||
|
|
@ -163,15 +163,15 @@ struct SmvWorker
|
|||
if (width >= 0) {
|
||||
if (is_signed) {
|
||||
if (GetSize(sig) > width)
|
||||
s = stringf("signed(resize(%s, %d))", s.c_str(), width);
|
||||
s = stringf("signed(resize(%s, %d))", s, width);
|
||||
else
|
||||
s = stringf("resize(signed(%s), %d)", s.c_str(), width);
|
||||
s = stringf("resize(signed(%s), %d)", s, width);
|
||||
} else
|
||||
s = stringf("resize(%s, %d)", s.c_str(), width);
|
||||
s = stringf("resize(%s, %d)", s, width);
|
||||
} else if (is_signed)
|
||||
s = stringf("signed(%s)", s.c_str());
|
||||
s = stringf("signed(%s)", s);
|
||||
else if (count_chunks > 1)
|
||||
s = stringf("(%s)", s.c_str());
|
||||
s = stringf("(%s)", s);
|
||||
|
||||
strbuf.push_back(s);
|
||||
return strbuf.back().c_str();
|
||||
|
|
@ -262,7 +262,7 @@ struct SmvWorker
|
|||
if (cell->type == ID($sshr) && signed_a)
|
||||
{
|
||||
expr_a = rvalue_s(sig_a, width);
|
||||
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a.c_str(), op.c_str(), rvalue(sig_b.extract(0, shift_b_width)), width_y);
|
||||
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a, op, rvalue(sig_b.extract(0, shift_b_width)), width_y);
|
||||
if (shift_b_width < GetSize(sig_b))
|
||||
expr = stringf("%s != 0ud%d_0 ? (bool(%s) ? !0ud%d_0 : 0ud%d_0) : %s",
|
||||
rvalue(sig_b.extract(shift_b_width, GetSize(sig_b) - shift_b_width)), GetSize(sig_b) - shift_b_width,
|
||||
|
|
@ -278,8 +278,8 @@ struct SmvWorker
|
|||
// f << stringf(" %s : unsigned word[%d]; -- neg(%s)\n", b_shl, GetSize(sig_b), log_signal(sig_b));
|
||||
definitions.push_back(stringf("%s := unsigned(-%s);", b_shl, rvalue_s(sig_b)));
|
||||
|
||||
string expr_shl = stringf("resize(%s << %s[%d:0], %d)", expr_a.c_str(), b_shl, shift_b_width-1, width_y);
|
||||
string expr_shr = stringf("resize(%s >> %s[%d:0], %d)", expr_a.c_str(), b_shr, shift_b_width-1, width_y);
|
||||
string expr_shl = stringf("resize(%s << %s[%d:0], %d)", expr_a, b_shl, shift_b_width-1, width_y);
|
||||
string expr_shr = stringf("resize(%s >> %s[%d:0], %d)", expr_a, b_shr, shift_b_width-1, width_y);
|
||||
|
||||
if (shift_b_width < GetSize(sig_b)) {
|
||||
expr_shl = stringf("%s[%d:%d] != 0ud%d_0 ? 0ud%d_0 : %s", b_shl, GetSize(sig_b)-1, shift_b_width,
|
||||
|
|
@ -288,7 +288,7 @@ struct SmvWorker
|
|||
GetSize(sig_b)-shift_b_width, width_y, expr_shr.c_str());
|
||||
}
|
||||
|
||||
expr = stringf("bool(%s) ? %s : %s", rvalue(sig_b[GetSize(sig_b)-1]), expr_shl.c_str(), expr_shr.c_str());
|
||||
expr = stringf("bool(%s) ? %s : %s", rvalue(sig_b[GetSize(sig_b)-1]), expr_shl, expr_shr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -297,13 +297,13 @@ struct SmvWorker
|
|||
else
|
||||
expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width);
|
||||
|
||||
expr = stringf("resize(%s %s %s[%d:0], %d)", expr_a.c_str(), op.c_str(), rvalue_u(sig_b), shift_b_width-1, width_y);
|
||||
expr = stringf("resize(%s %s %s[%d:0], %d)", expr_a, op, rvalue_u(sig_b), shift_b_width-1, width_y);
|
||||
if (shift_b_width < GetSize(sig_b))
|
||||
expr = stringf("%s[%d:%d] != 0ud%d_0 ? 0ud%d_0 : %s", rvalue_u(sig_b), GetSize(sig_b)-1, shift_b_width,
|
||||
GetSize(sig_b)-shift_b_width, width_y, expr.c_str());
|
||||
}
|
||||
|
||||
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
|
||||
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -426,7 +426,7 @@ struct SmvWorker
|
|||
if (cell->type == ID($reduce_or)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
|
||||
if (cell->type == ID($reduce_bool)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
|
||||
|
||||
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
|
||||
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -445,7 +445,7 @@ struct SmvWorker
|
|||
if (cell->type == ID($reduce_xnor))
|
||||
expr = "!(" + expr + ")";
|
||||
|
||||
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr.c_str(), width_y));
|
||||
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr, width_y));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -463,7 +463,7 @@ struct SmvWorker
|
|||
if (cell->type == ID($logic_and)) expr = expr_a + " & " + expr_b;
|
||||
if (cell->type == ID($logic_or)) expr = expr_a + " | " + expr_b;
|
||||
|
||||
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
|
||||
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +475,7 @@ struct SmvWorker
|
|||
string expr_a = stringf("(%s = 0ub%d_0)", rvalue(cell->getPort(ID::A)), width_a);
|
||||
const char *expr_y = lvalue(cell->getPort(ID::Y));
|
||||
|
||||
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr_a.c_str(), width_y));
|
||||
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr_a, width_y));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -491,7 +491,7 @@ struct SmvWorker
|
|||
expr += stringf("bool(%s) ? %s : ", rvalue(sig_s[i]), rvalue(sig_b.extract(i*width, width)));
|
||||
expr += rvalue(sig_a);
|
||||
|
||||
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
|
||||
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -505,7 +505,7 @@ struct SmvWorker
|
|||
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
|
||||
{
|
||||
string op = cell->type == ID($_NOT_) ? "!" : "";
|
||||
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)), op.c_str(), rvalue(cell->getPort(ID::A))));
|
||||
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)), op, rvalue(cell->getPort(ID::A))));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -650,7 +650,7 @@ struct SmvWorker
|
|||
for (int k = GetSize(sig)-1; k >= 0; k--)
|
||||
bits += sig[k] == State::S1 ? '1' : '0';
|
||||
|
||||
expr = stringf("0ub%d_%s", GetSize(bits), bits.c_str()) + expr;
|
||||
expr = stringf("0ub%d_%s", GetSize(bits), bits) + expr;
|
||||
}
|
||||
else if (sigmap(SigBit(wire, i)) == SigBit(wire, i))
|
||||
{
|
||||
|
|
@ -683,36 +683,36 @@ struct SmvWorker
|
|||
}
|
||||
}
|
||||
|
||||
definitions.push_back(stringf("%s := %s;", cid(wire->name), expr.c_str()));
|
||||
definitions.push_back(stringf("%s := %s;", cid(wire->name), expr));
|
||||
}
|
||||
|
||||
if (!inputvars.empty()) {
|
||||
f << stringf(" IVAR\n");
|
||||
for (const string &line : inputvars)
|
||||
f << stringf(" %s\n", line.c_str());
|
||||
f << stringf(" %s\n", line);
|
||||
}
|
||||
|
||||
if (!vars.empty()) {
|
||||
f << stringf(" VAR\n");
|
||||
for (const string &line : vars)
|
||||
f << stringf(" %s\n", line.c_str());
|
||||
f << stringf(" %s\n", line);
|
||||
}
|
||||
|
||||
if (!definitions.empty()) {
|
||||
f << stringf(" DEFINE\n");
|
||||
for (const string &line : definitions)
|
||||
f << stringf(" %s\n", line.c_str());
|
||||
f << stringf(" %s\n", line);
|
||||
}
|
||||
|
||||
if (!assignments.empty()) {
|
||||
f << stringf(" ASSIGN\n");
|
||||
for (const string &line : assignments)
|
||||
f << stringf(" %s\n", line.c_str());
|
||||
f << stringf(" %s\n", line);
|
||||
}
|
||||
|
||||
if (!invarspecs.empty()) {
|
||||
for (const string &line : invarspecs)
|
||||
f << stringf(" INVARSPEC %s\n", line.c_str());
|
||||
f << stringf(" INVARSPEC %s\n", line);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -756,7 +756,7 @@ struct SmvBackend : public Backend {
|
|||
if (args[argidx] == "-tpl" && argidx+1 < args.size()) {
|
||||
template_f.open(args[++argidx]);
|
||||
if (template_f.fail())
|
||||
log_error("Can't open template file `%s'.\n", args[argidx].c_str());
|
||||
log_error("Can't open template file `%s'.\n", args[argidx]);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-verbose") {
|
||||
|
|
@ -795,9 +795,9 @@ struct SmvBackend : public Backend {
|
|||
modules.erase(module);
|
||||
|
||||
if (module == nullptr)
|
||||
log_error("Module '%s' not found.\n", stmt[1].c_str());
|
||||
log_error("Module '%s' not found.\n", stmt[1]);
|
||||
|
||||
*f << stringf("-- SMV description generated by %s\n", yosys_version_str);
|
||||
*f << stringf("-- SMV description generated by %s\n", yosys_maybe_version());
|
||||
|
||||
log("Creating SMV representation of module %s.\n", log_id(module));
|
||||
SmvWorker worker(module, verbose, *f);
|
||||
|
|
@ -816,7 +816,7 @@ struct SmvBackend : public Backend {
|
|||
|
||||
if (!modules.empty())
|
||||
{
|
||||
*f << stringf("-- SMV description generated by %s\n", yosys_version_str);
|
||||
*f << stringf("-- SMV description generated by %s\n", yosys_maybe_version());
|
||||
|
||||
for (auto module : modules) {
|
||||
log("Creating SMV representation of module %s.\n", log_id(module));
|
||||
|
|
|
|||
|
|
@ -51,16 +51,16 @@ static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg,
|
|||
if (s.wire->port_id)
|
||||
use_inames = true;
|
||||
if (s.wire->width > 1)
|
||||
f << stringf(" %s.%d", spice_id2str(s.wire->name, use_inames, inums).c_str(), s.offset);
|
||||
f << stringf(" %s.%d", spice_id2str(s.wire->name, use_inames, inums), s.offset);
|
||||
else
|
||||
f << stringf(" %s", spice_id2str(s.wire->name, use_inames, inums).c_str());
|
||||
f << stringf(" %s", spice_id2str(s.wire->name, use_inames, inums));
|
||||
} else {
|
||||
if (s == RTLIL::State::S0)
|
||||
f << stringf(" %s", neg.c_str());
|
||||
f << stringf(" %s", neg);
|
||||
else if (s == RTLIL::State::S1)
|
||||
f << stringf(" %s", pos.c_str());
|
||||
f << stringf(" %s", pos);
|
||||
else
|
||||
f << stringf(" %s%d", ncpf.c_str(), nc_counter++);
|
||||
f << stringf(" %s%d", ncpf, nc_counter++);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
|
|||
}
|
||||
}
|
||||
|
||||
f << stringf(" %s\n", spice_id2str(cell->type).c_str());
|
||||
f << stringf(" %s\n", spice_id2str(cell->type));
|
||||
}
|
||||
|
||||
for (auto &conn : module->connections())
|
||||
|
|
@ -127,7 +127,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
|
|||
f << (buf == "DC" ? stringf("V%d", conn_counter++) : stringf("X%d", cell_counter++));
|
||||
print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
|
||||
print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
|
||||
f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf.c_str()));
|
||||
f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +215,7 @@ struct SpiceBackend : public Backend {
|
|||
if (module->get_bool_attribute(ID::top))
|
||||
top_module_name = module->name.str();
|
||||
|
||||
*f << stringf("* SPICE netlist generated by %s\n", yosys_version_str);
|
||||
*f << stringf("* SPICE netlist generated by %s\n", yosys_maybe_version());
|
||||
*f << stringf("\n");
|
||||
|
||||
for (auto module : design->modules())
|
||||
|
|
@ -242,23 +242,23 @@ struct SpiceBackend : public Backend {
|
|||
ports.at(wire->port_id-1) = wire;
|
||||
}
|
||||
|
||||
*f << stringf(".SUBCKT %s", spice_id2str(module->name).c_str());
|
||||
*f << stringf(".SUBCKT %s", spice_id2str(module->name));
|
||||
for (RTLIL::Wire *wire : ports) {
|
||||
log_assert(wire != NULL);
|
||||
if (wire->width > 1) {
|
||||
for (int i = 0; i < wire->width; i++)
|
||||
*f << stringf(" %s.%d", spice_id2str(wire->name).c_str(), big_endian ? wire->width - 1 - i : i);
|
||||
*f << stringf(" %s.%d", spice_id2str(wire->name), big_endian ? wire->width - 1 - i : i);
|
||||
} else
|
||||
*f << stringf(" %s", spice_id2str(wire->name).c_str());
|
||||
*f << stringf(" %s", spice_id2str(wire->name));
|
||||
}
|
||||
*f << stringf("\n");
|
||||
print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames);
|
||||
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name).c_str());
|
||||
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name));
|
||||
}
|
||||
|
||||
if (!top_module_name.empty()) {
|
||||
if (top_module == NULL)
|
||||
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
|
||||
log_error("Can't find top module `%s'!\n", top_module_name);
|
||||
print_spice_module(*f, top_module, design, neg, pos, buf, ncpf, big_endian, use_inames);
|
||||
*f << stringf("\n");
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,36 +17,23 @@
|
|||
*
|
||||
* ---
|
||||
*
|
||||
* A very simple and straightforward frontend for the RTLIL text
|
||||
* representation.
|
||||
* A simple and straightforward Verilog backend.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RTLIL_FRONTEND_H
|
||||
#define RTLIL_FRONTEND_H
|
||||
#ifndef VERILOG_BACKEND_H
|
||||
#define VERILOG_BACKEND_H
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
#include <string>
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
namespace VERILOG_BACKEND {
|
||||
|
||||
namespace RTLIL_FRONTEND {
|
||||
extern std::istream *lexin;
|
||||
extern RTLIL::Design *current_design;
|
||||
extern bool flag_nooverwrite;
|
||||
extern bool flag_overwrite;
|
||||
extern bool flag_lib;
|
||||
}
|
||||
const pool<string> verilog_keywords();
|
||||
bool char_is_verilog_escaped(char c);
|
||||
bool id_is_verilog_escaped(const std::string &str);
|
||||
|
||||
}; /* namespace VERILOG_BACKEND */
|
||||
YOSYS_NAMESPACE_END
|
||||
|
||||
extern int rtlil_frontend_yydebug;
|
||||
int rtlil_frontend_yylex(void);
|
||||
void rtlil_frontend_yyerror(char const *s);
|
||||
void rtlil_frontend_yywarning(char const *s);
|
||||
void rtlil_frontend_yyrestart(FILE *f);
|
||||
int rtlil_frontend_yyparse(void);
|
||||
int rtlil_frontend_yylex_destroy(void);
|
||||
int rtlil_frontend_yyget_lineno(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* VERILOG_BACKEND_H */
|
||||
2
docs/.gitignore
vendored
2
docs/.gitignore
vendored
|
|
@ -1,5 +1,4 @@
|
|||
/build/
|
||||
/source/cmd
|
||||
/source/generated
|
||||
/source/_images/**/*.log
|
||||
/source/_images/**/*.aux
|
||||
|
|
@ -7,3 +6,4 @@
|
|||
/source/_images/**/*.svg
|
||||
/source/_images/**/*.dot
|
||||
/source/_images/code_examples
|
||||
/venv
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ help:
|
|||
.PHONY: clean
|
||||
clean: clean-examples
|
||||
rm -rf $(BUILDDIR)/*
|
||||
rm -rf source/cmd util/__pycache__
|
||||
rm -rf util/__pycache__
|
||||
rm -rf source/generated
|
||||
$(MAKE) -C source/_images clean
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ all: examples all_tex
|
|||
# set a fake time in pdf generation to prevent unnecessary differences in output
|
||||
FAKETIME := TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001'
|
||||
|
||||
ifneq ($(shell :; command -v rsync),)
|
||||
RSYNC_CP ?= rsync -t
|
||||
else
|
||||
RSYNC_CP ?= cp -a
|
||||
endif
|
||||
|
||||
# find all code example makefiles
|
||||
.PHONY: examples
|
||||
CODE_EXAMPLES := ../code_examples/*/Makefile
|
||||
|
|
@ -19,7 +25,7 @@ FORCE:
|
|||
../%/Makefile: FORCE
|
||||
@make -C $(@D) dots
|
||||
@mkdir -p $*
|
||||
@find $(@D) -name *.dot -exec rsync -t {} $* \;
|
||||
@find $(@D) -name *.dot -exec $(RSYNC_CP) {} $* \;
|
||||
|
||||
# find and build all tex files
|
||||
.PHONY: all_tex
|
||||
|
|
|
|||
|
|
@ -18,3 +18,8 @@
|
|||
.literal-block-wrapper .code-block-caption .caption-number {
|
||||
padding-right: 0.5em
|
||||
}
|
||||
|
||||
/* Don't double shrink text in a literal in an optionlist */
|
||||
kbd .option>.literal {
|
||||
font-size: revert;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ ezSAT
|
|||
|
||||
The files in ``libs/ezsat`` provide a library for simplifying generating CNF
|
||||
formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT
|
||||
library is written by C. Wolf. It is used by the `sat` pass (see
|
||||
:doc:`/cmd/sat`).
|
||||
library is written by C. Wolf. It is used by the `sat` pass.
|
||||
|
||||
fst
|
||||
---
|
||||
|
|
@ -78,4 +77,4 @@ SubCircuit
|
|||
The files in ``libs/subcircuit`` provide a library for solving the subcircuit
|
||||
isomorphism problem. It is written by C. Wolf and based on the Ullmann Subgraph
|
||||
Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the
|
||||
extract pass (see :doc:`../cmd/extract`).
|
||||
`extract` pass.
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ circuits.
|
|||
Tools exist to synthesize high level code (usually in the form of C/C++/SystemC
|
||||
code with additional metadata) to behavioural HDL code (usually in the form of
|
||||
Verilog or VHDL code). Aside from the many commercial tools for high level
|
||||
synthesis there are also a number of FOSS tools for high level synthesis .
|
||||
synthesis there are also a number of FOSS tools for high level synthesis.
|
||||
|
||||
Behavioural level
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -185,7 +185,7 @@ advantage that it has a unique normalized form. The latter has much better worst
|
|||
case performance and is therefore better suited for the synthesis of large logic
|
||||
functions.
|
||||
|
||||
Good FOSS tools exists for multi-level logic synthesis .
|
||||
Good FOSS tools exists for multi-level logic synthesis.
|
||||
|
||||
Yosys contains basic logic synthesis functionality but can also use ABC for the
|
||||
logic synthesis step. Using ABC is recommended.
|
||||
|
|
@ -221,7 +221,7 @@ design description as input and generates an RTL, logical gate or physical gate
|
|||
level description of the design as output. Yosys' main strengths are behavioural
|
||||
and RTL synthesis. A wide range of commands (synthesis passes) exist within
|
||||
Yosys that can be used to perform a wide range of synthesis tasks within the
|
||||
domain of behavioural, rtl and logic synthesis. Yosys is designed to be
|
||||
domain of behavioural, RTL and logic synthesis. Yosys is designed to be
|
||||
extensible and therefore is a good basis for implementing custom synthesis tools
|
||||
for specialised tasks.
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ of lexical tokens given in :numref:`Tab. %s <tab:Basics_tokens>`.
|
|||
TOK_SEMICOLON \-
|
||||
============== ===============
|
||||
|
||||
The lexer is usually generated by a lexer generator (e.g. flex ) from a
|
||||
The lexer is usually generated by a lexer generator (e.g. flex) from a
|
||||
description file that is using regular expressions to specify the text pattern
|
||||
that should match the individual tokens.
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ significant bit first. Bits may be any of:
|
|||
- ``m``: A marked bit (internal use only)
|
||||
- ``-``: A don't care value
|
||||
|
||||
When the bit representation has fewer bits than the width, it is padded to the width with
|
||||
the most significant explicit bit, or ``0`` if the most significant explicit bit is ``1``,
|
||||
or ``x`` if there are no explicit bits.
|
||||
|
||||
An *integer* is simply a signed integer value in decimal format. **Warning:**
|
||||
Integer constants are limited to 32 bits. That is, they may only be in the range
|
||||
:math:`[-2147483648, 2147483648)`. Integers outside this range will result in an
|
||||
|
|
@ -133,6 +137,7 @@ wires, memories, cells, processes, and connections.
|
|||
<module> ::= <attr-stmt>* <module-stmt> <module-body> <module-end-stmt>
|
||||
<module-stmt> ::= module <id> <eol>
|
||||
<module-body> ::= (<param-stmt>
|
||||
| <conn-stmt>
|
||||
| <wire>
|
||||
| <memory>
|
||||
| <cell>
|
||||
|
|
@ -170,6 +175,11 @@ See :ref:`sec:rtlil_sigspec` for an overview of signal specifications.
|
|||
| <sigspec> [ <integer> (:<integer>)? ]
|
||||
| { <sigspec>* }
|
||||
|
||||
When a ``<wire-id>`` is specified, the wire must have been previously declared.
|
||||
|
||||
When a signal slice is specified, the left-hand integer must be greather than or
|
||||
equal to the right-hand integer.
|
||||
|
||||
Connections
|
||||
^^^^^^^^^^^
|
||||
|
||||
|
|
@ -268,7 +278,7 @@ may have zero or more attributes.
|
|||
.. code:: BNF
|
||||
|
||||
<switch> ::= <switch-stmt> <case>* <switch-end-stmt>
|
||||
<switch-stmt> := <attr-stmt>* switch <sigspec> <eol>
|
||||
<switch-stmt> ::= <attr-stmt>* switch <sigspec> <eol>
|
||||
<case> ::= <attr-stmt>* <case-stmt> <case-body>
|
||||
<case-stmt> ::= case <compare>? <eol>
|
||||
<compare> ::= <sigspec> (, <sigspec>)*
|
||||
|
|
@ -295,3 +305,4 @@ be:
|
|||
| sync always <eol>
|
||||
<sync-type> ::= low | high | posedge | negedge | edge
|
||||
<update-stmt> ::= update <dest-sigspec> <src-sigspec> <eol>
|
||||
| <attr-stmt>* memwr <id> <sigspec> <sigspec> <sigspec> <constant> <eol>
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ are zero, the value from ``A`` input is sent to the output. If the :math:`n`\
|
|||
'th bit from ``S`` is set, the value :math:`n`\ 'th ``WIDTH`` bits wide slice of
|
||||
the ``B`` input is sent to the output. When more than one bit from ``S`` is set
|
||||
the output is undefined. Cells of this type are used to model "parallel cases"
|
||||
(defined by using the ``parallel_case`` attribute or detected by an
|
||||
optimization).
|
||||
(defined by using the ``parallel_case`` attribute, the ``unique`` or ``unique0``
|
||||
SystemVerilog keywords, or detected by an optimization).
|
||||
|
||||
The `$tribuf` cell is used to implement tristate logic. Cells of this type have
|
||||
a ``WIDTH`` parameter and inputs ``A`` and ``EN`` and an output ``Y``. The ``A``
|
||||
|
|
|
|||
5
docs/source/cmd/index_backends.rst
Normal file
5
docs/source/cmd/index_backends.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Writing output files
|
||||
--------------------
|
||||
|
||||
.. autocmdgroup:: backends
|
||||
:members:
|
||||
5
docs/source/cmd/index_formal.rst
Normal file
5
docs/source/cmd/index_formal.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Formal verification
|
||||
-------------------
|
||||
|
||||
.. autocmdgroup:: formal
|
||||
:members:
|
||||
5
docs/source/cmd/index_frontends.rst
Normal file
5
docs/source/cmd/index_frontends.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Reading input files
|
||||
-------------------
|
||||
|
||||
.. autocmdgroup:: frontends
|
||||
:members:
|
||||
152
docs/source/cmd/index_internal.rst
Normal file
152
docs/source/cmd/index_internal.rst
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
Internal commands for developers
|
||||
--------------------------------
|
||||
|
||||
.. autocmdgroup:: internal
|
||||
:members:
|
||||
|
||||
Writing command help
|
||||
--------------------
|
||||
|
||||
- use `chformal` as an example
|
||||
- generated help content below
|
||||
|
||||
.. _chformal autocmd:
|
||||
|
||||
.. autocmd:: chformal
|
||||
:noindex:
|
||||
|
||||
The ``formatted_help()`` method
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- ``PrettyHelp::get_current()``
|
||||
- ``PrettyHelp::set_group()``
|
||||
|
||||
+ used with ``.. autocmdgroup:: <group>``
|
||||
+ can assign group and return false
|
||||
+ if no group is set, will try to use ``source_location`` and assign group
|
||||
from path to source file
|
||||
|
||||
- return value
|
||||
|
||||
+ true means help content added to current ``PrettyHelp``
|
||||
+ false to use ``Pass::help()``
|
||||
|
||||
- adding content
|
||||
|
||||
+ help content is a list of ``ContentListing`` nodes, each one having a type,
|
||||
body, and its own list of children ``ContentListing``\ s
|
||||
+ ``PrettyHelp::get_root()`` returns the root ``ContentListing`` (``type="root"``)
|
||||
+ ``ContentListing::{usage, option, codeblock, paragraph}`` each add a
|
||||
``ContentListing`` to the current node, with type the same as the method
|
||||
|
||||
* the first argument is the body of the new node
|
||||
* ``usage`` shows how to call the command (i.e. its "signature")
|
||||
* ``paragraph`` content is formatted as a paragraph of text with line breaks
|
||||
added automatically
|
||||
* ``codeblock`` content is displayed verbatim, use line breaks as desired;
|
||||
takes an optional ``language`` argument for assigning the language in RST
|
||||
output for code syntax highlighting (use ``yoscrypt`` for yosys script
|
||||
syntax highlighting)
|
||||
* ``option`` lists a single option for the command, usually starting with a
|
||||
dash (``-``); takes an optional second argument which adds a paragraph
|
||||
node as a means of description
|
||||
|
||||
+ ``ContentListing::open_usage`` creates and returns a new usage node, can be
|
||||
used to e.g. add text/options specific to a given usage of the command
|
||||
+ ``ContentListing::open_option`` creates and returns a new option node, can
|
||||
be used to e.g. add multiple paragraphs to an option's description
|
||||
+ paragraphs are treated as raw RST, allowing for inline formatting and
|
||||
references as if it were written in the RST file itself
|
||||
|
||||
.. literalinclude:: /generated/chformal.cc
|
||||
:language: c++
|
||||
:start-at: bool formatted_help()
|
||||
:end-before: void execute
|
||||
:caption: ``ChformalPass::formatted_help()`` from :file:`passes/cmds/chformal.cc`
|
||||
|
||||
Dumping command help to json
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- `help -dump-cmds-json cmds.json`
|
||||
|
||||
+ generates a ``ContentListing`` for each command registered in Yosys
|
||||
+ tries to parse unformatted ``Pass::help()`` output if
|
||||
``Pass::formatted_help()`` is unimplemented or returns false
|
||||
|
||||
* if a line starts with four spaces followed by the name of the command then
|
||||
a space, it is parsed as a signature (usage node)
|
||||
* if a line is indented and starts with a dash (``-``), it is parsed as an
|
||||
option
|
||||
* anything else is parsed as a codeblock and added to either the root node
|
||||
or the current option depending on the indentation
|
||||
|
||||
+ dictionary of command name to ``ContentListing``
|
||||
|
||||
* uses ``ContentListing::to_json()`` recursively for each node in root
|
||||
* root node used for source location of class definition
|
||||
* includes flags set during pass constructor (e.g. ``experimental_flag`` set
|
||||
by ``Pass::experimental()``)
|
||||
* also title (``short_help`` argument in ``Pass::Pass``), group, and class
|
||||
name
|
||||
|
||||
+ dictionary of group name to list of commands in that group
|
||||
|
||||
- used by sphinx autodoc to generate help content
|
||||
|
||||
.. literalinclude:: /generated/cmds.json
|
||||
:language: json
|
||||
:start-at: "chformal": {
|
||||
:end-before: "chparam": {
|
||||
:caption: `chformal` in generated :file:`cmds.json`
|
||||
|
||||
.. note:: Synthesis command scripts are special cased
|
||||
|
||||
If the final block of help output starts with the string `"The following
|
||||
commands are executed by this synthesis command:\n"`, then the rest of the
|
||||
code block is formatted as ``yoscrypt`` (e.g. `synth_ice40`). The caveat
|
||||
here is that if the ``script()`` calls ``run()`` on any commands *prior* to
|
||||
the first ``check_label`` then the auto detection will break and revert to
|
||||
unformatted code (e.g. `synth_fabulous`).
|
||||
|
||||
Command line rendering
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- if ``Pass::formatted_help()`` returns true, will call
|
||||
``PrettyHelp::log_help()``
|
||||
|
||||
+ traverse over the children of the root node and render as plain text
|
||||
+ effectively the reverse of converting unformatted ``Pass::help()`` text
|
||||
+ lines are broken at 80 characters while maintaining indentation (controlled
|
||||
by ``MAX_LINE_LEN`` in :file:`kernel/log_help.cc`)
|
||||
+ each line is broken into words separated by spaces, if a given word starts
|
||||
and ends with backticks they will be stripped
|
||||
|
||||
- if it returns false it will call ``Pass::help()`` which should call ``log()``
|
||||
directly to print and format help text
|
||||
|
||||
+ if ``Pass::help()`` is not overridden then a default message about missing
|
||||
help will be displayed
|
||||
|
||||
.. literalinclude:: /generated/chformal.log
|
||||
:lines: 2-
|
||||
|
||||
RST generated from autocmd
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- below is the raw RST output from ``autocmd`` (``YosysCmdDocumenter`` class in
|
||||
:file:`docs/util/cmd_documenter.py`) for `chformal` command
|
||||
- heading will be rendered as a subheading of the most recent heading (see
|
||||
`chformal autocmd`_ above rendered under `Writing command help`_)
|
||||
- ``.. cmd:def:: <cmd>`` line is indexed for cross references with ``:cmd:ref:``
|
||||
directive (`chformal autocmd`_ above uses ``:noindex:`` option so that
|
||||
`chformal` still links to the correct location)
|
||||
|
||||
+ ``:title:`` option controls text that appears when hovering over the
|
||||
`chformal` link
|
||||
|
||||
- commands with warning flags (experimental or internal) add a ``.. warning``
|
||||
block before any of the help content
|
||||
- if a command has no ``source_location`` the ``.. note`` at the bottom will
|
||||
instead link to :doc:`/cmd/index_other`
|
||||
|
||||
.. autocmd_rst:: chformal
|
||||
5
docs/source/cmd/index_kernel.rst
Normal file
5
docs/source/cmd/index_kernel.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Yosys kernel commands
|
||||
---------------------
|
||||
|
||||
.. autocmdgroup:: kernel
|
||||
:members:
|
||||
9
docs/source/cmd/index_other.rst
Normal file
9
docs/source/cmd/index_other.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
:orphan:
|
||||
|
||||
Other commands
|
||||
==============
|
||||
|
||||
Unknown source location
|
||||
|
||||
.. autocmdgroup:: unknown
|
||||
:members:
|
||||
14
docs/source/cmd/index_passes.rst
Normal file
14
docs/source/cmd/index_passes.rst
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Passes
|
||||
------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
/cmd/index_passes_hierarchy
|
||||
/cmd/index_passes_proc
|
||||
/cmd/index_passes_fsm
|
||||
/cmd/index_passes_memory
|
||||
/cmd/index_passes_opt
|
||||
/cmd/index_passes_techmap
|
||||
/cmd/index_passes_*
|
||||
5
docs/source/cmd/index_passes_cmds.rst
Normal file
5
docs/source/cmd/index_passes_cmds.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Design modification
|
||||
-------------------
|
||||
|
||||
.. autocmdgroup:: passes/cmds
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_equiv.rst
Normal file
5
docs/source/cmd/index_passes_equiv.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Equivalence checking
|
||||
--------------------
|
||||
|
||||
.. autocmdgroup:: passes/equiv
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_fsm.rst
Normal file
5
docs/source/cmd/index_passes_fsm.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
FSM handling
|
||||
------------
|
||||
|
||||
.. autocmdgroup:: passes/fsm
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_hierarchy.rst
Normal file
5
docs/source/cmd/index_passes_hierarchy.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Working with hierarchy
|
||||
----------------------
|
||||
|
||||
.. autocmdgroup:: passes/hierarchy
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_memory.rst
Normal file
5
docs/source/cmd/index_passes_memory.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Memory handling
|
||||
---------------
|
||||
|
||||
.. autocmdgroup:: passes/memory
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_opt.rst
Normal file
5
docs/source/cmd/index_passes_opt.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Optimization passes
|
||||
-------------------
|
||||
|
||||
.. autocmdgroup:: passes/opt
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_proc.rst
Normal file
5
docs/source/cmd/index_passes_proc.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Converting process blocks
|
||||
-------------------------
|
||||
|
||||
.. autocmdgroup:: passes/proc
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_sat.rst
Normal file
5
docs/source/cmd/index_passes_sat.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Simulating circuits
|
||||
-------------------
|
||||
|
||||
.. autocmdgroup:: passes/sat
|
||||
:members:
|
||||
5
docs/source/cmd/index_passes_status.rst
Normal file
5
docs/source/cmd/index_passes_status.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Design status
|
||||
-------------
|
||||
|
||||
.. autocmdgroup:: passes/status
|
||||
:members:
|
||||
7
docs/source/cmd/index_passes_techmap.rst
Normal file
7
docs/source/cmd/index_passes_techmap.rst
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Technology mapping
|
||||
------------------
|
||||
|
||||
.. seealso:: :doc:`/cmd/index_techlibs`
|
||||
|
||||
.. autocmdgroup:: passes/techmap
|
||||
:members:
|
||||
11
docs/source/cmd/index_techlibs.rst
Normal file
11
docs/source/cmd/index_techlibs.rst
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
Technology libraries
|
||||
====================
|
||||
|
||||
Listed in alphabetical order.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
/cmd/index_techlibs_common
|
||||
/cmd/index_techlibs_*
|
||||
5
docs/source/cmd/index_techlibs_achronix.rst
Normal file
5
docs/source/cmd/index_techlibs_achronix.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Achronix
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/achronix
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_anlogic.rst
Normal file
5
docs/source/cmd/index_techlibs_anlogic.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Anlogic
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/anlogic
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_common.rst
Normal file
5
docs/source/cmd/index_techlibs_common.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Generic
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/common
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_coolrunner2.rst
Normal file
5
docs/source/cmd/index_techlibs_coolrunner2.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
CoolRunner-II
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/coolrunner2
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_easic.rst
Normal file
5
docs/source/cmd/index_techlibs_easic.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
eASIC
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/easic
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_fabulous.rst
Normal file
5
docs/source/cmd/index_techlibs_fabulous.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
FABulous
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/fabulous
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_gatemate.rst
Normal file
5
docs/source/cmd/index_techlibs_gatemate.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Gatemate
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/gatemate
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_gowin.rst
Normal file
5
docs/source/cmd/index_techlibs_gowin.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Gowin
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/gowin
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_greenpak4.rst
Normal file
5
docs/source/cmd/index_techlibs_greenpak4.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
GreenPAK4
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/greenpak4
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_ice40.rst
Normal file
5
docs/source/cmd/index_techlibs_ice40.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
iCE40
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/ice40
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_intel.rst
Normal file
5
docs/source/cmd/index_techlibs_intel.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Intel (MAX10, Cyclone IV)
|
||||
-------------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/intel
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_intel_alm.rst
Normal file
5
docs/source/cmd/index_techlibs_intel_alm.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Intel ALM (Cyclone V, Arria V, Cyclone 10 GX)
|
||||
---------------------------------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/intel_alm
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_lattice.rst
Normal file
5
docs/source/cmd/index_techlibs_lattice.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Lattice
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/lattice
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_microchip.rst
Normal file
5
docs/source/cmd/index_techlibs_microchip.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Microchip
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/microchip
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_microchip_sf2.rst
Normal file
5
docs/source/cmd/index_techlibs_microchip_sf2.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Microchip - SmartFusion2/IGLOO2
|
||||
-----------------------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/sf2
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_nanoxplore.rst
Normal file
5
docs/source/cmd/index_techlibs_nanoxplore.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
NanoXplore
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/nanoxplore
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_quicklogic.rst
Normal file
5
docs/source/cmd/index_techlibs_quicklogic.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
QuickLogic
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/quicklogic
|
||||
:members:
|
||||
5
docs/source/cmd/index_techlibs_xilinx.rst
Normal file
5
docs/source/cmd/index_techlibs_xilinx.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Xilinx
|
||||
------------------
|
||||
|
||||
.. autocmdgroup:: techlibs/xilinx
|
||||
:members:
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue