mirror of
https://github.com/YosysHQ/yosys
synced 2025-12-12 14:46:23 +00:00
Merge remote-tracking branch 'origin/main' into gussmith23-rosette-backend-updates
This commit is contained in:
commit
6fe35fa46c
694 changed files with 33466 additions and 17901 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 }}
|
||||
9
.github/workflows/codeql.yml
vendored
9
.github/workflows/codeql.yml
vendored
|
|
@ -10,15 +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
|
||||
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:
|
||||
|
|
|
|||
48
.github/workflows/extra-builds.yml
vendored
48
.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
|
||||
|
|
@ -27,19 +35,20 @@ jobs:
|
|||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
- run: sudo apt-get install libfl-dev
|
||||
- name: Build
|
||||
run: make vcxsrc YOSYS_VER=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
|
||||
|
|
@ -50,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
|
||||
|
|
@ -64,13 +73,24 @@ jobs:
|
|||
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
|
||||
|
|
@ -80,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)
|
||||
|
|
@ -98,7 +120,7 @@ jobs:
|
|||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
- uses: cachix/install-nix-action@v26
|
||||
- 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
|
||||
|
|
|
|||
6
.github/workflows/prepare-docs.yml
vendored
6
.github/workflows/prepare-docs.yml
vendored
|
|
@ -26,7 +26,7 @@ jobs:
|
|||
# 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,7 +47,8 @@ jobs:
|
|||
echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
make -j$procs ENABLE_LTO=1
|
||||
echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf
|
||||
make -j$procs
|
||||
|
||||
- name: Prepare docs
|
||||
shell: bash
|
||||
|
|
@ -59,7 +60,6 @@ jobs:
|
|||
with:
|
||||
name: cmd-ref-${{ github.sha }}
|
||||
path: |
|
||||
docs/source/cmd
|
||||
docs/source/generated
|
||||
docs/source/_images
|
||||
docs/source/code_examples
|
||||
|
|
|
|||
114
.github/workflows/test-build.yml
vendored
114
.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:
|
||||
|
|
@ -50,6 +60,9 @@ jobs:
|
|||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-build-deps: true
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
|
|
@ -57,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: |
|
||||
|
|
@ -84,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]
|
||||
|
|
@ -97,41 +108,10 @@ jobs:
|
|||
|
||||
- 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 }}-${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
|
||||
|
|
@ -158,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 }}
|
||||
|
|
@ -177,6 +196,10 @@ jobs:
|
|||
|
||||
- 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
|
||||
|
|
@ -201,7 +224,7 @@ jobs:
|
|||
name: Try build docs
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
needs: [pre_docs_job]
|
||||
if: needs.pre_docs_job.outputs.should_skip != 'true'
|
||||
if: ${{ needs.pre_docs_job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }}
|
||||
strategy:
|
||||
matrix:
|
||||
docs-target: [html, latexpdf]
|
||||
|
|
@ -221,6 +244,7 @@ jobs:
|
|||
run: |
|
||||
make config-clang
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf
|
||||
make -j$procs
|
||||
|
||||
- name: Install doc prereqs
|
||||
|
|
|
|||
32
.github/workflows/test-compile.yml
vendored
32
.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,11 +42,14 @@ 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
|
||||
|
|
@ -49,6 +60,9 @@ jobs:
|
|||
|
||||
- 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
|
||||
|
|
@ -70,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
|
||||
62
.github/workflows/test-verific.yml
vendored
62
.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
|
||||
|
|
@ -70,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
|
||||
|
|
|
|||
1
.github/workflows/update-flake-lock.yml
vendored
1
.github/workflows/update-flake-lock.yml
vendored
|
|
@ -6,6 +6,7 @@ on:
|
|||
|
||||
jobs:
|
||||
lockfile:
|
||||
if: github.repository == 'YosysHQ/Yosys'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
|
|
|||
8
.github/workflows/version.yml
vendored
8
.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
|
||||
|
|
@ -18,11 +19,8 @@ jobs:
|
|||
- 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"
|
||||
|
|
@ -30,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 }}
|
||||
|
|
|
|||
51
.github/workflows/wheels.yml
vendored
51
.github/workflows/wheels.yml
vendored
|
|
@ -4,7 +4,7 @@ name: Build Wheels for PyPI
|
|||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 10 * * 0'
|
||||
- cron: "0 10 * * 0"
|
||||
|
||||
jobs:
|
||||
build_wheels:
|
||||
|
|
@ -25,15 +25,15 @@ jobs:
|
|||
archs: "aarch64",
|
||||
},
|
||||
{
|
||||
name: "macOS 13",
|
||||
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
|
||||
|
|
@ -54,28 +54,25 @@ jobs:
|
|||
fetch-depth: 0
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
- if: ${{ matrix.os.family == 'linux' }}
|
||||
name: "[Linux] Set up QEMU"
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- 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: |
|
||||
|
|
@ -100,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
|
||||
|
|
@ -132,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
|
||||
|
|
|
|||
81
.gitignore
vendored
81
.gitignore
vendored
|
|
@ -1,26 +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__
|
||||
/.cache
|
||||
/.cproject
|
||||
/.project
|
||||
/.settings
|
||||
/qtcreator.files
|
||||
/qtcreator.includes
|
||||
/qtcreator.config
|
||||
/qtcreator.creator
|
||||
/qtcreator.creator.user
|
||||
/compile_commands.json
|
||||
/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
|
||||
|
|
@ -36,22 +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"
|
||||
|
|
|
|||
94
CHANGELOG
94
CHANGELOG
|
|
@ -2,9 +2,101 @@
|
|||
List of major changes and improvements between releases
|
||||
=======================================================
|
||||
|
||||
Yosys 0.53 .. Yosys 0.54-dev
|
||||
Yosys 0.59 .. Yosys 0.60-dev
|
||||
--------------------------
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
210
Makefile
210
Makefile
|
|
@ -23,10 +23,13 @@ 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 +46,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,15 +96,15 @@ 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 :=
|
||||
|
|
@ -109,18 +117,16 @@ PLUGIN_LINKFLAGS += -L"$(LIBDIR)"
|
|||
PLUGIN_LIBS := -lyosys_exe
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_HELP_SOURCE),1)
|
||||
CXXFLAGS += -DYOSYS_ENABLE_HELP_SOURCE
|
||||
endif
|
||||
|
||||
PKG_CONFIG ?= pkg-config
|
||||
SED ?= sed
|
||||
BISON ?= bison
|
||||
STRIP ?= strip
|
||||
AWK ?= awk
|
||||
|
||||
ifneq ($(shell :; command -v rsync),)
|
||||
RSYNC_CP ?= rsync -rc
|
||||
else
|
||||
RSYNC_CP ?= cp -ru
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Darwin)
|
||||
PLUGIN_LINKFLAGS += -undefined dynamic_lookup
|
||||
LINKFLAGS += -rdynamic
|
||||
|
|
@ -129,12 +135,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)
|
||||
|
|
@ -160,7 +162,7 @@ ifeq ($(OS), Haiku)
|
|||
CXXFLAGS += -D_DEFAULT_SOURCE
|
||||
endif
|
||||
|
||||
YOSYS_VER := 0.53+39
|
||||
YOSYS_VER := 0.59+134
|
||||
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)
|
||||
|
|
@ -183,7 +185,7 @@ endif
|
|||
OBJS = kernel/version_$(GIT_REV).o
|
||||
|
||||
bumpversion:
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 53c22ab.. | wc -l`/;" Makefile
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 03eb220.. | wc -l`/;" Makefile
|
||||
|
||||
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
|
||||
|
||||
|
|
@ -282,12 +284,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))
|
||||
|
|
@ -301,6 +302,7 @@ DISABLE_SPAWN := 1
|
|||
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
LINK_ABC := 1
|
||||
ENABLE_THREADS := 0
|
||||
DISABLE_ABC_THREADS := 1
|
||||
endif
|
||||
|
||||
|
|
@ -341,33 +343,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
|
||||
|
||||
UV_ENV :=
|
||||
ifeq ($(PYOSYS_USE_UV),1)
|
||||
UV_ENV := uv run --no-project --with 'pybind11>3,<4' --with 'cxxheaderparser'
|
||||
endif
|
||||
|
||||
LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags))
|
||||
LIBS += $(shell $(PYTHON_CONFIG) --libs)
|
||||
EXE_LIBS += $(filter-out $(LIBS),$(shell $(PYTHON_CONFIG_FOR_EXE) --libs))
|
||||
CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON
|
||||
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
|
||||
|
||||
# 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) $(EXE_LIBS) $(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)
|
||||
endif
|
||||
|
||||
LIBS += $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem
|
||||
PY_WRAPPER_FILE = kernel/python_wrappers
|
||||
OBJS += $(PY_WRAPPER_FILE).o
|
||||
PY_GEN_SCRIPT= py_wrap_generator
|
||||
PY_WRAP_INCLUDES := $(shell $(PYTHON_EXECUTABLE) -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)
|
||||
|
|
@ -455,6 +459,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)
|
||||
|
|
@ -468,6 +478,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
|
||||
|
||||
|
|
@ -519,8 +532,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
|
||||
|
|
@ -531,7 +548,6 @@ LIBS_VERIFIC += -Wl,--whole-archive $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VE
|
|||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(ENABLE_COVER),1)
|
||||
CXXFLAGS += -DYOSYS_ENABLE_COVER
|
||||
endif
|
||||
|
|
@ -551,6 +567,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)
|
||||
|
|
@ -613,6 +636,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))
|
||||
|
|
@ -626,15 +650,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 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
|
||||
|
|
@ -744,11 +774,14 @@ $(PROGRAM_PREFIX)yosys$(EXE): $(OBJS)
|
|||
|
||||
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) $<
|
||||
|
|
@ -758,9 +791,9 @@ 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_EXECUTABLE) -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
|
||||
|
|
@ -828,7 +861,17 @@ check-git-abc:
|
|||
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)
|
||||
|
||||
|
|
@ -866,12 +909,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
|
||||
|
|
@ -979,32 +1025,41 @@ 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 -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
$(INSTALL_SUDO) cp yosys-abc $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc
|
||||
endif
|
||||
$(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ENABLE_PLUGINS),1)
|
||||
|
|
@ -1019,6 +1074,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
|
||||
|
|
@ -1026,19 +1084,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_CP) 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_CP) 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 $@'
|
||||
|
|
@ -1055,6 +1102,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
|
||||
|
|
@ -1090,18 +1146,16 @@ 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 kernel/python_wrappers.o
|
||||
rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d
|
||||
rm -rf tests/asicworld/*.out tests/asicworld/*.log
|
||||
rm -rf tests/hana/*.out tests/hana/*.log
|
||||
|
|
@ -1113,14 +1167,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__
|
||||
rm -f *.whl
|
||||
-$(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
|
||||
|
|
@ -1221,5 +1281,5 @@ echo-cxx:
|
|||
|
||||
FORCE:
|
||||
|
||||
.PHONY: all top-all abc test install install-abc docs clean mrproper qtcreator coverage vcxsrc
|
||||
.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 e55d316cc9a7f72a84a76eda555aa6ec083c9d0d
|
||||
Subproject commit 1c5ed1ce378cc04beac30bb31abc4c37c8467042
|
||||
|
|
@ -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();
|
||||
|
|
@ -697,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));
|
||||
}
|
||||
|
||||
|
|
@ -901,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");
|
||||
|
|
@ -925,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;
|
||||
|
|
@ -955,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;
|
||||
|
|
@ -1008,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()) {
|
||||
|
|
@ -1016,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);
|
||||
}
|
||||
|
||||
|
|
@ -1027,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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,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 +105,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 +490,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 +574,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 +626,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 +731,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 +836,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();
|
||||
|
|
@ -838,7 +846,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
|
|||
|
||||
int max = 1;
|
||||
for (auto wire : mod->wires())
|
||||
if (wire->port_input)
|
||||
if (wire->port_input && !wire->port_output)
|
||||
for (int i = 0; i < wire->width; i++) {
|
||||
int ilevel = visit(cursor, driver->getPort(wire->name)[i]);
|
||||
max = std::max(max, ilevel + 1);
|
||||
|
|
@ -858,7 +866,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 +876,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 +891,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 +911,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 +955,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 +968,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 +983,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 +1025,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 +1052,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 +1100,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 +1122,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 +1154,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 +1175,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 +1198,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 +1211,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 +1466,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");
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -98,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>
|
||||
|
|
@ -129,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;
|
||||
|
|
@ -192,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 += " ";
|
||||
}
|
||||
}
|
||||
|
|
@ -201,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,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);
|
||||
|
|
@ -322,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));
|
||||
|
|
@ -368,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));
|
||||
|
||||
|
|
@ -394,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));
|
||||
|
|
@ -421,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));
|
||||
|
|
@ -452,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));
|
||||
|
|
@ -491,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));
|
||||
|
|
@ -509,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";
|
||||
|
|
@ -521,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) {
|
||||
|
|
@ -568,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));
|
||||
|
||||
|
|
@ -601,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));
|
||||
|
|
@ -640,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);
|
||||
|
|
@ -665,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;
|
||||
|
|
@ -709,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;
|
||||
|
||||
|
|
@ -753,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);
|
||||
|
||||
|
|
@ -776,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);
|
||||
|
||||
|
|
@ -1043,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);
|
||||
}
|
||||
|
|
@ -1215,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);
|
||||
|
||||
|
|
@ -1260,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)));
|
||||
}
|
||||
|
|
@ -1282,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));
|
||||
}
|
||||
|
||||
|
|
@ -1302,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1327,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));
|
||||
|
|
@ -1348,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];
|
||||
|
||||
|
|
@ -1371,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)));
|
||||
}
|
||||
|
|
@ -1430,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)));
|
||||
}
|
||||
|
|
@ -1463,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?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1489,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();
|
||||
|
|
@ -1528,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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -1533,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.
|
||||
|
|
@ -1668,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 << ") == ";
|
||||
|
|
@ -2429,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:
|
||||
|
|
@ -2438,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)
|
||||
|
|
@ -2854,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";
|
||||
|
|
@ -3041,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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3477,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
|
||||
|
|
@ -3799,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.
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1294,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) {}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -334,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 {
|
||||
|
|
@ -348,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)
|
||||
|
|
@ -513,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();
|
||||
}
|
||||
}
|
||||
|
|
@ -536,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");
|
||||
|
|
@ -577,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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1223,6 +1223,7 @@ struct FirrtlBackend : public Backend {
|
|||
Pass::call(design, "demuxmap");
|
||||
Pass::call(design, "bwmuxmap");
|
||||
|
||||
used_names.clear();
|
||||
namecache.clear();
|
||||
autoid_counter = 0;
|
||||
|
||||
|
|
@ -1248,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);
|
||||
|
||||
|
|
@ -1262,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
*/
|
||||
|
||||
#include "kernel/functional.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/sexpr.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include <ctype.h>
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
|
@ -29,26 +29,24 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
using SExprUtil::list;
|
||||
|
||||
const char *reserved_keywords[] = {
|
||||
// reserved keywords from the racket spec
|
||||
"struct", "lambda", "values", "extract", "concat", "bv", "let", "define", "cons", "list", "read", "write",
|
||||
"stream", "error", "raise", "exit", "for", "begin", "when", "unless", "module", "require", "provide", "apply",
|
||||
"if", "cond", "even", "odd", "any", "and", "or", "match", "command-line", "ffi-lib", "thread", "kill", "sync",
|
||||
"future", "touch", "subprocess", "make-custodian", "custodian-shutdown-all", "current-custodian", "make", "tcp",
|
||||
"connect", "prepare", "malloc", "free", "_fun", "_cprocedure", "build", "path", "file", "peek", "bytes",
|
||||
"flush", "with", "lexer", "parser", "syntax", "interface", "send", "make-object", "new", "instantiate",
|
||||
"define-generics", "set",
|
||||
// reserved keywords from the racket spec
|
||||
"struct", "lambda", "values", "extract", "concat", "bv", "let", "define", "cons", "list", "read", "write", "stream", "error", "raise", "exit",
|
||||
"for", "begin", "when", "unless", "module", "require", "provide", "apply", "if", "cond", "even", "odd", "any", "and", "or", "match", "command-line",
|
||||
"ffi-lib", "thread", "kill", "sync", "future", "touch", "subprocess", "make-custodian", "custodian-shutdown-all", "current-custodian", "make",
|
||||
"tcp", "connect", "prepare", "malloc", "free", "_fun", "_cprocedure", "build", "path", "file", "peek", "bytes", "flush", "with", "lexer", "parser",
|
||||
"syntax", "interface", "send", "make-object", "new", "instantiate", "define-generics", "set",
|
||||
|
||||
// reserved for our own purposes
|
||||
"inputs", "state", "name",
|
||||
nullptr
|
||||
};
|
||||
// reserved for our own purposes
|
||||
"inputs", "state", "name", nullptr};
|
||||
|
||||
struct SmtrScope : public Functional::Scope<int> {
|
||||
SmtrScope() {
|
||||
for(const char **p = reserved_keywords; *p != nullptr; p++)
|
||||
SmtrScope()
|
||||
{
|
||||
for (const char **p = reserved_keywords; *p != nullptr; p++)
|
||||
reserve(*p);
|
||||
}
|
||||
bool is_character_legal(char c, int index) override {
|
||||
bool is_character_legal(char c, int index) override
|
||||
{
|
||||
return isascii(c) && (isalpha(c) || (isdigit(c) && index > 0) || strchr("@$%^&_+=.", c));
|
||||
}
|
||||
};
|
||||
|
|
@ -56,10 +54,11 @@ struct SmtrScope : public Functional::Scope<int> {
|
|||
struct SmtrSort {
|
||||
Functional::Sort sort;
|
||||
SmtrSort(Functional::Sort sort) : sort(sort) {}
|
||||
SExpr to_sexpr() const {
|
||||
if(sort.is_memory()) {
|
||||
SExpr to_sexpr() const
|
||||
{
|
||||
if (sort.is_memory()) {
|
||||
return list("list", list("bitvector", sort.addr_width()), list("bitvector", sort.data_width()));
|
||||
} else if(sort.is_signal()) {
|
||||
} else if (sort.is_signal()) {
|
||||
return list("bitvector", sort.width());
|
||||
} else {
|
||||
log_error("unknown sort");
|
||||
|
|
@ -67,7 +66,8 @@ struct SmtrSort {
|
|||
}
|
||||
};
|
||||
|
||||
class SmtrStruct {
|
||||
class SmtrStruct
|
||||
{
|
||||
struct Field {
|
||||
SmtrSort sort;
|
||||
std::string accessor;
|
||||
|
|
@ -77,19 +77,22 @@ class SmtrStruct {
|
|||
vector<Field> fields;
|
||||
SmtrScope &global_scope;
|
||||
SmtrScope local_scope;
|
||||
public:
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
SmtrStruct(std::string name, SmtrScope &scope) : global_scope(scope), local_scope(), name(name) {}
|
||||
void insert(IdString field_name, SmtrSort sort) {
|
||||
void insert(IdString field_name, SmtrSort sort)
|
||||
{
|
||||
field_names(field_name);
|
||||
auto base_name = local_scope.unique_name(field_name);
|
||||
auto accessor = name + "-" + base_name;
|
||||
global_scope.reserve(accessor);
|
||||
fields.emplace_back(Field{sort, accessor, base_name});
|
||||
}
|
||||
void write_definition(SExprWriter &w) {
|
||||
void write_definition(SExprWriter &w)
|
||||
{
|
||||
vector<SExpr> field_list;
|
||||
for(const auto &field : fields) {
|
||||
for (const auto &field : fields) {
|
||||
field_list.emplace_back(field.name);
|
||||
}
|
||||
w.push();
|
||||
|
|
@ -102,23 +105,26 @@ public:
|
|||
}
|
||||
w.pop();
|
||||
}
|
||||
template<typename Fn> void write_value(SExprWriter &w, Fn fn) {
|
||||
template <typename Fn> void write_value(SExprWriter &w, Fn fn)
|
||||
{
|
||||
w.open(list(name));
|
||||
for(auto field_name : field_names) {
|
||||
for (auto field_name : field_names) {
|
||||
w << fn(field_name);
|
||||
w.comment(RTLIL::unescape_id(field_name), true);
|
||||
}
|
||||
w.close();
|
||||
}
|
||||
SExpr access(SExpr record, IdString name) {
|
||||
SExpr access(SExpr record, IdString name)
|
||||
{
|
||||
size_t i = field_names.at(name);
|
||||
return list(fields[i].accessor, std::move(record));
|
||||
}
|
||||
};
|
||||
|
||||
std::string smt_const(RTLIL::Const const &c) {
|
||||
std::string smt_const(RTLIL::Const const &c)
|
||||
{
|
||||
std::string s = "#b";
|
||||
for(int i = c.size(); i-- > 0; )
|
||||
for (int i = c.size(); i-- > 0;)
|
||||
s += c[i] == State::S1 ? '1' : '0';
|
||||
return s;
|
||||
}
|
||||
|
|
@ -131,15 +137,9 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
|
|||
|
||||
SmtrPrintVisitor(SmtrStruct &input_struct, SmtrStruct &state_struct) : input_struct(input_struct), state_struct(state_struct) {}
|
||||
|
||||
SExpr from_bool(SExpr &&arg) {
|
||||
return list("bool->bitvector", std::move(arg));
|
||||
}
|
||||
SExpr to_bool(SExpr &&arg) {
|
||||
return list("bitvector->bool", std::move(arg));
|
||||
}
|
||||
SExpr to_list(SExpr &&arg) {
|
||||
return list("bitvector->bits", std::move(arg));
|
||||
}
|
||||
SExpr from_bool(SExpr &&arg) { return list("bool->bitvector", std::move(arg)); }
|
||||
SExpr to_bool(SExpr &&arg) { return list("bitvector->bool", std::move(arg)); }
|
||||
SExpr to_list(SExpr &&arg) { return list("bitvector->bits", std::move(arg)); }
|
||||
|
||||
SExpr buf(Node, Node a) override { return n(a); }
|
||||
SExpr slice(Node, Node a, int offset, int out_width) override { return list("extract", offset + out_width - 1, offset, n(a)); }
|
||||
|
|
@ -166,8 +166,9 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
|
|||
SExpr unsigned_greater_than(Node, Node a, Node b) override { return from_bool(list("bvugt", n(a), n(b))); }
|
||||
SExpr unsigned_greater_equal(Node, Node a, Node b) override { return from_bool(list("bvuge", n(a), n(b))); }
|
||||
|
||||
SExpr extend(SExpr &&a, int in_width, int out_width) {
|
||||
if(in_width < out_width)
|
||||
SExpr extend(SExpr &&a, int in_width, int out_width)
|
||||
{
|
||||
if (in_width < out_width)
|
||||
return list("zero-extend", std::move(a), list("bitvector", out_width));
|
||||
else
|
||||
return std::move(a);
|
||||
|
|
@ -176,12 +177,20 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
|
|||
SExpr logical_shift_right(Node, Node a, Node b) override { return list("bvlshr", n(a), extend(n(b), b.width(), a.width())); }
|
||||
SExpr arithmetic_shift_right(Node, Node a, Node b) override { return list("bvashr", n(a), extend(n(b), b.width(), a.width())); }
|
||||
SExpr mux(Node, Node a, Node b, Node s) override { return list("if", to_bool(n(s)), n(b), n(a)); }
|
||||
SExpr constant(Node, RTLIL::Const const& value) override { return list("bv", smt_const(value), value.size()); }
|
||||
SExpr constant(Node, RTLIL::Const const &value) override { return list("bv", smt_const(value), value.size()); }
|
||||
SExpr memory_read(Node, Node mem, Node addr) override { return list("list-ref-bv", n(mem), n(addr)); }
|
||||
SExpr memory_write(Node, Node mem, Node addr, Node data) override { return list("list-set-bv", n(mem), n(addr), n(data)); }
|
||||
|
||||
SExpr input(Node, IdString name, IdString kind) override { log_assert(kind == ID($input)); return input_struct.access("inputs", name); }
|
||||
SExpr state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); return state_struct.access("state", name); }
|
||||
SExpr input(Node, IdString name, IdString kind) override
|
||||
{
|
||||
log_assert(kind == ID($input));
|
||||
return input_struct.access("inputs", name);
|
||||
}
|
||||
SExpr state(Node, IdString name, IdString kind) override
|
||||
{
|
||||
log_assert(kind == ID($state));
|
||||
return state_struct.access("state", name);
|
||||
}
|
||||
};
|
||||
|
||||
struct SmtrModule {
|
||||
|
|
@ -196,12 +205,10 @@ struct SmtrModule {
|
|||
SmtrStruct state_struct;
|
||||
|
||||
SmtrModule(Module *module, bool assoc_list_helpers)
|
||||
: 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)
|
||||
: 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)
|
||||
{
|
||||
scope.reserve(name + "_initial");
|
||||
if (assoc_list_helpers) {
|
||||
|
|
@ -222,19 +229,17 @@ struct SmtrModule {
|
|||
{
|
||||
w.push();
|
||||
w.open(list("define", list(name, "inputs", "state")));
|
||||
auto inlined = [&](Functional::Node n) {
|
||||
return n.fn() == Functional::Fn::constant;
|
||||
};
|
||||
auto inlined = [&](Functional::Node n) { return n.fn() == Functional::Fn::constant; };
|
||||
SmtrPrintVisitor visitor(input_struct, state_struct);
|
||||
auto node_to_sexpr = [&](Functional::Node n) -> SExpr {
|
||||
if(inlined(n))
|
||||
if (inlined(n))
|
||||
return n.visit(visitor);
|
||||
else
|
||||
return scope(n.id(), n.name());
|
||||
};
|
||||
visitor.n = node_to_sexpr;
|
||||
for(auto n : ir)
|
||||
if(!inlined(n)) {
|
||||
for (auto n : ir)
|
||||
if (!inlined(n)) {
|
||||
w.open(list("let", list(list(node_to_sexpr(n), n.visit(visitor)))), false);
|
||||
w.comment(SmtrSort(n.sort()).to_sexpr().to_string(), true);
|
||||
}
|
||||
|
|
@ -256,7 +261,7 @@ struct SmtrModule {
|
|||
else if (state->sort.is_memory()) {
|
||||
const auto &contents = state->initial_value_memory();
|
||||
w.open(list("list"));
|
||||
for(int i = 0; i < 1<<state->sort.addr_width(); i++) {
|
||||
for (int i = 0; i < 1 << state->sort.addr_width(); i++) {
|
||||
w << list("bv", smt_const(contents[i]), state->sort.data_width());
|
||||
}
|
||||
w.close();
|
||||
|
|
@ -303,7 +308,7 @@ struct SmtrModule {
|
|||
}
|
||||
|
||||
void write(std::ostream &out)
|
||||
{
|
||||
{
|
||||
SExprWriter w(out);
|
||||
|
||||
input_struct.write_definition(w);
|
||||
|
|
@ -324,8 +329,9 @@ struct SmtrModule {
|
|||
struct FunctionalSmtrBackend : public Backend {
|
||||
FunctionalSmtrBackend() : Backend("functional_rosette", "Generate Rosette compatible Racket from Functional IR") {}
|
||||
|
||||
void help() override {
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" write_functional_rosette [options] [filename]\n");
|
||||
log("\n");
|
||||
|
|
@ -347,8 +353,7 @@ struct FunctionalSmtrBackend : public Backend {
|
|||
log_header(design, "Executing Functional Rosette Backend.\n");
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-provides")
|
||||
provides = true;
|
||||
else if (args[argidx] == "-assoc-list-helpers")
|
||||
|
|
|
|||
|
|
@ -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_maybe_version()).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_maybe_version()).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);
|
||||
|
|
@ -309,13 +295,9 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
|
||||
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,13 +438,18 @@ 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());
|
||||
if (do_sort)
|
||||
design->sort();
|
||||
|
||||
*f << stringf("# Generated by %s\n", yosys_maybe_version());
|
||||
RTLIL_BACKEND::dump_design(*f, design, selected, true, false);
|
||||
|
|
@ -528,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 {
|
||||
|
|
@ -543,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) {
|
||||
|
|
|
|||
|
|
@ -82,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,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;
|
||||
|
|
@ -383,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;
|
||||
}
|
||||
|
||||
|
|
@ -495,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));
|
||||
|
|
@ -617,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));
|
||||
|
|
@ -722,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);
|
||||
|
|
@ -746,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)
|
||||
|
|
@ -1079,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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1131,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)));
|
||||
|
||||
|
|
@ -1180,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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1204,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")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1341,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();
|
||||
|
||||
|
|
@ -1361,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1402,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)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1415,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)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1429,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)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1442,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)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1455,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)";
|
||||
}
|
||||
}
|
||||
|
|
@ -1776,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") {
|
||||
|
|
@ -1846,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;
|
||||
|
||||
|
|
@ -1913,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,7 +795,7 @@ 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_maybe_version());
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
.. _cmd_ref:
|
||||
|
||||
================================================================================
|
||||
Command line reference
|
||||
================================================================================
|
||||
|
|
@ -7,10 +5,31 @@ Command line reference
|
|||
.. literalinclude:: /generated/yosys
|
||||
:start-at: Usage
|
||||
|
||||
.. toctree::
|
||||
:caption: Command reference
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
.. _cmd_ref:
|
||||
|
||||
/appendix/env_vars
|
||||
/cmd/*
|
||||
Command reference
|
||||
-----------------
|
||||
|
||||
.. todo:: Can we warn on command groups that aren't included anywhere?
|
||||
|
||||
:ref:`List of all commands<cmd-cmd>`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
/appendix/env_vars
|
||||
/cmd/index_frontends
|
||||
/cmd/index_backends
|
||||
/cmd/index_kernel
|
||||
/cmd/index_formal
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
/cmd/index_passes
|
||||
/cmd/index_techlibs
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
/cmd/index_internal
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ struct MyPass : public Pass {
|
|||
{
|
||||
log("Arguments to my_cmd:\n");
|
||||
for (auto &arg : args)
|
||||
log(" %s\n", arg.c_str());
|
||||
log(" %s\n", arg);
|
||||
|
||||
log("Modules in current design:\n");
|
||||
for (auto mod : design->modules())
|
||||
|
|
|
|||
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