mirror of
https://github.com/YosysHQ/yosys
synced 2026-06-26 10:38:47 +00:00
commit
e794961432
112 changed files with 17726 additions and 452 deletions
8
.github/workflows/extra-builds.yml
vendored
8
.github/workflows/extra-builds.yml
vendored
|
|
@ -86,7 +86,11 @@ jobs:
|
|||
name: "Build nix flake"
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
|
@ -94,4 +98,4 @@ jobs:
|
|||
- uses: cachix/install-nix-action@v26
|
||||
with:
|
||||
install_url: https://releases.nixos.org/nix/nix-2.18.1/install
|
||||
- run: nix build .?submodules=1
|
||||
- run: nix build .?submodules=1 -L
|
||||
|
|
|
|||
52
.github/workflows/prepare-docs.yml
vendored
Normal file
52
.github/workflows/prepare-docs.yml
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
name: Build docs artifact with Verific
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
prepare-docs:
|
||||
# docs builds are needed for anything on main, any tagged versions, and any tag
|
||||
# or branch starting with docs-preview
|
||||
if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/docs-preview') || startsWith(github.ref, 'refs/tags/') }}
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: true
|
||||
|
||||
- name: Runtime environment
|
||||
run: |
|
||||
echo "procs=$(nproc)" >> $GITHUB_ENV
|
||||
|
||||
- name: Build Yosys
|
||||
run: |
|
||||
make config-clang
|
||||
echo "ENABLE_VERIFIC := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_EDIF := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_LIBERTY := 1" >> Makefile.conf
|
||||
echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
make -j${{ env.procs }} ENABLE_LTO=1
|
||||
|
||||
- name: Prepare docs
|
||||
shell: bash
|
||||
run:
|
||||
make docs/prep TARGETS= EXTRA_TARGETS=
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cmd-ref-${{ github.sha }}
|
||||
path: |
|
||||
docs/source/cmd
|
||||
docs/source/generated
|
||||
docs/source/_images
|
||||
docs/source/code_examples
|
||||
|
||||
- name: Trigger RTDs build
|
||||
uses: dfm/rtds-action@v1.1.0
|
||||
with:
|
||||
webhook_url: ${{ secrets.RTDS_WEBHOOK_URL }}
|
||||
webhook_token: ${{ secrets.RTDS_WEBHOOK_TOKEN }}
|
||||
commit_ref: ${{ github.ref }}
|
||||
4
.github/workflows/test-compile.yml
vendored
4
.github/workflows/test-compile.yml
vendored
|
|
@ -40,8 +40,8 @@ jobs:
|
|||
- os: macos-13
|
||||
compiler: 'clang'
|
||||
# oldest clang not available on ubuntu-latest
|
||||
- os: ubuntu-22.04
|
||||
compiler: 'clang-11'
|
||||
- os: ubuntu-20.04
|
||||
compiler: 'clang-10'
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
|
|
|
|||
38
.github/workflows/test-verific.yml
vendored
38
.github/workflows/test-verific.yml
vendored
|
|
@ -3,7 +3,7 @@ name: Build and run tests with Verific (Linux)
|
|||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
pre-job:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
||||
|
|
@ -11,18 +11,16 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
paths_ignore: '["**/README.md"]'
|
||||
# don't cancel previous builds
|
||||
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'
|
||||
# we have special actions when running on main, so this should be off
|
||||
skip_after_successful_duplicate: 'false'
|
||||
|
||||
test-verific:
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
needs: pre-job
|
||||
if: needs.pre-job.outputs.should_skip != 'true'
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
steps:
|
||||
- name: Checkout Yosys
|
||||
uses: actions/checkout@v4
|
||||
|
|
@ -47,30 +45,6 @@ jobs:
|
|||
run: |
|
||||
make install DESTDIR=${GITHUB_WORKSPACE}/.local PREFIX=
|
||||
|
||||
- name: Checkout Documentation
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'yosys-cmd-ref'
|
||||
repository: 'YosysHQ-Docs/yosys-cmd-ref'
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.CI_DOCS_UPDATE_PAT }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Update documentation
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
run: |
|
||||
make docs
|
||||
rm -rf docs/build
|
||||
cd yosys-cmd-ref
|
||||
rm -rf *
|
||||
git checkout README.md
|
||||
cp -R ../docs/* .
|
||||
rm -rf util/__pycache__
|
||||
git add -A .
|
||||
git diff-index --quiet HEAD || git commit -m "Update"
|
||||
git push
|
||||
|
||||
- name: Checkout SBY
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
|
|
|
|||
20
.readthedocs.yaml
Normal file
20
.readthedocs.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# .readthedocs.yaml
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: '3.12'
|
||||
|
||||
formats:
|
||||
- pdf
|
||||
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
fail_on_warning: true
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/source/requirements.txt
|
||||
10
CHANGELOG
10
CHANGELOG
|
|
@ -2,9 +2,17 @@
|
|||
List of major changes and improvements between releases
|
||||
=======================================================
|
||||
|
||||
Yosys 0.44 .. Yosys 0.45-dev
|
||||
Yosys 0.45 .. Yosys 0.46-dev
|
||||
--------------------------
|
||||
|
||||
Yosys 0.44 .. Yosys 0.45
|
||||
--------------------------
|
||||
* Various
|
||||
- Added cell types help messages.
|
||||
|
||||
* New back-ends
|
||||
- Added initial NG-Ultra support. ( synth_nanoxplore )
|
||||
|
||||
Yosys 0.43 .. Yosys 0.44
|
||||
--------------------------
|
||||
* Various
|
||||
|
|
|
|||
20
Makefile
20
Makefile
|
|
@ -153,7 +153,7 @@ ifeq ($(OS), Haiku)
|
|||
CXXFLAGS += -D_DEFAULT_SOURCE
|
||||
endif
|
||||
|
||||
YOSYS_VER := 0.44+0
|
||||
YOSYS_VER := 0.45+0
|
||||
|
||||
# Note: We arrange for .gitcommit to contain the (short) commit hash in
|
||||
# tarballs generated with git-archive(1) using .gitattributes. The git repo
|
||||
|
|
@ -169,7 +169,7 @@ endif
|
|||
OBJS = kernel/version_$(GIT_REV).o
|
||||
|
||||
bumpversion:
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 80ba43d.. | wc -l`/;" Makefile
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9ed031d.. | wc -l`/;" Makefile
|
||||
|
||||
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
|
||||
|
||||
|
|
@ -807,7 +807,7 @@ check-git-abc:
|
|||
exit 1; \
|
||||
fi
|
||||
|
||||
abc/abc$(EXE) abc/libabc.a: 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)
|
||||
|
||||
|
|
@ -877,6 +877,7 @@ endif
|
|||
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/nanoxplore && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/nexus && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/quicklogic/pp3 && bash run-test.sh $(SEEDOPT)
|
||||
+cd tests/arch/quicklogic/qlf_k6n10f && bash run-test.sh $(SEEDOPT)
|
||||
|
|
@ -984,8 +985,8 @@ docs/guidelines docs/source/generated:
|
|||
|
||||
# some commands return an error and print the usage text to stderr
|
||||
define DOC_USAGE_STDERR
|
||||
docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated
|
||||
-$(Q) ./$$< --help 2> $$@
|
||||
docs/source/generated/$(1): $(TARGETS) docs/source/generated
|
||||
-$(Q) ./$(PROGRAM_PREFIX)$(1) --help 2> $$@
|
||||
endef
|
||||
DOCS_USAGE_STDERR := yosys-config yosys-filterlib
|
||||
|
||||
|
|
@ -998,8 +999,8 @@ $(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage))))
|
|||
|
||||
# others print to stdout
|
||||
define DOC_USAGE_STDOUT
|
||||
docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated
|
||||
$(Q) ./$$< --help > $$@
|
||||
docs/source/generated/$(1): $(TARGETS) docs/source/generated
|
||||
$(Q) ./$(PROGRAM_PREFIX)$(1) --help > $$@
|
||||
endef
|
||||
DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness
|
||||
$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage))))
|
||||
|
|
@ -1009,8 +1010,11 @@ docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE
|
|||
docs/reqs:
|
||||
$(Q) $(MAKE) -C docs reqs
|
||||
|
||||
.PHONY: docs/prep
|
||||
docs/prep: docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage
|
||||
|
||||
DOC_TARGET ?= html
|
||||
docs: docs/source/cmd/abc.rst docs/gen_examples docs/gen_images docs/guidelines docs/usage docs/reqs
|
||||
docs: docs/prep
|
||||
$(Q) $(MAKE) -C docs $(DOC_TARGET)
|
||||
|
||||
clean:
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -629,11 +629,21 @@ following are used for building the website:
|
|||
|
||||
$ sudo apt install pdf2svg faketime
|
||||
|
||||
Or for MacOS, using homebrew:
|
||||
|
||||
$ brew install pdf2svg libfaketime
|
||||
|
||||
PDFLaTeX, included with most LaTeX distributions, is also needed during the
|
||||
build process for the website. Or, run the following:
|
||||
|
||||
$ sudo apt install texlive-latex-base texlive-latex-extra latexmk
|
||||
|
||||
Or for MacOS, using homebrew:
|
||||
|
||||
$ brew install basictex
|
||||
$ sudo tlmgr update --self
|
||||
$ sudo tlmgr install collection-latexextra latexmk tex-gyre
|
||||
|
||||
The Python package, Sphinx, is needed along with those listed in
|
||||
`docs/source/requirements.txt`:
|
||||
|
||||
|
|
|
|||
2
abc
2
abc
|
|
@ -1 +1 @@
|
|||
Subproject commit 28d955ca97a1c4be3aed4062aec0241a734fac5d
|
||||
Subproject commit 2188bc71228b0788569d83ad2b7e7b91ca5dcc09
|
||||
|
|
@ -51,6 +51,9 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi
|
|||
}
|
||||
}
|
||||
f << stringf("%d'", width);
|
||||
if (data.flags & RTLIL::CONST_FLAG_SIGNED) {
|
||||
f << stringf("s");
|
||||
}
|
||||
if (data.is_fully_undef_x_only()) {
|
||||
f << "x";
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ test-macros:
|
|||
.PHONY: images
|
||||
images:
|
||||
$(MAKE) -C source/_images
|
||||
$(MAKE) -C source/_images convert
|
||||
|
||||
.PHONY: reqs
|
||||
reqs:
|
||||
|
|
|
|||
|
|
@ -8,24 +8,22 @@ FAKETIME := TZ='Z' faketime -f '2022-01-01 00:00:00 x0,001'
|
|||
CODE_EXAMPLES := ../code_examples/*/Makefile
|
||||
examples: $(CODE_EXAMPLES)
|
||||
|
||||
# target to convert specified dot file(s)
|
||||
# target to convert all dot files
|
||||
# needs to be run *after* examples, otherwise no dot files will be found
|
||||
.PHONY: convert
|
||||
TARG_DOT ?=
|
||||
convert: $(TARG_DOT:.dot=.pdf) $(TARG_DOT:.dot=.svg)
|
||||
DOT_FILES := $(shell find . -name *.dot)
|
||||
convert: $(DOT_FILES:.dot=.pdf) $(DOT_FILES:.dot=.svg)
|
||||
|
||||
# use empty FORCE target because .PHONY ignores % expansion, using find allows
|
||||
# us to generate everything in one pass, since we don't know all of the possible
|
||||
# outputs until the sub-makes run
|
||||
# use empty FORCE target because .PHONY ignores % expansion
|
||||
FORCE:
|
||||
../%/Makefile: FORCE
|
||||
@make -C $(@D) dots
|
||||
@mkdir -p $*
|
||||
@find $(@D) -name *.dot -exec cp -u {} -t $* \;
|
||||
@find $* -name *.dot -printf "%p " | xargs -i make --no-print-directory convert TARG_DOT="{}"
|
||||
@find $(@D) -name *.dot -exec rsync -t {} $* \;
|
||||
|
||||
# find and build all tex files
|
||||
.PHONY: all_tex
|
||||
TEX_FILES := $(wildcard **/*.tex)
|
||||
TEX_FILES := $(shell find . -name *.tex)
|
||||
all_tex: $(TEX_FILES:.tex=.pdf) $(TEX_FILES:.tex=.svg)
|
||||
|
||||
%.pdf: %.dot
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ dots: $(DOTS)
|
|||
$(YOSYS) $<
|
||||
|
||||
%.dot: %_full.dot
|
||||
gvpack -u $*_full.dot -o $@
|
||||
gvpack -u -o $@ $*_full.dot
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
TARGETS += proc_01 proc_02 proc_03
|
||||
TARGETS += memory_01 memory_02
|
||||
TARGETS += techmap_01
|
||||
DOT_TARGETS += proc_01 proc_02 proc_03
|
||||
DOT_TARGETS += memory_01 memory_02
|
||||
DOT_TARGETS += techmap_01
|
||||
|
||||
PROGRAM_PREFIX :=
|
||||
|
||||
YOSYS ?= ../../../../$(PROGRAM_PREFIX)yosys
|
||||
|
||||
DOTS = $(addsuffix .dot,$(TARGETS))
|
||||
DOTS = $(addsuffix .dot,$(DOT_TARGETS))
|
||||
|
||||
.PHONY: all dots
|
||||
all: dots
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import os
|
|||
project = 'YosysHQ Yosys'
|
||||
author = 'YosysHQ GmbH'
|
||||
copyright ='2024 YosysHQ GmbH'
|
||||
yosys_ver = "0.44"
|
||||
yosys_ver = "0.45"
|
||||
|
||||
# select HTML theme
|
||||
html_theme = 'furo'
|
||||
|
|
@ -43,15 +43,42 @@ highlight_language = 'none'
|
|||
|
||||
extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex']
|
||||
|
||||
if os.getenv("READTHEDOCS"):
|
||||
# Use rtds_action if we are building on read the docs and have a github token env var
|
||||
if os.getenv("GITHUB_TOKEN"):
|
||||
extensions += ['rtds_action']
|
||||
rtds_action_github_repo = "YosysHQ/yosys"
|
||||
rtds_action_path = "."
|
||||
rtds_action_artifact_prefix = "cmd-ref-"
|
||||
rtds_action_github_token = os.environ["GITHUB_TOKEN"]
|
||||
else:
|
||||
# We're on read the docs but have no github token, this is probably a PR preview build
|
||||
html_theme_options["announcement"] = 'Missing content? Check <a class="reference internal" href="https://tyrtd--2.org.readthedocs.build/en/2/appendix/building_docs.html#pr-previews-and-limitations">PR preview limitations</a>.'
|
||||
html_theme_options["light_css_variables"]["color-announcement-background"] = "var(--color-admonition-title-background--caution)"
|
||||
html_theme_options["light_css_variables"]["color-announcement-text"] = "var(--color-content-foreground)"
|
||||
|
||||
# Ensure that autosectionlabel will produce unique names
|
||||
autosectionlabel_prefix_document = True
|
||||
autosectionlabel_maxdepth = 1
|
||||
|
||||
# include todos for previews
|
||||
extensions.append('sphinx.ext.todo')
|
||||
|
||||
# set version
|
||||
if os.getenv("READTHEDOCS") and os.getenv("READTHEDOCS_VERSION") == "latest":
|
||||
release = yosys_ver + "-dev"
|
||||
if os.getenv("READTHEDOCS"):
|
||||
rtds_version = os.getenv("READTHEDOCS_VERSION")
|
||||
if rtds_version == "latest":
|
||||
release = yosys_ver + "-dev"
|
||||
todo_include_todos = False
|
||||
elif rtds_version.startswith("docs"):
|
||||
release = rtds_version
|
||||
todo_include_todos = True
|
||||
else:
|
||||
release = yosys_ver
|
||||
todo_include_todos = False
|
||||
else:
|
||||
release = yosys_ver
|
||||
todo_include_todos = True
|
||||
|
||||
# assign figure numbers
|
||||
numfig = True
|
||||
|
|
@ -66,10 +93,6 @@ latex_elements = {
|
|||
'''
|
||||
}
|
||||
|
||||
# include todos during rewrite
|
||||
extensions.append('sphinx.ext.todo')
|
||||
todo_include_todos = False
|
||||
|
||||
# custom cmd-ref parsing/linking
|
||||
sys.path += [os.path.dirname(__file__) + "/../"]
|
||||
extensions.append('util.cmdref')
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ To use a compiler different than the default, use:
|
|||
|
||||
.. seealso::
|
||||
|
||||
Refer to :doc:`/test_suites` for details on testing Yosys once compiled.
|
||||
Refer to :doc:`/yosys_internals/extending_yosys/test_suites` for details on
|
||||
testing Yosys once compiled.
|
||||
|
||||
Source tree and build system
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -193,7 +194,7 @@ directories:
|
|||
|
||||
``tests/``
|
||||
This directory contains the suite of unit tests and regression tests used by
|
||||
Yosys. See :doc:`/test_suites`.
|
||||
Yosys. See :doc:`/yosys_internals/extending_yosys/test_suites`.
|
||||
|
||||
The top-level Makefile includes :file:`frontends/{*}/Makefile.inc`,
|
||||
:file:`passes/{*}/Makefile.inc` and :file:`backends/{*}/Makefile.inc`. So when
|
||||
|
|
|
|||
|
|
@ -40,6 +40,5 @@ available, go to :ref:`commandindex`.
|
|||
getting_started/index
|
||||
using_yosys/index
|
||||
yosys_internals/index
|
||||
test_suites
|
||||
|
||||
appendix
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
furo
|
||||
sphinxcontrib-bibtex
|
||||
rtds-action
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ More scripting
|
|||
|
||||
.. todo:: brief overview for the more scripting index
|
||||
|
||||
.. todo:: troubleshooting document(?)
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ keyword: Frontends
|
|||
.. todo:: more info on other ``read_*`` commands, also is this the first time we
|
||||
mention verific?
|
||||
|
||||
.. note::
|
||||
|
||||
The Verific frontend for Yosys, which provides the :cmd:ref:`verific`
|
||||
command, requires Yosys to be built with Verific. For full functionality,
|
||||
custom modifications to the Verific source code from YosysHQ are required,
|
||||
but limited useability can be achieved with some stock Verific builds. Check
|
||||
:doc:`/yosys_internals/extending_yosys/build_verific` for more.
|
||||
|
||||
Others:
|
||||
|
||||
- :doc:`/cmd/read`
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
Troubleshooting
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. todo:: troubleshooting document(?)
|
||||
|
||||
See :doc:`/cmd/bugpoint`
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
The ABC toolbox
|
||||
---------------
|
||||
===============
|
||||
|
||||
.. role:: yoscrypt(code)
|
||||
:language: yoscrypt
|
||||
|
|
@ -21,7 +21,7 @@ global view of the mapping problem.
|
|||
.. _ABC: https://github.com/berkeley-abc/abc
|
||||
|
||||
ABC: the unit delay model, simple and efficient
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
-----------------------------------------------
|
||||
|
||||
The :cmd:ref:`abc` pass uses a highly simplified view of an FPGA:
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ But this approach has drawbacks, too:
|
|||
before clock edge) which affect the delay of a path.
|
||||
|
||||
ABC9: the generalised delay model, realistic and flexible
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
---------------------------------------------------------
|
||||
|
||||
ABC9 uses a more detailed and accurate model of an FPGA:
|
||||
|
||||
|
|
@ -101,3 +101,81 @@ optimise better around those boxes, and also permute inputs to give the critical
|
|||
path the fastest inputs.
|
||||
|
||||
.. todo:: more about logic minimization & register balancing et al with ABC
|
||||
|
||||
Setting up a flow for ABC9
|
||||
--------------------------
|
||||
|
||||
Much of the configuration comes from attributes and ``specify`` blocks in
|
||||
Verilog simulation models.
|
||||
|
||||
``specify`` syntax
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Since ``specify`` is a relatively obscure part of the Verilog standard, a quick
|
||||
guide to the syntax:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
specify // begins a specify block
|
||||
(A => B) = 123; // simple combinational path from A to B with a delay of 123.
|
||||
(A *> B) = 123; // simple combinational path from A to all bits of B with a delay of 123 for all.
|
||||
if (FOO) (A => B) = 123; // paths may apply under specific conditions.
|
||||
(posedge CLK => (Q : D)) = 123; // combinational path triggered on the positive edge of CLK; used for clock-to-Q arrival paths.
|
||||
$setup(A, posedge CLK, 123); // setup constraint for an input relative to a clock.
|
||||
endspecify // ends a specify block
|
||||
|
||||
By convention, all delays in ``specify`` blocks are in integer picoseconds.
|
||||
Files containing ``specify`` blocks should be read with the ``-specify`` option
|
||||
to :cmd:ref:`read_verilog` so that they aren't skipped.
|
||||
|
||||
LUTs
|
||||
^^^^
|
||||
|
||||
LUTs need to be annotated with an ``(* abc9_lut=N *)`` attribute, where ``N`` is
|
||||
the relative area of that LUT model. For example, if an architecture can combine
|
||||
LUTs to produce larger LUTs, then the combined LUTs would have increasingly
|
||||
larger ``N``. Conversely, if an architecture can split larger LUTs into smaller
|
||||
LUTs, then the smaller LUTs would have smaller ``N``.
|
||||
|
||||
LUTs are generally specified with simple combinational paths from the LUT inputs
|
||||
to the LUT output.
|
||||
|
||||
DFFs
|
||||
^^^^
|
||||
|
||||
DFFs should be annotated with an ``(* abc9_flop *)`` attribute, however ABC9 has
|
||||
some specific requirements for this to be valid: - the DFF must initialise to
|
||||
zero (consider using :cmd:ref:`dfflegalize` to ensure this). - the DFF cannot
|
||||
have any asynchronous resets/sets (see the simplification idiom and the Boxes
|
||||
section for what to do here).
|
||||
|
||||
It is worth noting that in pure ``abc9`` mode, only the setup and arrival times
|
||||
are passed to ABC9 (specifically, they are modelled as buffers with the given
|
||||
delay). In ``abc9 -dff``, the flop itself is passed to ABC9, permitting
|
||||
sequential optimisations.
|
||||
|
||||
Some vendors have universal DFF models which include async sets/resets even when
|
||||
they're unused. Therefore *the simplification idiom* exists to handle this: by
|
||||
using a ``techmap`` file to discover flops which have a constant driver to those
|
||||
asynchronous controls, they can be mapped into an intermediate, simplified flop
|
||||
which qualifies as an ``(* abc9_flop *)``, ran through :cmd:ref:`abc9`, and then
|
||||
mapped back to the original flop. This is used in :cmd:ref:`synth_intel_alm` and
|
||||
:cmd:ref:`synth_quicklogic` for the PolarPro3.
|
||||
|
||||
DFFs are usually specified to have setup constraints against the clock on the
|
||||
input signals, and an arrival time for the ``Q`` output.
|
||||
|
||||
Boxes
|
||||
^^^^^
|
||||
|
||||
A "box" is a purely-combinational piece of hard logic. If the logic is exposed
|
||||
to ABC9, it's a "whitebox", otherwise it's a "blackbox". Carry chains would be
|
||||
best implemented as whiteboxes, but a DSP would be best implemented as a
|
||||
blackbox (multipliers are too complex to easily work with). LUT RAMs can be
|
||||
implemented as whiteboxes too.
|
||||
|
||||
Boxes are arguably the biggest advantage that ABC9 has over ABC: by being aware
|
||||
of carry chains and DSPs, it avoids optimising for a path that isn't the actual
|
||||
critical path, while the generally-longer paths result in ABC9 being able to
|
||||
reduce design area by mapping other logic to larger-but-slower cells.
|
||||
|
||||
|
|
|
|||
|
|
@ -90,8 +90,10 @@ Mapping to hardware
|
|||
For this example, we are using a Liberty file to describe a cell library which
|
||||
our internal cell library will be mapped to:
|
||||
|
||||
.. todo:: find a Liberty pygments style?
|
||||
|
||||
.. literalinclude:: /code_examples/intro/mycells.lib
|
||||
:language: Liberty
|
||||
:language: text
|
||||
:linenos:
|
||||
:name: mycells-lib
|
||||
:caption: :file:`mycells.lib`
|
||||
|
|
|
|||
|
|
@ -697,6 +697,9 @@ TDP with multiple read ports
|
|||
Patterns only supported with Verific
|
||||
------------------------------------
|
||||
|
||||
The following patterns are only supported when the design is read in using the
|
||||
Verific front-end.
|
||||
|
||||
Synchronous SDP with write-first behavior via blocking assignments
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
Setting up a flow for ABC9
|
||||
--------------------------
|
||||
|
||||
Much of the configuration comes from attributes and ``specify`` blocks in
|
||||
Verilog simulation models.
|
||||
|
||||
``specify`` syntax
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Since ``specify`` is a relatively obscure part of the Verilog standard, a quick
|
||||
guide to the syntax:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
specify // begins a specify block
|
||||
(A => B) = 123; // simple combinational path from A to B with a delay of 123.
|
||||
(A *> B) = 123; // simple combinational path from A to all bits of B with a delay of 123 for all.
|
||||
if (FOO) (A => B) = 123; // paths may apply under specific conditions.
|
||||
(posedge CLK => (Q : D)) = 123; // combinational path triggered on the positive edge of CLK; used for clock-to-Q arrival paths.
|
||||
$setup(A, posedge CLK, 123); // setup constraint for an input relative to a clock.
|
||||
endspecify // ends a specify block
|
||||
|
||||
By convention, all delays in ``specify`` blocks are in integer picoseconds.
|
||||
Files containing ``specify`` blocks should be read with the ``-specify`` option
|
||||
to :cmd:ref:`read_verilog` so that they aren't skipped.
|
||||
|
||||
LUTs
|
||||
^^^^
|
||||
|
||||
LUTs need to be annotated with an ``(* abc9_lut=N *)`` attribute, where ``N`` is
|
||||
the relative area of that LUT model. For example, if an architecture can combine
|
||||
LUTs to produce larger LUTs, then the combined LUTs would have increasingly
|
||||
larger ``N``. Conversely, if an architecture can split larger LUTs into smaller
|
||||
LUTs, then the smaller LUTs would have smaller ``N``.
|
||||
|
||||
LUTs are generally specified with simple combinational paths from the LUT inputs
|
||||
to the LUT output.
|
||||
|
||||
DFFs
|
||||
^^^^
|
||||
|
||||
DFFs should be annotated with an ``(* abc9_flop *)`` attribute, however ABC9 has
|
||||
some specific requirements for this to be valid: - the DFF must initialise to
|
||||
zero (consider using :cmd:ref:`dfflegalize` to ensure this). - the DFF cannot
|
||||
have any asynchronous resets/sets (see the simplification idiom and the Boxes
|
||||
section for what to do here).
|
||||
|
||||
It is worth noting that in pure ``abc9`` mode, only the setup and arrival times
|
||||
are passed to ABC9 (specifically, they are modelled as buffers with the given
|
||||
delay). In ``abc9 -dff``, the flop itself is passed to ABC9, permitting
|
||||
sequential optimisations.
|
||||
|
||||
Some vendors have universal DFF models which include async sets/resets even when
|
||||
they're unused. Therefore *the simplification idiom* exists to handle this: by
|
||||
using a ``techmap`` file to discover flops which have a constant driver to those
|
||||
asynchronous controls, they can be mapped into an intermediate, simplified flop
|
||||
which qualifies as an ``(* abc9_flop *)``, ran through :cmd:ref:`abc9`, and then
|
||||
mapped back to the original flop. This is used in :cmd:ref:`synth_intel_alm` and
|
||||
:cmd:ref:`synth_quicklogic` for the PolarPro3.
|
||||
|
||||
DFFs are usually specified to have setup constraints against the clock on the
|
||||
input signals, and an arrival time for the ``Q`` output.
|
||||
|
||||
Boxes
|
||||
^^^^^
|
||||
|
||||
A "box" is a purely-combinational piece of hard logic. If the logic is exposed
|
||||
to ABC9, it's a "whitebox", otherwise it's a "blackbox". Carry chains would be
|
||||
best implemented as whiteboxes, but a DSP would be best implemented as a
|
||||
blackbox (multipliers are too complex to easily work with). LUT RAMs can be
|
||||
implemented as whiteboxes too.
|
||||
|
||||
Boxes are arguably the biggest advantage that ABC9 has over ABC: by being aware
|
||||
of carry chains and DSPs, it avoids optimising for a path that isn't the actual
|
||||
critical path, while the generally-longer paths result in ABC9 being able to
|
||||
reduce design area by mapping other logic to larger-but-slower cells.
|
||||
155
docs/source/yosys_internals/extending_yosys/build_verific.rst
Normal file
155
docs/source/yosys_internals/extending_yosys/build_verific.rst
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
Compiling with Verific library
|
||||
==============================
|
||||
|
||||
The easiest way to get Yosys with Verific support is to `contact YosysHQ`_ for a
|
||||
`Tabby CAD Suite`_ evaluation license and download link. The TabbyCAD Suite
|
||||
includes additional patches and a custom extensions library in order to get the
|
||||
most out of the Verific parser when using Yosys.
|
||||
|
||||
If you already have a license for the Verific parser, in either source or binary
|
||||
form, you may be able to compile Yosys with partial Verific support yourself.
|
||||
|
||||
.. _contact YosysHQ : https://www.yosyshq.com/contact
|
||||
.. _Tabby CAD Suite: https://www.yosyshq.com/tabby-cad-datasheet
|
||||
|
||||
The Yosys-Verific patch
|
||||
-----------------------
|
||||
|
||||
YosysHQ maintains and develops a patch for Verific in order to better integrate
|
||||
with Yosys and to provide features required by some of the formal verification
|
||||
front-end tools. To license this patch for your own Yosys builds, `contact
|
||||
YosysHQ`_.
|
||||
|
||||
.. warning::
|
||||
|
||||
While synthesis from RTL may be possible without this patch, YosysHQ provides
|
||||
no guarantees of correctness and is unable to provide support.
|
||||
|
||||
We recommend against using unpatched Yosys+Verific builds in conjunction with
|
||||
the formal verification front-end tools unless you are familiar with their inner
|
||||
workings. There are cases where the tools will appear to work, while producing
|
||||
incorrect results.
|
||||
|
||||
.. note::
|
||||
|
||||
Some of the formal verification front-end tools may not be fully supported
|
||||
without the full TabbyCAD suite. If you want to use these tools, including
|
||||
SBY, make sure to ask us if the Yosys-Verific patch is right for you.
|
||||
|
||||
Compile options
|
||||
---------------
|
||||
|
||||
To enable Verific support ``ENABLE_VERIFIC`` has to be set to ``1`` and
|
||||
``VERIFIC_DIR`` needs to point to the location where the library is located.
|
||||
|
||||
============== ========================== ===============================
|
||||
Parameter Default Description
|
||||
============== ========================== ===============================
|
||||
ENABLE_VERIFIC 0 Enable compilation with Verific
|
||||
VERIFIC_DIR /usr/local/src/verific_lib Library and headers location
|
||||
============== ========================== ===============================
|
||||
|
||||
Since there are multiple Verific library builds and they can have different
|
||||
features, there are compile options to select them.
|
||||
|
||||
================================= ======= ===================================
|
||||
Parameter Default Description
|
||||
================================= ======= ===================================
|
||||
ENABLE_VERIFIC_SYSTEMVERILOG 1 SystemVerilog support
|
||||
ENABLE_VERIFIC_VHDL 1 VHDL support
|
||||
ENABLE_VERIFIC_HIER_TREE 1 Hierarchy tree support
|
||||
ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS 0 YosysHQ specific extensions support
|
||||
ENABLE_VERIFIC_EDIF 0 EDIF support
|
||||
ENABLE_VERIFIC_LIBERTY 0 Liberty file support
|
||||
================================= ======= ===================================
|
||||
|
||||
To find the compile options used for a given Yosys build, call ``yosys-config
|
||||
--cxxflags``. This documentation was built with the following compile options:
|
||||
|
||||
.. literalinclude:: /generated/yosys-config
|
||||
:start-at: --cxxflags
|
||||
:end-before: --linkflags
|
||||
|
||||
.. note::
|
||||
|
||||
The YosysHQ specific extensions are only available with the TabbyCAD suite.
|
||||
|
||||
Required Verific features
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following features, along with their corresponding Yosys build parameters,
|
||||
are required for the Yosys-Verific patch:
|
||||
|
||||
* RTL elaboration with
|
||||
|
||||
* SystemVerilog with ``ENABLE_VERIFIC_SYSTEMVERILOG``, and/or
|
||||
* VHDL support with ``ENABLE_VERIFIC_VHDL``.
|
||||
|
||||
* Hierarchy tree support and static elaboration with
|
||||
``ENABLE_VERIFIC_HIER_TREE``.
|
||||
|
||||
Please be aware that the following Verific configuration build parameter needs
|
||||
to be enabled in order to create the fully supported build:
|
||||
|
||||
::
|
||||
|
||||
database/DBCompileFlags.h:
|
||||
DB_PRESERVE_INITIAL_VALUE
|
||||
|
||||
.. note::
|
||||
|
||||
Yosys+Verific builds may compile without these features, but we provide no
|
||||
guarantees and cannot offer support if they are disabled or the Yosys-Verific
|
||||
patch is not used.
|
||||
|
||||
Optional Verific features
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following Verific features are available with TabbyCAD and can be enabled in
|
||||
Yosys builds:
|
||||
|
||||
* EDIF support with ``ENABLE_VERIFIC_EDIF``, and
|
||||
* Liberty file support with ``ENABLE_VERIFIC_LIBERTY``.
|
||||
|
||||
Partially supported builds
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section describes Yosys+Verific configurations which we have confirmed as
|
||||
working in the past, however they are not a part of our regular tests so we
|
||||
cannot guarantee they are still functional.
|
||||
|
||||
To be able to compile Yosys with Verific, the Verific library must have support
|
||||
for at least one HDL language with RTL elaboration enabled. The following table
|
||||
lists a series of build configurations which are possible, but only provide a
|
||||
limited subset of features. Please note that support is limited without YosysHQ
|
||||
specific extensions of Verific library.
|
||||
|
||||
Configuration values:
|
||||
a. ``ENABLE_VERIFIC_SYSTEMVERILOG``
|
||||
b. ``ENABLE_VERIFIC_VHDL``
|
||||
c. ``ENABLE_VERIFIC_HIER_TREE``
|
||||
d. ``ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS``
|
||||
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| | Configuration values |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| Features | a | b | c | d |
|
||||
+==========================================================================+=====+=====+=====+=====+
|
||||
| SystemVerilog + RTL elaboration | 1 | 0 | 0 | 0 |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| VHDL + RTL elaboration | 0 | 1 | 0 | 0 |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| SystemVerilog + VHDL + RTL elaboration | 1 | 1 | 0 | 0 |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| SystemVerilog + RTL elaboration + Static elaboration + Hier tree | 1 | 0 | 1 | 0 |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| VHDL + RTL elaboration + Static elaboration + Hier tree | 0 | 1 | 1 | 0 |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
| SystemVerilog + VHDL + RTL elaboration + Static elaboration + Hier tree | 1 | 1 | 1 | 0 |
|
||||
+--------------------------------------------------------------------------+-----+-----+-----+-----+
|
||||
|
||||
.. note::
|
||||
|
||||
In case your Verific build has EDIF and/or Liberty support, you can enable
|
||||
those options. These are not mentioned above for simplification and since
|
||||
they are disabled by default.
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
Extending Yosys
|
||||
---------------
|
||||
Working with the Yosys codebase
|
||||
-------------------------------
|
||||
|
||||
.. todo:: brief overview for the extending Yosys index
|
||||
This section goes into additional detail on the Yosys source code and git
|
||||
repository. This information is not needed for simply using Yosys, but may be
|
||||
of interest for developers looking to customise Yosys builds.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
extensions
|
||||
abc_flow
|
||||
build_verific
|
||||
test_suites
|
||||
|
||||
|
|
|
|||
|
|
@ -53,47 +53,12 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&
|
|||
return module->wires_.at(id);
|
||||
}
|
||||
|
||||
static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A)
|
||||
{
|
||||
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(ID::Y, module->addWire(NEW_ID));
|
||||
return cell->getPort(ID::Y);
|
||||
}
|
||||
|
||||
static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
|
||||
{
|
||||
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_XOR_));
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(ID::Y, module->addWire(NEW_ID));
|
||||
return cell->getPort(ID::Y);
|
||||
}
|
||||
|
||||
static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
|
||||
{
|
||||
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_AND_));
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(ID::Y, module->addWire(NEW_ID));
|
||||
return cell->getPort(ID::Y);
|
||||
}
|
||||
|
||||
static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
|
||||
{
|
||||
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_OR_));
|
||||
cell->setPort(ID::A, A);
|
||||
cell->setPort(ID::B, B);
|
||||
cell->setPort(ID::Y, module->addWire(NEW_ID));
|
||||
return cell->getPort(ID::Y);
|
||||
}
|
||||
|
||||
static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack, token_t next_token)
|
||||
{
|
||||
int top = int(stack.size())-1;
|
||||
|
||||
if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type == '!') {
|
||||
token_t t = token_t(0, create_inv_cell(module, stack[top].sig));
|
||||
token_t t = token_t(0, module->NotGate(NEW_ID, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.push_back(t);
|
||||
|
|
@ -101,7 +66,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-1 && stack[top].type == '\'' && stack[top-1].type == 0) {
|
||||
token_t t = token_t(0, create_inv_cell(module, stack[top-1].sig));
|
||||
token_t t = token_t(0, module->NotGate(NEW_ID, stack[top-1].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.push_back(t);
|
||||
|
|
@ -116,7 +81,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type == '^' && stack[top].type == 1) {
|
||||
token_t t = token_t(1, create_xor_cell(module, stack[top-2].sig, stack[top].sig));
|
||||
token_t t = token_t(1, module->XorGate(NEW_ID, stack[top-2].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
|
@ -132,7 +97,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) {
|
||||
token_t t = token_t(2, create_and_cell(module, stack[top-1].sig, stack[top].sig));
|
||||
token_t t = token_t(2, module->AndGate(NEW_ID, stack[top-1].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.push_back(t);
|
||||
|
|
@ -140,7 +105,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type == '*' || stack[top-1].type == '&') && stack[top].type == 2) {
|
||||
token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig));
|
||||
token_t t = token_t(2, module->AndGate(NEW_ID, stack[top-2].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
|
@ -156,7 +121,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
|
|||
}
|
||||
|
||||
if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type == '+' || stack[top-1].type == '|') && stack[top].type == 3) {
|
||||
token_t t = token_t(3, create_or_cell(module, stack[top-2].sig, stack[top].sig));
|
||||
token_t t = token_t(3, module->OrGate(NEW_ID, stack[top-2].sig, stack[top].sig));
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
|
@ -221,12 +186,12 @@ static RTLIL::SigSpec create_tristate(RTLIL::Module *module, RTLIL::SigSpec func
|
|||
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($tribuf));
|
||||
cell->setParam(ID::WIDTH, GetSize(func));
|
||||
cell->setPort(ID::A, func);
|
||||
cell->setPort(ID::EN, create_inv_cell(module, three_state));
|
||||
cell->setPort(ID::EN, module->NotGate(NEW_ID, three_state));
|
||||
cell->setPort(ID::Y, module->addWire(NEW_ID));
|
||||
return cell->getPort(ID::Y);
|
||||
}
|
||||
|
||||
static void create_ff(RTLIL::Module *module, LibertyAst *node)
|
||||
static void create_ff(RTLIL::Module *module, const LibertyAst *node)
|
||||
{
|
||||
RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0))));
|
||||
RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1))));
|
||||
|
|
@ -303,7 +268,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node)
|
|||
log_assert(!cell->type.empty());
|
||||
}
|
||||
|
||||
static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_ignore_miss_data_latch)
|
||||
static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool flag_ignore_miss_data_latch)
|
||||
{
|
||||
RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0))));
|
||||
RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1))));
|
||||
|
|
@ -422,7 +387,7 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
|
|||
return true;
|
||||
}
|
||||
|
||||
void parse_type_map(std::map<std::string, std::tuple<int, int, bool>> &type_map, LibertyAst *ast)
|
||||
void parse_type_map(std::map<std::string, std::tuple<int, int, bool>> &type_map, const LibertyAst *ast)
|
||||
{
|
||||
for (auto type_node : ast->children)
|
||||
{
|
||||
|
|
@ -604,7 +569,7 @@ struct LibertyFrontend : public Frontend {
|
|||
for (auto node : cell->children)
|
||||
{
|
||||
if (node->id == "pin" && node->args.size() == 1) {
|
||||
LibertyAst *dir = node->find("direction");
|
||||
const LibertyAst *dir = node->find("direction");
|
||||
if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal"))
|
||||
{
|
||||
if (!flag_ignore_miss_dir)
|
||||
|
|
@ -625,10 +590,10 @@ struct LibertyFrontend : public Frontend {
|
|||
if (!flag_lib)
|
||||
log_error("Error in cell %s: bus interfaces are only supported in -lib mode.\n", log_id(cell_name));
|
||||
|
||||
LibertyAst *dir = node->find("direction");
|
||||
const LibertyAst *dir = node->find("direction");
|
||||
|
||||
if (dir == nullptr) {
|
||||
LibertyAst *pin = node->find("pin");
|
||||
const LibertyAst *pin = node->find("pin");
|
||||
if (pin != nullptr)
|
||||
dir = pin->find("direction");
|
||||
}
|
||||
|
|
@ -639,7 +604,7 @@ struct LibertyFrontend : public Frontend {
|
|||
if (dir->value == "internal")
|
||||
continue;
|
||||
|
||||
LibertyAst *bus_type_node = node->find("bus_type");
|
||||
const LibertyAst *bus_type_node = node->find("bus_type");
|
||||
|
||||
if (!bus_type_node || !type_map.count(bus_type_node->value))
|
||||
log_error("Unknown or unsupported type for bus interface %s on cell %s.\n",
|
||||
|
|
@ -681,7 +646,7 @@ struct LibertyFrontend : public Frontend {
|
|||
{
|
||||
if (node->id == "pin" && node->args.size() == 1)
|
||||
{
|
||||
LibertyAst *dir = node->find("direction");
|
||||
const LibertyAst *dir = node->find("direction");
|
||||
|
||||
if (flag_lib && dir->value == "internal")
|
||||
continue;
|
||||
|
|
@ -704,7 +669,7 @@ struct LibertyFrontend : public Frontend {
|
|||
if (flag_lib)
|
||||
continue;
|
||||
|
||||
LibertyAst *func = node->find("function");
|
||||
const LibertyAst *func = node->find("function");
|
||||
if (func == NULL)
|
||||
{
|
||||
if (dir->value != "inout") { // allow inout with missing function, can be used for power pins
|
||||
|
|
@ -719,7 +684,7 @@ struct LibertyFrontend : public Frontend {
|
|||
}
|
||||
} else {
|
||||
RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str());
|
||||
LibertyAst *three_state = node->find("three_state");
|
||||
const LibertyAst *three_state = node->find("three_state");
|
||||
if (three_state) {
|
||||
out_sig = create_tristate(module, out_sig, three_state->value.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ USING_YOSYS_NAMESPACE
|
|||
"\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
|
||||
"$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
|
||||
|
||||
[0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; }
|
||||
[0-9]+'s?[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; }
|
||||
-?[0-9]+ {
|
||||
char *end = nullptr;
|
||||
errno = 0;
|
||||
|
|
|
|||
|
|
@ -412,8 +412,16 @@ constant:
|
|||
TOK_VALUE {
|
||||
char *ep;
|
||||
int width = strtol($1, &ep, 10);
|
||||
bool is_signed = false;
|
||||
if (*ep == '\'') {
|
||||
ep++;
|
||||
}
|
||||
if (*ep == 's') {
|
||||
is_signed = true;
|
||||
ep++;
|
||||
}
|
||||
std::list<RTLIL::State> bits;
|
||||
while (*(++ep) != 0) {
|
||||
while (*ep != 0) {
|
||||
RTLIL::State bit = RTLIL::Sx;
|
||||
switch (*ep) {
|
||||
case '0': bit = RTLIL::S0; break;
|
||||
|
|
@ -424,7 +432,9 @@ constant:
|
|||
case 'm': bit = RTLIL::Sm; break;
|
||||
}
|
||||
bits.push_front(bit);
|
||||
ep++;
|
||||
}
|
||||
|
||||
if (bits.size() == 0)
|
||||
bits.push_back(RTLIL::Sx);
|
||||
while ((int)bits.size() < width) {
|
||||
|
|
@ -438,6 +448,9 @@ constant:
|
|||
$$ = new RTLIL::Const;
|
||||
for (auto it = bits.begin(); it != bits.end(); it++)
|
||||
$$->bits.push_back(*it);
|
||||
if (is_signed) {
|
||||
$$->flags |= RTLIL::CONST_FLAG_SIGNED;
|
||||
}
|
||||
free($1);
|
||||
} |
|
||||
TOK_INT {
|
||||
|
|
|
|||
|
|
@ -721,13 +721,17 @@ int main(int argc, char **argv)
|
|||
ru_buffer.ru_utime.tv_usec += ru_buffer_children.ru_utime.tv_usec;
|
||||
ru_buffer.ru_stime.tv_sec += ru_buffer_children.ru_stime.tv_sec;
|
||||
ru_buffer.ru_stime.tv_usec += ru_buffer_children.ru_stime.tv_usec;
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
ru_buffer.ru_maxrss = std::max(ru_buffer.ru_maxrss, ru_buffer_children.ru_maxrss);
|
||||
#endif
|
||||
}
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
meminfo = stringf(", MEM: %.2f MB peak",
|
||||
ru_buffer.ru_maxrss / 1024.0);
|
||||
#elif defined(__APPLE__)
|
||||
// https://stackoverflow.com/questions/59913657/strange-values-of-get-rusage-maxrss-on-macos-and-linux
|
||||
meminfo = stringf(", MEM: %.2f MB peak",
|
||||
ru_buffer.ru_maxrss / (1024.0 * 1024.0));
|
||||
#endif
|
||||
log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash.c_str(),
|
||||
stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec,
|
||||
|
|
|
|||
|
|
@ -832,7 +832,7 @@ std::string Fmt::render() const
|
|||
}
|
||||
} else log_abort();
|
||||
if (part.justify == FmtPart::NUMERIC && part.group && part.padding == '0') {
|
||||
int group_size = part.base == 10 ? 3 : 4;
|
||||
size_t group_size = part.base == 10 ? 3 : 4;
|
||||
while (prefix.size() + buf.size() < part.width) {
|
||||
if (buf.size() % (group_size + 1) == group_size)
|
||||
buf += '_';
|
||||
|
|
|
|||
|
|
@ -1228,7 +1228,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
if (ff.has_srst && ff.has_ce && ff.ce_over_srst) {
|
||||
int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||
std::vector<int> rval = importDefSigSpec(ff.val_srst, timestep-1);
|
||||
int undef_srst;
|
||||
int undef_srst = -1;
|
||||
std::vector<int> undef_rval;
|
||||
if (model_undef) {
|
||||
undef_srst = importUndefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||
|
|
@ -1242,7 +1242,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
if (ff.has_ce) {
|
||||
int ce = importDefSigSpec(ff.sig_ce, timestep-1).at(0);
|
||||
std::vector<int> old_q = importDefSigSpec(ff.sig_q, timestep-1);
|
||||
int undef_ce;
|
||||
int undef_ce = -1;
|
||||
std::vector<int> undef_old_q;
|
||||
if (model_undef) {
|
||||
undef_ce = importUndefSigSpec(ff.sig_ce, timestep-1).at(0);
|
||||
|
|
@ -1256,7 +1256,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
if (ff.has_srst && !(ff.has_ce && ff.ce_over_srst)) {
|
||||
int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||
std::vector<int> rval = importDefSigSpec(ff.val_srst, timestep-1);
|
||||
int undef_srst;
|
||||
int undef_srst = -1;
|
||||
std::vector<int> undef_rval;
|
||||
if (model_undef) {
|
||||
undef_srst = importUndefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||
|
|
|
|||
|
|
@ -1907,7 +1907,8 @@ void fstWriterClose(void *ctx)
|
|||
int zfd;
|
||||
int fourpack_duo = 0;
|
||||
#ifndef __MINGW32__
|
||||
char *fnam = (char *)malloc(strlen(xc->filename) + 5 + 1);
|
||||
auto fnam_size = strlen(xc->filename) + 5 + 1;
|
||||
char *fnam = (char *)malloc(fnam_size);
|
||||
#endif
|
||||
|
||||
fixup_offs = ftello(xc->handle);
|
||||
|
|
@ -1991,7 +1992,7 @@ void fstWriterClose(void *ctx)
|
|||
fflush(xc->handle);
|
||||
|
||||
#ifndef __MINGW32__
|
||||
sprintf(fnam, "%s.hier", xc->filename);
|
||||
snprintf(fnam, fnam_size, "%s.hier", xc->filename);
|
||||
unlink(fnam);
|
||||
free(fnam);
|
||||
#endif
|
||||
|
|
@ -2616,7 +2617,7 @@ fstEnumHandle fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t ele
|
|||
uint32_t i;
|
||||
|
||||
name_len = strlen(name);
|
||||
elem_count_len = sprintf(elem_count_buf, "%" PRIu32, elem_count);
|
||||
elem_count_len = snprintf(elem_count_buf, sizeof(elem_count_buf), "%" PRIu32, elem_count);
|
||||
|
||||
literal_lens = (unsigned int *)calloc(elem_count, sizeof(unsigned int));
|
||||
val_lens = (unsigned int *)calloc(elem_count, sizeof(unsigned int));
|
||||
|
|
@ -3579,7 +3580,8 @@ static int fstReaderRecreateHierFile(struct fstReaderContext *xc)
|
|||
|
||||
if (!xc->fh) {
|
||||
fst_off_t offs_cache = ftello(xc->f);
|
||||
char *fnam = (char *)malloc(strlen(xc->filename) + 6 + 16 + 32 + 1);
|
||||
auto fnam_size = strlen(xc->filename) + 6 + 16 + 32 + 1;
|
||||
char *fnam = (char *)malloc(fnam_size);
|
||||
unsigned char *mem = (unsigned char *)malloc(FST_GZIO_LEN);
|
||||
fst_off_t hl, uclen;
|
||||
fst_off_t clen = 0;
|
||||
|
|
@ -3594,7 +3596,7 @@ static int fstReaderRecreateHierFile(struct fstReaderContext *xc)
|
|||
htyp = xc->contains_hier_section_lz4duo ? FST_BL_HIER_LZ4DUO : FST_BL_HIER_LZ4;
|
||||
}
|
||||
|
||||
sprintf(fnam, "%s.hier_%d_%p", xc->filename, getpid(), (void *)xc);
|
||||
snprintf(fnam, fnam_size, "%s.hier_%d_%p", xc->filename, getpid(), (void *)xc);
|
||||
fstReaderFseeko(xc, xc->f, xc->hier_pos, SEEK_SET);
|
||||
uclen = fstReaderUint64(xc->f);
|
||||
#ifndef __MINGW32__
|
||||
|
|
@ -4239,9 +4241,10 @@ int fstReaderInit(struct fstReaderContext *xc)
|
|||
if (!seclen)
|
||||
return (0); /* not finished compressing, this is a failed read */
|
||||
|
||||
hf = (char *)calloc(1, flen + 16 + 32 + 1);
|
||||
size_t hf_size = flen + 16 + 32 + 1;
|
||||
hf = (char *)calloc(1, hf_size);
|
||||
|
||||
sprintf(hf, "%s.upk_%d_%p", xc->filename, getpid(), (void *)xc);
|
||||
snprintf(hf, hf_size, "%s.upk_%d_%p", xc->filename, getpid(), (void *)xc);
|
||||
fcomp = fopen(hf, "w+b");
|
||||
if (!fcomp) {
|
||||
fcomp = tmpfile_open(&xc->f_nam);
|
||||
|
|
@ -4799,21 +4802,21 @@ int fstReaderIterBlocks2(void *ctx,
|
|||
|
||||
if (beg_tim) {
|
||||
if (dumpvars_state == 1) {
|
||||
wx_len = sprintf(wx_buf, "$end\n");
|
||||
wx_len = snprintf(wx_buf, 6, "$end\n");
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
dumpvars_state = 2;
|
||||
}
|
||||
wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", beg_tim);
|
||||
wx_len = snprintf(wx_buf, 20, "#%" PRIu64 "\n", beg_tim);
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
if (!dumpvars_state) {
|
||||
wx_len = sprintf(wx_buf, "$dumpvars\n");
|
||||
wx_len = snprintf(wx_buf, 11, "$dumpvars\n");
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
dumpvars_state = 1;
|
||||
}
|
||||
}
|
||||
if ((xc->num_blackouts) && (cur_blackout != xc->num_blackouts)) {
|
||||
if (beg_tim == xc->blackout_times[cur_blackout]) {
|
||||
wx_len = sprintf(wx_buf, "$dump%s $end\n",
|
||||
wx_len = snprintf(wx_buf, 16, "$dump%s $end\n",
|
||||
(xc->blackout_activity[cur_blackout++]) ? "on" : "off");
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
}
|
||||
|
|
@ -4914,7 +4917,7 @@ int fstReaderIterBlocks2(void *ctx,
|
|||
clone_d[j] = srcdata[7 - j];
|
||||
}
|
||||
}
|
||||
sprintf((char *)xc->temp_signal_value_buf, "%.16g", d);
|
||||
snprintf((char *)xc->temp_signal_value_buf, 32, "%.16g", d);
|
||||
value_change_callback(user_callback_data_pointer, beg_tim, idx + 1,
|
||||
xc->temp_signal_value_buf);
|
||||
}
|
||||
|
|
@ -4936,7 +4939,7 @@ int fstReaderIterBlocks2(void *ctx,
|
|||
}
|
||||
|
||||
fstVcdID(vcdid_buf, idx + 1);
|
||||
wx_len = sprintf(wx_buf, "r%.16g %s\n", d, vcdid_buf);
|
||||
wx_len = snprintf(wx_buf, sizeof(wx_buf), "r%.16g %s\n", d, vcdid_buf);
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
}
|
||||
}
|
||||
|
|
@ -5179,21 +5182,21 @@ int fstReaderIterBlocks2(void *ctx,
|
|||
}
|
||||
|
||||
if (dumpvars_state == 1) {
|
||||
wx_len = sprintf(wx_buf, "$end\n");
|
||||
wx_len = snprintf(wx_buf, 6, "$end\n");
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
dumpvars_state = 2;
|
||||
}
|
||||
wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", time_table[i]);
|
||||
wx_len = snprintf(wx_buf, 20, "#%" PRIu64 "\n", time_table[i]);
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
if (!dumpvars_state) {
|
||||
wx_len = sprintf(wx_buf, "$dumpvars\n");
|
||||
wx_len = snprintf(wx_buf, 11, "$dumpvars\n");
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
dumpvars_state = 1;
|
||||
}
|
||||
|
||||
if ((xc->num_blackouts) && (cur_blackout != xc->num_blackouts)) {
|
||||
if (time_table[i] == xc->blackout_times[cur_blackout]) {
|
||||
wx_len = sprintf(wx_buf, "$dump%s $end\n",
|
||||
wx_len = snprintf(wx_buf, 16, "$dump%s $end\n",
|
||||
(xc->blackout_activity[cur_blackout++]) ? "on" : "off");
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
}
|
||||
|
|
@ -5407,7 +5410,7 @@ int fstReaderIterBlocks2(void *ctx,
|
|||
clone_d[j] = srcdata[7 - j];
|
||||
}
|
||||
}
|
||||
sprintf((char *)xc->temp_signal_value_buf, "%.16g", d);
|
||||
snprintf((char *)xc->temp_signal_value_buf, 32, "%.16g", d);
|
||||
value_change_callback(user_callback_data_pointer, time_table[i], idx + 1,
|
||||
xc->temp_signal_value_buf);
|
||||
}
|
||||
|
|
@ -5427,7 +5430,7 @@ int fstReaderIterBlocks2(void *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
wx_len = sprintf(wx_buf, "r%.16g", d);
|
||||
wx_len = snprintf(wx_buf, sizeof(wx_buf), "r%.16g", d);
|
||||
fstWritex(xc, wx_buf, wx_len);
|
||||
}
|
||||
}
|
||||
|
|
@ -5523,7 +5526,7 @@ static char *fstExtractRvatDataFromFrame(struct fstReaderContext *xc, fstHandle
|
|||
}
|
||||
}
|
||||
|
||||
sprintf((char *)buf, "%.16g", d);
|
||||
snprintf((char *)buf, 32, "%.16g", d);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5536,7 +5539,9 @@ char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facid
|
|||
fst_off_t blkpos = 0, prev_blkpos;
|
||||
uint64_t beg_tim, end_tim, beg_tim2, end_tim2;
|
||||
int sectype;
|
||||
#ifdef FST_DEBUG
|
||||
unsigned int secnum = 0;
|
||||
#endif
|
||||
uint64_t seclen;
|
||||
uint64_t tsec_uclen = 0, tsec_clen = 0;
|
||||
uint64_t tsec_nitems;
|
||||
|
|
@ -5620,7 +5625,9 @@ char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facid
|
|||
}
|
||||
|
||||
blkpos += seclen;
|
||||
#ifdef FST_DEBUG
|
||||
secnum++;
|
||||
#endif
|
||||
}
|
||||
|
||||
xc->rvat_beg_tim = beg_tim;
|
||||
|
|
@ -6041,7 +6048,7 @@ process_value:
|
|||
}
|
||||
}
|
||||
|
||||
sprintf(buf, "r%.16g", d);
|
||||
snprintf(buf, 32, "r%.16g", d);
|
||||
return (buf);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
37
libs/minisat/00_PATCH_warnings.patch
Normal file
37
libs/minisat/00_PATCH_warnings.patch
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
--- System.cc
|
||||
+++ System.cc
|
||||
@@ -43,7 +43,7 @@ static inline int memReadStat(int field)
|
||||
pid_t pid = getpid();
|
||||
int value;
|
||||
|
||||
- sprintf(name, "/proc/%d/statm", pid);
|
||||
+ snprintf(name, 256, "/proc/%d/statm", pid);
|
||||
FILE* in = fopen(name, "rb");
|
||||
if (in == NULL) return 0;
|
||||
|
||||
@@ -60,7 +60,7 @@ static inline int memReadPeak(void)
|
||||
char name[256];
|
||||
pid_t pid = getpid();
|
||||
|
||||
- sprintf(name, "/proc/%d/status", pid);
|
||||
+ snprintf(name, 256, "/proc/%d/status", pid);
|
||||
FILE* in = fopen(name, "rb");
|
||||
if (in == NULL) return 0;
|
||||
|
||||
--- Vec.h
|
||||
+++ Vec.h
|
||||
@@ -100,7 +100,13 @@ void vec<T,_Size>::capacity(Size min_cap) {
|
||||
Size add = max((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2
|
||||
const Size size_max = std::numeric_limits<Size>::max();
|
||||
if ( ((size_max <= std::numeric_limits<int>::max()) && (add > size_max - cap))
|
||||
- || (((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM) )
|
||||
+ || (
|
||||
+#ifdef _DEFAULT_SOURCE
|
||||
+ ((data = (T*)::reallocarray(data, (cap += add), sizeof(T))) == NULL)
|
||||
+#else
|
||||
+ ((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL)
|
||||
+#endif
|
||||
+ && errno == ENOMEM) )
|
||||
throw OutOfMemoryException();
|
||||
}
|
||||
|
||||
|
|
@ -17,3 +17,4 @@ patch -p0 < 00_PATCH_remove_zlib.patch
|
|||
patch -p0 < 00_PATCH_no_fpu_control.patch
|
||||
patch -p0 < 00_PATCH_typofixes.patch
|
||||
patch -p0 < 00_PATCH_wasm.patch
|
||||
patch -p0 < 00_PATCH_warnings.patch
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static inline int memReadStat(int field)
|
|||
pid_t pid = getpid();
|
||||
int value;
|
||||
|
||||
sprintf(name, "/proc/%d/statm", pid);
|
||||
snprintf(name, 256, "/proc/%d/statm", pid);
|
||||
FILE* in = fopen(name, "rb");
|
||||
if (in == NULL) return 0;
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ static inline int memReadPeak(void)
|
|||
char name[256];
|
||||
pid_t pid = getpid();
|
||||
|
||||
sprintf(name, "/proc/%d/status", pid);
|
||||
snprintf(name, 256, "/proc/%d/status", pid);
|
||||
FILE* in = fopen(name, "rb");
|
||||
if (in == NULL) return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,13 @@ void vec<T,_Size>::capacity(Size min_cap) {
|
|||
Size add = max((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2
|
||||
const Size size_max = std::numeric_limits<Size>::max();
|
||||
if ( ((size_max <= std::numeric_limits<int>::max()) && (add > size_max - cap))
|
||||
|| (((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM) )
|
||||
|| (
|
||||
#ifdef _DEFAULT_SOURCE
|
||||
((data = (T*)::reallocarray(data, (cap += add), sizeof(T))) == NULL)
|
||||
#else
|
||||
((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL)
|
||||
#endif
|
||||
&& errno == ENOMEM) )
|
||||
throw OutOfMemoryException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ struct ExecPass : public Pass {
|
|||
}
|
||||
|
||||
} else
|
||||
log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.", args[argidx].c_str());
|
||||
log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.\n", args[argidx].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string libert
|
|||
if (cell->id != "cell" || cell->args.size() != 1)
|
||||
continue;
|
||||
|
||||
LibertyAst *ar = cell->find("area");
|
||||
const LibertyAst *ar = cell->find("area");
|
||||
bool is_flip_flop = cell->find("ff") != nullptr;
|
||||
if (ar != nullptr && !ar->value.empty())
|
||||
cell_area["\\" + cell->args[0]] = {/*area=*/atof(ar->value.c_str()), is_flip_flop};
|
||||
|
|
|
|||
|
|
@ -63,10 +63,12 @@ match add
|
|||
|
||||
define <bool> constport_signed param(add, !varport_A ? \A_SIGNED : \B_SIGNED).as_bool()
|
||||
define <bool> varport_signed param(add, varport_A ? \A_SIGNED : \B_SIGNED).as_bool();
|
||||
define <bool> offset_negative ((port(add, constport).bits().back() == State::S1) ^ (is_sub && varport_A))
|
||||
define <bool> const_negative (constport_signed && (port(add, constport).bits().back() == State::S1))
|
||||
define <bool> offset_negative ((is_sub && varport_A) ^ const_negative)
|
||||
|
||||
// checking some value boundaries as well:
|
||||
// data[...-c +:W1] is fine for +/-var (pad at LSB, all data still accessible)
|
||||
// data[...-c +:W1] is fine for any signed var (pad at LSB, all data still accessible)
|
||||
// unsigned shift may underflow (eg var-3 with var<3) -> cannot be converted
|
||||
// data[...+c +:W1] is only fine for +var(add) and var unsigned
|
||||
// (+c cuts lower C bits, making them inaccessible, a signed var could try to access them)
|
||||
// either its an add or the variable port is A (it must be positive)
|
||||
|
|
@ -74,6 +76,8 @@ match add
|
|||
|
||||
// -> data[var+c +:W1] (with var signed) is illegal
|
||||
filter !(!offset_negative && varport_signed)
|
||||
// -> data >> (var-c) (with var unsigned) is illegal
|
||||
filter !(offset_negative && !varport_signed)
|
||||
|
||||
// state-variables are assigned at the end only:
|
||||
// shift the log2scale offset in-front of add to get true value: (var+c)<<N -> (var<<N)+(c<<N)
|
||||
|
|
|
|||
|
|
@ -54,90 +54,35 @@ RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc)
|
|||
}
|
||||
|
||||
void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::SigSpec clk, bool clk_polarity,
|
||||
std::map<RTLIL::SigSpec, std::set<RTLIL::SyncRule*>> &async_rules, RTLIL::Process *proc)
|
||||
std::vector<std::pair<RTLIL::SigSpec, RTLIL::SyncRule*>> &async_rules, RTLIL::Process *proc)
|
||||
{
|
||||
// A signal should be set/cleared if there is a load trigger that is enabled
|
||||
// such that the load value is 1/0 and it is the highest priority trigger
|
||||
RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.size());
|
||||
RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.size());
|
||||
|
||||
for (auto &it : async_rules)
|
||||
// Reverse iterate through the rules as the first ones are the highest priority
|
||||
// so need to be at the top of the mux trees
|
||||
for (auto it = async_rules.crbegin(); it != async_rules.crend(); it++)
|
||||
{
|
||||
RTLIL::SigSpec sync_value = it.first;
|
||||
RTLIL::SigSpec sync_value_inv;
|
||||
RTLIL::SigSpec sync_high_signals;
|
||||
RTLIL::SigSpec sync_low_signals;
|
||||
const auto& [sync_value, rule] = *it;
|
||||
const auto pos_trig = rule->type == RTLIL::SyncType::ST1 ? rule->signal : mod->Not(NEW_ID, rule->signal);
|
||||
|
||||
for (auto &it2 : it.second)
|
||||
if (it2->type == RTLIL::SyncType::ST0)
|
||||
sync_low_signals.append(it2->signal);
|
||||
else if (it2->type == RTLIL::SyncType::ST1)
|
||||
sync_high_signals.append(it2->signal);
|
||||
else
|
||||
log_abort();
|
||||
// If pos_trig is true, we have priority at this point in the tree so
|
||||
// set a bit if sync_value has a set bit. Otherwise, defer to the rest
|
||||
// of the priority tree
|
||||
sig_sr_set = mod->Mux(NEW_ID, sig_sr_set, sync_value, pos_trig);
|
||||
|
||||
if (sync_low_signals.size() > 1) {
|
||||
RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($reduce_or));
|
||||
cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
|
||||
cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_low_signals.size());
|
||||
cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
|
||||
cell->setPort(ID::A, sync_low_signals);
|
||||
cell->setPort(ID::Y, sync_low_signals = mod->addWire(NEW_ID));
|
||||
}
|
||||
|
||||
if (sync_low_signals.size() > 0) {
|
||||
RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($not));
|
||||
cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
|
||||
cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_low_signals.size());
|
||||
cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
|
||||
cell->setPort(ID::A, sync_low_signals);
|
||||
cell->setPort(ID::Y, mod->addWire(NEW_ID));
|
||||
sync_high_signals.append(cell->getPort(ID::Y));
|
||||
}
|
||||
|
||||
if (sync_high_signals.size() > 1) {
|
||||
RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($reduce_or));
|
||||
cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
|
||||
cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_high_signals.size());
|
||||
cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
|
||||
cell->setPort(ID::A, sync_high_signals);
|
||||
cell->setPort(ID::Y, sync_high_signals = mod->addWire(NEW_ID));
|
||||
}
|
||||
|
||||
RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, ID($not));
|
||||
inv_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
|
||||
inv_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig_d.size());
|
||||
inv_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(sig_d.size());
|
||||
inv_cell->setPort(ID::A, sync_value);
|
||||
inv_cell->setPort(ID::Y, sync_value_inv = mod->addWire(NEW_ID, sig_d.size()));
|
||||
|
||||
RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, ID($mux));
|
||||
mux_set_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
|
||||
mux_set_cell->setPort(ID::A, sig_sr_set);
|
||||
mux_set_cell->setPort(ID::B, sync_value);
|
||||
mux_set_cell->setPort(ID::S, sync_high_signals);
|
||||
mux_set_cell->setPort(ID::Y, sig_sr_set = mod->addWire(NEW_ID, sig_d.size()));
|
||||
|
||||
RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, ID($mux));
|
||||
mux_clr_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
|
||||
mux_clr_cell->setPort(ID::A, sig_sr_clr);
|
||||
mux_clr_cell->setPort(ID::B, sync_value_inv);
|
||||
mux_clr_cell->setPort(ID::S, sync_high_signals);
|
||||
mux_clr_cell->setPort(ID::Y, sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()));
|
||||
// Same deal with clear bit
|
||||
const auto sync_value_inv = mod->Not(NEW_ID, sync_value);
|
||||
sig_sr_clr = mod->Mux(NEW_ID, sig_sr_clr, sync_value_inv, pos_trig);
|
||||
}
|
||||
|
||||
std::stringstream sstr;
|
||||
sstr << "$procdff$" << (autoidx++);
|
||||
|
||||
RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($dffsr));
|
||||
RTLIL::Cell *cell = mod->addDffsr(sstr.str(), clk, sig_sr_set, sig_sr_clr, sig_d, sig_q, clk_polarity);
|
||||
cell->attributes = proc->attributes;
|
||||
cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
|
||||
cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
|
||||
cell->parameters[ID::SET_POLARITY] = RTLIL::Const(true, 1);
|
||||
cell->parameters[ID::CLR_POLARITY] = RTLIL::Const(true, 1);
|
||||
cell->setPort(ID::D, sig_d);
|
||||
cell->setPort(ID::Q, sig_q);
|
||||
cell->setPort(ID::CLK, clk);
|
||||
cell->setPort(ID::SET, sig_sr_set);
|
||||
cell->setPort(ID::CLR, sig_sr_clr);
|
||||
|
||||
log(" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n",
|
||||
cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative");
|
||||
|
|
@ -204,7 +149,6 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
|
|||
while (1)
|
||||
{
|
||||
RTLIL::SigSpec sig = find_any_lvalue(proc);
|
||||
bool free_sync_level = false;
|
||||
|
||||
if (sig.size() == 0)
|
||||
break;
|
||||
|
|
@ -213,13 +157,17 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
|
|||
mod->name.c_str(), log_signal(sig), mod->name.c_str(), proc->name.c_str());
|
||||
|
||||
RTLIL::SigSpec insig = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
RTLIL::SigSpec rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
RTLIL::SyncRule *sync_level = NULL;
|
||||
RTLIL::SyncRule *sync_edge = NULL;
|
||||
RTLIL::SyncRule *sync_always = NULL;
|
||||
bool global_clock = false;
|
||||
|
||||
std::map<RTLIL::SigSpec, std::set<RTLIL::SyncRule*>> many_async_rules;
|
||||
// A priority ordered set of rules, pairing the value to be assigned for
|
||||
// that rule to the rule
|
||||
std::vector<std::pair<RTLIL::SigSpec, RTLIL::SyncRule*>> async_rules;
|
||||
|
||||
// Needed when the async rules are collapsed into one as async_rules
|
||||
// works with pointers to SyncRule
|
||||
RTLIL::SyncRule single_async_rule;
|
||||
|
||||
for (auto sync : proc->syncs)
|
||||
for (auto &action : sync->actions)
|
||||
|
|
@ -228,14 +176,9 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
|
|||
continue;
|
||||
|
||||
if (sync->type == RTLIL::SyncType::ST0 || sync->type == RTLIL::SyncType::ST1) {
|
||||
if (sync_level != NULL && sync_level != sync) {
|
||||
// log_error("Multiple level sensitive events found for this signal!\n");
|
||||
many_async_rules[rstval].insert(sync_level);
|
||||
rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
}
|
||||
rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
RTLIL::SigSpec rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
sig.replace(action.first, action.second, &rstval);
|
||||
sync_level = sync;
|
||||
async_rules.emplace_back(rstval, sync);
|
||||
}
|
||||
else if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) {
|
||||
if (sync_edge != NULL && sync_edge != sync)
|
||||
|
|
@ -260,59 +203,51 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
|
|||
action.first.remove2(sig, &action.second);
|
||||
}
|
||||
|
||||
if (many_async_rules.size() > 0)
|
||||
// If all async rules assign the same value, priority ordering between
|
||||
// them doesn't matter so they can be collapsed together into one rule
|
||||
// with the disjunction of triggers
|
||||
if (!async_rules.empty() &&
|
||||
std::all_of(async_rules.begin(), async_rules.end(), [&](auto& p) {
|
||||
return p.first == async_rules.front().first;
|
||||
}))
|
||||
{
|
||||
many_async_rules[rstval].insert(sync_level);
|
||||
if (many_async_rules.size() == 1)
|
||||
{
|
||||
sync_level = new RTLIL::SyncRule;
|
||||
sync_level->type = RTLIL::SyncType::ST1;
|
||||
sync_level->signal = mod->addWire(NEW_ID);
|
||||
sync_level->actions.push_back(RTLIL::SigSig(sig, rstval));
|
||||
free_sync_level = true;
|
||||
const auto rstval = async_rules.front().first;
|
||||
|
||||
RTLIL::SigSpec inputs, compare;
|
||||
for (auto &it : many_async_rules[rstval]) {
|
||||
inputs.append(it->signal);
|
||||
compare.append(it->type == RTLIL::SyncType::ST0 ? RTLIL::State::S1 : RTLIL::State::S0);
|
||||
}
|
||||
log_assert(inputs.size() == compare.size());
|
||||
// The trigger is the disjunction of existing triggers
|
||||
// (with appropriate negation)
|
||||
RTLIL::SigSpec triggers;
|
||||
for (const auto &[_, it] : async_rules)
|
||||
triggers.append(it->type == RTLIL::SyncType::ST1 ? it->signal : mod->Not(NEW_ID, it->signal));
|
||||
|
||||
RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($ne));
|
||||
cell->parameters[ID::A_SIGNED] = RTLIL::Const(false, 1);
|
||||
cell->parameters[ID::B_SIGNED] = RTLIL::Const(false, 1);
|
||||
cell->parameters[ID::A_WIDTH] = RTLIL::Const(inputs.size());
|
||||
cell->parameters[ID::B_WIDTH] = RTLIL::Const(inputs.size());
|
||||
cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
|
||||
cell->setPort(ID::A, inputs);
|
||||
cell->setPort(ID::B, compare);
|
||||
cell->setPort(ID::Y, sync_level->signal);
|
||||
// Put this into the dummy sync rule so it can be treated the same
|
||||
// as ones coming from the module
|
||||
single_async_rule.type = RTLIL::SyncType::ST1;
|
||||
single_async_rule.signal = mod->ReduceOr(NEW_ID, triggers);
|
||||
single_async_rule.actions.push_back(RTLIL::SigSig(sig, rstval));
|
||||
|
||||
many_async_rules.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
sync_level = NULL;
|
||||
}
|
||||
// Replace existing rules with this new rule
|
||||
async_rules.clear();
|
||||
async_rules.emplace_back(rstval, &single_async_rule);
|
||||
}
|
||||
|
||||
SigSpec sig_q = sig;
|
||||
ce.assign_map.apply(insig);
|
||||
ce.assign_map.apply(rstval);
|
||||
ce.assign_map.apply(sig);
|
||||
|
||||
if (rstval == sig && sync_level) {
|
||||
if (sync_level->type == RTLIL::SyncType::ST1)
|
||||
insig = mod->Mux(NEW_ID, insig, sig, sync_level->signal);
|
||||
// If the reset value assigns the reg to itself, add this as part of
|
||||
// the input signal and delete the rule
|
||||
if (async_rules.size() == 1 && async_rules.front().first == sig) {
|
||||
const auto& [_, rule] = async_rules.front();
|
||||
if (rule->type == RTLIL::SyncType::ST1)
|
||||
insig = mod->Mux(NEW_ID, insig, sig, rule->signal);
|
||||
else
|
||||
insig = mod->Mux(NEW_ID, sig, insig, sync_level->signal);
|
||||
rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
|
||||
sync_level = NULL;
|
||||
insig = mod->Mux(NEW_ID, sig, insig, rule->signal);
|
||||
|
||||
async_rules.clear();
|
||||
}
|
||||
|
||||
if (sync_always) {
|
||||
if (sync_edge || sync_level || many_async_rules.size() > 0)
|
||||
if (sync_edge || !async_rules.empty())
|
||||
log_error("Mixed always event with edge and/or level sensitive events!\n");
|
||||
log(" created direct connection (no actual register cell created).\n");
|
||||
mod->connect(RTLIL::SigSig(sig, insig));
|
||||
|
|
@ -322,28 +257,34 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
|
|||
if (!sync_edge && !global_clock)
|
||||
log_error("Missing edge-sensitive event for this signal!\n");
|
||||
|
||||
if (many_async_rules.size() > 0)
|
||||
// More than one reset value so we derive a dffsr formulation
|
||||
if (async_rules.size() > 1)
|
||||
{
|
||||
log_warning("Complex async reset for dff `%s'.\n", log_signal(sig));
|
||||
gen_dffsr_complex(mod, insig, sig, sync_edge->signal, sync_edge->type == RTLIL::SyncType::STp, many_async_rules, proc);
|
||||
gen_dffsr_complex(mod, insig, sig, sync_edge->signal, sync_edge->type == RTLIL::SyncType::STp, async_rules, proc);
|
||||
return;
|
||||
}
|
||||
else if (!rstval.is_fully_const() && !ce.eval(rstval))
|
||||
|
||||
// If there is a reset condition in the async rules, use it
|
||||
SigSpec rstval = async_rules.empty() ? RTLIL::SigSpec(RTLIL::State::Sz, sig.size()) : async_rules.front().first;
|
||||
RTLIL::SyncRule* sync_level = async_rules.empty() ? nullptr : async_rules.front().second;
|
||||
ce.assign_map.apply(rstval);
|
||||
|
||||
if (!rstval.is_fully_const() && !ce.eval(rstval))
|
||||
{
|
||||
log_warning("Async reset value `%s' is not constant!\n", log_signal(rstval));
|
||||
gen_aldff(mod, insig, rstval, sig_q,
|
||||
sync_edge->type == RTLIL::SyncType::STp,
|
||||
sync_level && sync_level->type == RTLIL::SyncType::ST1,
|
||||
sync_edge->signal, sync_level->signal, proc);
|
||||
return;
|
||||
}
|
||||
else
|
||||
gen_dff(mod, insig, rstval.as_const(), sig_q,
|
||||
sync_edge && sync_edge->type == RTLIL::SyncType::STp,
|
||||
sync_level && sync_level->type == RTLIL::SyncType::ST1,
|
||||
sync_edge ? sync_edge->signal : SigSpec(),
|
||||
sync_level ? &sync_level->signal : NULL, proc);
|
||||
|
||||
if (free_sync_level)
|
||||
delete sync_level;
|
||||
gen_dff(mod, insig, rstval.as_const(), sig_q,
|
||||
sync_edge && sync_edge->type == RTLIL::SyncType::STp,
|
||||
sync_level && sync_level->type == RTLIL::SyncType::ST1,
|
||||
sync_edge ? sync_edge->signal : SigSpec(),
|
||||
sync_level ? &sync_level->signal : NULL, proc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1718,7 +1718,7 @@ struct AbcPass : public Pass {
|
|||
show_tempdir = true;
|
||||
}
|
||||
|
||||
size_t argidx, g_argidx;
|
||||
size_t argidx, g_argidx = -1;
|
||||
bool g_arg_from_cmd = false;
|
||||
#if defined(__wasm)
|
||||
const char *pwd = ".";
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static void logmap_all()
|
|||
logmap(ID($_DFFSR_PPP_));
|
||||
}
|
||||
|
||||
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
|
||||
static bool parse_pin(const LibertyAst *cell, const LibertyAst *attr, std::string &pin_name, bool &pin_pol)
|
||||
{
|
||||
if (cell == nullptr || attr == nullptr || attr->value.empty())
|
||||
return false;
|
||||
|
|
@ -115,9 +115,9 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, std::vector<std::string> &dont_use_cells)
|
||||
static void find_cell(const LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, std::vector<std::string> &dont_use_cells)
|
||||
{
|
||||
LibertyAst *best_cell = nullptr;
|
||||
const LibertyAst *best_cell = nullptr;
|
||||
std::map<std::string, char> best_cell_ports;
|
||||
int best_cell_pins = 0;
|
||||
bool best_cell_noninv = false;
|
||||
|
|
@ -131,7 +131,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
if (cell->id != "cell" || cell->args.size() != 1)
|
||||
continue;
|
||||
|
||||
LibertyAst *dn = cell->find("dont_use");
|
||||
const LibertyAst *dn = cell->find("dont_use");
|
||||
if (dn != nullptr && dn->value == "true")
|
||||
continue;
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
if (dont_use)
|
||||
continue;
|
||||
|
||||
LibertyAst *ff = cell->find("ff");
|
||||
const LibertyAst *ff = cell->find("ff");
|
||||
if (ff == nullptr)
|
||||
continue;
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
this_cell_ports[cell_next_pin] = 'D';
|
||||
|
||||
double area = 0;
|
||||
LibertyAst *ar = cell->find("area");
|
||||
const LibertyAst *ar = cell->find("area");
|
||||
if (ar != nullptr && !ar->value.empty())
|
||||
area = atof(ar->value.c_str());
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
if (pin->id != "pin" || pin->args.size() != 1)
|
||||
continue;
|
||||
|
||||
LibertyAst *dir = pin->find("direction");
|
||||
const LibertyAst *dir = pin->find("direction");
|
||||
if (dir == nullptr || dir->value == "internal")
|
||||
continue;
|
||||
num_pins++;
|
||||
|
|
@ -194,7 +194,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
|
||||
goto continue_cell_loop;
|
||||
|
||||
LibertyAst *func = pin->find("function");
|
||||
const LibertyAst *func = pin->find("function");
|
||||
if (dir->value == "output" && func != nullptr) {
|
||||
std::string value = func->value;
|
||||
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
|
||||
|
|
@ -239,9 +239,9 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
}
|
||||
}
|
||||
|
||||
static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, std::vector<std::string> &dont_use_cells)
|
||||
static void find_cell_sr(const LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, std::vector<std::string> &dont_use_cells)
|
||||
{
|
||||
LibertyAst *best_cell = nullptr;
|
||||
const LibertyAst *best_cell = nullptr;
|
||||
std::map<std::string, char> best_cell_ports;
|
||||
int best_cell_pins = 0;
|
||||
bool best_cell_noninv = false;
|
||||
|
|
@ -255,7 +255,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
|
|||
if (cell->id != "cell" || cell->args.size() != 1)
|
||||
continue;
|
||||
|
||||
LibertyAst *dn = cell->find("dont_use");
|
||||
const LibertyAst *dn = cell->find("dont_use");
|
||||
if (dn != nullptr && dn->value == "true")
|
||||
continue;
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
|
|||
if (dont_use)
|
||||
continue;
|
||||
|
||||
LibertyAst *ff = cell->find("ff");
|
||||
const LibertyAst *ff = cell->find("ff");
|
||||
if (ff == nullptr)
|
||||
continue;
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
|
|||
this_cell_ports[cell_next_pin] = 'D';
|
||||
|
||||
double area = 0;
|
||||
LibertyAst *ar = cell->find("area");
|
||||
const LibertyAst *ar = cell->find("area");
|
||||
if (ar != nullptr && !ar->value.empty())
|
||||
area = atof(ar->value.c_str());
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
|
|||
if (pin->id != "pin" || pin->args.size() != 1)
|
||||
continue;
|
||||
|
||||
LibertyAst *dir = pin->find("direction");
|
||||
const LibertyAst *dir = pin->find("direction");
|
||||
if (dir == nullptr || dir->value == "internal")
|
||||
continue;
|
||||
num_pins++;
|
||||
|
|
@ -314,7 +314,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
|
|||
if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
|
||||
goto continue_cell_loop;
|
||||
|
||||
LibertyAst *func = pin->find("function");
|
||||
const LibertyAst *func = pin->find("function");
|
||||
if (dir->value == "output" && func != nullptr) {
|
||||
std::string value = func->value;
|
||||
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
|
||||
|
|
|
|||
|
|
@ -32,9 +32,6 @@
|
|||
|
||||
using namespace Yosys;
|
||||
|
||||
std::set<std::string> LibertyAst::blacklist;
|
||||
std::set<std::string> LibertyAst::whitelist;
|
||||
|
||||
LibertyAst::~LibertyAst()
|
||||
{
|
||||
for (auto child : children)
|
||||
|
|
@ -42,7 +39,7 @@ LibertyAst::~LibertyAst()
|
|||
children.clear();
|
||||
}
|
||||
|
||||
LibertyAst *LibertyAst::find(std::string name)
|
||||
const LibertyAst *LibertyAst::find(std::string name) const
|
||||
{
|
||||
for (auto child : children)
|
||||
if (child->id == name)
|
||||
|
|
@ -50,7 +47,7 @@ LibertyAst *LibertyAst::find(std::string name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void LibertyAst::dump(FILE *f, std::string indent, std::string path, bool path_ok)
|
||||
void LibertyAst::dump(FILE *f, sieve &blacklist, sieve &whitelist, std::string indent, std::string path, bool path_ok) const
|
||||
{
|
||||
if (whitelist.count(path + "/*") > 0)
|
||||
path_ok = true;
|
||||
|
|
@ -77,7 +74,7 @@ void LibertyAst::dump(FILE *f, std::string indent, std::string path, bool path_o
|
|||
if (!children.empty()) {
|
||||
fprintf(f, " {\n");
|
||||
for (size_t i = 0; i < children.size(); i++)
|
||||
children[i]->dump(f, indent + " ", path, path_ok);
|
||||
children[i]->dump(f, blacklist, whitelist, indent + " ", path, path_ok);
|
||||
fprintf(f, "%s}\n", indent.c_str());
|
||||
} else
|
||||
fprintf(f, " ;\n");
|
||||
|
|
@ -406,9 +403,9 @@ void LibertyParser::error(const std::string &str)
|
|||
|
||||
/**** END: http://svn.clairexen.net/tools/trunk/examples/check.h ****/
|
||||
|
||||
LibertyAst *find_non_null(LibertyAst *node, const char *name)
|
||||
const LibertyAst *find_non_null(const LibertyAst *node, const char *name)
|
||||
{
|
||||
LibertyAst *ret = node->find(name);
|
||||
const LibertyAst *ret = node->find(name);
|
||||
if (ret == NULL)
|
||||
fprintf(stderr, "Error: expected to find `%s' node.\n", name);
|
||||
return ret;
|
||||
|
|
@ -455,7 +452,7 @@ std::string func2vl(std::string str)
|
|||
return str;
|
||||
}
|
||||
|
||||
void event2vl(LibertyAst *ast, std::string &edge, std::string &expr)
|
||||
void event2vl(const LibertyAst *ast, std::string &edge, std::string &expr)
|
||||
{
|
||||
edge.clear();
|
||||
expr.clear();
|
||||
|
|
@ -489,7 +486,7 @@ void clear_preset_var(std::string var, std::string type)
|
|||
}
|
||||
}
|
||||
|
||||
void gen_verilogsim_cell(LibertyAst *ast)
|
||||
void gen_verilogsim_cell(const LibertyAst *ast)
|
||||
{
|
||||
if (ast->find("statetable") != NULL)
|
||||
return;
|
||||
|
|
@ -522,8 +519,8 @@ void gen_verilogsim_cell(LibertyAst *ast)
|
|||
if (child->id != "pin")
|
||||
continue;
|
||||
CHECK_NV(child->args.size(), == 1);
|
||||
LibertyAst *dir = find_non_null(child, "direction");
|
||||
LibertyAst *func = child->find("function");
|
||||
const LibertyAst *dir = find_non_null(child, "direction");
|
||||
const LibertyAst *func = child->find("function");
|
||||
printf(" %s %s;\n", dir->value.c_str(), child->args[0].c_str());
|
||||
if (func != NULL)
|
||||
printf(" assign %s = %s; // %s\n", child->args[0].c_str(), func2vl(func->value).c_str(), func->value.c_str());
|
||||
|
|
@ -649,7 +646,7 @@ void gen_verilogsim_cell(LibertyAst *ast)
|
|||
printf("endmodule\n");
|
||||
}
|
||||
|
||||
void gen_verilogsim(LibertyAst *ast)
|
||||
void gen_verilogsim(const LibertyAst *ast)
|
||||
{
|
||||
CHECK_COND(ast->id == "library");
|
||||
|
||||
|
|
@ -668,6 +665,7 @@ void usage()
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
bool flag_verilogsim = false;
|
||||
std::set<std::string> whitelist, blacklist;
|
||||
|
||||
if (argc > 3)
|
||||
usage();
|
||||
|
|
@ -678,26 +676,26 @@ int main(int argc, char **argv)
|
|||
flag_verilogsim = true;
|
||||
if (!strcmp(argv[1], "-") || !strcmp(argv[1], "-verilogsim"))
|
||||
{
|
||||
LibertyAst::whitelist.insert("/library");
|
||||
LibertyAst::whitelist.insert("/library/cell");
|
||||
LibertyAst::whitelist.insert("/library/cell/area");
|
||||
LibertyAst::whitelist.insert("/library/cell/cell_footprint");
|
||||
LibertyAst::whitelist.insert("/library/cell/dont_touch");
|
||||
LibertyAst::whitelist.insert("/library/cell/dont_use");
|
||||
LibertyAst::whitelist.insert("/library/cell/ff");
|
||||
LibertyAst::whitelist.insert("/library/cell/ff/*");
|
||||
LibertyAst::whitelist.insert("/library/cell/latch");
|
||||
LibertyAst::whitelist.insert("/library/cell/latch/*");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin/clock");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin/direction");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin/driver_type");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin/function");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin_opposite");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin/state_function");
|
||||
LibertyAst::whitelist.insert("/library/cell/pin/three_state");
|
||||
LibertyAst::whitelist.insert("/library/cell/statetable");
|
||||
LibertyAst::whitelist.insert("/library/cell/statetable/*");
|
||||
whitelist.insert("/library");
|
||||
whitelist.insert("/library/cell");
|
||||
whitelist.insert("/library/cell/area");
|
||||
whitelist.insert("/library/cell/cell_footprint");
|
||||
whitelist.insert("/library/cell/dont_touch");
|
||||
whitelist.insert("/library/cell/dont_use");
|
||||
whitelist.insert("/library/cell/ff");
|
||||
whitelist.insert("/library/cell/ff/*");
|
||||
whitelist.insert("/library/cell/latch");
|
||||
whitelist.insert("/library/cell/latch/*");
|
||||
whitelist.insert("/library/cell/pin");
|
||||
whitelist.insert("/library/cell/pin/clock");
|
||||
whitelist.insert("/library/cell/pin/direction");
|
||||
whitelist.insert("/library/cell/pin/driver_type");
|
||||
whitelist.insert("/library/cell/pin/function");
|
||||
whitelist.insert("/library/cell/pin_opposite");
|
||||
whitelist.insert("/library/cell/pin/state_function");
|
||||
whitelist.insert("/library/cell/pin/three_state");
|
||||
whitelist.insert("/library/cell/statetable");
|
||||
whitelist.insert("/library/cell/statetable/*");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -723,10 +721,10 @@ int main(int argc, char **argv)
|
|||
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n' || *p == '#') {
|
||||
if (!id.empty()) {
|
||||
if (mode == '-')
|
||||
LibertyAst::blacklist.insert(id);
|
||||
blacklist.insert(id);
|
||||
else
|
||||
if (mode == '+')
|
||||
LibertyAst::whitelist.insert(id);
|
||||
whitelist.insert(id);
|
||||
else
|
||||
goto syntax_error;
|
||||
}
|
||||
|
|
@ -764,7 +762,7 @@ int main(int argc, char **argv)
|
|||
if (flag_verilogsim)
|
||||
gen_verilogsim(parser.ast);
|
||||
else
|
||||
parser.ast->dump(stdout);
|
||||
parser.ast->dump(stdout, blacklist, whitelist);
|
||||
}
|
||||
|
||||
if (argc == 3)
|
||||
|
|
|
|||
|
|
@ -33,32 +33,35 @@ namespace Yosys
|
|||
std::vector<std::string> args;
|
||||
std::vector<LibertyAst*> children;
|
||||
~LibertyAst();
|
||||
LibertyAst *find(std::string name);
|
||||
void dump(FILE *f, std::string indent = "", std::string path = "", bool path_ok = false);
|
||||
static std::set<std::string> blacklist;
|
||||
static std::set<std::string> whitelist;
|
||||
const LibertyAst *find(std::string name) const;
|
||||
|
||||
typedef std::set<std::string> sieve;
|
||||
void dump(FILE *f, sieve &blacklist, sieve &whitelist, std::string indent = "", std::string path = "", bool path_ok = false) const;
|
||||
};
|
||||
|
||||
struct LibertyParser
|
||||
class LibertyParser
|
||||
{
|
||||
private:
|
||||
std::istream &f;
|
||||
int line;
|
||||
LibertyAst *ast;
|
||||
LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {}
|
||||
~LibertyParser() { if (ast) delete ast; }
|
||||
|
||||
/* lexer return values:
|
||||
'v': identifier, string, array range [...] -> str holds the token string
|
||||
'n': newline
|
||||
anything else is a single character.
|
||||
*/
|
||||
|
||||
/* lexer return values:
|
||||
'v': identifier, string, array range [...] -> str holds the token string
|
||||
'n': newline
|
||||
anything else is a single character.
|
||||
*/
|
||||
int lexer(std::string &str);
|
||||
|
||||
LibertyAst *parse();
|
||||
LibertyAst *parse();
|
||||
void error();
|
||||
void error(const std::string &str);
|
||||
void error(const std::string &str);
|
||||
|
||||
public:
|
||||
const LibertyAst *ast;
|
||||
|
||||
LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {}
|
||||
~LibertyParser() { if (ast) delete ast; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -371,6 +371,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $shl (A, B, Y)
|
||||
//-
|
||||
//- A logical shift-left operation. This corresponds to the Verilog '<<' operator.
|
||||
//-
|
||||
module \$shl (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -395,6 +401,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $shr (A, B, Y)
|
||||
//-
|
||||
//- A logical shift-right operation. This corresponds to the Verilog '>>' operator.
|
||||
//-
|
||||
module \$shr (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -419,6 +431,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $sshl (A, B, Y)
|
||||
//-
|
||||
//- An arithmatic shift-left operation.
|
||||
//- This corresponds to the Verilog '<<<' operator.
|
||||
//-
|
||||
module \$sshl (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -443,6 +462,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $sshr (A, B, Y)
|
||||
//-
|
||||
//- An arithmatic shift-right operation.
|
||||
//- This corresponds to the Verilog '>>>' operator.
|
||||
//-
|
||||
module \$sshr (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -639,6 +665,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $lt (A, B, Y)
|
||||
//-
|
||||
//- A less-than comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '<' operator.
|
||||
//-
|
||||
module \$lt (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -663,6 +696,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $le (A, B, Y)
|
||||
//-
|
||||
//- A less-than-or-equal-to comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '<=' operator.
|
||||
//-
|
||||
module \$le (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -687,6 +727,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $eq (A, B, Y)
|
||||
//-
|
||||
//- An equality comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '==' operator.
|
||||
//-
|
||||
module \$eq (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -711,6 +758,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $ne (A, B, Y)
|
||||
//-
|
||||
//- An inequality comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '!=' operator.
|
||||
//-
|
||||
module \$ne (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -735,6 +789,15 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $eqx (A, B, Y)
|
||||
//-
|
||||
//- An exact equality comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '===' operator.
|
||||
//- Unlike equality comparison that can give 'x' as output,
|
||||
//- an exact equality comparison will strictly give '0' or '1' as output.
|
||||
//-
|
||||
module \$eqx (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -759,6 +822,15 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $nex (A, B, Y)
|
||||
//-
|
||||
//- An exact inequality comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '!==' operator.
|
||||
//- Unlike inequality comparison that can give 'x' as output,
|
||||
//- an exact inequality comparison will strictly give '0' or '1' as output.
|
||||
//-
|
||||
module \$nex (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -783,6 +855,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $ge (A, B, Y)
|
||||
//-
|
||||
//- A greater-than-or-equal-to comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '>=' operator.
|
||||
//-
|
||||
module \$ge (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -807,6 +886,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $gt (A, B, Y)
|
||||
//-
|
||||
//- A greater-than comparison between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '>' operator.
|
||||
//-
|
||||
module \$gt (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -831,6 +917,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $add (A, B, Y)
|
||||
//-
|
||||
//- Addition of inputs 'A' and 'B'. This corresponds to the Verilog '+' operator.
|
||||
//-
|
||||
module \$add (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -855,6 +947,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $sub (A, B, Y)
|
||||
//-
|
||||
//- Subtraction between inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '-' operator.
|
||||
//-
|
||||
module \$sub (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -879,6 +978,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $mul (A, B, Y)
|
||||
//-
|
||||
//- Multiplication of inputs 'A' and 'B'.
|
||||
//- This corresponds to the Verilog '*' operator.
|
||||
//-
|
||||
module \$mul (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -1191,6 +1297,14 @@ endgenerate
|
|||
endmodule
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $pow (A, B, Y)
|
||||
//-
|
||||
//- Exponentiation of an input (Y = A ** B).
|
||||
//- This corresponds to the Verilog '**' operator.
|
||||
//-
|
||||
`ifndef SIMLIB_NOPOW
|
||||
|
||||
module \$pow (A, B, Y);
|
||||
|
|
@ -1222,6 +1336,12 @@ endmodule
|
|||
`endif
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $logic_not (A, Y)
|
||||
//-
|
||||
//- A logical inverter. This corresponds to the Verilog unary prefix '!' operator.
|
||||
//-
|
||||
module \$logic_not (A, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -1243,6 +1363,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $logic_and (A, B, Y)
|
||||
//-
|
||||
//- A logical AND. This corresponds to the Verilog '&&' operator.
|
||||
//-
|
||||
module \$logic_and (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -1267,6 +1393,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $logic_or (A, B, Y)
|
||||
//-
|
||||
//- A logical OR. This corresponds to the Verilog '||' operator.
|
||||
//-
|
||||
module \$logic_or (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
@ -1306,6 +1438,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $concat (A, B, Y)
|
||||
//-
|
||||
//- Concatenation of inputs into a single output ( Y = {B, A} ).
|
||||
//-
|
||||
module \$concat (A, B, Y);
|
||||
|
||||
parameter A_WIDTH = 0;
|
||||
|
|
@ -1321,6 +1459,12 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $mux (A, B, S, Y)
|
||||
//-
|
||||
//- Multiplexer i.e selecting between two inputs based on select signal.
|
||||
//-
|
||||
module \$mux (A, B, S, Y);
|
||||
|
||||
parameter WIDTH = 0;
|
||||
|
|
@ -1396,6 +1540,13 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $demux (A, S, Y)
|
||||
//-
|
||||
//- Demultiplexer i.e routing single input to several outputs based on select signal.
|
||||
//- Unselected outputs are driven to zero.
|
||||
//-
|
||||
module \$demux (A, S, Y);
|
||||
|
||||
parameter WIDTH = 1;
|
||||
|
|
@ -1460,6 +1611,14 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $tribuf (A, EN, Y)
|
||||
//-
|
||||
//- A tri-state buffer.
|
||||
//- This buffer conditionally drives the output with the value of the input
|
||||
//- based on the enable signal.
|
||||
//-
|
||||
module \$tribuf (A, EN, Y);
|
||||
|
||||
parameter WIDTH = 0;
|
||||
|
|
|
|||
|
|
@ -618,6 +618,21 @@ module OSER4(D3, D2, D1, D0, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0);
|
|||
parameter HWL = "false";
|
||||
endmodule
|
||||
|
||||
module OSER4_MEM (Q0, Q1, D0, D1, D2, D3, TX0, TX1, PCLK, FCLK, TCLK, RESET) ;
|
||||
parameter GSREN = "";
|
||||
parameter LSREN = "";
|
||||
parameter HWL = "";
|
||||
parameter TCLK_SOURCE = "";
|
||||
parameter TXCLK_POL = "";
|
||||
|
||||
input D0, D1, D2, D3;
|
||||
input TX0, TX1;
|
||||
input PCLK, FCLK, TCLK, RESET;
|
||||
output Q0, Q1;
|
||||
|
||||
parameter ID = "";
|
||||
endmodule
|
||||
|
||||
module OSER8(D7, D6, D5, D4, D3, D2, D1, D0, TX3, TX2, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0);
|
||||
output Q1;
|
||||
output Q0;
|
||||
|
|
@ -729,6 +744,21 @@ RESET, CALIB, D);
|
|||
parameter LSREN = "true";
|
||||
endmodule
|
||||
|
||||
module IDES4_MEM (Q0, Q1, Q2, Q3, D, WADDR,
|
||||
RADDR, CALIB, PCLK, FCLK, ICLK, RESET) ;
|
||||
parameter GSREN = "";
|
||||
parameter LSREN = "";
|
||||
|
||||
input D, ICLK, FCLK, PCLK;
|
||||
input [2:0] WADDR;
|
||||
input [2:0] RADDR;
|
||||
input CALIB, RESET;
|
||||
|
||||
output Q0,Q1,Q2,Q3;
|
||||
|
||||
parameter ID = "";
|
||||
endmodule
|
||||
|
||||
module IDES8(Q7, Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK,
|
||||
RESET, CALIB, D);
|
||||
input D;
|
||||
|
|
@ -842,6 +872,28 @@ module IDDRC(D, CLK, CLEAR, Q0, Q1);
|
|||
parameter Q1_INIT = 1'b0;
|
||||
endmodule
|
||||
|
||||
module DQS(DQSR90, DQSW0, DQSW270, RPOINT, WPOINT, RVALID, RBURST, RFLAG,
|
||||
WFLAG, DQSIN, DLLSTEP, WSTEP, READ, RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR,
|
||||
HOLD, RCLKSEL, PCLK, FCLK, RESET) ;
|
||||
input DQSIN,PCLK,FCLK,RESET;
|
||||
input [3:0] READ;
|
||||
input [2:0] RCLKSEL;
|
||||
input [7:0] DLLSTEP;
|
||||
input [7:0] WSTEP;
|
||||
input RLOADN, RMOVE, RDIR, WLOADN, WMOVE, WDIR, HOLD;
|
||||
|
||||
output DQSR90, DQSW0, DQSW270;
|
||||
output [2:0] RPOINT, WPOINT;
|
||||
output RVALID,RBURST, RFLAG, WFLAG;
|
||||
|
||||
parameter FIFO_MODE_SEL = "";
|
||||
parameter RD_PNTR = "";
|
||||
parameter DQS_MODE = "";
|
||||
parameter HWL = "";
|
||||
parameter GSREN = "";
|
||||
parameter ID = "";
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module ODDR(D0, D1, TX, CLK, Q0, Q1);
|
||||
input D0;
|
||||
|
|
|
|||
31
techlibs/nanoxplore/Makefile.inc
Normal file
31
techlibs/nanoxplore/Makefile.inc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
OBJS += techlibs/nanoxplore/synth_nanoxplore.o
|
||||
OBJS += techlibs/nanoxplore/nx_carry.o
|
||||
|
||||
# Techmap
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/arith_map.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/brams_init.vh))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/brams_map.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/brams.txt))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb_l.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb_m.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb_u.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_map.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim_l.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim_m.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim_u.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap_l.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap_m.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap_u.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/io_map.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/latches_map.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_init.vh))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_l.txt))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_m.txt))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_u.txt))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_map_l.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_map_m.v))
|
||||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_map_u.v))
|
||||
76
techlibs/nanoxplore/arith_map.v
Normal file
76
techlibs/nanoxplore/arith_map.v
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.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
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
(* techmap_celltype = "$alu" *)
|
||||
module _80_nx_cy_alu (A, B, CI, BI, X, Y, CO);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
(* force_downto *)
|
||||
input [A_WIDTH-1:0] A;
|
||||
(* force_downto *)
|
||||
input [B_WIDTH-1:0] B;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] X, Y;
|
||||
|
||||
input CI, BI;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] CO;
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] COx;
|
||||
|
||||
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
|
||||
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] A_buf, B_buf;
|
||||
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
|
||||
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
||||
|
||||
genvar i;
|
||||
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice
|
||||
NX_CY_1BIT #(.first(i==0))
|
||||
alu_i (
|
||||
.CI(i==0 ? CI : COx[i-1]),
|
||||
.A(AA[i]),
|
||||
.B(BB[i]),
|
||||
.S(Y[i]),
|
||||
.CO(COx[i])
|
||||
);
|
||||
|
||||
end: slice
|
||||
endgenerate
|
||||
|
||||
NX_CY_1BIT alu_cout(
|
||||
.CI(COx[Y_WIDTH-1]),
|
||||
.A(1'b0),
|
||||
.B(1'b0),
|
||||
.S(CO[Y_WIDTH-1])
|
||||
);
|
||||
|
||||
/* End implementation */
|
||||
assign X = AA ^ BB;
|
||||
endmodule
|
||||
50
techlibs/nanoxplore/brams.txt
Normal file
50
techlibs/nanoxplore/brams.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
ram block $__NX_RAM_ {
|
||||
option "STD_MODE" "NOECC_48kx1" {
|
||||
# only 32k used
|
||||
abits 15;
|
||||
widths 1 per_port;
|
||||
}
|
||||
option "STD_MODE" "NOECC_24kx2" {
|
||||
# only 16k used
|
||||
abits 14;
|
||||
widths 2 per_port;
|
||||
}
|
||||
ifndef IS_NG_MEDIUM {
|
||||
option "STD_MODE" "NOECC_16kx3" {
|
||||
abits 14;
|
||||
widths 3 per_port;
|
||||
}
|
||||
}
|
||||
option "STD_MODE" "NOECC_12kx4" {
|
||||
# only 8k used
|
||||
abits 13;
|
||||
widths 4 per_port;
|
||||
}
|
||||
ifndef IS_NG_MEDIUM {
|
||||
option "STD_MODE" "NOECC_8kx6" {
|
||||
abits 13;
|
||||
widths 6 per_port;
|
||||
}
|
||||
}
|
||||
option "STD_MODE" "NOECC_6kx8" {
|
||||
# only 4k used
|
||||
abits 12;
|
||||
widths 8 per_port;
|
||||
}
|
||||
option "STD_MODE" "NOECC_4kx12" {
|
||||
abits 12;
|
||||
widths 12 per_port;
|
||||
}
|
||||
option "STD_MODE" "NOECC_2kx24" {
|
||||
abits 11;
|
||||
widths 24 per_port;
|
||||
}
|
||||
cost 64;
|
||||
init no_undef;
|
||||
port srsw "A" "B" {
|
||||
clock anyedge;
|
||||
clken;
|
||||
rdwr no_change;
|
||||
rdinit none;
|
||||
}
|
||||
}
|
||||
23
techlibs/nanoxplore/brams_init.vh
Normal file
23
techlibs/nanoxplore/brams_init.vh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
function [409600-1:0] bram_init_to_string;
|
||||
input [49152-1:0] array;
|
||||
input integer blocks;
|
||||
input integer width;
|
||||
reg [409600-1:0] temp; // (49152+2048)*8 48K bit data + 2k commas
|
||||
reg [24-1:0] temp2;
|
||||
integer i;
|
||||
integer j;
|
||||
begin
|
||||
temp = "";
|
||||
for (i = 0; i < 2048; i = i + 1) begin
|
||||
if (i != 0) begin
|
||||
temp = {temp, ","};
|
||||
end
|
||||
temp2 = 24'b0;
|
||||
for (j = 0; j < blocks; j = j + 1) begin
|
||||
temp2[j*width +: width] = array[{j, i[10:0]}*width +: width];
|
||||
end
|
||||
temp = {temp, $sformatf("%b",temp2[23:0])};
|
||||
end
|
||||
bram_init_to_string = temp;
|
||||
end
|
||||
endfunction
|
||||
84
techlibs/nanoxplore/brams_map.v
Normal file
84
techlibs/nanoxplore/brams_map.v
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
module $__NX_RAM_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_STD_MODE = "NOECC_24kx2";
|
||||
|
||||
parameter PORT_A_WIDTH = 24;
|
||||
parameter PORT_B_WIDTH = 24;
|
||||
|
||||
parameter PORT_A_CLK_POL = 1;
|
||||
|
||||
input PORT_A_CLK;
|
||||
input PORT_A_CLK_EN;
|
||||
input PORT_A_WR_EN;
|
||||
input [15:0] PORT_A_ADDR;
|
||||
input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
|
||||
wire [24-1:0] A_DATA;
|
||||
output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
|
||||
|
||||
parameter PORT_B_CLK_POL = 1;
|
||||
|
||||
input PORT_B_CLK;
|
||||
input PORT_B_CLK_EN;
|
||||
input PORT_B_WR_EN;
|
||||
input [15:0] PORT_B_ADDR;
|
||||
input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
|
||||
wire [24-1:0] B_DATA;
|
||||
output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
|
||||
|
||||
`include "brams_init.vh"
|
||||
|
||||
localparam raw_config1_val = OPTION_STD_MODE == "NOECC_48kx1" ? 16'b0000000000000000:
|
||||
OPTION_STD_MODE == "NOECC_24kx2" ? 16'b0000001001001001:
|
||||
OPTION_STD_MODE == "NOECC_16kx3" ? 16'b0000110110110110:
|
||||
OPTION_STD_MODE == "NOECC_12kx4" ? 16'b0000010010010010:
|
||||
OPTION_STD_MODE == "NOECC_8kx6" ? 16'b0000111111111111:
|
||||
OPTION_STD_MODE == "NOECC_6kx8" ? 16'b0000011011011011:
|
||||
OPTION_STD_MODE == "NOECC_4kx12" ? 16'b0000100100100100:
|
||||
OPTION_STD_MODE == "NOECC_2kx24" ? 16'b0000101101101101:
|
||||
16'bx;
|
||||
|
||||
localparam A_REPEAT = 24 / PORT_A_WIDTH;
|
||||
localparam B_REPEAT = 24 / PORT_B_WIDTH;
|
||||
|
||||
assign A_DATA = {A_REPEAT{PORT_A_WR_DATA[PORT_A_WIDTH-1:0]}};
|
||||
assign B_DATA = {B_REPEAT{PORT_B_WR_DATA[PORT_B_WIDTH-1:0]}};
|
||||
|
||||
NX_RAM_WRAP #(
|
||||
.std_mode(OPTION_STD_MODE),
|
||||
.mcka_edge(PORT_A_CLK_POL == 1 ? 1'b0 : 1'b1),
|
||||
.mckb_edge(PORT_B_CLK_POL == 1 ? 1'b0 : 1'b1),
|
||||
.pcka_edge(PORT_A_CLK_POL == 1 ? 1'b0 : 1'b1),
|
||||
.pckb_edge(PORT_B_CLK_POL == 1 ? 1'b0 : 1'b1),
|
||||
.raw_config0(4'b0000),
|
||||
.raw_config1(raw_config1_val[15:0]),
|
||||
.mem_ctxt($sformatf("%s",bram_init_to_string(INIT,A_REPEAT,PORT_A_WIDTH))),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ACK(PORT_A_CLK),
|
||||
//.ACKS(PORT_A_CLK),
|
||||
//.ACKD(), // Not used in Non-ECC modes
|
||||
//.ACKR(),
|
||||
//.AR(),
|
||||
//.ACOR(),
|
||||
//.AERR(),
|
||||
.ACS(PORT_A_CLK_EN),
|
||||
.AWE(PORT_A_WR_EN),
|
||||
|
||||
.AA(PORT_A_ADDR),
|
||||
.AI(A_DATA),
|
||||
.AO(PORT_A_RD_DATA),
|
||||
|
||||
.BCK(PORT_B_CLK),
|
||||
//.BCKC(PORT_B_CLK),
|
||||
//.BCKD(), // Not used in Non-ECC modes
|
||||
//.BCKR()
|
||||
//.BR(),
|
||||
//.BCOR(),
|
||||
//.BERR(),
|
||||
.BCS(PORT_B_CLK_EN),
|
||||
.BWE(PORT_B_WR_EN),
|
||||
.BA(PORT_B_ADDR),
|
||||
.BI(B_DATA),
|
||||
.BO(PORT_B_RD_DATA)
|
||||
);
|
||||
endmodule
|
||||
127
techlibs/nanoxplore/cells_bb.v
Normal file
127
techlibs/nanoxplore/cells_bb.v
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
// NX_RAM related
|
||||
(* blackbox *)
|
||||
module NX_ECC(CKD, CHK, COR, ERR);
|
||||
input CHK;
|
||||
input CKD;
|
||||
output COR;
|
||||
output ERR;
|
||||
endmodule
|
||||
|
||||
//TODO
|
||||
(* blackbox *)
|
||||
module NX_IOM_BIN2GRP(GS, DS, GVON, GVIN, GVDN, PA, LA);
|
||||
input [1:0] DS;
|
||||
input GS;
|
||||
output [2:0] GVDN;
|
||||
output [2:0] GVIN;
|
||||
output [2:0] GVON;
|
||||
input [5:0] LA;
|
||||
output [3:0] PA;
|
||||
endmodule
|
||||
|
||||
//TODO
|
||||
(* blackbox *)
|
||||
module NX_SER(FCK, SCK, R, IO, DCK, DRL, I, DS, DRA, DRI, DRO, DID);
|
||||
input DCK;
|
||||
output [5:0] DID;
|
||||
input [5:0] DRA;
|
||||
input [5:0] DRI;
|
||||
input DRL;
|
||||
output [5:0] DRO;
|
||||
input [1:0] DS;
|
||||
input FCK;
|
||||
input [4:0] I;
|
||||
output IO;
|
||||
input R;
|
||||
input SCK;
|
||||
parameter data_size = 5;
|
||||
parameter differential = "";
|
||||
parameter drive = "";
|
||||
parameter location = "";
|
||||
parameter locked = 1'b0;
|
||||
parameter outputCapacity = "";
|
||||
parameter outputDelayLine = "";
|
||||
parameter slewRate = "";
|
||||
parameter spath_dynamic = 1'b0;
|
||||
parameter standard = "";
|
||||
endmodule
|
||||
|
||||
//TODO
|
||||
(* blackbox *)
|
||||
module NX_DES(FCK, SCK, R, IO, DCK, DRL, DIG, FZ, FLD, FLG, O, DS, DRA, DRI, DRO, DID);
|
||||
input DCK;
|
||||
output [5:0] DID;
|
||||
input DIG;
|
||||
input [5:0] DRA;
|
||||
input [5:0] DRI;
|
||||
input DRL;
|
||||
output [5:0] DRO;
|
||||
input [1:0] DS;
|
||||
input FCK;
|
||||
output FLD;
|
||||
output FLG;
|
||||
input FZ;
|
||||
input IO;
|
||||
output [4:0] O;
|
||||
input R;
|
||||
input SCK;
|
||||
parameter data_size = 5;
|
||||
parameter differential = "";
|
||||
parameter dpath_dynamic = 1'b0;
|
||||
parameter drive = "";
|
||||
parameter inputDelayLine = "";
|
||||
parameter inputSignalSlope = "";
|
||||
parameter location = "";
|
||||
parameter locked = 1'b0;
|
||||
parameter standard = "";
|
||||
parameter termination = "";
|
||||
parameter terminationReference = "";
|
||||
parameter turbo = "";
|
||||
parameter weakTermination = "";
|
||||
endmodule
|
||||
|
||||
//TODO
|
||||
(* blackbox *)
|
||||
module NX_SERDES(FCK, SCK, RTX, RRX, CI, CCK, CL, CR, IO, DCK, DRL, DIG, FZ, FLD, FLG, I, O, DS, DRA, DRI, DRO
|
||||
, DID);
|
||||
input CCK;
|
||||
input CI;
|
||||
input CL;
|
||||
input CR;
|
||||
input DCK;
|
||||
output [5:0] DID;
|
||||
input DIG;
|
||||
input [5:0] DRA;
|
||||
input [5:0] DRI;
|
||||
input DRL;
|
||||
output [5:0] DRO;
|
||||
input [1:0] DS;
|
||||
input FCK;
|
||||
output FLD;
|
||||
output FLG;
|
||||
input FZ;
|
||||
input [4:0] I;
|
||||
inout IO;
|
||||
output [4:0] O;
|
||||
input RRX;
|
||||
input RTX;
|
||||
input SCK;
|
||||
parameter cpath_registered = 1'b0;
|
||||
parameter data_size = 5;
|
||||
parameter differential = "";
|
||||
parameter dpath_dynamic = 1'b0;
|
||||
parameter drive = "";
|
||||
parameter inputDelayLine = "";
|
||||
parameter inputSignalSlope = "";
|
||||
parameter location = "";
|
||||
parameter locked = 1'b0;
|
||||
parameter outputCapacity = "";
|
||||
parameter outputDelayLine = "";
|
||||
parameter slewRate = "";
|
||||
parameter spath_dynamic = 1'b0;
|
||||
parameter standard = "";
|
||||
parameter termination = "";
|
||||
parameter terminationReference = "";
|
||||
parameter turbo = "";
|
||||
parameter weakTermination = "";
|
||||
endmodule
|
||||
2156
techlibs/nanoxplore/cells_bb_l.v
Normal file
2156
techlibs/nanoxplore/cells_bb_l.v
Normal file
File diff suppressed because it is too large
Load diff
1527
techlibs/nanoxplore/cells_bb_m.v
Normal file
1527
techlibs/nanoxplore/cells_bb_m.v
Normal file
File diff suppressed because it is too large
Load diff
2758
techlibs/nanoxplore/cells_bb_u.v
Normal file
2758
techlibs/nanoxplore/cells_bb_u.v
Normal file
File diff suppressed because it is too large
Load diff
95
techlibs/nanoxplore/cells_map.v
Normal file
95
techlibs/nanoxplore/cells_map.v
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
`default_nettype none
|
||||
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
parameter LUT = 0;
|
||||
|
||||
(* force_downto *)
|
||||
input [WIDTH-1:0] A;
|
||||
output Y;
|
||||
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
localparam [15:0] INIT = {{2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}},
|
||||
{2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}}};
|
||||
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I1(A[0]), .I2(1'b0), .I3(1'b0), .I4(1'b0));
|
||||
end else
|
||||
if (WIDTH == 2) begin
|
||||
localparam [15:0] INIT = {{4{LUT[3:0]}}, {4{LUT[3:0]}}, {4{LUT[3:0]}}, {4{LUT[3:0]}}};
|
||||
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I1(A[0]), .I2(A[1]), .I3(1'b0), .I4(1'b0), );
|
||||
end else
|
||||
if (WIDTH == 3) begin
|
||||
localparam [15:0] INIT = {{8{LUT[7:0]}}, {8{LUT[7:0]}}};
|
||||
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I1(A[0]), .I2(A[1]), .I3(A[2]), .I4(1'b0));
|
||||
end else
|
||||
if (WIDTH == 4) begin
|
||||
NX_LUT #(.lut_table(LUT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I1(A[0]), .I2(A[1]), .I3(A[2]), .I4(A[3]));
|
||||
end else begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$_DFF_[NP]P[01]_" *)
|
||||
module \$_DFF_xxxx_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_CELLTYPE_ = "";
|
||||
localparam dff_edge = _TECHMAP_CELLTYPE_[3*8 +: 8] == "N";
|
||||
localparam dff_type = _TECHMAP_CELLTYPE_[1*8 +: 8] == "1";
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b0), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(R), .O(Q));
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$_SDFF_[NP]P[01]_" *)
|
||||
module \$_SDFF_xxxx_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_CELLTYPE_ = "";
|
||||
localparam dff_edge = _TECHMAP_CELLTYPE_[3*8 +: 8] == "N";
|
||||
localparam dff_type = _TECHMAP_CELLTYPE_[1*8 +: 8] == "1";
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b1), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(R), .O(Q));
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$_DFFE_[NP]P[01]P_" *)
|
||||
module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
|
||||
parameter _TECHMAP_CELLTYPE_ = "";
|
||||
localparam dff_edge = _TECHMAP_CELLTYPE_[4*8 +: 8] == "N";
|
||||
localparam dff_type = _TECHMAP_CELLTYPE_[2*8 +: 8] == "1";
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(R), .O(Q));
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$_SDFFE_[NP]P[01]P_" *)
|
||||
module \$_SDFFE_xxxx_ (input D, C, R, E, output Q);
|
||||
parameter _TECHMAP_CELLTYPE_ = "";
|
||||
localparam dff_edge = _TECHMAP_CELLTYPE_[4*8 +: 8] == "N";
|
||||
localparam dff_type = _TECHMAP_CELLTYPE_[2*8 +: 8] == "1";
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b1), .dff_sync(1'b1), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(R), .O(Q));
|
||||
endmodule
|
||||
|
||||
module \$_DFF_P_ (input D, C, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b0), .dff_init(1'b0), .dff_load(1'b0), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(1'b0), .O(Q));
|
||||
endmodule
|
||||
|
||||
module \$_DFF_N_ (input D, C, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b1), .dff_init(1'b0), .dff_load(1'b0), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(1'b0), .O(Q));
|
||||
endmodule
|
||||
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b0), .dff_init(1'b0), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(1'b0), .O(Q));
|
||||
endmodule
|
||||
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b1), .dff_init(1'b0), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(1'b0), .O(Q));
|
||||
endmodule
|
||||
421
techlibs/nanoxplore/cells_sim.v
Normal file
421
techlibs/nanoxplore/cells_sim.v
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
(* abc9_lut=1 *)
|
||||
module NX_LUT(input I1, I2, I3, I4, output O);
|
||||
|
||||
parameter lut_table = 16'h0000;
|
||||
|
||||
wire [7:0] s1 = I4 ? lut_table[15:8] : lut_table[7:0];
|
||||
wire [3:0] s2 = I3 ? s1[7:4] : s1[3:0];
|
||||
wire [1:0] s3 = I2 ? s2[3:2] : s2[1:0];
|
||||
assign O = I1 ? s3[1] : s3[0];
|
||||
|
||||
endmodule
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_DFF(input I, CK, L, R, output reg O);
|
||||
|
||||
parameter dff_ctxt = 1'bx;
|
||||
parameter dff_edge = 1'b0;
|
||||
parameter dff_init = 1'b0;
|
||||
parameter dff_load = 1'b0;
|
||||
parameter dff_sync = 1'b0;
|
||||
parameter dff_type = 1'b0;
|
||||
|
||||
initial begin
|
||||
O = dff_ctxt;
|
||||
end
|
||||
|
||||
wire clock = CK ^ dff_edge;
|
||||
wire load = dff_load ? L : 1'b1;
|
||||
wire async_reset = !dff_sync && dff_init && R;
|
||||
wire sync_reset = dff_sync && dff_init && R;
|
||||
|
||||
always @(posedge clock, posedge async_reset)
|
||||
if (async_reset) O <= dff_type;
|
||||
else if (sync_reset) O <= dff_type;
|
||||
else if (load) O <= I;
|
||||
|
||||
endmodule
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_DFR(input I, CK, L, R, output O);
|
||||
|
||||
parameter data_inv = 1'b0;
|
||||
parameter dff_edge = 1'b0;
|
||||
parameter dff_init = 1'b0;
|
||||
parameter dff_load = 1'b0;
|
||||
parameter dff_sync = 1'b0;
|
||||
parameter dff_type = 1'b0;
|
||||
parameter iobname = "";
|
||||
parameter location = "";
|
||||
parameter mode = 0;
|
||||
parameter path = 0;
|
||||
parameter ring = 0;
|
||||
|
||||
wire clock = CK ^ dff_edge;
|
||||
wire load = dff_load ? L : 1'b1;
|
||||
wire async_reset = !dff_sync && dff_init && R;
|
||||
wire sync_reset = dff_sync && dff_init && R;
|
||||
reg O_reg;
|
||||
|
||||
always @(posedge clock, posedge async_reset)
|
||||
if (async_reset) O_reg <= dff_type;
|
||||
else if (sync_reset) O_reg <= dff_type;
|
||||
else if (load) O_reg <= I;
|
||||
|
||||
assign O = data_inv ? O_reg : ~O_reg;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_CY(input A1, A2, A3, A4, B1, B2, B3, B4, (* abc9_carry *) input CI, output S1, S2, S3, S4, (* abc9_carry *) output CO);
|
||||
parameter add_carry = 0;
|
||||
|
||||
wire CI_1;
|
||||
wire CO1, CO2, CO3;
|
||||
|
||||
assign CI_1 = (add_carry==2) ? CI : ((add_carry==1) ? 1'b1 : 1'b0);
|
||||
|
||||
assign { CO1, S1 } = A1 + B1 + CI_1;
|
||||
assign { CO2, S2 } = A2 + B2 + CO1;
|
||||
assign { CO3, S3 } = A3 + B3 + CO2;
|
||||
assign { CO, S4 } = A4 + B4 + CO3;
|
||||
|
||||
endmodule
|
||||
|
||||
module NX_IOB(I, C, T, O, IO);
|
||||
input C;
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
output O;
|
||||
input T;
|
||||
parameter differential = "";
|
||||
parameter drive = "";
|
||||
parameter dynDrive = "";
|
||||
parameter dynInput = "";
|
||||
parameter dynTerm = "";
|
||||
parameter extra = 3;
|
||||
parameter inputDelayLine = "";
|
||||
parameter inputDelayOn = "";
|
||||
parameter inputSignalSlope = "";
|
||||
parameter location = "";
|
||||
parameter locked = 1'b0;
|
||||
parameter outputCapacity = "";
|
||||
parameter outputDelayLine = "";
|
||||
parameter outputDelayOn = "";
|
||||
parameter slewRate = "";
|
||||
parameter standard = "";
|
||||
parameter termination = "";
|
||||
parameter terminationReference = "";
|
||||
parameter turbo = "";
|
||||
parameter weakTermination = "";
|
||||
|
||||
assign O = IO;
|
||||
assign IO = C ? I : 1'bz;
|
||||
endmodule
|
||||
|
||||
module NX_IOB_I(C, T, IO, O);
|
||||
input C;
|
||||
(* iopad_external_pin *)
|
||||
input IO;
|
||||
output O;
|
||||
input T;
|
||||
parameter differential = "";
|
||||
parameter drive = "";
|
||||
parameter dynDrive = "";
|
||||
parameter dynInput = "";
|
||||
parameter dynTerm = "";
|
||||
parameter extra = 1;
|
||||
parameter inputDelayLine = "";
|
||||
parameter inputDelayOn = "";
|
||||
parameter inputSignalSlope = "";
|
||||
parameter location = "";
|
||||
parameter locked = 1'b0;
|
||||
parameter outputCapacity = "";
|
||||
parameter outputDelayLine = "";
|
||||
parameter outputDelayOn = "";
|
||||
parameter slewRate = "";
|
||||
parameter standard = "";
|
||||
parameter termination = "";
|
||||
parameter terminationReference = "";
|
||||
parameter turbo = "";
|
||||
parameter weakTermination = "";
|
||||
|
||||
assign O = IO;
|
||||
endmodule
|
||||
|
||||
module NX_IOB_O(I, C, T, IO);
|
||||
input C;
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
output IO;
|
||||
input T;
|
||||
parameter differential = "";
|
||||
parameter drive = "";
|
||||
parameter dynDrive = "";
|
||||
parameter dynInput = "";
|
||||
parameter dynTerm = "";
|
||||
parameter extra = 2;
|
||||
parameter inputDelayLine = "";
|
||||
parameter inputDelayOn = "";
|
||||
parameter inputSignalSlope = "";
|
||||
parameter location = "";
|
||||
parameter locked = 1'b0;
|
||||
parameter outputCapacity = "";
|
||||
parameter outputDelayLine = "";
|
||||
parameter outputDelayOn = "";
|
||||
parameter slewRate = "";
|
||||
parameter standard = "";
|
||||
parameter termination = "";
|
||||
parameter terminationReference = "";
|
||||
parameter turbo = "";
|
||||
parameter weakTermination = "";
|
||||
|
||||
assign IO = C ? I : 1'bz;
|
||||
endmodule
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_CY_1BIT(CI, A, B, S, CO);
|
||||
(* abc9_carry *)
|
||||
input CI;
|
||||
input A;
|
||||
input B;
|
||||
output S;
|
||||
(* abc9_carry *)
|
||||
output CO;
|
||||
parameter first = 1'b0;
|
||||
|
||||
assign {CO, S} = A + B + CI;
|
||||
endmodule
|
||||
|
||||
module NX_BD(I, O);
|
||||
input I;
|
||||
output O;
|
||||
parameter mode = "global_lowskew";
|
||||
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module NX_BFF(I, O);
|
||||
input I;
|
||||
output O;
|
||||
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module NX_BFR(I, O);
|
||||
input I;
|
||||
output O;
|
||||
parameter data_inv = 1'b0;
|
||||
parameter iobname = "";
|
||||
parameter location = "";
|
||||
parameter mode = 0;
|
||||
parameter path = 0;
|
||||
parameter ring = 0;
|
||||
|
||||
assign O = data_inv ? ~I : I;
|
||||
endmodule
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_RAM(ACK, ACKC, ACKD, ACKR, BCK, BCKC, BCKD, BCKR, AI1, AI2, AI3, AI4, AI5, AI6, AI7, AI8, AI9, AI10, AI11, AI12, AI13
|
||||
, AI14, AI15, AI16, AI17, AI18, AI19, AI20, AI21, AI22, AI23, AI24, BI1, BI2, BI3, BI4, BI5, BI6, BI7, BI8, BI9, BI10
|
||||
, BI11, BI12, BI13, BI14, BI15, BI16, BI17, BI18, BI19, BI20, BI21, BI22, BI23, BI24, ACOR, AERR, BCOR, BERR, AO1, AO2, AO3
|
||||
, AO4, AO5, AO6, AO7, AO8, AO9, AO10, AO11, AO12, AO13, AO14, AO15, AO16, AO17, AO18, AO19, AO20, AO21, AO22, AO23, AO24
|
||||
, BO1, BO2, BO3, BO4, BO5, BO6, BO7, BO8, BO9, BO10, BO11, BO12, BO13, BO14, BO15, BO16, BO17, BO18, BO19, BO20, BO21
|
||||
, BO22, BO23, BO24, AA1, AA2, AA3, AA4, AA5, AA6, AA7, AA8, AA9, AA10, AA11, AA12, AA13, AA14, AA15, AA16, ACS, AWE
|
||||
, AR, BA1, BA2, BA3, BA4, BA5, BA6, BA7, BA8, BA9, BA10, BA11, BA12, BA13, BA14, BA15, BA16, BCS, BWE, BR);
|
||||
input AA1;
|
||||
input AA10;
|
||||
input AA11;
|
||||
input AA12;
|
||||
input AA13;
|
||||
input AA14;
|
||||
input AA15;
|
||||
input AA16;
|
||||
input AA2;
|
||||
input AA3;
|
||||
input AA4;
|
||||
input AA5;
|
||||
input AA6;
|
||||
input AA7;
|
||||
input AA8;
|
||||
input AA9;
|
||||
input ACK;
|
||||
input ACKC;
|
||||
input ACKD;
|
||||
input ACKR;
|
||||
output ACOR;
|
||||
input ACS;
|
||||
output AERR;
|
||||
input AI1;
|
||||
input AI10;
|
||||
input AI11;
|
||||
input AI12;
|
||||
input AI13;
|
||||
input AI14;
|
||||
input AI15;
|
||||
input AI16;
|
||||
input AI17;
|
||||
input AI18;
|
||||
input AI19;
|
||||
input AI2;
|
||||
input AI20;
|
||||
input AI21;
|
||||
input AI22;
|
||||
input AI23;
|
||||
input AI24;
|
||||
input AI3;
|
||||
input AI4;
|
||||
input AI5;
|
||||
input AI6;
|
||||
input AI7;
|
||||
input AI8;
|
||||
input AI9;
|
||||
output reg AO1;
|
||||
output reg AO10;
|
||||
output reg AO11;
|
||||
output reg AO12;
|
||||
output reg AO13;
|
||||
output reg AO14;
|
||||
output reg AO15;
|
||||
output reg AO16;
|
||||
output reg AO17;
|
||||
output reg AO18;
|
||||
output reg AO19;
|
||||
output reg AO2;
|
||||
output reg AO20;
|
||||
output reg AO21;
|
||||
output reg AO22;
|
||||
output reg AO23;
|
||||
output reg AO24;
|
||||
output reg AO3;
|
||||
output reg AO4;
|
||||
output reg AO5;
|
||||
output reg AO6;
|
||||
output reg AO7;
|
||||
output reg AO8;
|
||||
output reg AO9;
|
||||
input AR;
|
||||
input AWE;
|
||||
input BA1;
|
||||
input BA10;
|
||||
input BA11;
|
||||
input BA12;
|
||||
input BA13;
|
||||
input BA14;
|
||||
input BA15;
|
||||
input BA16;
|
||||
input BA2;
|
||||
input BA3;
|
||||
input BA4;
|
||||
input BA5;
|
||||
input BA6;
|
||||
input BA7;
|
||||
input BA8;
|
||||
input BA9;
|
||||
input BCK;
|
||||
input BCKC;
|
||||
input BCKD;
|
||||
input BCKR;
|
||||
output BCOR;
|
||||
input BCS;
|
||||
output BERR;
|
||||
input BI1;
|
||||
input BI10;
|
||||
input BI11;
|
||||
input BI12;
|
||||
input BI13;
|
||||
input BI14;
|
||||
input BI15;
|
||||
input BI16;
|
||||
input BI17;
|
||||
input BI18;
|
||||
input BI19;
|
||||
input BI2;
|
||||
input BI20;
|
||||
input BI21;
|
||||
input BI22;
|
||||
input BI23;
|
||||
input BI24;
|
||||
input BI3;
|
||||
input BI4;
|
||||
input BI5;
|
||||
input BI6;
|
||||
input BI7;
|
||||
input BI8;
|
||||
input BI9;
|
||||
output reg BO1;
|
||||
output reg BO10;
|
||||
output reg BO11;
|
||||
output reg BO12;
|
||||
output reg BO13;
|
||||
output reg BO14;
|
||||
output reg BO15;
|
||||
output reg BO16;
|
||||
output reg BO17;
|
||||
output reg BO18;
|
||||
output reg BO19;
|
||||
output reg BO2;
|
||||
output reg BO20;
|
||||
output reg BO21;
|
||||
output reg BO22;
|
||||
output reg BO23;
|
||||
output reg BO24;
|
||||
output reg BO3;
|
||||
output reg BO4;
|
||||
output reg BO5;
|
||||
output reg BO6;
|
||||
output reg BO7;
|
||||
output reg BO8;
|
||||
output reg BO9;
|
||||
input BR;
|
||||
input BWE;
|
||||
parameter mcka_edge = 1'b0;
|
||||
parameter mckb_edge = 1'b0;
|
||||
parameter mem_ctxt = "";
|
||||
parameter pcka_edge = 1'b0;
|
||||
parameter pckb_edge = 1'b0;
|
||||
parameter pipe_ia = 1'b0;
|
||||
parameter pipe_ib = 1'b0;
|
||||
parameter pipe_oa = 1'b0;
|
||||
parameter pipe_ob = 1'b0;
|
||||
parameter raw_config0 = 4'b0000;
|
||||
parameter raw_config1 = 16'b0000000000000000;
|
||||
//parameter raw_l_enable = 1'b0;
|
||||
//parameter raw_l_extend = 4'b0000;
|
||||
//parameter raw_u_enable = 1'b0;
|
||||
//parameter raw_u_extend = 8'b00000000;
|
||||
parameter std_mode = "";
|
||||
|
||||
reg [24-1:0] mem [2048-1:0]; // 48 Kbit of memory
|
||||
|
||||
/*integer i;
|
||||
initial begin
|
||||
for (i = 0; i < 2048; i = i + 1)
|
||||
mem[i] = 24'b0;
|
||||
end*/
|
||||
|
||||
wire [15:0] AA = { AA16, AA15, AA14, AA13, AA12, AA11, AA10, AA9, AA8, AA7, AA6, AA5, AA4, AA3, AA2, AA1 };
|
||||
wire [23:0] AI = { AI24, AI23, AI22, AI21, AI20, AI19, AI18, AI17, AI16, AI15, AI14, AI13, AI12, AI11, AI10, AI9, AI8, AI7, AI6, AI5, AI4, AI3, AI2, AI1 };
|
||||
wire [23:0] AO = { AO24, AO23, AO22, AO21, AO20, AO19, AO18, AO17, AO16, AO15, AO14, AO13, AO12, AO11, AO10, AO9, AO8, AO7, AO6, AO5, AO4, AO3, AO2, AO1 };
|
||||
wire [15:0] BA = { BA16, BA15, BA14, BA13, BA12, BA11, BA10, BA9, BA8, BA7, BA6, BA5, BA4, BA3, BA2, BA1 };
|
||||
wire [23:0] BI = { BI24, BI23, BI22, BI21, BI20, BI19, BI18, BI17, BI16, BI15, BI14, BI13, BI12, BI11, BI10, BI9, BI8, BI7, BI6, BI5, BI4, BI3, BI2, BI1 };
|
||||
wire [23:0] BO = { BO24, BO23, BO22, BO21, BO20, BO19, BO18, BO17, BO16, BO15, BO14, BO13, BO12, BO11, BO10, BO9, BO8, BO7, BO6, BO5, BO4, BO3, BO2, BO1 };
|
||||
|
||||
always @(posedge ACK)
|
||||
if (AWE)
|
||||
mem[AA[10:0]] <= AI;
|
||||
else
|
||||
{ AO24, AO23, AO22, AO21, AO20, AO19, AO18, AO17, AO16, AO15, AO14, AO13, AO12, AO11, AO10, AO9, AO8, AO7, AO6, AO5, AO4, AO3, AO2, AO1 } <= mem[AA[10:0]];
|
||||
assign ACOR = 1'b0;
|
||||
assign AERR = 1'b0;
|
||||
|
||||
always @(posedge BCK)
|
||||
if (BWE)
|
||||
mem[BA[10:0]] <= BI;
|
||||
else
|
||||
{ BO24, BO23, BO22, BO21, BO20, BO19, BO18, BO17, BO16, BO15, BO14, BO13, BO12, BO11, BO10, BO9, BO8, BO7, BO6, BO5, BO4, BO3, BO2, BO1 } <= mem[BA[10:0]];
|
||||
assign BCOR = 1'b0;
|
||||
assign BERR = 1'b0;
|
||||
endmodule
|
||||
0
techlibs/nanoxplore/cells_sim_l.v
Normal file
0
techlibs/nanoxplore/cells_sim_l.v
Normal file
0
techlibs/nanoxplore/cells_sim_m.v
Normal file
0
techlibs/nanoxplore/cells_sim_m.v
Normal file
306
techlibs/nanoxplore/cells_sim_u.v
Normal file
306
techlibs/nanoxplore/cells_sim_u.v
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
(* abc9_box, lib_whitebox *)
|
||||
module NX_GCK_U(SI1, SI2, CMD, SO);
|
||||
input CMD;
|
||||
input SI1;
|
||||
input SI2;
|
||||
output SO;
|
||||
parameter inv_in = 1'b0;
|
||||
parameter inv_out = 1'b0;
|
||||
parameter std_mode = "BYPASS";
|
||||
|
||||
wire SI1_int = inv_in ? ~SI1 : SI1;
|
||||
wire SI2_int = inv_in ? ~SI2 : SI2;
|
||||
|
||||
wire SO_int;
|
||||
generate
|
||||
if (std_mode == "BYPASS") begin
|
||||
assign SO_int = SI1_int;
|
||||
end
|
||||
else if (std_mode == "MUX") begin
|
||||
assign SO_int = CMD ? SI1_int : SI2_int;
|
||||
end
|
||||
else if (std_mode == "CKS") begin
|
||||
assign SO_int = CMD ? SI1_int : 1'b0;
|
||||
end
|
||||
else if (std_mode == "CSC") begin
|
||||
assign SO_int = CMD;
|
||||
end
|
||||
else
|
||||
$error("Unrecognised std_mode");
|
||||
endgenerate
|
||||
assign SO = inv_out ? ~SO_int : SO_int;
|
||||
endmodule
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_RFB_U(WCK, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20
|
||||
, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, I32, I33, I34, I35, I36, O1, O2, O3, O4, O5
|
||||
, O6, O7, O8, O9, O10, O11, O12, O13, O14, O15, O16, O17, O18, O19, O20, O21, O22, O23, O24, O25, O26
|
||||
, O27, O28, O29, O30, O31, O32, O33, O34, O35, O36, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA8, RA9, RA10, WA1
|
||||
, WA2, WA3, WA4, WA5, WA6, WE, WEA);
|
||||
input I1;
|
||||
input I10;
|
||||
input I11;
|
||||
input I12;
|
||||
input I13;
|
||||
input I14;
|
||||
input I15;
|
||||
input I16;
|
||||
input I17;
|
||||
input I18;
|
||||
input I19;
|
||||
input I2;
|
||||
input I20;
|
||||
input I21;
|
||||
input I22;
|
||||
input I23;
|
||||
input I24;
|
||||
input I25;
|
||||
input I26;
|
||||
input I27;
|
||||
input I28;
|
||||
input I29;
|
||||
input I3;
|
||||
input I30;
|
||||
input I31;
|
||||
input I32;
|
||||
input I33;
|
||||
input I34;
|
||||
input I35;
|
||||
input I36;
|
||||
input I4;
|
||||
input I5;
|
||||
input I6;
|
||||
input I7;
|
||||
input I8;
|
||||
input I9;
|
||||
output O1;
|
||||
output O10;
|
||||
output O11;
|
||||
output O12;
|
||||
output O13;
|
||||
output O14;
|
||||
output O15;
|
||||
output O16;
|
||||
output O17;
|
||||
output O18;
|
||||
output O19;
|
||||
output O2;
|
||||
output O20;
|
||||
output O21;
|
||||
output O22;
|
||||
output O23;
|
||||
output O24;
|
||||
output O25;
|
||||
output O26;
|
||||
output O27;
|
||||
output O28;
|
||||
output O29;
|
||||
output O3;
|
||||
output O30;
|
||||
output O31;
|
||||
output O32;
|
||||
output O33;
|
||||
output O34;
|
||||
output O35;
|
||||
output O36;
|
||||
output O4;
|
||||
output O5;
|
||||
output O6;
|
||||
output O7;
|
||||
output O8;
|
||||
output O9;
|
||||
input RA1;
|
||||
input RA10;
|
||||
input RA2;
|
||||
input RA3;
|
||||
input RA4;
|
||||
input RA5;
|
||||
input RA6;
|
||||
input RA7;
|
||||
input RA8;
|
||||
input RA9;
|
||||
input WA1;
|
||||
input WA2;
|
||||
input WA3;
|
||||
input WA4;
|
||||
input WA5;
|
||||
input WA6;
|
||||
input WCK;
|
||||
input WE;
|
||||
input WEA;
|
||||
parameter mem_ctxt = "";
|
||||
parameter mode = 0;
|
||||
parameter wck_edge = 1'b0;
|
||||
|
||||
wire clock = WCK ^ wck_edge;
|
||||
|
||||
localparam MEM_SIZE = mode == 2 ? 64 : 32;
|
||||
localparam MEM_WIDTH = mode == 3 ? 36 : 18;
|
||||
localparam ADDR_WIDTH = mode == 2 ? 6 : 5;
|
||||
localparam DATA_SIZE = MEM_SIZE * MEM_WIDTH;
|
||||
localparam MAX_SIZE = DATA_SIZE + MEM_SIZE + 1;
|
||||
|
||||
reg [MEM_WIDTH-1:0] mem [MEM_SIZE-1:0];
|
||||
|
||||
function [DATA_SIZE-1:0] convert_initval;
|
||||
input [8*MAX_SIZE-1:0] hex_initval;
|
||||
reg done;
|
||||
reg [DATA_SIZE-1:0] temp;
|
||||
reg [7:0] char;
|
||||
integer i,j;
|
||||
begin
|
||||
done = 1'b0;
|
||||
temp = 0;
|
||||
j = 0;
|
||||
for (i = 0; i < MAX_SIZE; i = i + 1) begin
|
||||
char = hex_initval[8*i +: 8];
|
||||
if (char >= "0" && char <= "1") begin
|
||||
temp[j] = char - "0";
|
||||
j = j + 1;
|
||||
end
|
||||
end
|
||||
convert_initval = temp;
|
||||
end
|
||||
endfunction
|
||||
|
||||
integer i;
|
||||
reg [DATA_SIZE-1:0] mem_data;
|
||||
initial begin
|
||||
mem_data = convert_initval(mem_ctxt);
|
||||
for (i = 0; i < MEM_SIZE; i = i + 1)
|
||||
mem[i] = mem_data[MEM_WIDTH*(MEM_SIZE-i-1) +: MEM_WIDTH];
|
||||
end
|
||||
|
||||
wire [ADDR_WIDTH-1:0] WA = (mode==2) ? { WA6, WA5, WA4, WA3, WA2, WA1 } : { WA5, WA4, WA3, WA2, WA1 };
|
||||
wire [36-1:0] O = { O36, O35, O34, O33, O32, O31, O30, O29, O28,
|
||||
O27, O26, O25, O24, O23, O22, O21, O20, O19,
|
||||
O18, O17, O16, O15, O14, O13, O12, O11, O10,
|
||||
O9, O8, O7, O6, O5, O4, O3, O2, O1 };
|
||||
wire [36-1:0] I = { I36, I35, I34, I33, I32, I31, I30, I29, I28,
|
||||
I27, I26, I25, I24, I23, I22, I21, I20, I19,
|
||||
I18, I17, I16, I15, I14, I13, I12, I11, I10,
|
||||
I9, I8, I7, I6, I5, I4, I3, I2, I1 };
|
||||
generate
|
||||
if (mode==0) begin
|
||||
assign O = mem[{ RA5, RA4, RA3, RA2, RA1 }];
|
||||
end
|
||||
else if (mode==1) begin
|
||||
assign O = mem[{ WA5, WA4, WA3, WA2, WA1 }];
|
||||
end
|
||||
else if (mode==2) begin
|
||||
assign O = mem[{ RA6, RA5, RA4, RA3, RA2, RA1 }];
|
||||
end
|
||||
else if (mode==3) begin
|
||||
assign O = mem[{ RA5, RA4, RA3, RA2, RA1 }];
|
||||
end
|
||||
else if (mode==4) begin
|
||||
assign O = { mem[{ RA10, RA9, RA8, RA7, RA6 }], mem[{ RA5, RA4, RA3, RA2, RA1 }] };
|
||||
end
|
||||
else
|
||||
$error("Unknown NX_RFB_U mode");
|
||||
endgenerate
|
||||
|
||||
always @(posedge clock)
|
||||
if (WE)
|
||||
mem[WA] <= I[MEM_WIDTH-1:0];
|
||||
endmodule
|
||||
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module NX_WFG_U(R, SI, ZI, SO, ZO);
|
||||
input R;
|
||||
input SI;
|
||||
output SO;
|
||||
input ZI;
|
||||
output ZO;
|
||||
parameter delay = 0;
|
||||
parameter delay_on = 1'b0;
|
||||
parameter div_phase = 1'b0;
|
||||
parameter div_ratio = 0;
|
||||
parameter location = "";
|
||||
parameter mode = 0;
|
||||
parameter pattern = 16'b0000000000000000;
|
||||
parameter pattern_end = 0;
|
||||
parameter reset_on_cal_lock_n = 1'b0;
|
||||
parameter reset_on_pll_lock_n = 1'b0;
|
||||
parameter reset_on_pll_locka_n = 1'b0;
|
||||
parameter wfg_edge = 1'b0;
|
||||
|
||||
generate
|
||||
if (mode==0) begin
|
||||
assign SO = SI;
|
||||
end
|
||||
else if (mode==1) begin
|
||||
wire clock = ZI ^ wfg_edge;
|
||||
wire reset = R || SI;
|
||||
reg [3:0] counter = 0;
|
||||
reg [15:0] rom = pattern;
|
||||
|
||||
always @(posedge clock)
|
||||
begin
|
||||
if (reset)
|
||||
counter <= 4'b0;
|
||||
else
|
||||
counter <= counter + 1;
|
||||
end
|
||||
assign SO = counter == pattern_end;
|
||||
assign ZO = rom[counter];
|
||||
end
|
||||
else if (mode==2) begin
|
||||
end
|
||||
else
|
||||
$error("Unknown NX_WFG_U mode");
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module NX_DDFR_U(CK,CKF,R,I,I2,L,O,O2);
|
||||
input CK;
|
||||
input CKF;
|
||||
input R;
|
||||
input I;
|
||||
input I2;
|
||||
input L;
|
||||
output O;
|
||||
output O2;
|
||||
|
||||
parameter location = "";
|
||||
parameter path = 0;
|
||||
parameter dff_type = 1'b0;
|
||||
parameter dff_sync = 1'b0;
|
||||
parameter dff_load = 1'b0;
|
||||
|
||||
wire load = dff_load ? 1'b1 : L; // reversed when compared to DFF
|
||||
wire async_reset = !dff_sync && R;
|
||||
wire sync_reset = dff_sync && R;
|
||||
|
||||
generate
|
||||
if (path==1) begin
|
||||
// IDDFR
|
||||
always @(posedge CK, posedge async_reset)
|
||||
if (async_reset) O <= dff_type;
|
||||
else if (sync_reset) O <= dff_type;
|
||||
else if (load) O <= I;
|
||||
|
||||
always @(posedge CKF, posedge async_reset)
|
||||
if (async_reset) O2 <= dff_type;
|
||||
else if (sync_reset) O2 <= dff_type;
|
||||
else if (load) O2 <= I;
|
||||
end
|
||||
else if (path==0 || path==2) begin
|
||||
reg q1, q2;
|
||||
// ODDFR
|
||||
always @(posedge CK, posedge async_reset)
|
||||
if (async_reset) q1 <= dff_type;
|
||||
else if (sync_reset) q1 <= dff_type;
|
||||
else if (load) q1 <= I;
|
||||
|
||||
always @(posedge CKF, posedge async_reset)
|
||||
if (async_reset) q2 <= dff_type;
|
||||
else if (sync_reset) q2 <= dff_type;
|
||||
else if (load) q2 <= I2;
|
||||
|
||||
assign O = CK ? q1 : q2;
|
||||
end
|
||||
else
|
||||
$error("Unknown NX_DDFR_U path");
|
||||
endgenerate
|
||||
endmodule
|
||||
201
techlibs/nanoxplore/cells_wrap.v
Normal file
201
techlibs/nanoxplore/cells_wrap.v
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
module NX_RAM_WRAP(ACK, ACKD, ACKR, BCK, BCKD, BCKR, ACOR, AERR, BCOR, BERR, ACS, AWE, AR, BCS, BWE, BR, BI, AO, BO, AI, AA
|
||||
, BA);
|
||||
input [15:0] AA;
|
||||
input ACK;
|
||||
input ACKD;
|
||||
input ACKR;
|
||||
output ACOR;
|
||||
input ACS;
|
||||
output AERR;
|
||||
input [23:0] AI;
|
||||
output [23:0] AO;
|
||||
input AR;
|
||||
input AWE;
|
||||
input [15:0] BA;
|
||||
input BCK;
|
||||
input BCKD;
|
||||
input BCKR;
|
||||
output BCOR;
|
||||
input BCS;
|
||||
output BERR;
|
||||
input [23:0] BI;
|
||||
output [23:0] BO;
|
||||
input BR;
|
||||
input BWE;
|
||||
parameter mcka_edge = 1'b0;
|
||||
parameter mckb_edge = 1'b0;
|
||||
parameter mem_ctxt = "";
|
||||
parameter pcka_edge = 1'b0;
|
||||
parameter pckb_edge = 1'b0;
|
||||
parameter pipe_ia = 1'b0;
|
||||
parameter pipe_ib = 1'b0;
|
||||
parameter pipe_oa = 1'b0;
|
||||
parameter pipe_ob = 1'b0;
|
||||
parameter raw_config0 = 4'b0000;
|
||||
parameter raw_config1 = 16'b0000000000000000;
|
||||
parameter std_mode = "";
|
||||
|
||||
NX_RAM #(
|
||||
.mcka_edge(mcka_edge),
|
||||
.mckb_edge(mckb_edge),
|
||||
.mem_ctxt(mem_ctxt),
|
||||
.pcka_edge(pcka_edge),
|
||||
.pckb_edge(pckb_edge),
|
||||
.pipe_ia(pipe_ia),
|
||||
.pipe_ib(pipe_ib),
|
||||
.pipe_oa(pipe_oa),
|
||||
.pipe_ob(pipe_ob),
|
||||
.raw_config0(raw_config0),
|
||||
.raw_config1(raw_config1),
|
||||
.std_mode(std_mode)
|
||||
) ram (
|
||||
.AA1(AA[0]),
|
||||
.AA10(AA[9]),
|
||||
.AA11(AA[10]),
|
||||
.AA12(AA[11]),
|
||||
.AA13(AA[12]),
|
||||
.AA14(AA[13]),
|
||||
.AA15(AA[14]),
|
||||
.AA16(AA[15]),
|
||||
.AA2(AA[1]),
|
||||
.AA3(AA[2]),
|
||||
.AA4(AA[3]),
|
||||
.AA5(AA[4]),
|
||||
.AA6(AA[5]),
|
||||
.AA7(AA[6]),
|
||||
.AA8(AA[7]),
|
||||
.AA9(AA[8]),
|
||||
.ACK(ACK),
|
||||
.ACKC(ACK),
|
||||
.ACKD(ACKD),
|
||||
.ACKR(ACKR),
|
||||
.ACOR(ACOR),
|
||||
.ACS(ACS),
|
||||
.AERR(AERR),
|
||||
.AI1(AI[0]),
|
||||
.AI10(AI[9]),
|
||||
.AI11(AI[10]),
|
||||
.AI12(AI[11]),
|
||||
.AI13(AI[12]),
|
||||
.AI14(AI[13]),
|
||||
.AI15(AI[14]),
|
||||
.AI16(AI[15]),
|
||||
.AI17(AI[16]),
|
||||
.AI18(AI[17]),
|
||||
.AI19(AI[18]),
|
||||
.AI2(AI[1]),
|
||||
.AI20(AI[19]),
|
||||
.AI21(AI[20]),
|
||||
.AI22(AI[21]),
|
||||
.AI23(AI[22]),
|
||||
.AI24(AI[23]),
|
||||
.AI3(AI[2]),
|
||||
.AI4(AI[3]),
|
||||
.AI5(AI[4]),
|
||||
.AI6(AI[5]),
|
||||
.AI7(AI[6]),
|
||||
.AI8(AI[7]),
|
||||
.AI9(AI[8]),
|
||||
.AO1(AO[0]),
|
||||
.AO10(AO[9]),
|
||||
.AO11(AO[10]),
|
||||
.AO12(AO[11]),
|
||||
.AO13(AO[12]),
|
||||
.AO14(AO[13]),
|
||||
.AO15(AO[14]),
|
||||
.AO16(AO[15]),
|
||||
.AO17(AO[16]),
|
||||
.AO18(AO[17]),
|
||||
.AO19(AO[18]),
|
||||
.AO2(AO[1]),
|
||||
.AO20(AO[19]),
|
||||
.AO21(AO[20]),
|
||||
.AO22(AO[21]),
|
||||
.AO23(AO[22]),
|
||||
.AO24(AO[23]),
|
||||
.AO3(AO[2]),
|
||||
.AO4(AO[3]),
|
||||
.AO5(AO[4]),
|
||||
.AO6(AO[5]),
|
||||
.AO7(AO[6]),
|
||||
.AO8(AO[7]),
|
||||
.AO9(AO[8]),
|
||||
.AR(AR),
|
||||
.AWE(AWE),
|
||||
.BA1(BA[0]),
|
||||
.BA10(BA[9]),
|
||||
.BA11(BA[10]),
|
||||
.BA12(BA[11]),
|
||||
.BA13(BA[12]),
|
||||
.BA14(BA[13]),
|
||||
.BA15(BA[14]),
|
||||
.BA16(BA[15]),
|
||||
.BA2(BA[1]),
|
||||
.BA3(BA[2]),
|
||||
.BA4(BA[3]),
|
||||
.BA5(BA[4]),
|
||||
.BA6(BA[5]),
|
||||
.BA7(BA[6]),
|
||||
.BA8(BA[7]),
|
||||
.BA9(BA[8]),
|
||||
.BCK(BCK),
|
||||
.BCKC(BCK),
|
||||
.BCKD(BCKD),
|
||||
.BCKR(BCKR),
|
||||
.BCOR(BCOR),
|
||||
.BCS(BCS),
|
||||
.BERR(BERR),
|
||||
.BI1(BI[0]),
|
||||
.BI10(BI[9]),
|
||||
.BI11(BI[10]),
|
||||
.BI12(BI[11]),
|
||||
.BI13(BI[12]),
|
||||
.BI14(BI[13]),
|
||||
.BI15(BI[14]),
|
||||
.BI16(BI[15]),
|
||||
.BI17(BI[16]),
|
||||
.BI18(BI[17]),
|
||||
.BI19(BI[18]),
|
||||
.BI2(BI[1]),
|
||||
.BI20(BI[19]),
|
||||
.BI21(BI[20]),
|
||||
.BI22(BI[21]),
|
||||
.BI23(BI[22]),
|
||||
.BI24(BI[23]),
|
||||
.BI3(BI[2]),
|
||||
.BI4(BI[3]),
|
||||
.BI5(BI[4]),
|
||||
.BI6(BI[5]),
|
||||
.BI7(BI[6]),
|
||||
.BI8(BI[7]),
|
||||
.BI9(BI[8]),
|
||||
.BO1(BO[0]),
|
||||
.BO10(BO[9]),
|
||||
.BO11(BO[10]),
|
||||
.BO12(BO[11]),
|
||||
.BO13(BO[12]),
|
||||
.BO14(BO[13]),
|
||||
.BO15(BO[14]),
|
||||
.BO16(BO[15]),
|
||||
.BO17(BO[16]),
|
||||
.BO18(BO[17]),
|
||||
.BO19(BO[18]),
|
||||
.BO2(BO[1]),
|
||||
.BO20(BO[19]),
|
||||
.BO21(BO[20]),
|
||||
.BO22(BO[21]),
|
||||
.BO23(BO[22]),
|
||||
.BO24(BO[23]),
|
||||
.BO3(BO[2]),
|
||||
.BO4(BO[3]),
|
||||
.BO5(BO[4]),
|
||||
.BO6(BO[5]),
|
||||
.BO7(BO[6]),
|
||||
.BO8(BO[7]),
|
||||
.BO9(BO[8]),
|
||||
.BR(BR),
|
||||
.BWE(BWE)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
1713
techlibs/nanoxplore/cells_wrap_l.v
Normal file
1713
techlibs/nanoxplore/cells_wrap_l.v
Normal file
File diff suppressed because it is too large
Load diff
1501
techlibs/nanoxplore/cells_wrap_m.v
Normal file
1501
techlibs/nanoxplore/cells_wrap_m.v
Normal file
File diff suppressed because it is too large
Load diff
3506
techlibs/nanoxplore/cells_wrap_u.v
Normal file
3506
techlibs/nanoxplore/cells_wrap_u.v
Normal file
File diff suppressed because it is too large
Load diff
15
techlibs/nanoxplore/io_map.v
Normal file
15
techlibs/nanoxplore/io_map.v
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
module \$__BEYOND_IBUF (input PAD, output O);
|
||||
NX_IOB_I _TECHMAP_REPLACE_ (.IO(PAD), .O(O), .C(1'b0));
|
||||
endmodule
|
||||
|
||||
module \$__BEYOND_OBUF (output PAD, input I);
|
||||
NX_IOB_O _TECHMAP_REPLACE_ (.IO(PAD), .I(I), .C(1'b1));
|
||||
endmodule
|
||||
|
||||
module \$__BEYOND_TOBUF (output PAD, input I, input C);
|
||||
NX_IOB _TECHMAP_REPLACE_ (.IO(PAD), .I(I), .C(C));
|
||||
endmodule
|
||||
|
||||
module \$__BEYOND_IOBUF (output PAD, input I, output O, output C);
|
||||
NX_IOB _TECHMAP_REPLACE_ (.IO(PAD), .I(I), .O(O), .C(C));
|
||||
endmodule
|
||||
11
techlibs/nanoxplore/latches_map.v
Normal file
11
techlibs/nanoxplore/latches_map.v
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
module \$_DLATCH_N_ (E, D, Q);
|
||||
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||
input E, D;
|
||||
output Q = !E ? D : Q;
|
||||
endmodule
|
||||
|
||||
module \$_DLATCH_P_ (E, D, Q);
|
||||
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||
input E, D;
|
||||
output Q = E ? D : Q;
|
||||
endmodule
|
||||
164
techlibs/nanoxplore/nx_carry.cc
Normal file
164
techlibs/nanoxplore/nx_carry.cc
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.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
|
||||
* 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"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
static SigBit get_bit_or_zero(const SigSpec &sig)
|
||||
{
|
||||
if (GetSize(sig) == 0)
|
||||
return State::S0;
|
||||
return sig[0];
|
||||
}
|
||||
|
||||
static void nx_carry_chain(Module *module)
|
||||
{
|
||||
SigMap sigmap(module);
|
||||
|
||||
dict<SigBit,Cell*> carry;
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID(NX_CY_1BIT)) {
|
||||
if (cell->getParam(ID(first)).as_int() == 1) continue;
|
||||
if (!cell->hasPort(ID(CI)))
|
||||
log_error("Not able to find connected carry.\n");
|
||||
SigBit ci = sigmap(cell->getPort(ID(CI)).as_bit());
|
||||
carry[ci] = cell;
|
||||
}
|
||||
}
|
||||
|
||||
dict<Cell*,vector<Cell*>> carry_chains;
|
||||
log("Detecting carry chains\n");
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == ID(NX_CY_1BIT)) {
|
||||
if (cell->getParam(ID(first)).as_int() == 0) continue;
|
||||
|
||||
vector<Cell*> chain;
|
||||
Cell *current = cell;
|
||||
chain.push_back(current);
|
||||
|
||||
SigBit co = sigmap(cell->getPort(ID(CO)).as_bit());
|
||||
while (co.is_wire())
|
||||
{
|
||||
if (carry.count(co)==0)
|
||||
break;
|
||||
//log_error("Not able to find connected carry.\n");
|
||||
current = carry[co];
|
||||
chain.push_back(current);
|
||||
if (!current->hasPort(ID(CO))) break;
|
||||
co = sigmap(current->getPort(ID(CO)).as_bit());
|
||||
}
|
||||
carry_chains[cell] = chain;
|
||||
}
|
||||
}
|
||||
|
||||
log("Creating NX_CY cells.\n");
|
||||
for(auto& c : carry_chains) {
|
||||
Cell *cell = nullptr;
|
||||
int j = 0;
|
||||
int cnt = 0;
|
||||
IdString names_A[] = { ID(A1), ID(A2), ID(A3), ID(A4) };
|
||||
IdString names_B[] = { ID(B1), ID(B2), ID(B3), ID(B4) };
|
||||
IdString names_S[] = { ID(S1), ID(S2), ID(S3), ID(S4) };
|
||||
if (!c.second.at(0)->getPort(ID(CI)).is_fully_const()) {
|
||||
cell = module->addCell(NEW_ID, ID(NX_CY));
|
||||
cell->setParam(ID(add_carry), Const(1,2));
|
||||
cell->setPort(ID(CI), State::S1);
|
||||
|
||||
cell->setPort(names_A[0], c.second.at(0)->getPort(ID(CI)).as_bit());
|
||||
cell->setPort(names_B[0], State::S0);
|
||||
j++;
|
||||
}
|
||||
|
||||
for (size_t i=0 ; i<c.second.size(); i++) {
|
||||
if (j==0) {
|
||||
cell = module->addCell(NEW_ID, ID(NX_CY));
|
||||
SigBit ci = c.second.at(i)->getPort(ID(CI)).as_bit();
|
||||
cell->setPort(ID(CI), ci);
|
||||
if (ci.is_wire()) {
|
||||
cell->setParam(ID(add_carry), Const(2,2));
|
||||
} else {
|
||||
if (ci == State::S0)
|
||||
cell->setParam(ID(add_carry), Const(0,2));
|
||||
else
|
||||
cell->setParam(ID(add_carry), Const(1,2));
|
||||
}
|
||||
}
|
||||
if (j==3) {
|
||||
if (cnt !=0 && (cnt % 24 == 0)) {
|
||||
SigBit new_co = module->addWire(NEW_ID);
|
||||
cell->setPort(ID(A4), State::S0);
|
||||
cell->setPort(ID(B4), State::S0);
|
||||
cell->setPort(ID(S4), new_co);
|
||||
cell = module->addCell(NEW_ID, ID(NX_CY));
|
||||
cell->setParam(ID(add_carry), Const(1,2));
|
||||
cell->setPort(ID(CI), State::S1);
|
||||
cell->setPort(ID(A1), new_co);
|
||||
cell->setPort(ID(B1), State::S0);
|
||||
j = 1;
|
||||
} else {
|
||||
if (c.second.at(i)->hasPort(ID(CO)))
|
||||
cell->setPort(ID(CO), c.second.at(i)->getPort(ID(CO)));
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
cell->setPort(names_A[j], get_bit_or_zero(c.second.at(i)->getPort(ID(A))));
|
||||
cell->setPort(names_B[j], get_bit_or_zero(c.second.at(i)->getPort(ID(B))));
|
||||
|
||||
if (c.second.at(i)->hasPort(ID(S)))
|
||||
cell->setPort(names_S[j], c.second.at(i)->getPort(ID(S)));
|
||||
|
||||
j = (j + 1) % 4;
|
||||
module->remove(c.second.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NXCarryPass : public Pass {
|
||||
NXCarryPass() : Pass("nx_carry", "NanoXplore: create carry cells") { }
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" nx_carry [options] [selection]\n");
|
||||
log("\n");
|
||||
log("Fixes carry chain if needed, break it on 24 elements and group by 4 into NX_CY.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing NX_CARRY pass.\n");
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
nx_carry_chain(module);
|
||||
}
|
||||
} NXCarryPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
17
techlibs/nanoxplore/rf_init.vh
Normal file
17
techlibs/nanoxplore/rf_init.vh
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
function [9728-1:0] rf_init_to_string;
|
||||
input [1152-1:0] array;
|
||||
input integer blocks;
|
||||
input integer width;
|
||||
reg [9728-1:0] temp; // (1152+1152/18)*8
|
||||
integer i;
|
||||
begin
|
||||
temp = "";
|
||||
for (i = 0; i < blocks; i = i + 1) begin
|
||||
if (i != 0) begin
|
||||
temp = {temp, ","};
|
||||
end
|
||||
temp = {temp, $sformatf("%b",array[(i+1)*width-1: i*width])};
|
||||
end
|
||||
rf_init_to_string = temp;
|
||||
end
|
||||
endfunction
|
||||
15
techlibs/nanoxplore/rf_rams_l.txt
Normal file
15
techlibs/nanoxplore/rf_rams_l.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
ram distributed $__NX_RFB_L_ {
|
||||
abits 6;
|
||||
width 16;
|
||||
cost 10;
|
||||
init no_undef;
|
||||
prune_rom;
|
||||
|
||||
port sw "W" {
|
||||
clock anyedge;
|
||||
}
|
||||
port sr "R" {
|
||||
clock anyedge;
|
||||
rden;
|
||||
}
|
||||
}
|
||||
15
techlibs/nanoxplore/rf_rams_m.txt
Normal file
15
techlibs/nanoxplore/rf_rams_m.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
ram distributed $__NX_RFB_M_ {
|
||||
abits 6;
|
||||
width 16;
|
||||
cost 10;
|
||||
init no_undef;
|
||||
prune_rom;
|
||||
|
||||
port sw "W" {
|
||||
clock anyedge;
|
||||
}
|
||||
port sr "R" {
|
||||
clock anyedge;
|
||||
rden;
|
||||
}
|
||||
}
|
||||
30
techlibs/nanoxplore/rf_rams_map_l.v
Normal file
30
techlibs/nanoxplore/rf_rams_map_l.v
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
module $__NX_RFB_L_ (
|
||||
input PORT_W_CLK,
|
||||
input PORT_W_WR_EN,
|
||||
input [5:0] PORT_W_ADDR,
|
||||
input [15:0] PORT_W_WR_DATA,
|
||||
input PORT_R_CLK,
|
||||
input PORT_R_RD_EN,
|
||||
input [5:0] PORT_R_ADDR,
|
||||
output [15:0] PORT_R_RD_DATA,
|
||||
);
|
||||
parameter INIT = 1152'bx;
|
||||
parameter PORT_W_CLK_POL = 1'b1;
|
||||
parameter PORT_R_CLK_POL = 1'b1;
|
||||
|
||||
NX_RFB_L_WRAP #(
|
||||
.mode(0),
|
||||
.mem_ctxt(INIT),
|
||||
.rck_edge(~PORT_R_CLK_POL),
|
||||
.wck_edge(~PORT_W_CLK_POL)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.RCK(PORT_R_CLK),
|
||||
.WCK(PORT_W_CLK),
|
||||
.I(PORT_W_WR_DATA),
|
||||
.RA(PORT_R_ADDR),
|
||||
.WA(PORT_W_ADDR),
|
||||
.RE(PORT_R_RD_EN),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.O(PORT_R_RD_DATA)
|
||||
);
|
||||
endmodule
|
||||
30
techlibs/nanoxplore/rf_rams_map_m.v
Normal file
30
techlibs/nanoxplore/rf_rams_map_m.v
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
module $__NX_RFB_M_ (
|
||||
input PORT_W_CLK,
|
||||
input PORT_W_WR_EN,
|
||||
input [5:0] PORT_W_ADDR,
|
||||
input [15:0] PORT_W_WR_DATA,
|
||||
input PORT_R_CLK,
|
||||
input PORT_R_RD_EN,
|
||||
input [5:0] PORT_R_ADDR,
|
||||
output [15:0] PORT_R_RD_DATA,
|
||||
);
|
||||
parameter INIT = 1152'bx;
|
||||
parameter PORT_W_CLK_POL = 1'b1;
|
||||
parameter PORT_R_CLK_POL = 1'b1;
|
||||
|
||||
NX_RFB_M_WRAP #(
|
||||
.mode(0),
|
||||
.mem_ctxt(INIT),
|
||||
.rck_edge(~PORT_R_CLK_POL),
|
||||
.wck_edge(~PORT_W_CLK_POL)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.RCK(PORT_R_CLK),
|
||||
.WCK(PORT_W_CLK),
|
||||
.I(PORT_W_WR_DATA),
|
||||
.RA(PORT_R_ADDR),
|
||||
.WA(PORT_W_ADDR),
|
||||
.RE(PORT_R_RD_EN),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.O(PORT_R_RD_DATA)
|
||||
);
|
||||
endmodule
|
||||
345
techlibs/nanoxplore/rf_rams_map_u.v
Normal file
345
techlibs/nanoxplore/rf_rams_map_u.v
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
|
||||
module $__NX_RFB_U_DPREG_ (
|
||||
input PORT_W_CLK,
|
||||
input [6-1:0] PORT_W_ADDR,
|
||||
input [6-1:0] PORT_R_ADDR,
|
||||
input [36-1:0] PORT_W_WR_DATA,
|
||||
input PORT_W_WR_EN,
|
||||
output [36-1:0] PORT_R_RD_DATA
|
||||
);
|
||||
parameter INIT = 1152'bx;
|
||||
parameter PORT_W_CLK_POL = 1'b1;
|
||||
parameter OPTION_MODE = 0;
|
||||
parameter WIDTH = 18;
|
||||
parameter BITS_USED = 0;
|
||||
localparam BLOCK_NUM = OPTION_MODE == 2 ? 64 : 32;
|
||||
localparam BLOCK_SIZE = OPTION_MODE == 3 ? 36 : 18;
|
||||
|
||||
`include "rf_init.vh"
|
||||
|
||||
// mode 0 - DPREG
|
||||
// mode 2 - NX_XRFB_64x18
|
||||
// mode 3 - NX_XRFB_32x36
|
||||
NX_RFB_U #(
|
||||
.mode(OPTION_MODE),
|
||||
.mem_ctxt($sformatf("%s",rf_init_to_string(INIT, BLOCK_NUM, BLOCK_SIZE))),
|
||||
.wck_edge(PORT_W_CLK_POL == 1 ? 1'b0 : 1'b1)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.WCK(PORT_W_CLK),
|
||||
.I1(PORT_W_WR_DATA[0]),
|
||||
.I2(PORT_W_WR_DATA[1]),
|
||||
.I3(PORT_W_WR_DATA[2]),
|
||||
.I4(PORT_W_WR_DATA[3]),
|
||||
.I5(PORT_W_WR_DATA[4]),
|
||||
.I6(PORT_W_WR_DATA[5]),
|
||||
.I7(PORT_W_WR_DATA[6]),
|
||||
.I8(PORT_W_WR_DATA[7]),
|
||||
.I9(PORT_W_WR_DATA[8]),
|
||||
.I10(PORT_W_WR_DATA[9]),
|
||||
.I11(PORT_W_WR_DATA[10]),
|
||||
.I12(PORT_W_WR_DATA[11]),
|
||||
.I13(PORT_W_WR_DATA[12]),
|
||||
.I14(PORT_W_WR_DATA[13]),
|
||||
.I15(PORT_W_WR_DATA[14]),
|
||||
.I16(PORT_W_WR_DATA[15]),
|
||||
.I17(PORT_W_WR_DATA[16]),
|
||||
.I18(PORT_W_WR_DATA[17]),
|
||||
.I19(PORT_W_WR_DATA[18]),
|
||||
.I20(PORT_W_WR_DATA[19]),
|
||||
.I21(PORT_W_WR_DATA[20]),
|
||||
.I22(PORT_W_WR_DATA[21]),
|
||||
.I23(PORT_W_WR_DATA[22]),
|
||||
.I24(PORT_W_WR_DATA[23]),
|
||||
.I25(PORT_W_WR_DATA[24]),
|
||||
.I26(PORT_W_WR_DATA[25]),
|
||||
.I27(PORT_W_WR_DATA[26]),
|
||||
.I28(PORT_W_WR_DATA[27]),
|
||||
.I29(PORT_W_WR_DATA[28]),
|
||||
.I30(PORT_W_WR_DATA[29]),
|
||||
.I31(PORT_W_WR_DATA[30]),
|
||||
.I32(PORT_W_WR_DATA[31]),
|
||||
.I33(PORT_W_WR_DATA[32]),
|
||||
.I34(PORT_W_WR_DATA[33]),
|
||||
.I35(PORT_W_WR_DATA[34]),
|
||||
.I36(PORT_W_WR_DATA[35]),
|
||||
.O1(PORT_R_RD_DATA[0]),
|
||||
.O2(PORT_R_RD_DATA[1]),
|
||||
.O3(PORT_R_RD_DATA[2]),
|
||||
.O4(PORT_R_RD_DATA[3]),
|
||||
.O5(PORT_R_RD_DATA[4]),
|
||||
.O6(PORT_R_RD_DATA[5]),
|
||||
.O7(PORT_R_RD_DATA[6]),
|
||||
.O8(PORT_R_RD_DATA[7]),
|
||||
.O9(PORT_R_RD_DATA[8]),
|
||||
.O10(PORT_R_RD_DATA[9]),
|
||||
.O11(PORT_R_RD_DATA[10]),
|
||||
.O12(PORT_R_RD_DATA[11]),
|
||||
.O13(PORT_R_RD_DATA[12]),
|
||||
.O14(PORT_R_RD_DATA[13]),
|
||||
.O15(PORT_R_RD_DATA[14]),
|
||||
.O16(PORT_R_RD_DATA[15]),
|
||||
.O17(PORT_R_RD_DATA[16]),
|
||||
.O18(PORT_R_RD_DATA[17]),
|
||||
.O19(PORT_R_RD_DATA[18]),
|
||||
.O20(PORT_R_RD_DATA[19]),
|
||||
.O21(PORT_R_RD_DATA[20]),
|
||||
.O22(PORT_R_RD_DATA[21]),
|
||||
.O23(PORT_R_RD_DATA[22]),
|
||||
.O24(PORT_R_RD_DATA[23]),
|
||||
.O25(PORT_R_RD_DATA[24]),
|
||||
.O26(PORT_R_RD_DATA[25]),
|
||||
.O27(PORT_R_RD_DATA[26]),
|
||||
.O28(PORT_R_RD_DATA[27]),
|
||||
.O29(PORT_R_RD_DATA[28]),
|
||||
.O30(PORT_R_RD_DATA[29]),
|
||||
.O31(PORT_R_RD_DATA[30]),
|
||||
.O32(PORT_R_RD_DATA[31]),
|
||||
.O33(PORT_R_RD_DATA[32]),
|
||||
.O34(PORT_R_RD_DATA[33]),
|
||||
.O35(PORT_R_RD_DATA[34]),
|
||||
.O36(PORT_R_RD_DATA[35]),
|
||||
.RA1(PORT_R_ADDR[0]),
|
||||
.RA2(PORT_R_ADDR[1]),
|
||||
.RA3(PORT_R_ADDR[2]),
|
||||
.RA4(PORT_R_ADDR[3]),
|
||||
.RA5(PORT_R_ADDR[4]),
|
||||
.RA6(PORT_R_ADDR[5]),
|
||||
.RA7(),
|
||||
.RA8(),
|
||||
.RA9(),
|
||||
.RA10(),
|
||||
.WA1(PORT_W_ADDR[0]),
|
||||
.WA2(PORT_W_ADDR[1]),
|
||||
.WA3(PORT_W_ADDR[2]),
|
||||
.WA4(PORT_W_ADDR[3]),
|
||||
.WA5(PORT_W_ADDR[4]),
|
||||
.WA6(PORT_W_ADDR[5]),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.WEA(1'b0)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module $__NX_RFB_U_SPREG_ (
|
||||
input PORT_RW_CLK,
|
||||
input [4:0] PORT_RW_ADDR,
|
||||
input [17:0] PORT_RW_WR_DATA,
|
||||
input PORT_RW_WR_EN,
|
||||
output [17:0] PORT_RW_RD_DATA
|
||||
);
|
||||
parameter INIT = 576'bx;
|
||||
parameter PORT_RW_CLK_POL = 1'b1;
|
||||
parameter BITS_USED = 0;
|
||||
`include "rf_init.vh"
|
||||
|
||||
NX_RFB_U #(
|
||||
.mode(1),
|
||||
.mem_ctxt($sformatf("%s",rf_init_to_string(INIT, 32, 18))),
|
||||
.wck_edge(PORT_RW_CLK_POL == 1 ? 1'b0 : 1'b1)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.WCK(PORT_RW_CLK),
|
||||
.I1(PORT_RW_WR_DATA[0]),
|
||||
.I2(PORT_RW_WR_DATA[1]),
|
||||
.I3(PORT_RW_WR_DATA[2]),
|
||||
.I4(PORT_RW_WR_DATA[3]),
|
||||
.I5(PORT_RW_WR_DATA[4]),
|
||||
.I6(PORT_RW_WR_DATA[5]),
|
||||
.I7(PORT_RW_WR_DATA[6]),
|
||||
.I8(PORT_RW_WR_DATA[7]),
|
||||
.I9(PORT_RW_WR_DATA[8]),
|
||||
.I10(PORT_RW_WR_DATA[9]),
|
||||
.I11(PORT_RW_WR_DATA[10]),
|
||||
.I12(PORT_RW_WR_DATA[11]),
|
||||
.I13(PORT_RW_WR_DATA[12]),
|
||||
.I14(PORT_RW_WR_DATA[13]),
|
||||
.I15(PORT_RW_WR_DATA[14]),
|
||||
.I16(PORT_RW_WR_DATA[15]),
|
||||
.I17(PORT_RW_WR_DATA[16]),
|
||||
.I18(PORT_RW_WR_DATA[17]),
|
||||
.I19(),
|
||||
.I20(),
|
||||
.I21(),
|
||||
.I22(),
|
||||
.I23(),
|
||||
.I24(),
|
||||
.I25(),
|
||||
.I26(),
|
||||
.I27(),
|
||||
.I28(),
|
||||
.I29(),
|
||||
.I30(),
|
||||
.I31(),
|
||||
.I32(),
|
||||
.I33(),
|
||||
.I34(),
|
||||
.I35(),
|
||||
.I36(),
|
||||
.O1(PORT_RW_RD_DATA[0]),
|
||||
.O2(PORT_RW_RD_DATA[1]),
|
||||
.O3(PORT_RW_RD_DATA[2]),
|
||||
.O4(PORT_RW_RD_DATA[3]),
|
||||
.O5(PORT_RW_RD_DATA[4]),
|
||||
.O6(PORT_RW_RD_DATA[5]),
|
||||
.O7(PORT_RW_RD_DATA[6]),
|
||||
.O8(PORT_RW_RD_DATA[7]),
|
||||
.O9(PORT_RW_RD_DATA[8]),
|
||||
.O10(PORT_RW_RD_DATA[9]),
|
||||
.O11(PORT_RW_RD_DATA[10]),
|
||||
.O12(PORT_RW_RD_DATA[11]),
|
||||
.O13(PORT_RW_RD_DATA[12]),
|
||||
.O14(PORT_RW_RD_DATA[13]),
|
||||
.O15(PORT_RW_RD_DATA[14]),
|
||||
.O16(PORT_RW_RD_DATA[15]),
|
||||
.O17(PORT_RW_RD_DATA[16]),
|
||||
.O18(PORT_RW_RD_DATA[17]),
|
||||
.O19(),
|
||||
.O20(),
|
||||
.O21(),
|
||||
.O22(),
|
||||
.O23(),
|
||||
.O24(),
|
||||
.O25(),
|
||||
.O26(),
|
||||
.O27(),
|
||||
.O28(),
|
||||
.O29(),
|
||||
.O30(),
|
||||
.O31(),
|
||||
.O32(),
|
||||
.O33(),
|
||||
.O34(),
|
||||
.O35(),
|
||||
.O36(),
|
||||
.RA1(),
|
||||
.RA2(),
|
||||
.RA3(),
|
||||
.RA4(),
|
||||
.RA5(),
|
||||
.RA6(),
|
||||
.RA7(),
|
||||
.RA8(),
|
||||
.RA9(),
|
||||
.RA10(),
|
||||
.WA1(PORT_RW_ADDR[0]),
|
||||
.WA2(PORT_RW_ADDR[1]),
|
||||
.WA3(PORT_RW_ADDR[2]),
|
||||
.WA4(PORT_RW_ADDR[3]),
|
||||
.WA5(PORT_RW_ADDR[4]),
|
||||
.WA6(),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WEA(1'b0)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module $__NX_XRFB_2R_1W_ (
|
||||
input PORT_W_CLK,
|
||||
input [4:0] PORT_W_ADDR,
|
||||
input [4:0] PORT_A_ADDR,
|
||||
input [4:0] PORT_B_ADDR,
|
||||
input [17:0] PORT_W_WR_DATA,
|
||||
input PORT_W_WR_EN,
|
||||
output [17:0] PORT_A_RD_DATA,
|
||||
output [17:0] PORT_B_RD_DATA
|
||||
);
|
||||
parameter INIT = 576'bx;
|
||||
parameter PORT_W_CLK_POL = 1'b1;
|
||||
parameter BITS_USED = 0;
|
||||
`include "rf_init.vh"
|
||||
|
||||
NX_RFB_U #(
|
||||
.mode(4),
|
||||
.mem_ctxt($sformatf("%s",rf_init_to_string(INIT, 32, 18))),
|
||||
.wck_edge(PORT_W_CLK_POL == 1 ? 1'b0 : 1'b1)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.WCK(PORT_W_CLK),
|
||||
.I1(PORT_W_WR_DATA[0]),
|
||||
.I2(PORT_W_WR_DATA[1]),
|
||||
.I3(PORT_W_WR_DATA[2]),
|
||||
.I4(PORT_W_WR_DATA[3]),
|
||||
.I5(PORT_W_WR_DATA[4]),
|
||||
.I6(PORT_W_WR_DATA[5]),
|
||||
.I7(PORT_W_WR_DATA[6]),
|
||||
.I8(PORT_W_WR_DATA[7]),
|
||||
.I9(PORT_W_WR_DATA[8]),
|
||||
.I10(PORT_W_WR_DATA[9]),
|
||||
.I11(PORT_W_WR_DATA[10]),
|
||||
.I12(PORT_W_WR_DATA[11]),
|
||||
.I13(PORT_W_WR_DATA[12]),
|
||||
.I14(PORT_W_WR_DATA[13]),
|
||||
.I15(PORT_W_WR_DATA[14]),
|
||||
.I16(PORT_W_WR_DATA[15]),
|
||||
.I17(PORT_W_WR_DATA[16]),
|
||||
.I18(PORT_W_WR_DATA[17]),
|
||||
.I19(),
|
||||
.I20(),
|
||||
.I21(),
|
||||
.I22(),
|
||||
.I23(),
|
||||
.I24(),
|
||||
.I25(),
|
||||
.I26(),
|
||||
.I27(),
|
||||
.I28(),
|
||||
.I29(),
|
||||
.I30(),
|
||||
.I31(),
|
||||
.I32(),
|
||||
.I33(),
|
||||
.I34(),
|
||||
.I35(),
|
||||
.I36(),
|
||||
.O1(PORT_A_RD_DATA[0]),
|
||||
.O2(PORT_A_RD_DATA[1]),
|
||||
.O3(PORT_A_RD_DATA[2]),
|
||||
.O4(PORT_A_RD_DATA[3]),
|
||||
.O5(PORT_A_RD_DATA[4]),
|
||||
.O6(PORT_A_RD_DATA[5]),
|
||||
.O7(PORT_A_RD_DATA[6]),
|
||||
.O8(PORT_A_RD_DATA[7]),
|
||||
.O9(PORT_A_RD_DATA[8]),
|
||||
.O10(PORT_A_RD_DATA[9]),
|
||||
.O11(PORT_A_RD_DATA[10]),
|
||||
.O12(PORT_A_RD_DATA[11]),
|
||||
.O13(PORT_A_RD_DATA[12]),
|
||||
.O14(PORT_A_RD_DATA[13]),
|
||||
.O15(PORT_A_RD_DATA[14]),
|
||||
.O16(PORT_A_RD_DATA[15]),
|
||||
.O17(PORT_A_RD_DATA[16]),
|
||||
.O18(PORT_A_RD_DATA[17]),
|
||||
.O19(PORT_B_RD_DATA[0]),
|
||||
.O20(PORT_B_RD_DATA[1]),
|
||||
.O21(PORT_B_RD_DATA[2]),
|
||||
.O22(PORT_B_RD_DATA[3]),
|
||||
.O23(PORT_B_RD_DATA[4]),
|
||||
.O24(PORT_B_RD_DATA[5]),
|
||||
.O25(PORT_B_RD_DATA[6]),
|
||||
.O26(PORT_B_RD_DATA[7]),
|
||||
.O27(PORT_B_RD_DATA[8]),
|
||||
.O28(PORT_B_RD_DATA[9]),
|
||||
.O29(PORT_B_RD_DATA[10]),
|
||||
.O30(PORT_B_RD_DATA[11]),
|
||||
.O31(PORT_B_RD_DATA[12]),
|
||||
.O32(PORT_B_RD_DATA[13]),
|
||||
.O33(PORT_B_RD_DATA[14]),
|
||||
.O34(PORT_B_RD_DATA[15]),
|
||||
.O35(PORT_B_RD_DATA[16]),
|
||||
.O36(PORT_B_RD_DATA[17]),
|
||||
.RA1(PORT_A_ADDR[0]),
|
||||
.RA2(PORT_A_ADDR[1]),
|
||||
.RA3(PORT_A_ADDR[2]),
|
||||
.RA4(PORT_A_ADDR[3]),
|
||||
.RA5(PORT_A_ADDR[4]),
|
||||
.RA6(PORT_B_ADDR[0]),
|
||||
.RA7(PORT_B_ADDR[1]),
|
||||
.RA8(PORT_B_ADDR[2]),
|
||||
.RA9(PORT_B_ADDR[3]),
|
||||
.RA10(PORT_B_ADDR[4]),
|
||||
.WA1(PORT_W_ADDR[0]),
|
||||
.WA2(PORT_W_ADDR[1]),
|
||||
.WA3(PORT_W_ADDR[2]),
|
||||
.WA4(PORT_W_ADDR[3]),
|
||||
.WA5(PORT_W_ADDR[4]),
|
||||
.WA6(),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.WEA(1'b0)
|
||||
);
|
||||
endmodule
|
||||
66
techlibs/nanoxplore/rf_rams_u.txt
Normal file
66
techlibs/nanoxplore/rf_rams_u.txt
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Register-File RAMs for NanoXplore NG-ULTRA
|
||||
|
||||
# Dual-port RAMs.
|
||||
# NX_RFB_U in mode 0 (DPREG)
|
||||
# NX_RFB_U in mode 2 (NX_XRFB_64x18)
|
||||
# NX_RFB_U in mode 3 (NX_XRFB_32x36)
|
||||
|
||||
ram distributed $__NX_RFB_U_DPREG_ {
|
||||
option "MODE" 0 {
|
||||
cost 30;
|
||||
widthscale 30;
|
||||
abits 5;
|
||||
widths 18 global;
|
||||
}
|
||||
option "MODE" 2 {
|
||||
cost 50;
|
||||
widthscale 30;
|
||||
abits 6;
|
||||
widths 18 global;
|
||||
}
|
||||
option "MODE" 3 {
|
||||
cost 50;
|
||||
widthscale 30;
|
||||
abits 5;
|
||||
widths 36 global;
|
||||
}
|
||||
init no_undef;
|
||||
|
||||
port sw "W" {
|
||||
clock anyedge;
|
||||
}
|
||||
port ar "R" {
|
||||
}
|
||||
}
|
||||
|
||||
# Single-port RAMs.
|
||||
# NX_RFB_U in mode 1 (SPREG)
|
||||
|
||||
ram distributed $__NX_RFB_U_SPREG_ {
|
||||
cost 30;
|
||||
widthscale;
|
||||
abits 5;
|
||||
width 18;
|
||||
init no_undef;
|
||||
port arsw "RW" {
|
||||
clock anyedge;
|
||||
}
|
||||
}
|
||||
|
||||
# Single write dual read RAMs.
|
||||
# NX_RFB_U in mode 4 (NX_XRFB_2R_1W)
|
||||
|
||||
ram distributed $__NX_XRFB_2R_1W_ {
|
||||
cost 40;
|
||||
widthscale 30;
|
||||
abits 5;
|
||||
width 18;
|
||||
init no_undef;
|
||||
port sw "W" {
|
||||
clock anyedge;
|
||||
}
|
||||
port ar "A" {
|
||||
}
|
||||
port ar "B" {
|
||||
}
|
||||
}
|
||||
370
techlibs/nanoxplore/synth_nanoxplore.cc
Normal file
370
techlibs/nanoxplore/synth_nanoxplore.cc
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2024 Hannah Ravensloft <lofty@yosyshq.com>
|
||||
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.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
|
||||
* 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/register.h"
|
||||
#include "kernel/celltypes.h"
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/log.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct SynthNanoXplorePass : public ScriptPass
|
||||
{
|
||||
SynthNanoXplorePass() : ScriptPass("synth_nanoxplore", "synthesis for NanoXplore FPGAs") { }
|
||||
|
||||
void on_register() override
|
||||
{
|
||||
RTLIL::constpad["synth_nanoxplore.abc9.W"] = "300";
|
||||
}
|
||||
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" synth_nanoxplore [options]\n");
|
||||
log("\n");
|
||||
log("This command runs synthesis for NanoXplore FPGAs.\n");
|
||||
log("\n");
|
||||
log(" -top <module>\n");
|
||||
log(" use the specified module as top module\n");
|
||||
log("\n");
|
||||
log(" -family <family>\n");
|
||||
log(" run synthesis for the specified NanoXplore architecture\n");
|
||||
log(" generate the synthesis netlist for the specified family.\n");
|
||||
log(" supported values:\n");
|
||||
log(" - medium: NG-Medium\n");
|
||||
log(" - large: NG-Large\n");
|
||||
log(" - ultra: NG-Ultra\n");
|
||||
log("\n");
|
||||
log(" -json <file>\n");
|
||||
log(" write the design to the specified JSON file. writing of an output file\n");
|
||||
log(" is omitted if this parameter is not specified.\n");
|
||||
log("\n");
|
||||
log(" -run <from_label>:<to_label>\n");
|
||||
log(" only run the commands between the labels (see below). an empty\n");
|
||||
log(" from label is synonymous to 'begin', and empty to label is\n");
|
||||
log(" synonymous to the end of the command list.\n");
|
||||
log("\n");
|
||||
log(" -noflatten\n");
|
||||
log(" do not flatten design before synthesis\n");
|
||||
log("\n");
|
||||
log(" -abc9\n");
|
||||
log(" use new ABC9 flow (EXPERIMENTAL)\n");
|
||||
log("\n");
|
||||
log(" -nocy\n");
|
||||
log(" do not map adders to CY cells\n");
|
||||
log("\n");
|
||||
log(" -nodffe\n");
|
||||
log(" do not use flipflops with L in output netlist\n");
|
||||
log("\n");
|
||||
log(" -min_ce_use <min_ce_use>\n");
|
||||
log(" do not use flip-flops with load signal if the resulting count is less\n");
|
||||
log(" than min_ce_use in output netlist\n");
|
||||
log("\n");
|
||||
log(" -min_srst_use <min_srst_use>\n");
|
||||
log(" do not use flip-flops with async reset signal if the resulting count is less\n");
|
||||
log(" than min_srst_use in output netlist\n");
|
||||
log("\n");
|
||||
log(" -norfram\n");
|
||||
log(" do not use Register File RAM cells in output netlist\n");
|
||||
log("\n");
|
||||
log(" -nobram\n");
|
||||
log(" do not use block NX_RAM cells in output netlist\n");
|
||||
log("\n");
|
||||
log(" -noiopad\n");
|
||||
log(" do not insert IO buffers\n");
|
||||
log("\n");
|
||||
log(" -no-rw-check\n");
|
||||
log(" marks all recognized read ports as \"return don't-care value on\n");
|
||||
log(" read/write collision\" (same result as setting the no_rw_check\n");
|
||||
log(" attribute on all memories).\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
help_script();
|
||||
log("\n");
|
||||
}
|
||||
|
||||
string top_opt, json_file, family;
|
||||
bool flatten, abc9, nocy, nodffe, norfram, nobram, noiopad, no_rw_check;
|
||||
std::string postfix;
|
||||
int min_ce_use, min_srst_use;
|
||||
|
||||
void clear_flags() override
|
||||
{
|
||||
top_opt = "-auto-top";
|
||||
json_file = "";
|
||||
family = "";
|
||||
flatten = true;
|
||||
abc9 = false;
|
||||
nocy = false;
|
||||
nodffe = false;
|
||||
norfram = false;
|
||||
nobram = false;
|
||||
noiopad = false;
|
||||
no_rw_check = false;
|
||||
postfix = "";
|
||||
min_ce_use = 8;
|
||||
min_srst_use = 8;
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
string run_from, run_to;
|
||||
clear_flags();
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (args[argidx] == "-top" && argidx+1 < args.size()) {
|
||||
top_opt = "-top " + args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) {
|
||||
family = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-json" && argidx+1 < args.size()) {
|
||||
json_file = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-run" && argidx+1 < args.size()) {
|
||||
size_t pos = args[argidx+1].find(':');
|
||||
if (pos == std::string::npos)
|
||||
break;
|
||||
run_from = args[++argidx].substr(0, pos);
|
||||
run_to = args[argidx].substr(pos+1);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-flatten") {
|
||||
flatten = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noflatten") {
|
||||
flatten = false;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-abc9") {
|
||||
abc9 = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nocy") {
|
||||
nocy = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodffe") {
|
||||
nodffe = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-min_ce_use" && argidx+1 < args.size()) {
|
||||
min_ce_use = atoi(args[++argidx].c_str());
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-min_srst_use" && argidx+1 < args.size()) {
|
||||
min_srst_use = atoi(args[++argidx].c_str());
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-norfram") {
|
||||
norfram = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nobram") {
|
||||
nobram = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-iopad") {
|
||||
noiopad = false;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noiopad") {
|
||||
noiopad = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-no-rw-check") {
|
||||
no_rw_check = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (family.empty()) {
|
||||
//log_warning("NanoXplore family not set, setting it to NG-ULTRA.\n");
|
||||
family = "ultra";
|
||||
}
|
||||
|
||||
if (family == "ultra") {
|
||||
postfix = "_u";
|
||||
} else if (family == "medium") {
|
||||
postfix = "_m";
|
||||
} else if (family == "large") {
|
||||
postfix = "_l";
|
||||
} else
|
||||
log_cmd_error("Invalid NanoXplore -family setting: '%s'.\n", family.c_str());
|
||||
|
||||
if (!design->full_selection())
|
||||
log_cmd_error("This command only operates on fully selected designs!\n");
|
||||
|
||||
log_header(design, "Executing SYNTH_NANOXPLORE pass.\n");
|
||||
log_push();
|
||||
|
||||
run_script(design, run_from, run_to);
|
||||
|
||||
log_pop();
|
||||
}
|
||||
|
||||
void script() override
|
||||
{
|
||||
std::string no_rw_check_opt = "";
|
||||
if (no_rw_check)
|
||||
no_rw_check_opt = " -no-rw-check";
|
||||
if (help_mode)
|
||||
no_rw_check_opt = " [-no-rw-check]";
|
||||
|
||||
if (check_label("begin"))
|
||||
{
|
||||
run("read_verilog -lib -specify +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim" + postfix + ".v +/nanoxplore/cells_bb.v +/nanoxplore/cells_bb" + postfix + ".v");
|
||||
run("techmap -map +/nanoxplore/cells_wrap.v");
|
||||
run("techmap -map +/nanoxplore/cells_wrap" + postfix + ".v");
|
||||
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
|
||||
}
|
||||
|
||||
if (check_label("coarse"))
|
||||
{
|
||||
run("proc");
|
||||
if (flatten || help_mode)
|
||||
run("flatten", "(skip if -noflatten)");
|
||||
run("tribuf -logic");
|
||||
run("deminout");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
run("check");
|
||||
run("opt -nodffe -nosdff");
|
||||
run("fsm");
|
||||
run("opt");
|
||||
run("wreduce");
|
||||
run("peepopt");
|
||||
run("opt_clean");
|
||||
run("share");
|
||||
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
run("alumacc");
|
||||
run("opt");
|
||||
run("memory -nomap" + no_rw_check_opt);
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
if (check_label("map_ram"))
|
||||
{
|
||||
std::string args = "";
|
||||
if (family == "medium")
|
||||
args += " -D IS_NG_MEDIUM";
|
||||
if (nobram)
|
||||
args += " -no-auto-block";
|
||||
if (norfram)
|
||||
args += " -no-auto-distributed";
|
||||
if (help_mode)
|
||||
args += " [-no-auto-block] [-no-auto-distributed]";
|
||||
run("memory_libmap -lib +/nanoxplore/rf_rams"+ postfix + ".txt -lib +/nanoxplore/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -norfram)");
|
||||
run("techmap -map +/nanoxplore/rf_rams_map"+ postfix + ".v -map +/nanoxplore/brams_map.v");
|
||||
run("techmap -map +/nanoxplore/cells_wrap.v t:NX_RAM*");
|
||||
run("techmap -map +/nanoxplore/cells_wrap" + postfix + ".v t:NX_XRFB* t:NX_RFB*");
|
||||
}
|
||||
|
||||
if (check_label("map_ffram"))
|
||||
{
|
||||
run("opt -fast -mux_undef -undriven -fine");
|
||||
run("memory_map");
|
||||
run("opt -undriven -fine -mux_undef");
|
||||
}
|
||||
|
||||
if (check_label("map_gates"))
|
||||
{
|
||||
if (nocy)
|
||||
run("techmap");
|
||||
else {
|
||||
run("techmap -map +/techmap.v -map +/nanoxplore/arith_map.v");
|
||||
run("nx_carry");
|
||||
}
|
||||
if (help_mode || !noiopad) {
|
||||
run("iopadmap -bits -outpad $__BEYOND_OBUF I:PAD -toutpad $__BEYOND_TOBUF C:I:PAD -inpad $__BEYOND_IBUF O:PAD -tinoutpad $__BEYOND_IOBUF C:O:I:PAD A:top", "(skip if '-noiopad')");
|
||||
run("techmap -map +/nanoxplore/io_map.v");
|
||||
}
|
||||
run("opt -fast");
|
||||
}
|
||||
|
||||
if (check_label("map_ffs"))
|
||||
{
|
||||
std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r";
|
||||
if (help_mode) {
|
||||
dfflegalize_args += " [-cell $_DFFE_?P_ 01 -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r]";
|
||||
} else if (!nodffe) {
|
||||
dfflegalize_args += " -cell $_DFFE_?P_ 01 -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r";
|
||||
}
|
||||
dfflegalize_args += stringf(" -cell $_DLATCH_?_ x -mince %d -minsrst %d", min_ce_use, min_srst_use);
|
||||
run("dfflegalize" + dfflegalize_args,"($_*DFFE_* only if not -nodffe)");
|
||||
run("opt_merge");
|
||||
run("techmap -map +/nanoxplore/latches_map.v");
|
||||
run("techmap -map +/nanoxplore/cells_map.v");
|
||||
run("opt_expr -undriven -mux_undef");
|
||||
run("clean -purge");
|
||||
}
|
||||
|
||||
if (check_label("map_luts"))
|
||||
{
|
||||
if (abc9) {
|
||||
std::string abc9_opts = " -maxlut 4";
|
||||
std::string k = "synth_nanoxplore.abc9.W";
|
||||
if (active_design && active_design->scratchpad.count(k))
|
||||
abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str());
|
||||
else
|
||||
abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str());
|
||||
run("abc9" + abc9_opts);
|
||||
} else {
|
||||
std::string abc_args = " -dress";
|
||||
abc_args += " -lut 4";
|
||||
run("abc" + abc_args);
|
||||
}
|
||||
run("techmap -map +/nanoxplore/cells_map.v t:$lut");
|
||||
run("opt -fast");
|
||||
run("clean");
|
||||
}
|
||||
|
||||
if (check_label("check"))
|
||||
{
|
||||
run("autoname");
|
||||
run("hierarchy -check");
|
||||
run("stat");
|
||||
run("check -noinit");
|
||||
run("blackbox =A:whitebox");
|
||||
run("setundef -zero -undriven");
|
||||
}
|
||||
|
||||
if (check_label("json"))
|
||||
{
|
||||
if (!json_file.empty() || help_mode)
|
||||
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
|
||||
}
|
||||
}
|
||||
} SynthNanoXplorePass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
2
tests/arch/nanoxplore/.gitignore
vendored
Normal file
2
tests/arch/nanoxplore/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*.log
|
||||
/run-test.mk
|
||||
71
tests/arch/nanoxplore/add_sub.ys
Normal file
71
tests/arch/nanoxplore/add_sub.ys
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
read_verilog ../common/add_sub.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
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:NX_CY
|
||||
select -assert-count 4 t:NX_LUT
|
||||
select -assert-none t:NX_CY t:NX_LUT %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog <<EOT
|
||||
module top
|
||||
(
|
||||
input [5:0] x,
|
||||
input [5:0] y,
|
||||
|
||||
output [5:0] A,
|
||||
input CI,
|
||||
output CO
|
||||
);
|
||||
|
||||
assign {CO, A} = x + y + CI;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd top
|
||||
stat
|
||||
select -assert-count 2 t:NX_CY
|
||||
select -assert-none t:NX_CY %% t:* %D
|
||||
|
||||
design -reset
|
||||
read_verilog <<EOT
|
||||
module top
|
||||
(
|
||||
input [189:0] x,
|
||||
input [189:0] y,
|
||||
|
||||
output [189:0] A
|
||||
);
|
||||
|
||||
assign A = x + y;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd top
|
||||
stat
|
||||
select -assert-count 48 t:NX_CY
|
||||
select -assert-none t:NX_CY %% t:* %D
|
||||
47
tests/arch/nanoxplore/adffs.ys
Normal file
47
tests/arch/nanoxplore/adffs.ys
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
read_verilog ../common/adffs.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top adff
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_DFF
|
||||
|
||||
select -assert-none t:NX_DFF %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top adffn
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_DFF
|
||||
select -assert-count 1 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top dffs
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_DFF
|
||||
select -assert-count 1 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top ndffnr
|
||||
proc
|
||||
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_DFF
|
||||
select -assert-count 1 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D
|
||||
22
tests/arch/nanoxplore/dffs.ys
Normal file
22
tests/arch/nanoxplore/dffs.ys
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
read_verilog ../common/dffs.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top dff
|
||||
proc
|
||||
equiv_opt -assert -async2sync -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_DFF
|
||||
|
||||
select -assert-none t:NX_DFF %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top dffe
|
||||
proc
|
||||
equiv_opt -assert -async2sync -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad -min_ce_use 0 # 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
|
||||
stat
|
||||
select -assert-count 1 t:NX_DFF
|
||||
|
||||
select -assert-none t:NX_DFF %% t:* %D
|
||||
16
tests/arch/nanoxplore/fsm.ys
Normal file
16
tests/arch/nanoxplore/fsm.ys
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
read_verilog ../common/fsm.v
|
||||
hierarchy -top fsm
|
||||
proc
|
||||
flatten
|
||||
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad
|
||||
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:NX_DFF
|
||||
select -assert-min 13 t:NX_LUT
|
||||
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D
|
||||
33
tests/arch/nanoxplore/latches.ys
Normal file
33
tests/arch/nanoxplore/latches.ys
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
read_verilog ../common/latches.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top latchp
|
||||
proc
|
||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||
synth_nanoxplore -noiopad
|
||||
cd latchp # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top latchn
|
||||
proc
|
||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||
synth_nanoxplore -noiopad
|
||||
cd latchn # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
|
||||
|
||||
design -load read
|
||||
hierarchy -top latchsr
|
||||
proc
|
||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||
synth_nanoxplore -noiopad
|
||||
cd latchsr # Constrain all select calls below inside the top module
|
||||
select -assert-count 2 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
9
tests/arch/nanoxplore/logic.ys
Normal file
9
tests/arch/nanoxplore/logic.ys
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
read_verilog ../common/logic.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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 9 t:NX_LUT
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
145
tests/arch/nanoxplore/lutram.ys
Normal file
145
tests/arch/nanoxplore/lutram.ys
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# Dual-port RAMs.
|
||||
# NX_RFB_U in mode 0 (DPREG)
|
||||
|
||||
read_verilog <<EOT
|
||||
module lutram_dpreg
|
||||
#(parameter D_WIDTH=18, A_WIDTH=5)
|
||||
(
|
||||
input [D_WIDTH-1:0] data,
|
||||
input [A_WIDTH:1] addr_w, addr_r,
|
||||
input we, clk,
|
||||
output reg [D_WIDTH-1:0] q
|
||||
);
|
||||
// Declare the RAM variable
|
||||
reg [D_WIDTH-1:0] ram[(2**A_WIDTH)-1:0];
|
||||
|
||||
// Port A
|
||||
always @ (posedge clk)
|
||||
begin
|
||||
if (we)
|
||||
ram[addr_w] <= data;
|
||||
q <= ram[addr_r];
|
||||
end
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -top lutram_dpreg
|
||||
proc
|
||||
memory -nomap
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
memory
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd lutram_dpreg
|
||||
stat
|
||||
select -assert-count 1 t:NX_RFB_U r:mode=0 %i
|
||||
select -assert-count 18 t:NX_DFF
|
||||
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
|
||||
|
||||
# Single-port RAMs.
|
||||
# NX_RFB_U in mode 1 (SPREG)
|
||||
design -reset
|
||||
|
||||
read_verilog ../common/lutram.v
|
||||
hierarchy -top lutram_1w1r -chparam A_WIDTH 5 -chparam D_WIDTH 18
|
||||
proc
|
||||
memory -nomap
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
memory
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd lutram_1w1r
|
||||
select -assert-count 1 t:NX_RFB_U r:mode=1 %i
|
||||
select -assert-count 18 t:NX_DFF
|
||||
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
|
||||
|
||||
# Dual-port RAMs.
|
||||
# NX_RFB_U in mode 2 (NX_XRFB_64x18)
|
||||
design -reset
|
||||
read_verilog ../common/lutram.v
|
||||
hierarchy -top lutram_1w1r -chparam A_WIDTH 6 -chparam D_WIDTH 18
|
||||
proc
|
||||
memory -nomap
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
memory
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd lutram_1w1r
|
||||
select -assert-count 1 t:NX_RFB_U r:mode=2 %i
|
||||
select -assert-count 18 t:NX_DFF
|
||||
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
|
||||
|
||||
# Dual-port RAMs.
|
||||
# NX_RFB_U in mode 3 (NX_XRFB_32x36)
|
||||
design -reset
|
||||
read_verilog ../common/lutram.v
|
||||
hierarchy -top lutram_1w1r -chparam A_WIDTH 5 -chparam D_WIDTH 36
|
||||
proc
|
||||
memory -nomap
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
memory
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd lutram_1w1r
|
||||
select -assert-count 1 t:NX_RFB_U r:mode=3 %i
|
||||
select -assert-count 36 t:NX_DFF
|
||||
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
|
||||
|
||||
# Single write dual read RAMs.
|
||||
# NX_RFB_U in mode 4 (NX_XRFB_2R_1W)
|
||||
design -reset
|
||||
|
||||
read_verilog <<EOT
|
||||
module lutram_1w2r
|
||||
#(parameter D_WIDTH=8, A_WIDTH=5)
|
||||
(
|
||||
input [D_WIDTH-1:0] data_a, data_b,
|
||||
input [A_WIDTH:1] addr_a, addr_b,
|
||||
input we_a, clk,
|
||||
output reg [D_WIDTH-1:0] q_a, q_b
|
||||
);
|
||||
// Declare the RAM variable
|
||||
reg [D_WIDTH-1:0] ram[(2**A_WIDTH)-1:0];
|
||||
|
||||
// Port A
|
||||
always @ (posedge clk)
|
||||
begin
|
||||
if (we_a)
|
||||
ram[addr_a] <= data_a;
|
||||
q_a <= ram[addr_a];
|
||||
q_b <= ram[addr_b];
|
||||
end
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -top lutram_1w2r -chparam A_WIDTH 5 -chparam D_WIDTH 18
|
||||
proc
|
||||
memory -nomap
|
||||
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
|
||||
memory
|
||||
opt -full
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||
|
||||
design -load postopt
|
||||
cd lutram_1w2r
|
||||
select -assert-count 1 t:NX_RFB_U r:mode=4 %i
|
||||
select -assert-count 36 t:NX_DFF
|
||||
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
|
||||
50
tests/arch/nanoxplore/meminit.v
Normal file
50
tests/arch/nanoxplore/meminit.v
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
module top(clk);
|
||||
parameter DEPTH_LOG2 = 10;
|
||||
parameter WIDTH = 36;
|
||||
parameter PRIME = 237481091;
|
||||
localparam DEPTH = 2**DEPTH_LOG2;
|
||||
|
||||
input wire clk;
|
||||
|
||||
(* syn_ramstyle = "distributed" *)
|
||||
reg [WIDTH-1:0] mem [DEPTH-1:0];
|
||||
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i < DEPTH; i = i + 1) begin
|
||||
// Make up data by multiplying a large prime with the address,
|
||||
// then cropping and retaining the lower bits
|
||||
mem[i] = PRIME * (i*2+1);
|
||||
end
|
||||
end
|
||||
|
||||
reg [DEPTH_LOG2-1:0] counter = 0;
|
||||
reg done = 1'b0;
|
||||
|
||||
reg did_read = 1'b0;
|
||||
reg [DEPTH_LOG2-1:0] read_addr;
|
||||
reg [WIDTH-1:0] read_val;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!done) begin
|
||||
did_read <= 1'b1;
|
||||
read_addr <= counter;
|
||||
read_val <= mem[counter];
|
||||
end else begin
|
||||
did_read <= 1'b0;
|
||||
end
|
||||
|
||||
if (!done)
|
||||
counter = counter + 1;
|
||||
if (counter == 0)
|
||||
done = 1;
|
||||
end
|
||||
|
||||
wire [WIDTH-1:0] expect_val = PRIME * (read_addr*2+1);
|
||||
always @(posedge clk) begin
|
||||
if (did_read) begin
|
||||
$display("addr %x expected %x actual %x", read_addr, expect_val, read_val);
|
||||
assert(read_val == expect_val);
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
44
tests/arch/nanoxplore/meminit.ys
Normal file
44
tests/arch/nanoxplore/meminit.ys
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
read_verilog -sv meminit.v
|
||||
chparam -set DEPTH_LOG2 5 -set WIDTH 36
|
||||
prep
|
||||
opt_dff
|
||||
prep -rdff
|
||||
synth_nanoxplore
|
||||
clean_zerowidth
|
||||
select -assert-none t:$mem_v2 t:$mem
|
||||
read_verilog +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim_u.v
|
||||
prep
|
||||
async2sync
|
||||
hierarchy -top top
|
||||
sim -assert -q -n 66 -clock clk
|
||||
|
||||
design -reset
|
||||
read_verilog -sv meminit.v
|
||||
chparam -set DEPTH_LOG2 6 -set WIDTH 18
|
||||
prep
|
||||
opt_dff
|
||||
prep -rdff
|
||||
synth_nanoxplore
|
||||
clean_zerowidth
|
||||
select -assert-none t:$mem_v2 t:$mem
|
||||
read_verilog +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim_u.v
|
||||
prep
|
||||
async2sync
|
||||
hierarchy -top top
|
||||
sim -assert -q -n 34 -clock clk
|
||||
|
||||
|
||||
design -reset
|
||||
read_verilog -sv meminit.v
|
||||
chparam -set DEPTH_LOG2 8 -set WIDTH 18
|
||||
prep
|
||||
opt_dff
|
||||
prep -rdff
|
||||
synth_nanoxplore
|
||||
clean_zerowidth
|
||||
select -assert-none t:$mem_v2 t:$mem
|
||||
read_verilog +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim_u.v
|
||||
prep
|
||||
async2sync
|
||||
hierarchy -top top
|
||||
sim -assert -q -n 258 -clock clk
|
||||
41
tests/arch/nanoxplore/mux.ys
Normal file
41
tests/arch/nanoxplore/mux.ys
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
read_verilog ../common/mux.v
|
||||
design -save read
|
||||
|
||||
hierarchy -top mux2
|
||||
proc
|
||||
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux4
|
||||
proc
|
||||
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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 2 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux8
|
||||
proc
|
||||
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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 5 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux16
|
||||
proc
|
||||
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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 13 t:NX_LUT
|
||||
|
||||
select -assert-none t:NX_LUT %% t:* %D
|
||||
4
tests/arch/nanoxplore/run-test.sh
Executable file
4
tests/arch/nanoxplore/run-test.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
source ../../gen-tests-makefile.sh
|
||||
run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'"
|
||||
10
tests/arch/nanoxplore/shifter.ys
Normal file
10
tests/arch/nanoxplore/shifter.ys
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
read_verilog ../common/shifter.v
|
||||
hierarchy -top top
|
||||
proc
|
||||
flatten
|
||||
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # 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:NX_DFF
|
||||
select -assert-none t:NX_DFF %% t:* %D
|
||||
13
tests/arch/nanoxplore/tribuf.ys
Normal file
13
tests/arch/nanoxplore/tribuf.ys
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
read_verilog ../common/tribuf.v
|
||||
hierarchy -top tristate
|
||||
proc
|
||||
tribuf
|
||||
flatten
|
||||
synth
|
||||
equiv_opt -assert -map +/nanoxplore/cells_sim.v -map +/simcells.v synth_nanoxplore # 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:NX_IOB
|
||||
select -assert-count 2 t:NX_IOB_I
|
||||
select -assert-none t:NX_IOB t:NX_IOB_I %% t:* %D
|
||||
2
tests/liberty/.gitignore
vendored
2
tests/liberty/.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
|||
*.log
|
||||
test.ys
|
||||
*.filtered
|
||||
*.verilogsim
|
||||
|
|
|
|||
15
tests/liberty/XNOR2X1.lib.filtered.ok
Normal file
15
tests/liberty/XNOR2X1.lib.filtered.ok
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
library(ls05_stdcells) {
|
||||
cell(XNOR2X1) {
|
||||
area : 206080.0 ;
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : !(B&!A|!B&A) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
6
tests/liberty/XNOR2X1.lib.verilogsim.ok
Normal file
6
tests/liberty/XNOR2X1.lib.verilogsim.ok
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
module XNOR2X1 (B, A, Y);
|
||||
input B;
|
||||
input A;
|
||||
output Y;
|
||||
assign Y = !(B&!A|!B&A); // !(B&!A|!B&A)
|
||||
endmodule
|
||||
8
tests/liberty/busdef.lib.filtered.ok
Normal file
8
tests/liberty/busdef.lib.filtered.ok
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
library(supergate) {
|
||||
cell(SRAM) {
|
||||
area : 1 ;
|
||||
pin(CE1) {
|
||||
direction : input ;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
tests/liberty/busdef.lib.verilogsim.ok
Normal file
3
tests/liberty/busdef.lib.verilogsim.ok
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module SRAM (CE1);
|
||||
input CE1;
|
||||
endmodule
|
||||
4
tests/liberty/issue3498_bad.lib.filtered.ok
Normal file
4
tests/liberty/issue3498_bad.lib.filtered.ok
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
library(fake) {
|
||||
cell(bugbad) {
|
||||
}
|
||||
}
|
||||
2
tests/liberty/issue3498_bad.lib.verilogsim.ok
Normal file
2
tests/liberty/issue3498_bad.lib.verilogsim.ok
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module bugbad ();
|
||||
endmodule
|
||||
211
tests/liberty/normal.lib.filtered.ok
Normal file
211
tests/liberty/normal.lib.filtered.ok
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
library(supergate) {
|
||||
cell(inv) {
|
||||
area : 1 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : A' ;
|
||||
}
|
||||
}
|
||||
cell(tri_inv) {
|
||||
area : 4 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(S) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Z) {
|
||||
direction : output ;
|
||||
function : A' ;
|
||||
}
|
||||
}
|
||||
cell(buffer) {
|
||||
area : 5 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : A ;
|
||||
}
|
||||
}
|
||||
cell(nand2) {
|
||||
area : 3 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : (A * B)' ;
|
||||
}
|
||||
}
|
||||
cell(nor2) {
|
||||
area : 3 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : (A + B)' ;
|
||||
}
|
||||
}
|
||||
cell(xor2) {
|
||||
area : 6 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : (A *B') + (A' * B) ;
|
||||
}
|
||||
}
|
||||
cell(imux2) {
|
||||
area : 5 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(S) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : ( (A * S) + (B * S') )' ;
|
||||
}
|
||||
}
|
||||
cell(dff) {
|
||||
area : 6 ;
|
||||
ff(IQ, IQN) {
|
||||
next_state : D ;
|
||||
clocked_on : CLK ;
|
||||
clear : RESET ;
|
||||
preset : PRESET ;
|
||||
clear_preset_var1 : L ;
|
||||
clear_preset_var2 : L ;
|
||||
}
|
||||
pin(D) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(CLK) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(RESET) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(PRESET) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Q) {
|
||||
direction : output ;
|
||||
function : IQ ;
|
||||
}
|
||||
pin(QN) {
|
||||
direction : output ;
|
||||
function : IQN ;
|
||||
}
|
||||
}
|
||||
cell(latch) {
|
||||
area : 5 ;
|
||||
latch(IQ, IQN) {
|
||||
enable : G ;
|
||||
data_in : D ;
|
||||
}
|
||||
pin(D) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(G) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Q) {
|
||||
direction : output ;
|
||||
function : IQ ;
|
||||
}
|
||||
pin(QN) {
|
||||
direction : output ;
|
||||
function : IQN ;
|
||||
}
|
||||
}
|
||||
cell(aoi211) {
|
||||
area : 3 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(C) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : ((A * B) + C)' ;
|
||||
}
|
||||
}
|
||||
cell(oai211) {
|
||||
area : 3 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(C) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : ((A + B) * C)' ;
|
||||
}
|
||||
}
|
||||
cell(halfadder) {
|
||||
area : 5 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(C) {
|
||||
direction : output ;
|
||||
function : (A * B) ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : (A *B') + (A' * B) ;
|
||||
}
|
||||
}
|
||||
cell(fulladder) {
|
||||
area : 8 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(CI) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(CO) {
|
||||
direction : output ;
|
||||
function : (((A * B)+(B * CI))+(CI * A)) ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : ((A^B)^CI) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue