mirror of
https://github.com/YosysHQ/yosys
synced 2026-06-26 18:48:51 +00:00
commit
ea9ff29eac
63 changed files with 940 additions and 1665 deletions
55
.github/ISSUE_TEMPLATE/docs_report.yml
vendored
Normal file
55
.github/ISSUE_TEMPLATE/docs_report.yml
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
name: Documentation Report
|
||||
description: Report a problem with the Yosys documentation
|
||||
labels: ["pending-verification"]
|
||||
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 found a bug in Yosys, or in building the documentation,
|
||||
please fill out the Bug Report issue form, this form is for problems
|
||||
with the live documentation on [Read the
|
||||
Docs](https://yosyshq.readthedocs.io/projects/yosys/). Please only
|
||||
report problems that appear on the latest version of the documentation.
|
||||
|
||||
|
||||
Please contact [YosysHQ GmbH](https://www.yosyshq.com/) if you need
|
||||
commercial support for Yosys.
|
||||
|
||||
- type: input
|
||||
id: docs_url
|
||||
attributes:
|
||||
label: Link to page
|
||||
description: "Please provide a link to the page where the problem was found."
|
||||
placeholder: "e.g. https://yosyshq.readthedocs.io/projects/yosys/"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: build_number
|
||||
attributes:
|
||||
label: Build number
|
||||
description: "If possible, please provide the latest build number from https://readthedocs.org/projects/yosys/builds/."
|
||||
placeholder: "e.g. Build #24078236"
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Issue
|
||||
description: "Please describe what is incorrect, invalid, or missing."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected
|
||||
description: "If applicable, please describe what should appear instead."
|
||||
validations:
|
||||
required: false
|
||||
33
.github/actions/setup-build-env/action.yml
vendored
Normal file
33
.github/actions/setup-build-env/action.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: Build environment setup
|
||||
description: Configure build env for Yosys builds
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install Linux 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
|
||||
|
||||
- name: Install macOS Dependencies
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install bison flex gawk libffi pkg-config bash autoconf
|
||||
|
||||
- name: Linux runtime environment
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "${{ github.workspace }}/.local/bin" >> $GITHUB_PATH
|
||||
echo "procs=$(nproc)" >> $GITHUB_ENV
|
||||
|
||||
- name: macOS runtime environment
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "${{ github.workspace }}/.local/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
|
||||
14
.github/workflows/extra-builds.yml
vendored
14
.github/workflows/extra-builds.yml
vendored
|
|
@ -81,3 +81,17 @@ jobs:
|
|||
END
|
||||
|
||||
make -C build -f ../Makefile CXX=clang -j$(nproc)
|
||||
|
||||
nix-build:
|
||||
name: "Build nix flake"
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: cachix/install-nix-action@v26
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.18.1/install
|
||||
- run: nix build .?submodules=1
|
||||
|
|
|
|||
181
.github/workflows/test-build.yml
vendored
Normal file
181
.github/workflows/test-build.yml
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
name: Build and run tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
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:
|
||||
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'
|
||||
pre_docs_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:
|
||||
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'
|
||||
|
||||
build-yosys:
|
||||
name: Reusable build
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: pre_docs_job
|
||||
if: needs.pre_docs_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
CC: clang
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
make -f ../Makefile config-$CC
|
||||
make -f ../Makefile -j$procs
|
||||
|
||||
- name: Log yosys-config output
|
||||
run: |
|
||||
./yosys-config || true
|
||||
|
||||
- name: Compress build
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
tar -cvf ../build.tar share/ yosys yosys-*
|
||||
|
||||
- name: Store build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-${{ matrix.os }}
|
||||
path: build.tar
|
||||
retention-days: 1
|
||||
|
||||
test-yosys:
|
||||
name: Run tests
|
||||
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, macos-latest]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- 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: Cache iverilog
|
||||
id: cache-iverilog
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .local/
|
||||
key: ${{ matrix.os }}-${{ env.IVERILOG_GIT }}
|
||||
|
||||
- name: Build iverilog
|
||||
if: steps.cache-iverilog.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.local/
|
||||
cd iverilog
|
||||
autoconf
|
||||
CC=gcc CXX=g++ ./configure --prefix=${{ github.workspace }}/.local
|
||||
make -j$procs
|
||||
make install
|
||||
|
||||
- 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: Log yosys-config output
|
||||
run: |
|
||||
./yosys-config || true
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs test TARGETS= EXTRA_TARGETS= CONFIG=$CC
|
||||
|
||||
- name: Report errors
|
||||
if: ${{ failure() }}
|
||||
shell: bash
|
||||
run: |
|
||||
find tests/**/*.err -print -exec cat {} \;
|
||||
|
||||
test-docs:
|
||||
name: Run docs tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [build-yosys, pre_docs_job]
|
||||
if: needs.pre_docs_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
CC: clang
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
|
||||
- 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: Log yosys-config output
|
||||
run: |
|
||||
./yosys-config || true
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -C docs test -j${{ env.procs }}
|
||||
79
.github/workflows/test-compile.yml
vendored
Normal file
79
.github/workflows/test-compile.yml
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
name: Compiler testing
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
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:
|
||||
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'
|
||||
|
||||
test-compile:
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
env:
|
||||
CXXFLAGS: ${{ startsWith(matrix.compiler, 'gcc') && '-Wp,-D_GLIBCXX_ASSERTIONS' || ''}}
|
||||
CC_SHORT: ${{ startsWith(matrix.compiler, 'gcc') && 'gcc' || 'clang' }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
compiler:
|
||||
# oldest supported
|
||||
- 'clang-14'
|
||||
- 'gcc-10'
|
||||
# newest
|
||||
- 'clang'
|
||||
- 'gcc'
|
||||
include:
|
||||
# macOS
|
||||
- os: macos-13
|
||||
compiler: 'clang'
|
||||
# oldest clang not available on ubuntu-latest
|
||||
- os: ubuntu-22.04
|
||||
compiler: 'clang-11'
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup environment
|
||||
uses: ./.github/actions/setup-build-env
|
||||
|
||||
- name: Setup Cpp
|
||||
uses: aminya/setup-cpp@v1
|
||||
with:
|
||||
compiler: ${{ matrix.compiler }}
|
||||
|
||||
- name: Tool versions
|
||||
shell: bash
|
||||
run: |
|
||||
$CC --version
|
||||
$CXX --version
|
||||
|
||||
# minimum standard
|
||||
- name: Build C++11
|
||||
shell: bash
|
||||
run: |
|
||||
make config-$CC_SHORT
|
||||
make -j$procs CXXSTD=c++11 compile-only
|
||||
|
||||
# maximum standard, only on newest compilers
|
||||
- name: Build C++20
|
||||
if: ${{ matrix.compiler == 'clang' || matrix.compiler == 'gcc'}}
|
||||
shell: bash
|
||||
run: |
|
||||
make config-$CC_SHORT
|
||||
make -j$procs CXXSTD=c++20 compile-only
|
||||
58
.github/workflows/test-docs.yml
vendored
58
.github/workflows/test-docs.yml
vendored
|
|
@ -1,58 +0,0 @@
|
|||
name: Build and test doc code samples
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
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:
|
||||
# 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'
|
||||
|
||||
test-docs:
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
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
|
||||
|
||||
- name: Setup GCC
|
||||
uses: Dup4/actions-setup-gcc@v1
|
||||
|
||||
- name: Runtime environment
|
||||
shell: bash
|
||||
env:
|
||||
WORKSPACE: ${{ github.workspace }}
|
||||
run: |
|
||||
echo "GITHUB_WORKSPACE=`pwd`" >> $GITHUB_ENV
|
||||
echo "$GITHUB_WORKSPACE/.local/bin" >> $GITHUB_PATH
|
||||
echo "procs=$(nproc)" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build yosys
|
||||
shell: bash
|
||||
run: |
|
||||
make config-gcc
|
||||
make -j${{ env.procs }}
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -C docs test -j${{ env.procs }}
|
||||
147
.github/workflows/test-linux.yml
vendored
147
.github/workflows/test-linux.yml
vendored
|
|
@ -1,147 +0,0 @@
|
|||
name: Build and run tests (Linux)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
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:
|
||||
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'
|
||||
|
||||
test-linux:
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: ${{ matrix.os.id }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- { id: ubuntu-20.04, name: focal }
|
||||
compiler:
|
||||
- 'clang-12'
|
||||
- 'gcc-11'
|
||||
cpp_std:
|
||||
- 'c++11'
|
||||
- 'c++14'
|
||||
- 'c++17'
|
||||
- 'c++20'
|
||||
include:
|
||||
# Limit the older compilers to C++11 mode
|
||||
- os: { id: ubuntu-20.04, name: focal }
|
||||
compiler: 'clang-11'
|
||||
cpp_std: 'c++11'
|
||||
- os: { id: ubuntu-20.04, name: focal }
|
||||
compiler: 'gcc-10'
|
||||
cpp_std: 'c++11'
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
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 python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev
|
||||
|
||||
- name: Setup GCC
|
||||
if: startsWith(matrix.compiler, 'gcc')
|
||||
shell: bash
|
||||
run: |
|
||||
CXX=${CC/#gcc/g++}
|
||||
sudo apt-add-repository ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get install $CC $CXX
|
||||
echo "CC=$CC" >> $GITHUB_ENV
|
||||
echo "CXX=$CXX" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS=-Wp,-D_GLIBCXX_ASSERTIONS" >> $GITHUB_ENV
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
|
||||
- name: Setup Clang
|
||||
if: startsWith(matrix.compiler, 'clang')
|
||||
shell: bash
|
||||
run: |
|
||||
wget https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||
sudo apt-key add llvm-snapshot.gpg.key
|
||||
rm llvm-snapshot.gpg.key
|
||||
sudo apt-add-repository "deb https://apt.llvm.org/${{ matrix.os.name }}/ llvm-toolchain-${{ matrix.os.name }} main"
|
||||
sudo apt-get update
|
||||
CXX=${CC/#clang/clang++}
|
||||
sudo apt-get install $CC $CXX
|
||||
echo "CC=$CC" >> $GITHUB_ENV
|
||||
echo "CXX=$CXX" >> $GITHUB_ENV
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
|
||||
- name: Runtime environment
|
||||
shell: bash
|
||||
env:
|
||||
WORKSPACE: ${{ github.workspace }}
|
||||
run: |
|
||||
echo "GITHUB_WORKSPACE=`pwd`" >> $GITHUB_ENV
|
||||
echo "$GITHUB_WORKSPACE/.local/bin" >> $GITHUB_PATH
|
||||
echo "procs=$(nproc)" >> $GITHUB_ENV
|
||||
|
||||
- name: Tool versions
|
||||
shell: bash
|
||||
run: |
|
||||
$CC --version
|
||||
$CXX --version
|
||||
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- 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: Cache iverilog
|
||||
id: cache-iverilog
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .local/
|
||||
key: ${{ matrix.os.id }}-${{ env.IVERILOG_GIT }}
|
||||
|
||||
- name: Build iverilog
|
||||
if: steps.cache-iverilog.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/.local/
|
||||
cd iverilog
|
||||
autoconf
|
||||
CC=gcc CXX=g++ ./configure --prefix=$GITHUB_WORKSPACE/.local
|
||||
make -j${{ env.procs }}
|
||||
make install
|
||||
|
||||
- name: Build yosys
|
||||
shell: bash
|
||||
run: |
|
||||
make config-${CC%%-*}
|
||||
make -j${{ env.procs }} CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC
|
||||
|
||||
- name: Store build artifact
|
||||
if: (matrix.cpp_std == 'c++11') && (matrix.compiler == 'gcc-11')
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: compiled-yosys
|
||||
path: yosys
|
||||
|
||||
- name: Run tests
|
||||
if: (matrix.cpp_std == 'c++11') && (matrix.compiler == 'gcc-11')
|
||||
shell: bash
|
||||
run: |
|
||||
make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=$CC CXX=$CC LD=$CC
|
||||
|
||||
- name: Log yosys-config output
|
||||
run: |
|
||||
./yosys-config || true
|
||||
92
.github/workflows/test-macos.yml
vendored
92
.github/workflows/test-macos.yml
vendored
|
|
@ -1,92 +0,0 @@
|
|||
name: Build and run tests (macOS)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
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:
|
||||
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'
|
||||
|
||||
test-macos:
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: ${{ matrix.os.id }}
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- { id: macos-13, name: 'Ventura' }
|
||||
cpp_std:
|
||||
- 'c++11'
|
||||
- 'c++17'
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install bison flex gawk libffi pkg-config bash
|
||||
|
||||
- name: Runtime environment
|
||||
shell: bash
|
||||
env:
|
||||
WORKSPACE: ${{ github.workspace }}
|
||||
run: |
|
||||
echo "GITHUB_WORKSPACE=`pwd`" >> $GITHUB_ENV
|
||||
echo "$GITHUB_WORKSPACE/.local/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: Tool versions
|
||||
shell: bash
|
||||
run: |
|
||||
cc --version
|
||||
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- 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: Cache iverilog
|
||||
id: cache-iverilog
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .local/
|
||||
key: ${{ matrix.os.id }}-${{ env.IVERILOG_GIT }}
|
||||
|
||||
- name: Build iverilog
|
||||
if: steps.cache-iverilog.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/.local/
|
||||
cd iverilog
|
||||
autoconf
|
||||
CC=gcc CXX=g++ ./configure --prefix=$GITHUB_WORKSPACE/.local/
|
||||
make -j${{ env.procs }}
|
||||
make install
|
||||
|
||||
- name: Build yosys
|
||||
shell: bash
|
||||
run: |
|
||||
make config-clang
|
||||
make -j${{ env.procs }} CXXSTD=${{ matrix.cpp_std }} CC=cc CXX=cc LD=cc
|
||||
|
||||
- name: Run tests
|
||||
if: matrix.cpp_std == 'c++11'
|
||||
shell: bash
|
||||
run: |
|
||||
make -j${{ env.procs }} test CXXSTD=${{ matrix.cpp_std }} CC=cc CXX=cc LD=cc
|
||||
22
.github/workflows/update-flake-lock.yml
vendored
Normal file
22
.github/workflows/update-flake-lock.yml
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: update-flake-lock
|
||||
on:
|
||||
workflow_dispatch: # allows manual triggering
|
||||
schedule:
|
||||
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
|
||||
|
||||
jobs:
|
||||
lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
- name: Update flake.lock
|
||||
uses: DeterminateSystems/update-flake-lock@main
|
||||
with:
|
||||
token: ${{CI_CREATE_PR_TOKEN}}
|
||||
pr-title: "Update flake.lock" # Title of PR to be created
|
||||
pr-labels: | # Labels to be set on the PR
|
||||
dependencies
|
||||
automated
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -45,4 +45,4 @@ __pycache__
|
|||
/tests/unit/bintest/
|
||||
/tests/unit/objtest/
|
||||
/tests/ystests
|
||||
/build
|
||||
/result
|
||||
11
CHANGELOG
11
CHANGELOG
|
|
@ -2,9 +2,18 @@
|
|||
List of major changes and improvements between releases
|
||||
=======================================================
|
||||
|
||||
Yosys 0.41 .. Yosys 0.42-dev
|
||||
Yosys 0.42 .. Yosys 0.43-dev
|
||||
--------------------------
|
||||
|
||||
Yosys 0.41 .. Yosys 0.42
|
||||
--------------------------
|
||||
* New commands and options
|
||||
- Added "box_derive" pass to derive box modules.
|
||||
- Added option "assert-mod-count" to "select" pass.
|
||||
- Added option "-header","-push" and "-pop" to "log" pass.
|
||||
* Intel support
|
||||
- Dropped Quartus support in "synth_intel_alm" pass.
|
||||
|
||||
Yosys 0.40 .. Yosys 0.41
|
||||
--------------------------
|
||||
* New commands and options
|
||||
|
|
|
|||
84
Makefile
84
Makefile
|
|
@ -3,7 +3,6 @@ CONFIG := none
|
|||
# CONFIG := clang
|
||||
# CONFIG := gcc
|
||||
# CONFIG := afl-gcc
|
||||
# CONFIG := emcc
|
||||
# CONFIG := wasi
|
||||
# CONFIG := mxe
|
||||
# CONFIG := msys2-32
|
||||
|
|
@ -142,7 +141,7 @@ LIBS += -lrt
|
|||
endif
|
||||
endif
|
||||
|
||||
YOSYS_VER := 0.41+8
|
||||
YOSYS_VER := 0.42+0
|
||||
|
||||
# Note: We arrange for .gitcommit to contain the (short) commit hash in
|
||||
# tarballs generated with git-archive(1) using .gitattributes. The git repo
|
||||
|
|
@ -158,7 +157,7 @@ endif
|
|||
OBJS = kernel/version_$(GIT_REV).o
|
||||
|
||||
bumpversion:
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline c1ad377.. | wc -l`/;" Makefile
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9b6afcf.. | wc -l`/;" Makefile
|
||||
|
||||
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
|
||||
|
||||
|
|
@ -254,45 +253,6 @@ CXX = g++
|
|||
CXXFLAGS += -std=gnu++11 -Os
|
||||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H"
|
||||
|
||||
else ifeq ($(CONFIG),emcc)
|
||||
CXX = emcc
|
||||
CXXFLAGS := -std=$(CXXSTD) $(filter-out -fPIC -ggdb,$(CXXFLAGS))
|
||||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8"
|
||||
EMCC_CXXFLAGS := -Os -Wno-warn-absolute-paths
|
||||
EMCC_LINKFLAGS := --embed-file share
|
||||
EMCC_LINKFLAGS += -s NO_EXIT_RUNTIME=1
|
||||
EMCC_LINKFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']"
|
||||
EMCC_LINKFLAGS += -s TOTAL_MEMORY=134217728
|
||||
EMCC_LINKFLAGS += -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
|
||||
# https://github.com/kripken/emscripten/blob/master/src/settings.js
|
||||
CXXFLAGS += $(EMCC_CXXFLAGS)
|
||||
LINKFLAGS += $(EMCC_LINKFLAGS)
|
||||
LIBS =
|
||||
EXE = .js
|
||||
|
||||
DISABLE_SPAWN := 1
|
||||
|
||||
TARGETS := $(filter-out $(PROGRAM_PREFIX)yosys-config,$(TARGETS))
|
||||
EXTRA_TARGETS += yosysjs-$(YOSYS_VER).zip
|
||||
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
LINK_ABC := 1
|
||||
DISABLE_ABC_THREADS := 1
|
||||
endif
|
||||
|
||||
viz.js:
|
||||
wget -O viz.js.part https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js
|
||||
mv viz.js.part viz.js
|
||||
|
||||
yosysjs-$(YOSYS_VER).zip: yosys.js viz.js misc/yosysjs/*
|
||||
rm -rf yosysjs-$(YOSYS_VER) yosysjs-$(YOSYS_VER).zip
|
||||
mkdir -p yosysjs-$(YOSYS_VER)
|
||||
cp viz.js misc/yosysjs/* yosys.js yosys.wasm yosysjs-$(YOSYS_VER)/
|
||||
zip -r yosysjs-$(YOSYS_VER).zip yosysjs-$(YOSYS_VER)
|
||||
|
||||
yosys.html: misc/yosys.html
|
||||
$(P) cp misc/yosys.html yosys.html
|
||||
|
||||
else ifeq ($(CONFIG),wasi)
|
||||
ifeq ($(WASI_SDK),)
|
||||
CXX = clang++
|
||||
|
|
@ -357,7 +317,7 @@ CXXFLAGS += -std=$(CXXSTD) -Os
|
|||
ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H $(ABC_ARCHFLAGS)"
|
||||
|
||||
else
|
||||
$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, emcc, mxe, msys2-32, msys2-64, none)
|
||||
$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, mxe, msys2-32, msys2-64, none)
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_LIBYOSYS),1)
|
||||
|
|
@ -495,7 +455,7 @@ LIBS += -lpthread
|
|||
endif
|
||||
else
|
||||
ifeq ($(ABCEXTERNAL),)
|
||||
TARGETS += $(PROGRAM_PREFIX)yosys-abc$(EXE)
|
||||
TARGETS := $(PROGRAM_PREFIX)yosys-abc$(EXE) $(TARGETS)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
|
@ -727,9 +687,11 @@ top-all: $(TARGETS) $(EXTRA_TARGETS)
|
|||
@echo " Build successful."
|
||||
@echo ""
|
||||
|
||||
ifeq ($(CONFIG),emcc)
|
||||
yosys.js: $(filter-out yosysjs-$(YOSYS_VER).zip,$(EXTRA_TARGETS))
|
||||
endif
|
||||
.PHONY: compile-only
|
||||
compile-only: $(OBJS) $(GENFILES) $(EXTRA_TARGETS)
|
||||
@echo ""
|
||||
@echo " Compile successful."
|
||||
@echo ""
|
||||
|
||||
$(PROGRAM_PREFIX)yosys$(EXE): $(OBJS)
|
||||
$(P) $(CXX) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LINKFLAGS) $(LINKFLAGS) $(OBJS) $(LIBS) $(LIBS_VERIFIC)
|
||||
|
|
@ -788,7 +750,6 @@ check-git-abc:
|
|||
echo "Initialize the submodule: Run 'git submodule update --init' to set up 'abc' as a submodule."; \
|
||||
exit 1; \
|
||||
elif git -C "$(YOSYS_SRC)" submodule status abc 2>/dev/null | grep -q '^ '; then \
|
||||
echo "'abc' is a git submodule. Continuing."; \
|
||||
exit 0; \
|
||||
elif [ -f "$(YOSYS_SRC)/abc/.gitcommit" ] && ! grep -q '\$$Format:%h\$$' "$(YOSYS_SRC)/abc/.gitcommit"; then \
|
||||
echo "'abc' comes from a tarball. Continuing."; \
|
||||
|
|
@ -806,9 +767,7 @@ check-git-abc:
|
|||
exit 1; \
|
||||
fi
|
||||
|
||||
ABC_SOURCES := $(wildcard $(YOSYS_SRC)/abc/*)
|
||||
|
||||
abc/abc$(EXE) abc/libabc.a: $(ABC_SOURCES) check-git-abc
|
||||
abc/abc$(EXE) abc/libabc.a: check-git-abc
|
||||
$(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)
|
||||
|
||||
|
|
@ -987,7 +946,13 @@ define DOC_USAGE_STDERR
|
|||
docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated
|
||||
-$(Q) ./$$< --help 2> $$@
|
||||
endef
|
||||
DOCS_USAGE_STDERR := yosys-config yosys-filterlib yosys-abc
|
||||
DOCS_USAGE_STDERR := yosys-config yosys-filterlib
|
||||
|
||||
# The in-tree ABC (yosys-abc) is only built when ABCEXTERNAL is not set.
|
||||
ifeq ($(ABCEXTERNAL),)
|
||||
DOCS_USAGE_STDERR += yosys-abc
|
||||
endif
|
||||
|
||||
$(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage))))
|
||||
|
||||
# others print to stdout
|
||||
|
|
@ -1022,7 +987,9 @@ clean:
|
|||
rm -rf vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_*
|
||||
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
|
||||
$(MAKE) -C docs clean
|
||||
-$(MAKE) -C docs clean
|
||||
-$(MAKE) -C docs/images clean
|
||||
rm -rf docs/source/cmd docs/util/__pycache__
|
||||
|
||||
clean-abc:
|
||||
$(MAKE) -C abc DEP= clean
|
||||
|
|
@ -1038,11 +1005,12 @@ coverage:
|
|||
genhtml coverage.info --output-directory coverage_html
|
||||
|
||||
qtcreator:
|
||||
echo "$(CXXFLAGS)" | grep -o '\-D[^ ]*' | tr ' ' '\n' | sed 's/-D/#define /' | sed 's/=/ /'> qtcreator.config
|
||||
{ for file in $(basename $(OBJS)); do \
|
||||
for prefix in cc y l; do if [ -f $${file}.$${prefix} ]; then echo $$file.$${prefix}; fi; done \
|
||||
done; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \); } > qtcreator.files
|
||||
{ echo .; find backends frontends kernel libs passes -type f \( -name '*.h' -o -name '*.hh' \) -printf '%h\n' | sort -u; } > qtcreator.includes
|
||||
touch qtcreator.config qtcreator.creator
|
||||
touch qtcreator.creator
|
||||
|
||||
vcxsrc: $(GENFILES) $(EXTRA_TARGETS)
|
||||
rm -rf yosys-win32-vcxsrc-$(YOSYS_VER){,.zip}
|
||||
|
|
@ -1085,14 +1053,6 @@ config-gcc-static: clean
|
|||
config-afl-gcc: clean
|
||||
echo 'CONFIG := afl-gcc' > Makefile.conf
|
||||
|
||||
config-emcc: clean
|
||||
echo 'CONFIG := emcc' > Makefile.conf
|
||||
echo 'ENABLE_TCL := 0' >> Makefile.conf
|
||||
echo 'ENABLE_ABC := 0' >> Makefile.conf
|
||||
echo 'ENABLE_PLUGINS := 0' >> Makefile.conf
|
||||
echo 'ENABLE_READLINE := 0' >> Makefile.conf
|
||||
echo 'ENABLE_ZLIB := 0' >> Makefile.conf
|
||||
|
||||
config-wasi: clean
|
||||
echo 'CONFIG := wasi' > Makefile.conf
|
||||
echo 'ENABLE_TCL := 0' >> Makefile.conf
|
||||
|
|
|
|||
|
|
@ -3263,6 +3263,7 @@ struct CxxrtlWorker {
|
|||
debug_wire_type = wire_type; // wire is a member
|
||||
|
||||
if (!debug_alias) continue;
|
||||
if (wire->port_input || wire->port_output) continue; // preserve input/output metadata in flags
|
||||
const RTLIL::Wire *it = wire;
|
||||
while (flow.is_inlinable(it)) {
|
||||
log_assert(flow.wire_comb_defs[it].size() == 1);
|
||||
|
|
|
|||
|
|
@ -719,6 +719,8 @@ def smt_extract_mask(smt_expr, mask):
|
|||
return combined_chunks, ''.join(mask_index_order[start:end] for start, end in chunks)[::-1]
|
||||
|
||||
def smt_concat(exprs):
|
||||
if not isinstance(exprs, (tuple, list)):
|
||||
exprs = tuple(exprs)
|
||||
if not exprs:
|
||||
return ""
|
||||
if len(exprs) == 1:
|
||||
|
|
@ -818,6 +820,9 @@ def ywfile_constraints(inywfile, constr_assumes, map_steps=None, skip_x=False):
|
|||
if not bits_re.match(bits):
|
||||
raise ValueError("unsupported bit value in Yosys witness file")
|
||||
|
||||
if bits.count('?') == len(bits):
|
||||
continue
|
||||
|
||||
smt_expr = ywfile_signal(sig, map_steps.get(t, t))
|
||||
|
||||
smt_expr, bits = smt_extract_mask(smt_expr, bits)
|
||||
|
|
|
|||
|
|
@ -24,3 +24,17 @@ a.external {
|
|||
th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
body[data-theme="dark"] {
|
||||
.invert-helper {
|
||||
filter: url("data:image/svg+xml,<svg xmlns='http%3A//www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='1.47 -1.73 -0.467 0 0.867 -0.733 0.467 -0.467 0 0.867 -0.667 -1.07 1.07 0 0.867 0 0 0 1.0 0'></feColorMatrix></filter></svg>#f");
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not([data-theme="light"]) {
|
||||
.invert-helper {
|
||||
filter: url("data:image/svg+xml,<svg xmlns='http%3A//www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='1.47 -1.73 -0.467 0 0.867 -0.733 0.467 -0.467 0 0.867 -0.667 -1.07 1.07 0 0.867 0 0 0 1.0 0'></feColorMatrix></filter></svg>#f");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ circuit to a functionally equivalent low-level representation of a circuit.
|
|||
abstraction and how they relate to different kinds of synthesis.
|
||||
|
||||
.. figure:: /_images/primer/basics_abstractions.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Basics_abstractions
|
||||
|
||||
Different levels of abstraction and synthesis.
|
||||
|
|
@ -499,7 +499,7 @@ using a series of tools and the results are again verified using simulation.
|
|||
This process is illustrated in :numref:`Fig. %s <fig:Basics_flow>`.
|
||||
|
||||
.. figure:: /_images/primer/basics_flow.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Basics_flow
|
||||
|
||||
Typical design flow. Green boxes represent manually created models.
|
||||
|
|
@ -598,7 +598,7 @@ Let's consider the following BNF (in Bison syntax):
|
|||
expr: TOK_IDENTIFIER | TOK_NUMBER | expr TOK_PLUS expr;
|
||||
|
||||
.. figure:: /_images/primer/basics_parsetree.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Basics_parsetree
|
||||
|
||||
Example parse tree for the Verilog expression
|
||||
|
|
@ -627,7 +627,7 @@ suitable for further processing. In compilers this is often an assembler-like
|
|||
three-address-code intermediate representation. :cite:p:`Dragonbook`
|
||||
|
||||
.. figure:: /_images/primer/basics_ast.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Basics_ast
|
||||
|
||||
Example abstract syntax tree for the Verilog expression
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import os
|
|||
project = 'YosysHQ Yosys'
|
||||
author = 'YosysHQ GmbH'
|
||||
copyright ='2024 YosysHQ GmbH'
|
||||
yosys_ver = "0.41"
|
||||
yosys_ver = "0.42"
|
||||
|
||||
# select HTML theme
|
||||
html_theme = 'furo'
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ Since we're just getting started, let's instead begin with :yoscrypt:`hierarchy
|
|||
Our ``addr_gen`` circuit now looks like this:
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_hier.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: addr_gen_hier
|
||||
|
||||
``addr_gen`` module after :cmd:ref:`hierarchy`
|
||||
|
|
@ -145,7 +145,7 @@ we run it. For now, we will call :yoscrypt:`proc -noopt` to prevent some
|
|||
automatic optimizations which would normally happen.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_proc.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: addr_gen_proc
|
||||
|
||||
``addr_gen`` module after :yoscrypt:`proc -noopt`
|
||||
|
|
@ -166,7 +166,7 @@ the same time by separating them with a colon and space: :yoscrypt:`opt_expr;
|
|||
clean`.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_clean.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: addr_gen_clean
|
||||
|
||||
``addr_gen`` module after :yoscrypt:`opt_expr; clean`
|
||||
|
|
@ -252,7 +252,7 @@ command only works with a single module, so you may need to call it with
|
|||
:doc:`/getting_started/scripting_intro` has more on how to use :cmd:ref:`show`.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_proc.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_proc
|
||||
|
||||
``rdata`` output after :cmd:ref:`proc`
|
||||
|
|
@ -298,7 +298,7 @@ optimizations between modules which would otherwise be missed. Let's run
|
|||
:caption: output of :yoscrypt:`flatten;;`
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_flat.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_flat
|
||||
|
||||
``rdata`` output after :yoscrypt:`flatten;;`
|
||||
|
|
@ -385,7 +385,7 @@ options is able to fold one of the ``$mux`` cells into the ``$adff`` to form an
|
|||
:caption: output of :cmd:ref:`opt_dff`
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_adffe.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_adffe
|
||||
|
||||
``rdata`` output after :cmd:ref:`opt_dff`
|
||||
|
|
@ -424,7 +424,7 @@ the schematic and see the output of that cell has now changed.
|
|||
.. todo:: pending bugfix in :cmd:ref:`wreduce` and/or :cmd:ref:`opt_clean`
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_wreduce.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_wreduce
|
||||
|
||||
``rdata`` output after :cmd:ref:`wreduce`
|
||||
|
|
@ -446,7 +446,7 @@ Our next command to run is
|
|||
:caption: output of :cmd:ref:`memory_dff`
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_memrdv2.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_memrdv2
|
||||
|
||||
``rdata`` output after :cmd:ref:`memory_dff`
|
||||
|
|
@ -535,7 +535,7 @@ example design:
|
|||
:caption: output of :cmd:ref:`alumacc`
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_alumacc.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_alumacc
|
||||
|
||||
``rdata`` output after :cmd:ref:`alumacc`
|
||||
|
|
@ -553,7 +553,7 @@ operating on the same memory only in the abstract. :cmd:ref:`memory_collect`
|
|||
combines all of the reads and writes for a memory block into a single cell.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_coarse.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_coarse
|
||||
|
||||
``rdata`` output after :cmd:ref:`memory_collect`
|
||||
|
|
@ -604,7 +604,7 @@ Mapping to hard memory blocks uses a combination of :cmd:ref:`memory_libmap` and
|
|||
:caption: ``map_ram`` section
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_map_ram.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_map_ram
|
||||
|
||||
``rdata`` output after :ref:`map_ram`
|
||||
|
|
@ -646,7 +646,7 @@ into flip flops (the ``logic fallback``) with :cmd:ref:`memory_map`.
|
|||
:caption: ``map_ffram`` section
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_map_ffram.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_map_ffram
|
||||
|
||||
``rdata`` output after :ref:`map_ffram`
|
||||
|
|
@ -682,7 +682,7 @@ replaced with single-bit ``$_MUX_`` and ``$_DFFE_PP0P_`` cells, while the
|
|||
:caption: ``map_gates`` section
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_map_gates.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_map_gates
|
||||
|
||||
``rdata`` output after :ref:`map_gates`
|
||||
|
|
@ -711,7 +711,7 @@ instead with an ``$_AND_`` cell.
|
|||
:caption: ``map_ffs`` section
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_map_ffs.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_map_ffs
|
||||
|
||||
``rdata`` output after :ref:`map_ffs`
|
||||
|
|
@ -737,7 +737,7 @@ what the difference between these two commands are, refer to
|
|||
:caption: ``map_luts`` section
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_map_luts.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_map_luts
|
||||
|
||||
``rdata`` output after :ref:`map_luts`
|
||||
|
|
@ -754,7 +754,7 @@ Finally we use :cmd:ref:`techmap` to map the generic ``$lut`` cells to iCE40
|
|||
:caption: ``map_cells`` section
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/rdata_map_cells.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: rdata_map_cells
|
||||
|
||||
``rdata`` output after :ref:`map_cells`
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ what the different symbols represent, see :ref:`interactive_show` and the
|
|||
:doc:`/using_yosys/more_scripting/interactive_investigation` page.
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_show.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: addr_gen_show
|
||||
|
||||
Calling :yoscrypt:`show addr_gen` after :cmd:ref:`hierarchy`
|
||||
|
|
@ -158,7 +158,7 @@ selection<select_new_cells>` and called it ``new_cells``? We saw in the
|
|||
``$eq``. We can call :cmd:ref:`show` on that selection just as easily:
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/new_cells_show.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: new_cells_show
|
||||
|
||||
Calling :yoscrypt:`show -notitle @new_cells`
|
||||
|
|
@ -173,7 +173,7 @@ the two ``PROC`` blocks. To achieve this highlight, we make use of the
|
|||
:yoscrypt:`-color` option:
|
||||
|
||||
.. figure:: /_images/code_examples/fifo/addr_gen_hier.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Calling :yoscrypt:`show -color maroon3 @new_cells -color cornflowerblue p:* -notitle`
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ extensible and therefore is a good basis for implementing custom synthesis tools
|
|||
for specialised tasks.
|
||||
|
||||
.. figure:: /_images/primer/levels_of_abstraction.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Levels_of_abstraction
|
||||
|
||||
Where Yosys exists in the layers of abstraction
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ is shown.
|
|||
``xdot example_first.dot`` etc.
|
||||
|
||||
.. figure:: /_images/code_examples/show/example_first.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of the first :cmd:ref:`show` command in :numref:`example_ys`
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ The :cmd:ref:`proc` command transforms the process from the first diagram into a
|
|||
multiplexer and a d-type flip-flop, which brings us to the second diagram:
|
||||
|
||||
.. figure:: /_images/code_examples/show/example_second.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of the second :cmd:ref:`show` command in :numref:`example_ys`
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ In this script we directly call :cmd:ref:`opt` as the next step, which finally
|
|||
leads us to the third diagram:
|
||||
|
||||
.. figure:: /_images/code_examples/show/example_third.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: example_out
|
||||
|
||||
Output of the third :cmd:ref:`show` command in :ref:`example_ys`
|
||||
|
|
@ -137,7 +137,7 @@ that operate on wide integers, it also introduces some additional complexity
|
|||
when the individual bits of of a signal vector are accessed.
|
||||
|
||||
.. figure:: /_images/code_examples/show/splice.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: splice_dia
|
||||
|
||||
Output of ``yosys -p 'prep -top splice_demo; show' splice.v``
|
||||
|
|
@ -165,7 +165,7 @@ Gate level netlists
|
|||
mapped to a cell library:
|
||||
|
||||
.. figure:: /_images/code_examples/show/cmos_00.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: first_pitfall
|
||||
|
||||
A half-adder built from simple CMOS gates, demonstrating common pitfalls when
|
||||
|
|
@ -185,7 +185,7 @@ column. Secondly the two-bit vector ``y`` requires breakout-boxes for its
|
|||
individual bits, resulting in an unnecessary complex diagram.
|
||||
|
||||
.. figure:: /_images/code_examples/show/cmos_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: second_pitfall
|
||||
|
||||
Effects of :cmd:ref:`splitnets` command and of providing a cell library on
|
||||
|
|
@ -358,10 +358,10 @@ reorganizing a module in Yosys and checking the resulting circuit.
|
|||
:end-before: cd ..
|
||||
|
||||
.. figure:: /_images/code_examples/scrambler/scrambler_p01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. figure:: /_images/code_examples/scrambler/scrambler_p02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Analyzing the resulting circuit with :doc:`/cmd/eval`:
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ if the circuit under investigation is encapsulated in a separate module.
|
|||
Recall the ``memdemo`` design from :ref:`advanced_logic_cones`:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_00.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
``memdemo``
|
||||
|
||||
|
|
@ -463,18 +463,18 @@ name of the new cell in the current module. The resulting circuits are shown
|
|||
below.
|
||||
|
||||
.. figure:: /_images/code_examples/selections/submod_02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
``outstage``
|
||||
|
||||
.. figure:: /_images/code_examples/selections/submod_03.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: selstage
|
||||
|
||||
``selstage``
|
||||
|
||||
.. figure:: /_images/code_examples/selections/submod_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
``scramble``
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ Selecting ``a:sumstuff`` in this module will yield the following circuit
|
|||
diagram:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/sumprod_00.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: sumprod_00
|
||||
|
||||
Output of ``show a:sumstuff`` on :numref:`sumprod`
|
||||
|
|
@ -177,7 +177,7 @@ selected wire it selects all cells connected to the wire and vice versa. So
|
|||
:yoscrypt:`show a:sumstuff %x` yields the diagram shown in :numref:`sumprod_01`:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/sumprod_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: sumprod_01
|
||||
|
||||
Output of ``show a:sumstuff %x`` on :numref:`sumprod`
|
||||
|
|
@ -200,22 +200,22 @@ input ports.
|
|||
The following sequence of diagrams demonstrates this step-wise expansion:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/sumprod_02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of :yoscrypt:`show prod` on :numref:`sumprod`
|
||||
|
||||
.. figure:: /_images/code_examples/selections/sumprod_03.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of :yoscrypt:`show prod %ci` on :numref:`sumprod`
|
||||
|
||||
.. figure:: /_images/code_examples/selections/sumprod_04.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of :yoscrypt:`show prod %ci %ci` on :numref:`sumprod`
|
||||
|
||||
.. figure:: /_images/code_examples/selections/sumprod_05.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of :yoscrypt:`show prod %ci %ci %ci` on :numref:`sumprod`
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ provided :file:`memdemo.v` is in the same directory. We can now change to the
|
|||
diagram in :numref:`memdemo_00`.
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_00.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: memdemo_00
|
||||
|
||||
Complete circuit diagram for the design shown in :numref:`memdemo_src`
|
||||
|
|
@ -291,7 +291,7 @@ output signal, ``y``, and its immediate predecessors. Remember `Selecting logic
|
|||
cones`_ from above, we can use :yoscrypt:`show y %ci2`:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: memdemo_01
|
||||
|
||||
Output of :yoscrypt:`show y %ci2`
|
||||
|
|
@ -303,7 +303,7 @@ wire into the input ``D`` of the flip-flop cell (indicated by the ``$`` at the
|
|||
start of the name). Let's go a bit further now and try :yoscrypt:`show y %ci5`:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: memdemo_02
|
||||
|
||||
Output of :yoscrypt:`show y %ci5`
|
||||
|
|
@ -317,7 +317,7 @@ brackets. In this case, we want to exclude the ``S`` port of the ``$mux`` cell
|
|||
type with :yoscrypt:`show y %ci5:-$mux[S]`:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_03.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: memdemo_03
|
||||
|
||||
Output of :yoscrypt:`show y %ci5:-$mux[S]`
|
||||
|
|
@ -328,7 +328,7 @@ flip-flop and the 2nd action selects the entire input cone without going over
|
|||
multiplexer select inputs and flip-flop cells:
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_05.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: memdemo_05
|
||||
|
||||
Output of ``show y %ci2:+$dff[Q,D] %ci*:-$mux[S]:-$dff``
|
||||
|
|
@ -340,7 +340,7 @@ ignoring any ports named ``CLK`` or ``S``:
|
|||
.. TODO:: pending discussion on whether rule ordering is a bug or a feature
|
||||
|
||||
.. figure:: /_images/code_examples/selections/memdemo_04.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: memdemo_04
|
||||
|
||||
Output of :yoscrypt:`show y %ci*:-[CLK,S]:+$dff,$mux`
|
||||
|
|
@ -417,6 +417,6 @@ Example code from |code_examples/selections|_:
|
|||
:name: select_ys
|
||||
|
||||
.. figure:: /_images/code_examples/selections/select.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Circuit diagram produced by :numref:`select_ys`
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ Loading the design
|
|||
Our circuit now looks like this:
|
||||
|
||||
.. figure:: /_images/code_examples/intro/counter_00.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: counter-hierarchy
|
||||
|
||||
``counter`` after :cmd:ref:`hierarchy`
|
||||
|
|
@ -66,7 +66,7 @@ Coarse-grain representation
|
|||
:caption: :file:`counter.ys` - the high-level stuff
|
||||
|
||||
.. figure:: /_images/code_examples/intro/counter_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Coarse-grain representation of the ``counter`` module
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ Logic gate mapping
|
|||
:caption: :file:`counter.ys` - mapping to internal cell library
|
||||
|
||||
.. figure:: /_images/code_examples/intro/counter_02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
``counter`` after :cmd:ref:`techmap`
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ Recall that the Yosys built-in logic gate types are ``$_NOT_``, ``$_AND_``,
|
|||
The final version of our ``counter`` module looks like this:
|
||||
|
||||
.. figure:: /_images/code_examples/intro/counter_03.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
``counter`` after hardware cell mapping
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Example code can be found in |code_examples/macc|_.
|
|||
:lines: 1-2
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_simple_test_00a.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
before :cmd:ref:`extract`
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ Example code can be found in |code_examples/macc|_.
|
|||
:lines: 6
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_simple_test_00b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
after :cmd:ref:`extract`
|
||||
|
||||
|
|
@ -49,20 +49,20 @@ Example code can be found in |code_examples/macc|_.
|
|||
:caption: :file:`macc_simple_test_01.v`
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_simple_test_01a.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_simple_test_01b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_simple_test_02.v
|
||||
:language: verilog
|
||||
:caption: :file:`macc_simple_test_02.v`
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_simple_test_02a.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_simple_test_02b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
The wrap-extract-unwrap method
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -149,10 +149,10 @@ Unwrapping adders: :file:`macc_xilinx_unwrap_map.v`
|
|||
:caption: ``test1`` of :file:`macc_xilinx_test.v`
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test1a.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_xilinx_test.v
|
||||
:language: verilog
|
||||
|
|
@ -160,15 +160,15 @@ Unwrapping adders: :file:`macc_xilinx_unwrap_map.v`
|
|||
:caption: ``test2`` of :file:`macc_xilinx_test.v`
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2a.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Wrapping in ``test1``:
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test1b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -176,12 +176,12 @@ Wrapping in ``test1``:
|
|||
:end-before: end part c
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Wrapping in ``test2``:
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2b.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -189,12 +189,12 @@ Wrapping in ``test2``:
|
|||
:end-before: end part c
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Extract in ``test1``:
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test1c.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -202,12 +202,12 @@ Extract in ``test1``:
|
|||
:end-before: end part d
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test1d.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Extract in ``test2``:
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2c.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -215,12 +215,12 @@ Extract in ``test2``:
|
|||
:end-before: end part d
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Unwrap in ``test2``:
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2d.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/macc/macc_xilinx_test.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -228,4 +228,4 @@ Unwrap in ``test2``:
|
|||
:end-before: end part e
|
||||
|
||||
.. figure:: /_images/code_examples/macc/macc_xilinx_test2e.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
|
@ -39,7 +39,7 @@ Example
|
|||
.. _code_examples/synth_flow: https://github.com/YosysHQ/yosys/tree/main/docs/source/code_examples/synth_flow
|
||||
|
||||
.. figure:: /_images/code_examples/synth_flow/memory_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/synth_flow/memory_01.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -50,7 +50,7 @@ Example
|
|||
:caption: :file:`memory_01.v`
|
||||
|
||||
.. figure:: /_images/code_examples/synth_flow/memory_02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/synth_flow/memory_02.v
|
||||
:language: verilog
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ trees can interfere with other optimizations.
|
|||
:caption: example verilog for demonstrating :cmd:ref:`opt_expr`
|
||||
|
||||
.. figure:: /_images/code_examples/opt/opt_expr.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Before and after :cmd:ref:`opt_expr`
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ possible optimizations.
|
|||
:caption: example verilog for demonstrating :cmd:ref:`opt_merge`
|
||||
|
||||
.. figure:: /_images/code_examples/opt/opt_merge.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Before and after :cmd:ref:`opt_merge`
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ detects this contradiction and replaces the inner multiplexer with a constant 1,
|
|||
yielding the logic for ``y = a ? b : d``.
|
||||
|
||||
.. figure:: /_images/code_examples/opt/opt_muxtree.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Before and after :cmd:ref:`opt_muxtree`
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ multiplexing its output to multiplexing the non-shared input signals.
|
|||
:caption: example verilog for demonstrating :cmd:ref:`opt_share`
|
||||
|
||||
.. figure:: /_images/code_examples/opt/opt_share.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Before and after :cmd:ref:`opt_share`
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ Example
|
|||
:caption: :file:`proc_01.ys`
|
||||
|
||||
.. figure:: /_images/code_examples/synth_flow/proc_01.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. figure:: /_images/code_examples/synth_flow/proc_02.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/synth_flow/proc_02.v
|
||||
:language: verilog
|
||||
|
|
@ -56,7 +56,7 @@ Example
|
|||
:caption: :file:`proc_02.ys`
|
||||
|
||||
.. figure:: /_images/code_examples/synth_flow/proc_03.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/synth_flow/proc_03.ys
|
||||
:language: yoscrypt
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ This document will focus on the much simpler version of RTLIL left after the
|
|||
commands :cmd:ref:`proc` and :cmd:ref:`memory` (or :yoscrypt:`memory -nomap`):
|
||||
|
||||
.. figure:: /_images/internals/simplified_rtlil.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Simplified_RTLIL
|
||||
|
||||
Simplified RTLIL entity-relationship diagram without memories and processes
|
||||
|
|
@ -140,7 +140,7 @@ We'll do the same as before and format it as a a ``Yosys::Pass``.
|
|||
And if we look at the schematic for this new module we see the following:
|
||||
|
||||
.. figure:: /_images/code_examples/extensions/test1.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
Output of ``yosys -m ./my_cmd.so -p 'test1; show'``
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ and generating the data for the next subsystem (see :numref:`Fig. %s
|
|||
<fig:approach_flow>`).
|
||||
|
||||
.. figure:: /_images/internals/approach_flow.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:approach_flow
|
||||
|
||||
General data- and control-flow of a synthesis tool
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ possible it is key that (1) all passes operate on the same data structure
|
|||
design in different stages of the synthesis.
|
||||
|
||||
.. figure:: /_images/internals/overview_flow.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Overview_flow
|
||||
|
||||
Yosys simplified data flow (ellipses: data structures, rectangles:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ is then passed to the AST frontend that converts it to RTLIL data, as
|
|||
illustrated in :numref:`Fig. %s <fig:Verilog_flow>`.
|
||||
|
||||
.. figure:: /_images/internals/verilog_flow.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Verilog_flow
|
||||
|
||||
Simplified Verilog to RTLIL data flow
|
||||
|
|
|
|||
|
|
@ -661,6 +661,50 @@ The CONFIG parameter carries the following information:
|
|||
|
||||
B is an array of concatenated 1-bit-wide unsigned integers to also be summed up.
|
||||
|
||||
Arbitrary logic functions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``$lut`` cell type implements a single-output LUT (lookup table).
|
||||
It implements an arbitrary logic function with its ``\LUT`` parameter to map
|
||||
input port ``\A`` to values of ``\Y`` output port values.
|
||||
In psuedocode: ``Y = \LUT[A]``.
|
||||
``\A`` has width set by parameter ``\WIDTH`` and ``\Y`` has a width of 1.
|
||||
Every logic function with a single bit output has a unique ``$lut``
|
||||
representation.
|
||||
|
||||
The ``$sop`` cell type implements a sum-of-products expression, also known
|
||||
as disjunctive normal form (DNF). It implements an arbitrary logic function.
|
||||
Its structure mimics a programmable logic array (PLA).
|
||||
Output port ``\Y`` is the sum of products of the bits of the input port ``\A``
|
||||
as defined by parameter ``\TABLE``. ``\A`` is ``\WIDTH`` bits wide.
|
||||
The number of products in the sum is set by parameter ``\DEPTH``, and each
|
||||
product has two bits for each input bit - for the presence of the
|
||||
unnegated and negated version of said input bit in the product.
|
||||
Therefore the ``\TABLE`` parameter holds ``2 * \WIDTH * \DEPTH`` bits.
|
||||
|
||||
For example:
|
||||
|
||||
Let ``\WIDTH`` be 3. We would like to represent ``\Y =~\A[0] + \A[1]~\A[2]``.
|
||||
There are 2 products to be summed, so ``\DEPTH`` shall be 2.
|
||||
|
||||
.. code-block::
|
||||
|
||||
~A[2]-----+
|
||||
A[2]----+|
|
||||
~A[1]---+||
|
||||
A[1]--+|||
|
||||
~A[0]-+||||
|
||||
A[0]+|||||
|
||||
|||||| product formula
|
||||
010000 ~\A[0]
|
||||
001001 \A[1]~\A[2]
|
||||
|
||||
So the value of ``\TABLE`` will become ``010000001001``.
|
||||
|
||||
Any logic function with a single bit output can be represented with
|
||||
``$sop`` but may have variously minimized or ordered summands represented
|
||||
in the ``\TABLE`` values.
|
||||
|
||||
Specify rules
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
|
@ -1192,6 +1236,6 @@ file via ABC using the abc pass.
|
|||
|
||||
.. todo:: Add information about ``$slice`` and ``$concat`` cells.
|
||||
|
||||
.. todo:: Add information about ``$lut`` and ``$sop`` cells.
|
||||
|
||||
.. todo:: Add information about ``$alu``, ``$fa``, and ``$lcu`` cells.
|
||||
|
||||
.. todo:: Add information about ``$demux`` cell.
|
||||
|
|
@ -24,7 +24,7 @@ create an additional ``RTLIL::Design`` object and call the Verilog frontend with
|
|||
this other object to parse the cell library.
|
||||
|
||||
.. figure:: /_images/internals/overview_rtlil.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
:name: fig:Overview_RTLIL
|
||||
|
||||
Simplified RTLIL Entity-Relationship Diagram
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Mapping OR3X1
|
|||
:caption: :file:`red_or3x1_map.v`
|
||||
|
||||
.. figure:: /_images/code_examples/techmap/red_or3x1.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/techmap/red_or3x1_test.ys
|
||||
:language: yoscrypt
|
||||
|
|
@ -61,7 +61,7 @@ Conditional techmap
|
|||
Example:
|
||||
|
||||
.. figure:: /_images/code_examples/techmap/sym_mul.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/techmap/sym_mul_map.v
|
||||
:language: verilog
|
||||
|
|
@ -100,7 +100,7 @@ Scripting in map modules
|
|||
Example:
|
||||
|
||||
.. figure:: /_images/code_examples/techmap/mymul.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/techmap/mymul_map.v
|
||||
:language: verilog
|
||||
|
|
@ -130,7 +130,7 @@ Handling constant inputs
|
|||
Example:
|
||||
|
||||
.. figure:: /_images/code_examples/techmap/mulshift.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/techmap/mulshift_map.v
|
||||
:language: verilog
|
||||
|
|
@ -162,7 +162,7 @@ Handling shorted inputs
|
|||
Example:
|
||||
|
||||
.. figure:: /_images/code_examples/techmap/addshift.*
|
||||
:class: width-helper
|
||||
:class: width-helper invert-helper
|
||||
|
||||
.. literalinclude:: /code_examples/techmap/addshift_map.v
|
||||
:language: verilog
|
||||
|
|
|
|||
|
|
@ -10,13 +10,14 @@ import sys
|
|||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# expects __file__ = yosys/docs/tests/macro_commands.py
|
||||
TESTS_DIR = Path(__file__).parent
|
||||
TESTS_DIR = Path(__file__).parent.absolute()
|
||||
ROOT_DIR = TESTS_DIR.parent.parent
|
||||
logging.log(logging.INFO, f"Using {ROOT_DIR} as root directory")
|
||||
THIS_FILE = (TESTS_DIR / "macro_commands.py").relative_to(ROOT_DIR)
|
||||
MACRO_SOURCE = TESTS_DIR.parent / "source" / "code_examples" / "macro_commands"
|
||||
assert MACRO_SOURCE.exists(), f"can't find macro_commands in {MACRO_SOURCE}"
|
||||
|
||||
YOSYS = TESTS_DIR.parent.parent / "yosys"
|
||||
YOSYS = ROOT_DIR / "yosys"
|
||||
assert YOSYS.exists(), f"can't find yosys executable in {YOSYS}"
|
||||
|
||||
raise_error = False
|
||||
|
|
|
|||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1708807242,
|
||||
"narHash": "sha256-sRTRkhMD4delO/hPxxi+XwLqPn8BuUq6nnj4JqLwOu0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "73de017ef2d18a04ac4bfd0c02650007ccb31c2a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
48
flake.nix
Normal file
48
flake.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
description = "A nix flake for the Yosys synthesis suite";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
};
|
||||
# TODO: don't override src when ./abc is empty
|
||||
# which happens when the command used is `nix build` and not `nix build ?submodules=1`
|
||||
abc-verifier = pkgs.abc-verifier.overrideAttrs(x: y: {src = ./abc;});
|
||||
yosys = pkgs.clangStdenv.mkDerivation {
|
||||
name = "yosys";
|
||||
src = ./. ;
|
||||
buildInputs = with pkgs; [ clang bison flex libffi tcl readline python3 llvmPackages.libcxxClang zlib git pkg-configUpstream ];
|
||||
checkInputs = with pkgs; [ gtest ];
|
||||
propagatedBuildInputs = [ abc-verifier ];
|
||||
preConfigure = "make config-clang";
|
||||
checkTarget = "test";
|
||||
installPhase = ''
|
||||
make install PREFIX=$out ABCEXTERNAL=yosys-abc
|
||||
ln -s ${abc-verifier}/bin/abc $out/bin/yosys-abc
|
||||
'';
|
||||
buildPhase = ''
|
||||
make -j$(nproc) ABCEXTERNAL=yosys-abc
|
||||
'';
|
||||
meta = with pkgs.lib; {
|
||||
description = "Yosys Open SYnthesis Suite";
|
||||
homepage = "https://yosyshq.net/yosys/";
|
||||
license = licenses.isc;
|
||||
maintainers = with maintainers; [ ];
|
||||
};
|
||||
};
|
||||
in {
|
||||
packages.default = yosys;
|
||||
defaultPackage = yosys;
|
||||
devShell = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [ clang bison flex libffi tcl readline python3 llvmPackages.libcxxClang zlib git gtest abc-verifier ];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -48,3 +48,4 @@ OBJS += passes/cmds/clean_zerowidth.o
|
|||
OBJS += passes/cmds/xprop.o
|
||||
OBJS += passes/cmds/dft_tag.o
|
||||
OBJS += passes/cmds/future.o
|
||||
OBJS += passes/cmds/box_derive.o
|
||||
|
|
|
|||
116
passes/cmds/box_derive.cc
Normal file
116
passes/cmds/box_derive.cc
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2024 Martin Povišer <povik@cutebit.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include "kernel/yosys.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct BoxDerivePass : Pass {
|
||||
BoxDerivePass() : Pass("box_derive", "derive box modules") {}
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" box_derive [-base <base_module>] [-naming_attr <attr>] [selection]\n");
|
||||
log("\n");
|
||||
log("As part of the assembly of the design hierarchy done by the 'hierarchy' command,\n");
|
||||
log("specializations of parametric modules are derived on demand: for each choice of\n");
|
||||
log("parameter values appearing in the design, a copy of the parametric module is\n");
|
||||
log("derived which is specialized to that choice.\n");
|
||||
log("\n");
|
||||
log("This derivation process ignores blackboxes and whiteboxes (boxes). To supplement,\n");
|
||||
log("this 'box_derive' command can be used to request the derivation of modules based\n");
|
||||
log("on box instances appearing in the design, which is desirable in certain use\n");
|
||||
log("cases. Only the selected cells are considered as the instances that steer the\n");
|
||||
log("derivation process.\n");
|
||||
log("\n");
|
||||
log(" -base <base_module>\n");
|
||||
log(" instead of deriving the module that directly corresponds to each box\n");
|
||||
log(" instance, derive a specialization of <base_module> (this option applies\n");
|
||||
log(" to all selected box cells)\n");
|
||||
log("\n");
|
||||
log(" -naming_attr <attr>\n");
|
||||
log(" once a specialization is derived, use the value of the module attribute\n");
|
||||
log(" <attr> for a name which should be used for the derived module (this\n");
|
||||
log(" replaces the internal Yosys naming scheme in which the names of derived\n");
|
||||
log(" modules start with '$paramod$')\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *d) override
|
||||
{
|
||||
log_header(d, "Executing BOX_DERIVE pass. (derive modules for boxes)\n");
|
||||
|
||||
size_t argidx;
|
||||
IdString naming_attr;
|
||||
IdString base_name;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-naming_attr" && argidx + 1 < args.size())
|
||||
naming_attr = RTLIL::escape_id(args[++argidx]);
|
||||
else if (args[argidx] == "-base" && argidx + 1 < args.size())
|
||||
base_name = RTLIL::escape_id(args[++argidx]);
|
||||
else
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, d);
|
||||
|
||||
Module *base_override = nullptr;
|
||||
if (!base_name.empty()) {
|
||||
base_override = d->module(base_name);
|
||||
if (!base_override)
|
||||
log_cmd_error("Base module %s not found.\n", log_id(base_name));
|
||||
}
|
||||
|
||||
dict<std::pair<RTLIL::IdString, dict<RTLIL::IdString, RTLIL::Const>>, Module*> done;
|
||||
|
||||
for (auto module : d->selected_modules()) {
|
||||
for (auto cell : module->selected_cells()) {
|
||||
Module *inst_module = d->module(cell->type);
|
||||
if (!inst_module || !inst_module->get_blackbox_attribute())
|
||||
continue;
|
||||
|
||||
Module *base = inst_module;
|
||||
if (base_override)
|
||||
base = base_override;
|
||||
|
||||
auto index = std::make_pair(base->name, cell->parameters);
|
||||
|
||||
if (cell->parameters.empty() || done.count(index))
|
||||
continue;
|
||||
|
||||
IdString derived_type = base->derive(d, cell->parameters);
|
||||
Module *derived = d->module(derived_type);
|
||||
log_assert(derived && "Failed to derive module\n");
|
||||
log_debug("derived %s\n", derived_type.c_str());
|
||||
|
||||
if (!naming_attr.empty() && derived->has_attribute(naming_attr)) {
|
||||
IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr));
|
||||
if (!new_name.isPublic())
|
||||
log_error("Derived module %s cannot be renamed to private name %s.\n",
|
||||
log_id(derived), log_id(new_name));
|
||||
derived->attributes.erase(naming_attr);
|
||||
d->rename(derived, new_name);
|
||||
}
|
||||
|
||||
done[index] = derived;
|
||||
}
|
||||
}
|
||||
}
|
||||
} BoxDerivePass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
|
|
@ -31,7 +31,8 @@ struct LogPass : public Pass {
|
|||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" log string\n");
|
||||
log(" log [options] string\n");
|
||||
log(" log [ -push | -pop ]\n");
|
||||
log("\n");
|
||||
log("Print the given string to the screen and/or the log file. This is useful for TCL\n");
|
||||
log("scripts, because the TCL command \"puts\" only goes to stdout but not to\n");
|
||||
|
|
@ -52,14 +53,26 @@ struct LogPass : public Pass {
|
|||
log(" -n\n");
|
||||
log(" do not append a newline\n");
|
||||
log("\n");
|
||||
log(" -header\n");
|
||||
log(" log a pass header\n");
|
||||
log("\n");
|
||||
log(" -push\n");
|
||||
log(" push a new level on the pass counter\n");
|
||||
log("\n");
|
||||
log(" -pop\n");
|
||||
log(" pop from the pass counter\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design*) override
|
||||
void execute(std::vector<std::string> args, RTLIL::Design* design) override
|
||||
{
|
||||
size_t argidx;
|
||||
bool to_stdout = false;
|
||||
bool to_stderr = false;
|
||||
bool to_log = true;
|
||||
bool newline = true;
|
||||
bool header = false;
|
||||
bool push = false;
|
||||
bool pop = false;
|
||||
std::string text;
|
||||
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
|
|
@ -68,15 +81,30 @@ struct LogPass : public Pass {
|
|||
else if (args[argidx] == "-stderr") to_stderr = true;
|
||||
else if (args[argidx] == "-nolog") to_log = false;
|
||||
else if (args[argidx] == "-n") newline = false;
|
||||
else if (args[argidx] == "-header") header = true;
|
||||
else if (args[argidx] == "-push") push = true;
|
||||
else if (args[argidx] == "-pop") pop = true;
|
||||
else break;
|
||||
}
|
||||
|
||||
if ((push || pop) && args.size() != 2)
|
||||
log_cmd_error("Bad usage: 'log -push' or 'log -pop' must be used without other arguments.\n");
|
||||
|
||||
if (push) { log_push(); return; }
|
||||
if (pop) { log_pop(); return; }
|
||||
|
||||
for (; argidx < args.size(); argidx++)
|
||||
text += args[argidx] + ' ';
|
||||
if (!text.empty()) text.resize(text.size()-1);
|
||||
|
||||
if (to_stdout) fprintf(stdout, (newline ? "%s\n" : "%s"), text.c_str());
|
||||
if (to_stderr) fprintf(stderr, (newline ? "%s\n" : "%s"), text.c_str());
|
||||
if (to_log) log ( (newline ? "%s\n" : "%s"), text.c_str());
|
||||
const char *fmtline = newline ? "%s\n" : "%s";
|
||||
|
||||
if (to_stdout) fprintf(stdout, fmtline, text.c_str());
|
||||
if (to_stderr) fprintf(stderr, fmtline, text.c_str());
|
||||
if (to_log) {
|
||||
if (!header) log(fmtline, text.c_str());
|
||||
else log_header(design, fmtline, text.c_str());
|
||||
}
|
||||
}
|
||||
} LogPass;
|
||||
|
||||
|
|
|
|||
|
|
@ -1065,6 +1065,10 @@ struct SelectPass : public Pass {
|
|||
log(" selection is non-empty. i.e. produce an error if no object or module\n");
|
||||
log(" matching the selection is found.\n");
|
||||
log("\n");
|
||||
log(" -assert-mod-count N\n");
|
||||
log(" do not modify the current selection. instead assert that the given\n");
|
||||
log(" selection contains exactly N modules (partially or fully selected).\n");
|
||||
log("\n");
|
||||
log(" -assert-count N\n");
|
||||
log(" do not modify the current selection. instead assert that the given\n");
|
||||
log(" selection contains exactly N objects.\n");
|
||||
|
|
@ -1263,6 +1267,7 @@ struct SelectPass : public Pass {
|
|||
bool got_module = false;
|
||||
bool assert_none = false;
|
||||
bool assert_any = false;
|
||||
int assert_modcount = -1;
|
||||
int assert_count = -1;
|
||||
int assert_max = -1;
|
||||
int assert_min = -1;
|
||||
|
|
@ -1291,6 +1296,10 @@ struct SelectPass : public Pass {
|
|||
assert_any = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-assert-mod-count" && argidx+1 < args.size()) {
|
||||
assert_modcount = atoi(args[++argidx].c_str());
|
||||
continue;
|
||||
}
|
||||
if (arg == "-assert-count" && argidx+1 < args.size()) {
|
||||
assert_count = atoi(args[++argidx].c_str());
|
||||
continue;
|
||||
|
|
@ -1345,7 +1354,8 @@ struct SelectPass : public Pass {
|
|||
}
|
||||
if (arg.size() > 0 && arg[0] == '-')
|
||||
log_cmd_error("Unknown option %s.\n", arg.c_str());
|
||||
bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1);
|
||||
bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_modcount != -1) ||
|
||||
(assert_count != -1) || (assert_max != -1) || (assert_min != -1);
|
||||
select_stmt(design, arg, disable_empty_warning);
|
||||
sel_str += " " + arg;
|
||||
}
|
||||
|
|
@ -1385,17 +1395,20 @@ struct SelectPass : public Pass {
|
|||
if (none_mode && args.size() != 2)
|
||||
log_cmd_error("Option -none can not be combined with any other options.\n");
|
||||
|
||||
if (add_mode + del_mode + assert_none + assert_any + (assert_count >= 0) + (assert_max >= 0) + (assert_min >= 0) > 1)
|
||||
log_cmd_error("Options -add, -del, -assert-none, -assert-any, assert-count, -assert-max or -assert-min can not be combined.\n");
|
||||
int common_flagset_tally = add_mode + del_mode + assert_none + assert_any + (assert_modcount >= 0) + (assert_count >= 0) + (assert_max >= 0) + (assert_min >= 0);
|
||||
const char *common_flagset = "-add, -del, -assert-none, -assert-any, -assert-mod-count, -assert-count, -assert-max, or -assert-min";
|
||||
|
||||
if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
|
||||
log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none, -assert-any, assert-count, -assert-max, or -assert-min.\n");
|
||||
if (common_flagset_tally > 1)
|
||||
log_cmd_error("Options %s can not be combined.\n", common_flagset);
|
||||
|
||||
if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || !unset_name.empty() || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
|
||||
log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -unset, -assert-none, -assert-any, -assert-count, -assert-max, or -assert-min.\n");
|
||||
if ((list_mode || !write_file.empty() || count_mode) && common_flagset_tally)
|
||||
log_cmd_error("Options -list, -write and -count can not be combined with %s.\n", common_flagset);
|
||||
|
||||
if (!unset_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || !set_name.empty() || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0))
|
||||
log_cmd_error("Option -unset can not be combined with -list, -write, -count, -add, -del, -set, -assert-none, -assert-any, -assert-count, -assert-max, or -assert-min.\n");
|
||||
if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || !unset_name.empty() || common_flagset_tally))
|
||||
log_cmd_error("Option -set can not be combined with -list, -write, -count, -unset, %s.\n", common_flagset);
|
||||
|
||||
if (!unset_name.empty() && (list_mode || !write_file.empty() || count_mode || !set_name.empty() || common_flagset_tally))
|
||||
log_cmd_error("Option -unset can not be combined with -list, -write, -count, -set, %s.\n", common_flagset);
|
||||
|
||||
if (work_stack.size() == 0 && got_module) {
|
||||
RTLIL::Selection sel;
|
||||
|
|
@ -1514,15 +1527,16 @@ struct SelectPass : public Pass {
|
|||
return;
|
||||
}
|
||||
|
||||
if (assert_count >= 0 || assert_max >= 0 || assert_min >= 0)
|
||||
if (assert_modcount >= 0 || assert_count >= 0 || assert_max >= 0 || assert_min >= 0)
|
||||
{
|
||||
int total_count = 0;
|
||||
int module_count = 0, total_count = 0;
|
||||
if (work_stack.size() == 0)
|
||||
log_cmd_error("No selection to check.\n");
|
||||
RTLIL::Selection *sel = &work_stack.back();
|
||||
sel->optimize(design);
|
||||
for (auto mod : design->modules())
|
||||
if (sel->selected_module(mod->name)) {
|
||||
module_count++;
|
||||
for (auto wire : mod->wires())
|
||||
if (sel->selected_member(mod->name, wire->name))
|
||||
total_count++;
|
||||
|
|
@ -1536,6 +1550,11 @@ struct SelectPass : public Pass {
|
|||
if (sel->selected_member(mod->name, it.first))
|
||||
total_count++;
|
||||
}
|
||||
if (assert_modcount >= 0 && assert_modcount != module_count)
|
||||
{
|
||||
log_error("Assertion failed: selection contains %d modules instead of the asserted %d:%s\n",
|
||||
module_count, assert_modcount, sel_str.c_str());
|
||||
}
|
||||
if (assert_count >= 0 && assert_count != total_count)
|
||||
{
|
||||
std::string desc = describe_selection_for_assert(design, sel);
|
||||
|
|
|
|||
|
|
@ -20,10 +20,7 @@ $(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclone
|
|||
# RAM
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k.txt))
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k_map.v))
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k.txt))
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k_map.v))
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab.txt))
|
||||
|
||||
# Miscellaneous
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/megafunction_bb.v))
|
||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/quartus_rename.v))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// The core logic primitive of the Cyclone V/10GX is the Adaptive Logic Module
|
||||
// The core logic primitive of the Cyclone V is the Adaptive Logic Module
|
||||
// (ALM). Each ALM is made up of an 8-input, 2-output look-up table, covered
|
||||
// in this file, connected to combinational outputs, a carry chain, and four
|
||||
// D flip-flops (which are covered as MISTRAL_FF in dff_sim.v).
|
||||
|
|
@ -77,14 +77,6 @@
|
|||
// SUMOUT 368 1342 1323 887 927 - 785 -
|
||||
// CARRYOUT 71 1082 1062 866 813 - 1198 -
|
||||
|
||||
// Arria V LUT output timings (picoseconds):
|
||||
//
|
||||
// CARRY A B C D E F G
|
||||
// COMBOUT - 387 375 316 317 - 76 319 (LUT6)
|
||||
// COMBOUT - 387 375 316 317 218 76 319 (LUT7)
|
||||
// SUMOUT 249 744 732 562 576 - 511 -
|
||||
// CARRYOUT 19 629 623 530 514 - 696 -
|
||||
|
||||
(* abc9_lut=2, lib_whitebox *)
|
||||
module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);
|
||||
|
||||
|
|
@ -100,26 +92,6 @@ specify
|
|||
(F => Q) = 97;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => Q) = 387;
|
||||
(B => Q) = 375;
|
||||
(C => Q) = 316;
|
||||
(D => Q) = 317;
|
||||
(E => Q) = 319;
|
||||
(F => Q) = 76;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => Q) = 275;
|
||||
(B => Q) = 272;
|
||||
(C => Q) = 175;
|
||||
(D => Q) = 165;
|
||||
(E => Q) = 162;
|
||||
(F => Q) = 53;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
assign Q = LUT >> {F, E, D, C, B, A};
|
||||
|
||||
|
|
@ -140,24 +112,6 @@ specify
|
|||
(E => Q) = 97;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => Q) = 375;
|
||||
(B => Q) = 316;
|
||||
(C => Q) = 317;
|
||||
(D => Q) = 319;
|
||||
(E => Q) = 76;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => Q) = 272;
|
||||
(B => Q) = 175;
|
||||
(C => Q) = 165;
|
||||
(D => Q) = 162;
|
||||
(E => Q) = 53;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
assign Q = LUT >> {E, D, C, B, A};
|
||||
|
||||
|
|
@ -177,22 +131,6 @@ specify
|
|||
(D => Q) = 97;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => Q) = 316;
|
||||
(B => Q) = 317;
|
||||
(C => Q) = 319;
|
||||
(D => Q) = 76;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => Q) = 175;
|
||||
(B => Q) = 165;
|
||||
(C => Q) = 162;
|
||||
(D => Q) = 53;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
assign Q = LUT >> {D, C, B, A};
|
||||
|
||||
|
|
@ -211,20 +149,6 @@ specify
|
|||
(C => Q) = 97;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => Q) = 316;
|
||||
(B => Q) = 317;
|
||||
(C => Q) = 76;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => Q) = 165;
|
||||
(B => Q) = 162;
|
||||
(C => Q) = 53;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
assign Q = LUT >> {C, B, A};
|
||||
|
||||
|
|
@ -242,18 +166,6 @@ specify
|
|||
(B => Q) = 97;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => Q) = 316;
|
||||
(B => Q) = 76;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => Q) = 162;
|
||||
(B => Q) = 53;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
assign Q = LUT >> {B, A};
|
||||
|
||||
|
|
@ -268,16 +180,6 @@ specify
|
|||
(A => Q) = 97;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => Q) = 76;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => Q) = 53;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
assign Q = ~A;
|
||||
|
||||
|
|
@ -306,40 +208,6 @@ specify
|
|||
(CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM)
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
(A => SO) = 744;
|
||||
(B => SO) = 732;
|
||||
(C => SO) = 562;
|
||||
(D0 => SO) = 576;
|
||||
(D1 => SO) = 511;
|
||||
(CI => SO) = 249;
|
||||
|
||||
(A => CO) = 629;
|
||||
(B => CO) = 623;
|
||||
(C => CO) = 530;
|
||||
(D0 => CO) = 514;
|
||||
(D1 => CO) = 696;
|
||||
(CI => CO) = 10; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM)
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
(A => SO) = 644;
|
||||
(B => SO) = 477;
|
||||
(C => SO) = 416;
|
||||
(D0 => SO) = 380;
|
||||
(D1 => SO) = 431;
|
||||
(CI => SO) = 276;
|
||||
|
||||
(A => CO) = 525;
|
||||
(B => CO) = 433;
|
||||
(C => CO) = 712;
|
||||
(D0 => CO) = 653;
|
||||
(D1 => CO) = 593;
|
||||
(CI => CO) = 16;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
wire q0, q1;
|
||||
|
||||
|
|
@ -349,283 +217,3 @@ assign q1 = LUT1 >> {D1, C, B, A};
|
|||
assign {CO, SO} = q0 + !q1 + CI;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
/*
|
||||
// A, B, C0, C1, E0, E1, F0, F1: data inputs
|
||||
// CARRYIN: carry input
|
||||
// SHAREIN: shared-arithmetic input
|
||||
// CLK0, CLK1, CLK2: clock inputs
|
||||
//
|
||||
// COMB0, COMB1: combinational outputs
|
||||
// FF0, FF1, FF2, FF3: DFF outputs
|
||||
// SUM0, SUM1: adder outputs
|
||||
// CARRYOUT: carry output
|
||||
// SHAREOUT: shared-arithmetic output
|
||||
module MISTRAL_ALM(
|
||||
input A, B, C0, C1, E0, E1, F0, F1, CARRYIN, SHAREIN, // LUT path
|
||||
input CLK0, CLK1, CLK2, AC0, AC1, // FF path
|
||||
output COMB0, COMB1, SUM0, SUM1, CARRYOUT, SHAREOUT,
|
||||
output FF0, FF1, FF2, FF3
|
||||
);
|
||||
|
||||
parameter LUT0 = 16'b0000;
|
||||
parameter LUT1 = 16'b0000;
|
||||
parameter LUT2 = 16'b0000;
|
||||
parameter LUT3 = 16'b0000;
|
||||
|
||||
parameter INIT0 = 1'b0;
|
||||
parameter INIT1 = 1'b0;
|
||||
parameter INIT2 = 1'b0;
|
||||
parameter INIT3 = 1'b0;
|
||||
|
||||
parameter C0_MUX = "C0";
|
||||
parameter C1_MUX = "C1";
|
||||
|
||||
parameter F0_MUX = "VCC";
|
||||
parameter F1_MUX = "GND";
|
||||
|
||||
parameter FEEDBACK0 = "FF0";
|
||||
parameter FEEDBACK1 = "FF2";
|
||||
|
||||
parameter ADD_MUX = "LUT";
|
||||
|
||||
parameter DFF01_DATA_MUX = "COMB";
|
||||
parameter DFF23_DATA_MUX = "COMB";
|
||||
|
||||
parameter DFF0_CLK = "CLK0";
|
||||
parameter DFF1_CLK = "CLK0";
|
||||
parameter DFF2_CLK = "CLK0";
|
||||
parameter DFF3_CLK = "CLK0";
|
||||
|
||||
parameter DFF0_AC = "AC0";
|
||||
parameter DFF1_AC = "AC0";
|
||||
parameter DFF2_AC = "AC0";
|
||||
parameter DFF3_AC = "AC0";
|
||||
|
||||
// Feedback muxes from the flip-flop outputs.
|
||||
wire ff_feedback_mux0, ff_feedback_mux1;
|
||||
|
||||
// C-input muxes which can be set to also use the F-input.
|
||||
wire c0_input_mux, c1_input_mux;
|
||||
|
||||
// F-input muxes which can be set to a constant to allow LUT5 use.
|
||||
wire f0_input_mux, f1_input_mux;
|
||||
|
||||
// Adder input muxes to select between shared-arithmetic mode and arithmetic mode.
|
||||
wire add0_input_mux, add1_input_mux;
|
||||
|
||||
// Combinational-output muxes for LUT #1 and LUT #3
|
||||
wire lut1_comb_mux, lut3_comb_mux;
|
||||
|
||||
// Sum-output muxes for LUT #1 and LUT #3
|
||||
wire lut1_sum_mux, lut3_sum_mux;
|
||||
|
||||
// DFF data-input muxes
|
||||
wire dff01_data_mux, dff23_data_mux;
|
||||
|
||||
// DFF clock selectors
|
||||
wire dff0_clk, dff1_clk, dff2_clk, dff3_clk;
|
||||
|
||||
// DFF asynchronous-clear selectors
|
||||
wire dff0_ac, dff1_ac, dff2_ac, dff3_ac;
|
||||
|
||||
// LUT, DFF and adder output wires for routing.
|
||||
wire lut0_out, lut1a_out, lut1b_out, lut2_out, lut3a_out, lut3b_out;
|
||||
wire dff0_out, dff1_out, dff2_out, dff3_out;
|
||||
wire add0_sum, add1_sum, add0_carry, add1_carry;
|
||||
|
||||
generate
|
||||
if (FEEDBACK0 === "FF0")
|
||||
assign ff_feedback_mux0 = dff0_out;
|
||||
else if (FEEDBACK0 === "FF1")
|
||||
assign ff_feedback_mux0 = dff1_out;
|
||||
else
|
||||
$error("Invalid FEEDBACK0 setting!");
|
||||
|
||||
if (FEEDBACK1 == "FF2")
|
||||
assign ff_feedback_mux1 = dff2_out;
|
||||
else if (FEEDBACK1 == "FF3")
|
||||
assign ff_feedback_mux1 = dff3_out;
|
||||
else
|
||||
$error("Invalid FEEDBACK1 setting!");
|
||||
|
||||
if (C0_MUX === "C0")
|
||||
assign c0_input_mux = C0;
|
||||
else if (C0_MUX === "F1")
|
||||
assign c0_input_mux = F1;
|
||||
else if (C0_MUX === "FEEDBACK1")
|
||||
assign c0_input_mux = ff_feedback_mux1;
|
||||
else
|
||||
$error("Invalid C0_MUX setting!");
|
||||
|
||||
if (C1_MUX === "C1")
|
||||
assign c1_input_mux = C1;
|
||||
else if (C1_MUX === "F0")
|
||||
assign c1_input_mux = F0;
|
||||
else if (C1_MUX === "FEEDBACK0")
|
||||
assign c1_input_mux = ff_feedback_mux0;
|
||||
else
|
||||
$error("Invalid C1_MUX setting!");
|
||||
|
||||
// F0 == VCC is LUT5
|
||||
// F0 == F0 is LUT6
|
||||
// F0 == FEEDBACK is unknown
|
||||
if (F0_MUX === "VCC")
|
||||
assign f0_input_mux = 1'b1;
|
||||
else if (F0_MUX === "F0")
|
||||
assign f0_input_mux = F0;
|
||||
else if (F0_MUX === "FEEDBACK0")
|
||||
assign f0_input_mux = ff_feedback_mux0;
|
||||
else
|
||||
$error("Invalid F0_MUX setting!");
|
||||
|
||||
// F1 == GND is LUT5
|
||||
// F1 == F1 is LUT6
|
||||
// F1 == FEEDBACK is unknown
|
||||
if (F1_MUX === "GND")
|
||||
assign f1_input_mux = 1'b0;
|
||||
else if (F1_MUX === "F1")
|
||||
assign f1_input_mux = F1;
|
||||
else if (F1_MUX === "FEEDBACK1")
|
||||
assign f1_input_mux = ff_feedback_mux1;
|
||||
else
|
||||
$error("Invalid F1_MUX setting!");
|
||||
|
||||
if (ADD_MUX === "LUT") begin
|
||||
assign add0_input_mux = ~lut1_sum_mux;
|
||||
assign add1_input_mux = ~lut3_sum_mux;
|
||||
end else if (ADD_MUX === "SHARE") begin
|
||||
assign add0_input_mux = SHAREIN;
|
||||
assign add1_input_mux = lut1_comb_mux;
|
||||
end else
|
||||
$error("Invalid ADD_MUX setting!");
|
||||
|
||||
if (DFF01_DATA_MUX === "COMB")
|
||||
assign dff01_data_mux = COMB0;
|
||||
else if (DFF01_DATA_MUX === "SUM")
|
||||
assign dff01_data_mux = SUM0;
|
||||
else
|
||||
$error("Invalid DFF01_DATA_MUX setting!");
|
||||
|
||||
if (DFF23_DATA_MUX === "COMB")
|
||||
assign dff23_data_mux = COMB0;
|
||||
else if (DFF23_DATA_MUX === "SUM")
|
||||
assign dff23_data_mux = SUM0;
|
||||
else
|
||||
$error("Invalid DFF23_DATA_MUX setting!");
|
||||
|
||||
if (DFF0_CLK === "CLK0")
|
||||
assign dff0_clk = CLK0;
|
||||
else if (DFF0_CLK === "CLK1")
|
||||
assign dff0_clk = CLK1;
|
||||
else if (DFF0_CLK === "CLK2")
|
||||
assign dff0_clk = CLK2;
|
||||
else
|
||||
$error("Invalid DFF0_CLK setting!");
|
||||
|
||||
if (DFF1_CLK === "CLK0")
|
||||
assign dff1_clk = CLK0;
|
||||
else if (DFF1_CLK === "CLK1")
|
||||
assign dff1_clk = CLK1;
|
||||
else if (DFF1_CLK === "CLK2")
|
||||
assign dff1_clk = CLK2;
|
||||
else
|
||||
$error("Invalid DFF1_CLK setting!");
|
||||
|
||||
if (DFF2_CLK === "CLK0")
|
||||
assign dff2_clk = CLK0;
|
||||
else if (DFF2_CLK === "CLK1")
|
||||
assign dff2_clk = CLK1;
|
||||
else if (DFF2_CLK === "CLK2")
|
||||
assign dff2_clk = CLK2;
|
||||
else
|
||||
$error("Invalid DFF2_CLK setting!");
|
||||
|
||||
if (DFF3_CLK === "CLK0")
|
||||
assign dff3_clk = CLK0;
|
||||
else if (DFF3_CLK === "CLK1")
|
||||
assign dff3_clk = CLK1;
|
||||
else if (DFF3_CLK === "CLK2")
|
||||
assign dff3_clk = CLK2;
|
||||
else
|
||||
$error("Invalid DFF3_CLK setting!");
|
||||
|
||||
if (DFF0_AC === "AC0")
|
||||
assign dff0_ac = AC0;
|
||||
else if (DFF0_AC === "AC1")
|
||||
assign dff0_ac = AC1;
|
||||
else
|
||||
$error("Invalid DFF0_AC setting!");
|
||||
|
||||
if (DFF1_AC === "AC0")
|
||||
assign dff1_ac = AC0;
|
||||
else if (DFF1_AC === "AC1")
|
||||
assign dff1_ac = AC1;
|
||||
else
|
||||
$error("Invalid DFF1_AC setting!");
|
||||
|
||||
if (DFF2_AC === "AC0")
|
||||
assign dff2_ac = AC0;
|
||||
else if (DFF2_AC === "AC1")
|
||||
assign dff2_ac = AC1;
|
||||
else
|
||||
$error("Invalid DFF2_AC setting!");
|
||||
|
||||
if (DFF3_AC === "AC0")
|
||||
assign dff3_ac = AC0;
|
||||
else if (DFF3_AC === "AC1")
|
||||
assign dff3_ac = AC1;
|
||||
else
|
||||
$error("Invalid DFF3_AC setting!");
|
||||
|
||||
endgenerate
|
||||
|
||||
// F0 on the Quartus diagram
|
||||
MISTRAL_ALUT4 #(.LUT(LUT0)) lut0 (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut0_out));
|
||||
|
||||
// F2 on the Quartus diagram
|
||||
MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_comb (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut1_comb_mux));
|
||||
MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_sum (.A(A), .B(B), .C(C0), .D(E0), .Q(lut1_sum_mux));
|
||||
|
||||
// F1 on the Quartus diagram
|
||||
MISTRAL_ALUT4 #(.LUT(LUT2)) lut2 (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut2_out));
|
||||
|
||||
// F3 on the Quartus diagram
|
||||
MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_comb (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut3_comb_mux));
|
||||
MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_sum (.A(A), .B(B), .C(C1), .D(E1), .Q(lut3_sum_mux));
|
||||
|
||||
MISTRAL_FF #(.INIT(INIT0)) dff0 (.D(dff01_data_mux), .CLK(dff0_clk), .ACn(dff0_ac), .Q(dff0_out));
|
||||
MISTRAL_FF #(.INIT(INIT1)) dff1 (.D(dff01_data_mux), .CLK(dff1_clk), .ACn(dff1_ac), .Q(dff1_out));
|
||||
MISTRAL_FF #(.INIT(INIT2)) dff2 (.D(dff23_data_mux), .CLK(dff2_clk), .ACn(dff2_ac), .Q(dff2_out));
|
||||
MISTRAL_FF #(.INIT(INIT3)) dff3 (.D(dff23_data_mux), .CLK(dff3_clk), .ACn(dff3_ac), .Q(dff3_out));
|
||||
|
||||
// Adders
|
||||
assign {add0_carry, add0_sum} = CARRYIN + lut0_out + lut1_sum_mux;
|
||||
assign {add1_carry, add1_sum} = add0_carry + lut2_out + lut3_sum_mux;
|
||||
|
||||
// COMBOUT outputs on the Quartus diagram
|
||||
assign COMB0 = E0 ? (f0_input_mux ? lut3_comb_mux : lut1_comb_mux)
|
||||
: (f0_input_mux ? lut2_out : lut0_out);
|
||||
|
||||
assign COMB1 = E1 ? (f1_input_mux ? lut3_comb_mux : lut1_comb_mux)
|
||||
: (f1_input_mux ? lut2_out : lut0_out);
|
||||
|
||||
// SUMOUT output on the Quartus diagram
|
||||
assign SUM0 = add0_sum;
|
||||
assign SUM1 = add1_sum;
|
||||
|
||||
// COUT output on the Quartus diagram
|
||||
assign CARRYOUT = add1_carry;
|
||||
|
||||
// SHAREOUT output on the Quartus diagram
|
||||
assign SHAREOUT = lut3_comb_mux;
|
||||
|
||||
// REGOUT outputs on the Quartus diagram
|
||||
assign FF0 = dff0_out;
|
||||
assign FF1 = dff1_out;
|
||||
assign FF2 = dff2_out;
|
||||
assign FF3 = dff3_out;
|
||||
|
||||
endmodule
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
bram __MISTRAL_M20K_SDP
|
||||
init 1 # TODO: Re-enable when I figure out how BRAM init works
|
||||
abits 14 @D16384x1
|
||||
dbits 1 @D16384x1
|
||||
abits 13 @D8192x2
|
||||
dbits 2 @D8192x2
|
||||
abits 12 @D4096x4 @D4096x5
|
||||
dbits 4 @D4096x4
|
||||
dbits 5 @D4096x5
|
||||
abits 11 @D2048x8 @D2048x10
|
||||
dbits 8 @D2048x8
|
||||
dbits 10 @D2048x10
|
||||
abits 10 @D1024x16 @D1024x20
|
||||
dbits 16 @D1024x16
|
||||
dbits 20 @D1024x20
|
||||
abits 9 @D512x32 @D512x40
|
||||
dbits 32 @D512x32
|
||||
dbits 40 @D512x40
|
||||
groups 2
|
||||
ports 1 1
|
||||
wrmode 1 0
|
||||
# read enable; write enable + byte enables (only for multiples of 8)
|
||||
enable 1 1
|
||||
transp 0 0
|
||||
clocks 1 1
|
||||
clkpol 1 1
|
||||
endbram
|
||||
|
||||
|
||||
match __MISTRAL_M20K_SDP
|
||||
min efficiency 5
|
||||
make_transp
|
||||
endmatch
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
|
||||
parameter CFG_ABITS = 10;
|
||||
parameter CFG_DBITS = 20;
|
||||
parameter CFG_ENABLE_A = 1;
|
||||
parameter CFG_ENABLE_B = 1;
|
||||
|
||||
input CLK1;
|
||||
input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
|
||||
input [CFG_DBITS-1:0] A1DATA;
|
||||
output [CFG_DBITS-1:0] B1DATA;
|
||||
input [CFG_ENABLE_A-1:0] A1EN, B1EN;
|
||||
|
||||
altsyncram #(
|
||||
.operation_mode("dual_port"),
|
||||
.ram_block_type("m20k"),
|
||||
.widthad_a(CFG_ABITS),
|
||||
.width_a(CFG_DBITS),
|
||||
.widthad_b(CFG_ABITS),
|
||||
.width_b(CFG_DBITS),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.address_a(A1ADDR),
|
||||
.data_a(A1DATA),
|
||||
.wren_a(A1EN),
|
||||
.address_b(B1ADDR),
|
||||
.q_b(B1DATA),
|
||||
.clock0(CLK1),
|
||||
.clock1(CLK1)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -77,38 +77,6 @@ specify
|
|||
if (ACLR === 1'b0) (ACLR => Q) = 282;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 470;
|
||||
if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 633;
|
||||
if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 439;
|
||||
|
||||
$setup(DATAIN, posedge CLK, /* -170 */ 0);
|
||||
$setup(ENA, posedge CLK, /* -170 */ 0);
|
||||
$setup(SCLR, posedge CLK, /* -170 */ 0);
|
||||
$setup(SLOAD, posedge CLK, /* -170 */ 0);
|
||||
$setup(SDATA, posedge CLK, /* -170 */ 0);
|
||||
|
||||
if (ACLR === 1'b0) (ACLR => Q) = 215;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
specify
|
||||
// TODO (long-term): investigate these numbers.
|
||||
// It seems relying on the Quartus Timing Analyzer was not the best idea; it's too fiddly.
|
||||
if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 219;
|
||||
if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 219;
|
||||
if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 219;
|
||||
|
||||
$setup(DATAIN, posedge CLK, 268);
|
||||
$setup(ENA, posedge CLK, 268);
|
||||
$setup(SCLR, posedge CLK, 268);
|
||||
$setup(SLOAD, posedge CLK, 268);
|
||||
$setup(SDATA, posedge CLK, 268);
|
||||
|
||||
if (ACLR === 1'b0) (ACLR => Q) = 0;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
initial begin
|
||||
// Altera flops initialise to zero.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// The MLAB
|
||||
// --------
|
||||
// In addition to Logic Array Blocks (LABs) that contain ten Adaptive Logic
|
||||
// Modules (ALMs, see alm_sim.v), the Cyclone V/10GX also contain
|
||||
// Modules (ALMs, see alm_sim.v), the Cyclone V also contains
|
||||
// Memory/Logic Array Blocks (MLABs) that can act as either ten ALMs, or utilise
|
||||
// the memory the ALM uses to store the look-up table data for general usage,
|
||||
// producing a 32 address by 20-bit block of memory. MLABs are spread out
|
||||
|
|
@ -14,11 +14,8 @@
|
|||
// or shift registers (by using the output of the Nth bit as input for the N+1th
|
||||
// bit).
|
||||
//
|
||||
// Oddly, instead of providing a block 32 address by 20-bit cell, Quartus asks
|
||||
// synthesis tools to build MLABs out of 32 address by 1-bit cells, and tries
|
||||
// to put these cells in the same MLAB during cell placement. Because of this
|
||||
// a MISTRAL_MLAB cell represents one of these 32 address by 1-bit cells, and
|
||||
// 20 of them represent a physical MLAB.
|
||||
// For historical reasons a MISTRAL_MLAB cell represents a 32 address by 1-bit cell,
|
||||
// and 20 of them represent a physical MLAB.
|
||||
//
|
||||
// How the MLAB works
|
||||
// ------------------
|
||||
|
|
@ -28,10 +25,7 @@
|
|||
// by the Yosys `memory_bram` pass, and it doesn't make sense to me to use
|
||||
// `techmap` just for the sake of renaming the cell ports.
|
||||
//
|
||||
// The MLAB can be initialised to any value, but unfortunately Quartus only
|
||||
// allows memory initialisation from a file. Since Yosys doesn't preserve input
|
||||
// file information, or write the contents of an `initial` block to a file,
|
||||
// Yosys can't currently initialise the MLAB in a way Quartus will accept.
|
||||
// The MLAB can be initialised to any value.
|
||||
//
|
||||
// The MLAB takes in data from A1DATA at the rising edge of CLK1, and if A1EN
|
||||
// is high, writes it to the address in A1ADDR. A1EN can therefore be used to
|
||||
|
|
@ -39,9 +33,7 @@
|
|||
//
|
||||
// Simultaneously, the MLAB reads data from B1ADDR, and outputs it to B1DATA,
|
||||
// asynchronous to CLK1 and ignoring A1EN. If a synchronous read is needed
|
||||
// then the output can be fed to embedded flops. Presently, Yosys assumes
|
||||
// Quartus will pack external flops into the MLAB, but this is an assumption
|
||||
// that needs testing.
|
||||
// then the output can be fed to embedded flops.
|
||||
|
||||
// The vendor sim model outputs 'x for a very short period (a few
|
||||
// combinational delta cycles) after each write. This has been omitted from
|
||||
|
|
@ -69,33 +61,6 @@ specify
|
|||
(B1ADDR[4] => B1DATA) = 96;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
$setup(A1ADDR, posedge CLK1, 62);
|
||||
$setup(A1DATA, posedge CLK1, 62);
|
||||
$setup(A1EN, posedge CLK1, 62);
|
||||
|
||||
(B1ADDR[0] => B1DATA) = 370;
|
||||
(B1ADDR[1] => B1DATA) = 292;
|
||||
(B1ADDR[2] => B1DATA) = 218;
|
||||
(B1ADDR[3] => B1DATA) = 74;
|
||||
(B1ADDR[4] => B1DATA) = 177;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
// TODO: Cyclone 10 GX timings; the below timings are for Cyclone V
|
||||
specify
|
||||
$setup(A1ADDR, posedge CLK1, 86);
|
||||
$setup(A1DATA, posedge CLK1, 86);
|
||||
$setup(A1EN, posedge CLK1, 86);
|
||||
|
||||
(B1ADDR[0] => B1DATA) = 487;
|
||||
(B1ADDR[1] => B1DATA) = 475;
|
||||
(B1ADDR[2] => B1DATA) = 382;
|
||||
(B1ADDR[3] => B1DATA) = 284;
|
||||
(B1ADDR[4] => B1DATA) = 96;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
always @(posedge CLK1)
|
||||
if (A1EN) mem[A1ADDR] <= A1DATA;
|
||||
|
|
@ -134,17 +99,6 @@ specify
|
|||
if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 1004;
|
||||
endspecify
|
||||
`endif
|
||||
`ifdef arriav
|
||||
specify
|
||||
$setup(A1ADDR, posedge CLK1, 97);
|
||||
$setup(A1DATA, posedge CLK1, 74);
|
||||
$setup(A1EN, posedge CLK1, 109);
|
||||
$setup(B1ADDR, posedge CLK1, 97);
|
||||
$setup(B1EN, posedge CLK1, 126);
|
||||
|
||||
if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 787;
|
||||
endspecify
|
||||
`endif
|
||||
|
||||
always @(posedge CLK1) begin
|
||||
if (!A1EN)
|
||||
|
|
|
|||
|
|
@ -1,311 +0,0 @@
|
|||
`ifdef cyclonev
|
||||
`define LCELL cyclonev_lcell_comb
|
||||
`define MAC cyclonev_mac
|
||||
`define MLAB cyclonev_mlab_cell
|
||||
`define RAM_BLOCK cyclonev_ram_block
|
||||
`define IBUF cyclonev_io_ibuf
|
||||
`define OBUF cyclonev_io_obuf
|
||||
`define CLKENA cyclonev_clkena
|
||||
`endif
|
||||
`ifdef arriav
|
||||
`define LCELL arriav_lcell_comb
|
||||
`define MAC arriav_mac
|
||||
`define MLAB arriav_mlab_cell
|
||||
`define RAM_BLOCK arriav_ram_block
|
||||
`define IBUF arriav_io_ibuf
|
||||
`define OBUF arriav_io_obuf
|
||||
`define CLKENA arriav_clkena
|
||||
`endif
|
||||
`ifdef cyclone10gx
|
||||
`define LCELL cyclone10gx_lcell_comb
|
||||
`define MAC cyclone10gx_mac
|
||||
`define MLAB cyclone10gx_mlab_cell
|
||||
`define RAM_BLOCK cyclone10gx_ram_block
|
||||
`define IBUF cyclone10gx_io_ibuf
|
||||
`define OBUF cyclone10gx_io_obuf
|
||||
`define CLKENA cyclone10gx_clkena
|
||||
`endif
|
||||
|
||||
module __MISTRAL_VCC(output Q);
|
||||
|
||||
MISTRAL_ALUT2 #(.LUT(4'b1111)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module __MISTRAL_GND(output Q);
|
||||
|
||||
MISTRAL_ALUT2 #(.LUT(4'b0000)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_FF(input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q);
|
||||
|
||||
dffeas #(.power_up("low"), .is_wysiwyg("true")) _TECHMAP_REPLACE_ (.d(DATAIN), .clk(CLK), .clrn(ACLR), .ena(ENA), .sclr(SCLR), .sload(SLOAD), .asdata(SDATA), .q(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);
|
||||
parameter [63:0] LUT = 64'h0000_0000_0000_0000;
|
||||
|
||||
`LCELL #(.lut_mask(LUT)) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .dataf(F), .combout(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_ALUT5(input A, B, C, D, E, output Q);
|
||||
parameter [31:0] LUT = 32'h0000_0000;
|
||||
|
||||
`LCELL #(.lut_mask({2{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .combout(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_ALUT4(input A, B, C, D, output Q);
|
||||
parameter [15:0] LUT = 16'h0000;
|
||||
|
||||
`LCELL #(.lut_mask({4{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .combout(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_ALUT3(input A, B, C, output Q);
|
||||
parameter [7:0] LUT = 8'h00;
|
||||
|
||||
`LCELL #(.lut_mask({8{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .combout(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_ALUT2(input A, B, output Q);
|
||||
parameter [3:0] LUT = 4'h0;
|
||||
|
||||
`LCELL #(.lut_mask({16{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .combout(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_NOT(input A, output Q);
|
||||
|
||||
NOT _TECHMAP_REPLACE_ (.IN(A), .OUT(Q));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, CI, output SO, CO);
|
||||
parameter LUT0 = 16'h0000;
|
||||
parameter LUT1 = 16'h0000;
|
||||
|
||||
`LCELL #(.lut_mask({16'h0, LUT1, 16'h0, LUT0})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D0), .dataf(D1), .cin(CI), .sumout(SO), .cout(CO));
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA);
|
||||
|
||||
parameter _TECHMAP_CELLNAME_ = "";
|
||||
|
||||
// Here we get to an unfortunate situation. The cell has a mem_init0 parameter,
|
||||
// which takes in a hexadecimal string that could be used to initialise RAM.
|
||||
// In the vendor simulation models, this appears to work fine, but Quartus,
|
||||
// either intentionally or not, forgets about this parameter and initialises the
|
||||
// RAM to zero.
|
||||
//
|
||||
// Because of this, RAM initialisation is presently disabled, but the source
|
||||
// used to generate mem_init0 is kept (commented out) in case this gets fixed
|
||||
// or an undocumented way to get Quartus to initialise from mem_init0 is found.
|
||||
|
||||
`MLAB #(
|
||||
.logical_ram_name(_TECHMAP_CELLNAME_),
|
||||
.logical_ram_depth(32),
|
||||
.logical_ram_width(1),
|
||||
.mixed_port_feed_through_mode("Dont Care"),
|
||||
.first_bit_number(0),
|
||||
.first_address(0),
|
||||
.last_address(31),
|
||||
.address_width(5),
|
||||
.data_width(1),
|
||||
.byte_enable_mask_width(1),
|
||||
.port_b_data_out_clock("NONE"),
|
||||
// .mem_init0($sformatf("%08x", INIT))
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.portaaddr(A1ADDR),
|
||||
.portadatain(A1DATA),
|
||||
.portbaddr(B1ADDR),
|
||||
.portbdataout(B1DATA),
|
||||
.ena0(A1EN),
|
||||
.clk0(CLK1)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_M10K(A1ADDR, A1DATA, A1EN, CLK1, B1ADDR, B1DATA, B1EN);
|
||||
|
||||
parameter CFG_ABITS = 10;
|
||||
parameter CFG_DBITS = 10;
|
||||
|
||||
parameter _TECHMAP_CELLNAME_ = "";
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
|
||||
input [CFG_DBITS-1:0] A1DATA;
|
||||
input CLK1, A1EN, B1EN;
|
||||
output [CFG_DBITS-1:0] B1DATA;
|
||||
|
||||
// Much like the MLAB, the M10K has mem_init[01234] parameters which would let
|
||||
// you initialise the RAM cell via hex literals. If they were implemented.
|
||||
|
||||
// Since the MISTRAL_M10K block has an inverted write-enable (like the real hardware)
|
||||
// but the Quartus primitive expects a normal write-enable, we add an inverter.
|
||||
wire A1EN_N;
|
||||
NOT wren_inv (.IN(A1EN), .OUT(A1EN_N));
|
||||
|
||||
`RAM_BLOCK #(
|
||||
.operation_mode("dual_port"),
|
||||
.logical_ram_name(_TECHMAP_CELLNAME_),
|
||||
.port_a_address_width(CFG_ABITS),
|
||||
.port_a_data_width(CFG_DBITS),
|
||||
.port_a_logical_ram_depth(2**CFG_ABITS),
|
||||
.port_a_logical_ram_width(CFG_DBITS),
|
||||
.port_a_first_address(0),
|
||||
.port_a_last_address(2**CFG_ABITS - 1),
|
||||
.port_a_first_bit_number(0),
|
||||
.port_b_address_width(CFG_ABITS),
|
||||
.port_b_data_width(CFG_DBITS),
|
||||
.port_b_logical_ram_depth(2**CFG_ABITS),
|
||||
.port_b_logical_ram_width(CFG_DBITS),
|
||||
.port_b_first_address(0),
|
||||
.port_b_last_address(2**CFG_ABITS - 1),
|
||||
.port_b_first_bit_number(0),
|
||||
.port_b_address_clock("clock0"),
|
||||
.port_b_read_enable_clock("clock0")
|
||||
) ram_block (
|
||||
.portaaddr(A1ADDR),
|
||||
.portadatain(A1DATA),
|
||||
.portawe(A1EN_N),
|
||||
.portbaddr(B1ADDR),
|
||||
.portbdataout(B1DATA),
|
||||
.portbre(B1EN),
|
||||
.clk0(CLK1)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_MUL27X27(input [26:0] A, B, output [53:0] Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
`MAC #(
|
||||
.ax_width(27),
|
||||
.signed_max(A_SIGNED ? "true" : "false"),
|
||||
.ay_scan_in_width(27),
|
||||
.signed_may(B_SIGNED ? "true" : "false"),
|
||||
.result_a_width(54),
|
||||
.operation_mode("M27x27")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ax(A),
|
||||
.ay(B),
|
||||
.resulta(Y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_MUL18X18(input [17:0] A, B, output [35:0] Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
`MAC #(
|
||||
.ax_width(18),
|
||||
.signed_max(A_SIGNED ? "true" : "false"),
|
||||
.ay_scan_in_width(18),
|
||||
.signed_may(B_SIGNED ? "true" : "false"),
|
||||
.result_a_width(36),
|
||||
.operation_mode("M18x18_FULL")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ax(A),
|
||||
.ay(B),
|
||||
.resulta(Y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module MISTRAL_MUL9X9(input [8:0] A, B, output [17:0] Y);
|
||||
|
||||
parameter A_SIGNED = 1;
|
||||
parameter B_SIGNED = 1;
|
||||
|
||||
`MAC #(
|
||||
.ax_width(9),
|
||||
.signed_max(A_SIGNED ? "true" : "false"),
|
||||
.ay_scan_in_width(9),
|
||||
.signed_may(B_SIGNED ? "true" : "false"),
|
||||
.result_a_width(18),
|
||||
.operation_mode("M9x9")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ax(A),
|
||||
.ay(B),
|
||||
.resulta(Y)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
module MISTRAL_IB(input PAD, output O);
|
||||
`IBUF #(
|
||||
.bus_hold("false"),
|
||||
.differential_mode("false")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.i(PAD),
|
||||
.o(O)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module MISTRAL_OB(output PAD, input I, OE);
|
||||
`OBUF #(
|
||||
.bus_hold("false"),
|
||||
.differential_mode("false")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.i(I),
|
||||
.o(PAD),
|
||||
.oe(OE)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module MISTRAL_IO(output PAD, input I, OE, output O);
|
||||
`IBUF #(
|
||||
.bus_hold("false"),
|
||||
.differential_mode("false")
|
||||
) ibuf (
|
||||
.i(PAD),
|
||||
.o(O)
|
||||
);
|
||||
|
||||
`OBUF #(
|
||||
.bus_hold("false"),
|
||||
.differential_mode("false")
|
||||
) obuf (
|
||||
.i(I),
|
||||
.o(PAD),
|
||||
.oe(OE)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module MISTRAL_CLKBUF (input A, output Q);
|
||||
`CLKENA #(
|
||||
.clock_type("auto"),
|
||||
.ena_register_mode("always enabled"),
|
||||
.ena_register_power_up("high"),
|
||||
.disable_mode("low"),
|
||||
.test_syn("high")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.inclk(A),
|
||||
.ena(1'b1),
|
||||
.outclk(Q)
|
||||
);
|
||||
endmodule
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* Copyright (C) 2019 Dan Ravensloft <dan.ravensloft@gmail.com>
|
||||
* Copyright (C) 2019 Hannah Ravensloft <dan.ravensloft@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -43,21 +43,11 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
log(" -family <family>\n");
|
||||
log(" target one of:\n");
|
||||
log(" \"cyclonev\" - Cyclone V (default)\n");
|
||||
log(" \"arriav\" - Arria V (non-GZ)\n");
|
||||
log(" \"cyclone10gx\" - Cyclone 10GX\n");
|
||||
log("\n");
|
||||
log(" -vqm <file>\n");
|
||||
log(" write the design to the specified Verilog Quartus Mapping File. Writing\n");
|
||||
log(" of an output file is omitted if this parameter is not specified. Implies\n");
|
||||
log(" -quartus.\n");
|
||||
log("\n");
|
||||
log(" -noflatten\n");
|
||||
log(" do not flatten design before synthesis; useful for per-module area\n");
|
||||
log(" statistics\n");
|
||||
log("\n");
|
||||
log(" -quartus\n");
|
||||
log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n");
|
||||
log("\n");
|
||||
log(" -dff\n");
|
||||
log(" pass DFFs to ABC to perform sequential logic optimisations\n");
|
||||
log(" (EXPERIMENTAL)\n");
|
||||
|
|
@ -87,17 +77,15 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
log("\n");
|
||||
}
|
||||
|
||||
string top_opt, family_opt, bram_type, vout_file;
|
||||
bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad, noclkbuf;
|
||||
string top_opt, family_opt, bram_type;
|
||||
bool flatten, nolutram, nobram, dff, nodsp, noiopad, noclkbuf;
|
||||
|
||||
void clear_flags() override
|
||||
{
|
||||
top_opt = "-auto-top";
|
||||
family_opt = "cyclonev";
|
||||
bram_type = "m10k";
|
||||
vout_file = "";
|
||||
flatten = true;
|
||||
quartus = false;
|
||||
nolutram = false;
|
||||
nobram = false;
|
||||
dff = false;
|
||||
|
|
@ -121,11 +109,6 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
top_opt = "-top " + args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-vqm" && argidx + 1 < args.size()) {
|
||||
quartus = true;
|
||||
vout_file = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-run" && argidx + 1 < args.size()) {
|
||||
size_t pos = args[argidx + 1].find(':');
|
||||
if (pos == std::string::npos)
|
||||
|
|
@ -134,10 +117,6 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
run_to = args[argidx].substr(pos + 1);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-quartus") {
|
||||
quartus = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nolutram") {
|
||||
nolutram = true;
|
||||
continue;
|
||||
|
|
@ -173,18 +152,6 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
if (!design->full_selection())
|
||||
log_cmd_error("This command only operates on fully selected designs!\n");
|
||||
|
||||
if (family_opt == "cyclonev" || family_opt == "arriav") {
|
||||
bram_type = "m10k";
|
||||
} else if (family_opt == "cyclone10gx") {
|
||||
bram_type = "m20k";
|
||||
} else if (family_opt == "arriva") {
|
||||
// I have typoed "arriav" as "arriva" (a local bus company)
|
||||
// so many times I thought it would be funny to have an easter egg.
|
||||
log_cmd_error("synth_intel_alm cannot synthesize for bus companies. (did you mean '-family arriav'?)\n");
|
||||
} else {
|
||||
log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str());
|
||||
}
|
||||
|
||||
log_header(design, "Executing SYNTH_INTEL_ALM pass.\n");
|
||||
log_push();
|
||||
|
||||
|
|
@ -237,22 +204,16 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
if (help_mode) {
|
||||
run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)");
|
||||
} else if (!nodsp) {
|
||||
// Cyclone V/Arria V supports 9x9 multiplication, Cyclone 10 GX does not.
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL27X27");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=19 -D DSP_NAME=__MUL27X27");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
if (family_opt == "cyclonev" || family_opt == "arriav") {
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL9X9");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
} else if (family_opt == "cyclone10gx") {
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
}
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL9X9");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
}
|
||||
run("alumacc");
|
||||
if (!noiopad)
|
||||
|
|
@ -269,7 +230,7 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
}
|
||||
|
||||
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) {
|
||||
run("memory_bram -rules +/intel_alm/common/lutram_mlab.txt", "(for Cyclone V / Cyclone 10GX)");
|
||||
run("memory_bram -rules +/intel_alm/common/lutram_mlab.txt", "(for Cyclone V)");
|
||||
}
|
||||
|
||||
if (check_label("map_ffram")) {
|
||||
|
|
@ -303,28 +264,6 @@ struct SynthIntelALMPass : public ScriptPass {
|
|||
run("check");
|
||||
run("blackbox =A:whitebox");
|
||||
}
|
||||
|
||||
if (check_label("quartus")) {
|
||||
if (quartus || help_mode) {
|
||||
// Quartus ICEs if you have a wire which has `[]` in its name,
|
||||
// which Yosys produces when building memories out of flops.
|
||||
run("rename -hide w:*[* w:*]*");
|
||||
// VQM mode does not support 'x, so replace those with zero.
|
||||
run("setundef -zero");
|
||||
// VQM mode does not support multi-bit constant assignments
|
||||
// (e.g. 2'b00 is an error), so as a workaround use references
|
||||
// to constant driver cells, which Quartus accepts.
|
||||
run("hilomap -singleton -hicell __MISTRAL_VCC Q -locell __MISTRAL_GND Q");
|
||||
// Rename from Yosys-internal MISTRAL_* cells to Quartus cells.
|
||||
run(stringf("techmap -D %s -map +/intel_alm/common/quartus_rename.v", family_opt.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("vqm")) {
|
||||
if (!vout_file.empty() || help_mode) {
|
||||
run(stringf("write_verilog -attr2comment -defparam -nohex -decimal %s", help_mode ? "<file-name>" : vout_file.c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} SynthIntelALMPass;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,3 @@ stat
|
|||
select -assert-count 9 t:MISTRAL_ALUT_ARITH
|
||||
select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/add_sub.v
|
||||
hierarchy -top top
|
||||
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
stat
|
||||
select -assert-count 9 t:MISTRAL_ALUT_ARITH
|
||||
select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D
|
||||
|
|
|
|||
|
|
@ -12,18 +12,6 @@ select -assert-count 1 t:MISTRAL_NOT
|
|||
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top adff
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd adff # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
select -assert-count 1 t:MISTRAL_NOT
|
||||
|
||||
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top adffn
|
||||
proc
|
||||
|
|
@ -35,17 +23,6 @@ select -assert-count 1 t:MISTRAL_FF
|
|||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top adffn
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd adffn # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top dffs
|
||||
proc
|
||||
|
|
@ -58,18 +35,6 @@ select -assert-count 1 t:MISTRAL_ALUT2
|
|||
select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top dffs
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dffs # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
select -assert-count 1 t:MISTRAL_ALUT2
|
||||
|
||||
select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top ndffnr
|
||||
proc
|
||||
|
|
@ -81,14 +46,3 @@ select -assert-count 2 t:MISTRAL_NOT
|
|||
|
||||
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top ndffnr
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd ndffnr # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
select -assert-count 2 t:MISTRAL_NOT
|
||||
|
||||
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ cd sync_ram_sdp
|
|||
select -assert-count 1 t:MISTRAL_NOT
|
||||
select -assert-count 1 t:MISTRAL_M10K
|
||||
select -assert-none t:MISTRAL_NOT t:MISTRAL_M10K %% t:* %D
|
||||
|
||||
|
|
|
|||
|
|
@ -11,17 +11,3 @@ select -assert-count 8 t:MISTRAL_ALUT_ARITH
|
|||
select -assert-count 8 t:MISTRAL_FF
|
||||
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D
|
||||
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/counter.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
flatten
|
||||
equiv_opt -assert -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 2 t:MISTRAL_NOT
|
||||
select -assert-count 8 t:MISTRAL_ALUT_ARITH
|
||||
select -assert-count 8 t:MISTRAL_FF
|
||||
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D
|
||||
|
|
|
|||
|
|
@ -7,17 +7,6 @@ equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm
|
|||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dff # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top dff
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dff # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
||||
|
||||
|
|
@ -28,16 +17,5 @@ equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm
|
|||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dffe # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top dffe
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd dffe # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_FF
|
||||
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
|
|
|||
|
|
@ -20,25 +20,3 @@ select -assert-max 6 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4
|
|||
select -assert-max 2 t:MISTRAL_ALUT6 # Clang returns 1, GCC returns 2
|
||||
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/fsm.v
|
||||
hierarchy -top fsm
|
||||
proc
|
||||
flatten
|
||||
|
||||
equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf
|
||||
async2sync
|
||||
miter -equiv -make_assert -flatten gold gate miter
|
||||
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
|
||||
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd fsm # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 6 t:MISTRAL_FF
|
||||
select -assert-max 1 t:MISTRAL_NOT
|
||||
select -assert-max 2 t:MISTRAL_ALUT2 # Clang returns 2, GCC returns 1
|
||||
select -assert-max 2 t:MISTRAL_ALUT3 # Clang returns 2, GCC returns 1
|
||||
select -assert-max 2 t:MISTRAL_ALUT4 # Clang returns 0, GCC returns 1
|
||||
select -assert-max 6 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4
|
||||
select -assert-max 2 t:MISTRAL_ALUT6 # Clang returns 1, GCC returns 2
|
||||
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
|
|
|||
|
|
@ -10,16 +10,3 @@ select -assert-count 6 t:MISTRAL_ALUT2
|
|||
select -assert-count 2 t:MISTRAL_ALUT4
|
||||
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
|
||||
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/logic.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:MISTRAL_NOT
|
||||
select -assert-count 6 t:MISTRAL_ALUT2
|
||||
select -assert-count 2 t:MISTRAL_ALUT4
|
||||
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
|
||||
|
|
@ -37,3 +37,4 @@ select -assert-count 2 t:MISTRAL_ALUT2
|
|||
select -assert-count 8 t:MISTRAL_ALUT3
|
||||
select -assert-count 8 t:MISTRAL_FF
|
||||
select -assert-none t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ cd top # Constrain all select calls below inside the top module
|
|||
select -assert-count 1 t:MISTRAL_MUL9X9
|
||||
select -assert-none t:MISTRAL_MUL9X9 %% t:* %D
|
||||
|
||||
# Cyclone 10 GX does not have 9x9 multipliers.
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34
|
||||
|
|
@ -23,18 +21,6 @@ cd top # Constrain all select calls below inside the top module
|
|||
select -assert-count 1 t:MISTRAL_MUL18X18
|
||||
select -assert-none t:MISTRAL_MUL18X18 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:MISTRAL_MUL18X18
|
||||
select -assert-none t:MISTRAL_MUL18X18 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52
|
||||
|
|
@ -47,14 +33,3 @@ cd top # Constrain all select calls below inside the top module
|
|||
select -assert-count 1 t:MISTRAL_MUL27X27
|
||||
select -assert-none t:MISTRAL_MUL27X27 %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/mul.v
|
||||
chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
|
||||
select -assert-count 1 t:MISTRAL_MUL27X27
|
||||
select -assert-none t:MISTRAL_MUL27X27 %% t:* %D
|
||||
|
|
|
|||
|
|
@ -11,16 +11,6 @@ select -assert-count 1 t:MISTRAL_ALUT3
|
|||
select -assert-none t:MISTRAL_ALUT3 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux2
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux2 # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_ALUT3
|
||||
select -assert-none t:MISTRAL_ALUT3 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux4
|
||||
proc
|
||||
|
|
@ -31,16 +21,6 @@ select -assert-count 1 t:MISTRAL_ALUT6
|
|||
select -assert-none t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux4
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux4 # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_ALUT6
|
||||
select -assert-none t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux8
|
||||
proc
|
||||
|
|
@ -52,17 +32,6 @@ select -assert-count 2 t:MISTRAL_ALUT6
|
|||
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux8
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux8 # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:MISTRAL_ALUT3
|
||||
select -assert-count 2 t:MISTRAL_ALUT6
|
||||
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux16
|
||||
proc
|
||||
|
|
@ -74,15 +43,3 @@ select -assert-max 2 t:MISTRAL_ALUT5
|
|||
select -assert-max 5 t:MISTRAL_ALUT6
|
||||
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux16
|
||||
proc
|
||||
equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux16 # Constrain all select calls below inside the top module
|
||||
select -assert-max 1 t:MISTRAL_ALUT3
|
||||
select -assert-max 2 t:MISTRAL_ALUT5
|
||||
select -assert-max 5 t:MISTRAL_ALUT6
|
||||
|
||||
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
read_verilog <<EOT
|
||||
// Verilog has syntax for raw identifiers, where you start it with \ and end it with a space.
|
||||
// This test crashes Quartus due to it parsing \a[10] as a wire slice and not a raw identifier.
|
||||
module top();
|
||||
(* keep *) wire [31:0] \a[10] ;
|
||||
(* keep *) wire b;
|
||||
assign b = \a[10] [31];
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
synth_intel_alm -family cyclonev -quartus
|
||||
select -assert-none w:*[* w:*]*
|
||||
|
||||
design -reset
|
||||
read_verilog <<EOT
|
||||
// Verilog has syntax for raw identifiers, where you start it with \ and end it with a space.
|
||||
// This test crashes Quartus due to it parsing \a[10] as a wire slice and not a raw identifier.
|
||||
module top();
|
||||
(* keep *) wire [31:0] \a[10] ;
|
||||
(* keep *) wire b;
|
||||
assign b = \a[10] [31];
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
synth_intel_alm -family cyclone10gx -quartus -noiopad -noclkbuf
|
||||
select -assert-none w:*[* w:*]*
|
||||
|
|
@ -8,14 +8,3 @@ cd top # Constrain all select calls below inside the top module
|
|||
select -assert-count 8 t:MISTRAL_FF
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/shifter.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
flatten
|
||||
equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd top # Constrain all select calls below inside the top module
|
||||
select -assert-count 8 t:MISTRAL_FF
|
||||
select -assert-none t:MISTRAL_FF %% t:* %D
|
||||
|
|
|
|||
|
|
@ -11,17 +11,3 @@ cd tristate # Constrain all select calls below inside the top module
|
|||
select -assert-count 1 t:$_TBUF_
|
||||
select -assert-none t:$_TBUF_ %% t:* %D
|
||||
|
||||
|
||||
design -reset
|
||||
read_verilog ../common/tribuf.v
|
||||
hierarchy -top tristate
|
||||
proc
|
||||
tribuf
|
||||
flatten
|
||||
synth
|
||||
equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd tristate # Constrain all select calls below inside the top module
|
||||
#Internal cell type used. Need support it.
|
||||
select -assert-count 1 t:$_TBUF_
|
||||
select -assert-none t:$_TBUF_ %% t:* %D
|
||||
|
|
|
|||
53
tests/various/box_derive.ys
Normal file
53
tests/various/box_derive.ys
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
read_verilog <<EOF
|
||||
(* whitebox *)
|
||||
(* final_name=$sformatf("aa%d", X) *)
|
||||
module aa(input wire d, output wire q);
|
||||
parameter [1:0] X = 0;
|
||||
assign q = X[d];
|
||||
endmodule
|
||||
|
||||
(* whitebox *)
|
||||
(* final_name=$sformatf("bb%d", X) *)
|
||||
module bb(input wire d, output wire q);
|
||||
parameter [1:0] X = 0;
|
||||
assign q = X[~d];
|
||||
endmodule
|
||||
|
||||
(* whitebox *)
|
||||
(* final_name=$sformatf("cc%d", X) *)
|
||||
module cc(input wire d, output wire q);
|
||||
parameter [1:0] X = 0;
|
||||
assign q = ~X[d];
|
||||
endmodule
|
||||
|
||||
module top;
|
||||
wire d, q1, q2, q3, q3, q4, q5, q6;
|
||||
|
||||
aa #(.X(1)) aa1(.d(d), .q(q1));
|
||||
aa #(.X(2)) aa2(.d(d), .q(q2));
|
||||
|
||||
bb #(.X(1)) bb1(.d(d), .q(q3));
|
||||
bb #(.X(3)) bb2(.d(d), .q(q4));
|
||||
|
||||
cc #(.X(1)) cc1(.d(d), .q(q5));
|
||||
cc #(.X(1)) cc2(.d(d), .q(q6));
|
||||
endmodule
|
||||
EOF
|
||||
|
||||
box_derive -naming_attr final_name top
|
||||
|
||||
select -assert-mod-count 1 =aa1
|
||||
select -assert-mod-count 1 =aa2
|
||||
select -assert-mod-count 0 =aa3
|
||||
|
||||
select -assert-mod-count 1 =bb1
|
||||
select -assert-mod-count 0 =bb2
|
||||
select -assert-mod-count 1 =bb3
|
||||
|
||||
select -assert-mod-count 1 =cc1
|
||||
select -assert-mod-count 0 =cc2
|
||||
select -assert-mod-count 0 =cc3
|
||||
|
||||
# we are expecting the original aa, bb, cc modules
|
||||
# and 5 specializations generated by box_derive
|
||||
select -assert-mod-count 8 =A:whitebox
|
||||
Loading…
Add table
Add a link
Reference in a new issue