Full Code of zeroasiccorp/logik for AI

main 0e3c3688bae1 cached
51 files
152.4 KB
45.6k tokens
45 symbols
1 requests
Download .txt
Repository: zeroasiccorp/logik
Branch: main
Commit: 0e3c3688bae1
Files: 51
Total size: 152.4 KB

Directory structure:
gitextract_iw5zrkjd/

├── .flake8
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── lint.yml
│       ├── regression.yml
│       └── wheels.yml
├── .gitignore
├── .readthedocs.yaml
├── LICENSE
├── README.md
├── docs/
│   ├── Makefile
│   ├── make.bat
│   └── source/
│       ├── bitstream_format.rst
│       ├── conf.py
│       ├── design_preparation.rst
│       ├── execution.rst
│       ├── external_links.rst
│       ├── index.rst
│       ├── pin_constraints.rst
│       ├── prerequisites.rst
│       ├── sc_preparation.rst
│       ├── timing_constraints.rst
│       └── tool_installations.rst
├── examples/
│   ├── __init__.py
│   ├── adder/
│   │   ├── adder.pcf
│   │   ├── adder.py
│   │   ├── adder.v
│   │   └── pin_constraints.py
│   ├── eth_mac_1g/
│   │   ├── constraints/
│   │   │   └── z1000/
│   │   │       └── pin_constraints.pcf
│   │   ├── eth_mac_1g.py
│   │   ├── eth_mac_1g.sdc
│   │   └── eth_mac_1g_wrapper.v
│   └── picorv32/
│       ├── constraints/
│       │   └── z1062/
│       │       └── picorv32.pcf
│       ├── picorv32.py
│       └── picorv32.sdc
├── logik/
│   ├── __init__.py
│   ├── devices/
│   │   ├── __init__.py
│   │   └── logik_fpga.py
│   ├── flows/
│   │   ├── __init__.py
│   │   └── logik_flow.py
│   └── tools/
│       ├── __init__.py
│       └── fasm_to_bitstream/
│           ├── __init__.py
│           ├── bitstream_bin_convert.py
│           ├── bitstream_finish.py
│           └── fasm_to_bitstream.py
├── pyproject.toml
└── tests/
    ├── conftest.py
    ├── data/
    │   └── z1000.py
    └── examples/
        ├── test_adder.py
        ├── test_eth_mac_1g.py
        ├── test_files.py
        └── test_picorv32.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .flake8
================================================
[flake8]
extend-exclude = testbench/build,build,.venv
max-line-length = 100
ignore =
    E125,
    E129,
    E128,
    W503


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  # Maintain dependencies for GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      actions:
        patterns:
          - "*"
  # Maintain dependencies for Python
  - package-ecosystem: pip
    directory: "/"
    schedule:
      interval: "daily"
    groups:
      python-packages:
        patterns:
          - "*"


================================================
FILE: .github/workflows/lint.yml
================================================
# Copyright (c) 2024 Zero ASIC Corporation
# This code is licensed under Apache License 2.0 (see LICENSE for details)

# modified from https://github.com/siliconcompiler/siliconcompiler/blob/main/.github/workflows/lint.yml

name: Lint
on:
  pull_request:
  workflow_dispatch:
  push:
    branches:
      - main

jobs:
  lint_python:
    name: Lint Python Code
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Set up Python 3.10
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Setup permissions
        run: |
          echo ${{ secrets.ZA_TOKEN }} | gh auth login --with-token
          gh auth setup-git
          git config --global url."https://github".insteadOf git://github

      - name: Install Requirements
        run: |
          python3 -m pip install --upgrade pip
          pip install .[test]

      - name: Lint with Flake8
        run: flake8 --statistics .


================================================
FILE: .github/workflows/regression.yml
================================================
---

name: Regression
on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - main

jobs:
  version-compatibility:
    name: Test Python ${{ matrix.python-version }} with ${{ matrix.resolution }} deps

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.14"]
        resolution: ["highest", "lowest-direct"]

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install uv
        uses: astral-sh/setup-uv@v7

      - name: Install dependencies with ${{ matrix.resolution }} resolution
        run: |
          uv pip install --system --resolution ${{ matrix.resolution }} -e .[test]

      - name: Verify installation and imports
        run: |
          python -c "import logik; import siliconcompiler; print('✓ Imports successful')"
          python -c "from logik.flows.logik_flow import LogikFlow; print('✓ LogikFlow imported')"

      - name: Run basic tests (no CAD tools)
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          pytest tests/examples/test_files.py -v

  pytest:
    name: Run CAD flow tests

    runs-on: ubuntu-latest
    container:
      image: ghcr.io/siliconcompiler/sc_runner:latest

    env:
      GIT_TOKEN: ${{ secrets.ZA_TOKEN }}

    steps:
      - uses: actions/checkout@v6

      - name: Setup permissions
        run: |
          apt update && apt install sudo -y
          type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
          curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
          && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
          && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
          && sudo apt update \
          && sudo apt install gh -y

          echo ${{ secrets.ZA_TOKEN }} | gh auth login --with-token
          gh auth setup-git

      - name: Setup git access
        run: |
          git config --global --add url."https://github.com/".insteadOf git@github.com:
          git config --global --add safe.directory "$GITHUB_WORKSPACE"

      - name: Setup python
        run: |
          python3 -m venv --system-site-packages .logik
          . .logik/bin/activate
          python3 -m pip install --upgrade pip
          pip3 install -e .[test]

      - name: Run tests
        run: |
          . .logik/bin/activate
          pytest


================================================
FILE: .github/workflows/wheels.yml
================================================
name: Wheels

on:
  workflow_dispatch:
  release:
    types:
      - published

jobs:
  build_wheels:
    name: Wheels
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v6
      with:
        submodules: true
        fetch-depth: 0

    - uses: hynek/build-and-inspect-python-package@v2

  publish:
    needs: [build_wheels]
    runs-on: ubuntu-latest
    permissions:
      id-token: write
    if: github.event_name == 'release' && github.event.action == 'published'

    steps:
    - uses: actions/download-artifact@v8
      with:
        name: Packages
        path: dist

    - name: Publish
      uses: pypa/gh-action-pypi-publish@v1.14.0

  save:
    needs: [publish]
    runs-on: ubuntu-latest

    permissions:
      contents: write

    steps:
    - uses: actions/download-artifact@v8
      with:
        name: Packages
        path: dist

    - name: Add wheels to GitHub release artifacts
      uses: softprops/action-gh-release@v3
      with:
        files: dist/*.whl


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
#   For a library or package, you might want to ignore these files since the code is
#   intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# poetry
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
#   in version control.
#   https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Emacs backup files
*~

# Switchboard
*.q

# scm version
logik/_version.py


================================================
FILE: .readthedocs.yaml
================================================
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

build:
  os: ubuntu-22.04
  tools:
    python: "3.11"
    
# Build documentation in the docs/ directory with Sphinx
sphinx:
  configuration: docs/source/conf.py

formats:
  - pdf

python:
    install:
    - method: pip
      path: .
      extra_requirements:
        - docs


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2025 Zero ASIC Corporation

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
Logik
-------------------------------------------------------------

[![Regression](https://github.com/siliconcompiler/logik/actions/workflows/regression.yml/badge.svg)](https://github.com/siliconcompiler/logik/actions/workflows/regression.yml)
[![Lint](https://github.com/siliconcompiler/logik/actions/workflows/lint.yml/badge.svg)](https://github.com/siliconcompiler/logik/actions/workflows/lint.yml)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

Logik is an open source FPGA tool chain with support for high level language parsing, synthesis, placement, routing, bitstream generation, and analysis. Users enter design sources, constraints, and compile options through a simple [SiliconCompiler](https://github.com/siliconcompiler/siliconcompiler/) Python API. Once setup is complete, automated compilation can be initiated with a single line run command. Logik relies on the [Logiklib](https://github.com/siliconcompiler/logiklib) project for all architecture and device descriptions.

![logik_flow](images/logik-plus-open-sta-flow.png)

Logik supports most of the features you would expect in a commercial proprietary FPGA tool chain.

| Feature                  | Status |
|--------------------------|--------|
| Design languages         | SystemVerilog, Verilog, VHDL
| DSP synthesis            | Supported
| RAM synthesis            | Supported
| Timing constraints (SDC) | Supported
| Pin Constraints (PCF)    | Supported
| Bitstream generation     | Supported
| IP management            | Supported
| Remote compilation       | Supported
| Multi-clock designs      | Supported
| Supported devices        | Logiklib devices

## Getting Started

The Logik tool chain is available through PyPi and can be installed using pip.

```sh
python -m pip install --upgrade logik
```

All open source FPGA pre-requisites can be installed via the SiliconCompiler `sc-install` utility.

```sh
sc-install -group fpga
```

The following example illustrates some essential Logik features. For complete documentation of all options available, see the [SiliconCompiler project](https://github.com/siliconcompiler/siliconcompiler/blob/main/README.md).

```python

import siliconcompiler
from logik.flows.logik_flow import LogikFlow
from logiklib.zeroasic.z1000 import z1000

# 1. Create a Design object to hold source files and constraints.
design = siliconcompiler.Design('adder')
design.add_file('adder.v', fileset="rtl")
design.set_topmodule('adder', fileset="rtl")

# Create an FPGA project
project = siliconcompiler.FPGA(design)

# Assign file sets to use for elaboration
project.add_fileset('rtl')

# Select the rtl2bits flow to use
project.set_flow(LogikFlow())

# Load FPGA part settings and associated flow and libraries.
project.set_fpga(z1000.z1000())

# User defined options
project.option.set_quiet(True)

# Run compilation
project.run()

# Display summary of results
project.summary()

```

> [!NOTE]
> The required files can be found [here](https://github.com/siliconcompiler/logik/tree/main/examples/adder)

## Examples

* [Ethernet](./examples/eth_mac_1g/eth_mac_1g.py): Ethernet MAC compiled for the `z1000` architecture.
* [Adder](examples/adder/adder.py): Small adder example compiled for the `z1000` architecture.
* [Picorv32](examples/picorv32/picorv32.py): picorv32 RISC-V CPU example compiled for the `z1062` architecture.

## Documentation

* [Logik Documentation](https://logik.readthedocs.io/en/latest/)
* [SiliconCompiler Documentation](https://docs.siliconcompiler.com/en/stable/)


## Installation

Logik is available as wheel packages on PyPI for macOS, Windows and Linux platforms. For working Python >= 3.10 environments, just use `pip` to install.

```sh
python -m pip install --upgrade logik
```

Running natively on your local machine will require installing a number of prerequisites:

* [Silicon Compiler](https://github.com/siliconcompiler/siliconcompiler): Hardware compiler framework
* [Slang](https://github.com/MikePopoloski/slang): SystemVerilog Parser
* [Yosys](https://github.com/YosysHQ/yosys): Logic synthesis platform
* [Wildebeest](https://github.com/zeroasiccorp/wildebeest): High-performance synthesis yosys plugin
* [VPR](https://github.com/verilog-to-routing/vtr-verilog-to-routing): FPGA place and route
* [FASM](https://github.com/chipsalliance/fasm): FPGA assembly parser and generator
* [OpenSTA](https://github.com/The-OpenROAD-Project/OpenSTA): Production-grade static timing analysis engine

We recommend using the SiliconCompiler `sc-install` utility to automatically install the correct versions of all open source FPGA tool dependencies.

```sh
sc-install -group fpga
```

Detailed installation instructions can be found in the [SiliconCompiler Installation Guide](https://docs.siliconcompiler.com/en/stable/user_guide/installation.html#external-tools).


## License

The Logik project is licensed under the open source [Apache License 2.0](LICENSE). For licensing terms of all dependencies, visit dependency repository.

## Issues / Bugs
We use [GitHub Issues](https://github.com/siliconcompiler/logik/issues) for tracking requests and bugs.


================================================
FILE: docs/Makefile
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS    ?=
SPHINXBUILD   ?= sphinx-build
SOURCEDIR     = source
BUILDDIR      = build

# Put it first so that "make" without argument is like "make help".
help:
	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)


================================================
FILE: docs/make.bat
================================================
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
	set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
	echo.
	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
	echo.installed, then set the SPHINXBUILD environment variable to point
	echo.to the full path of the 'sphinx-build' executable. Alternatively you
	echo.may add the Sphinx directory to PATH.
	echo.
	echo.If you don't have Sphinx installed, grab it from
	echo.https://www.sphinx-doc.org/
	exit /b 1
)

if "%1" == "" goto help

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd


================================================
FILE: docs/source/bitstream_format.rst
================================================
Bitstream Formatting
====================

Bitstream data is generated in this flow in multiple formats:

* `FASM <https://fasm.readthedocs.io/en/latest/>`_ is the bitstream format supported within the Verilog-to-Routing flow.  This format is a plain text, human-readable format originally developed for `F4PGA <https://f4pga.org/>`_ and its predecessor projects.  The genfasm step in this flow emits bitstreams in FASM format.
* A JSON intermediate representation of the bitstream is generated to provide a convenient intermediate representation between the FASM-formatted bitstream and the final binary bitstream.  It is generally used for internal purposes only.  See below for details on configuration bit organization.
* A binary representation of the bitstream is generated for delivery of the bitstream to other applications.  Generation of this file is referred to in the flow as bitstream finishing.

Understanding the details of bitstream formatting is typically necessary only for writing software drivers to perform bitstream loading for particular FPGA chips.

The following sections outline how bitstreams are organized in a general sense without specifying the bitstream format for a particular FPGA or eFPGA architecture.

Working with FASM Bitstream Data
--------------------------------

A FASM file is comprised of an enumeration of "features" that are enabled or have non-zero values.  Each feature is assigned a plain-text label.

End user post-processing of the FASM file is not recommended as making use of the data requires precise knowledge of the underlying FPGA architecture.  For all considerations related to parsing the format, please consult `FASM documentation <https://fasm.readthedocs.io/en/latest/>`_

Working with JSON Bitstream Data
--------------------------------

JSON is used as the file format for storing an intermediate representation (IR) of bitstream data between FASM and binary formats.

The IR organizes the bitstream into a four-dimensional on-chip address space organized by array location.  Each bit in the bitstream can thus be indexed by an X coordinate, Y coordinate, word address, and bit index in this IR.

For each FPGA architecture supported by the flow, a bitstream map file is provided that maps FASM features into this address space.  The bitstream finishing step in Logik uses this bitstream map file to convert FASM to the IR.

.. note::

   Architecture bitstream map files are cached by Silicon Compiler for use within the flow and may not be easily accessible by end users.

Working with Binary Bitstream Data
----------------------------------

The binary representation of bitstream data consolidates the bitstream IR described above into a ROM-style format.  The four-dimensional address space of individual bits is collapsed into a one-dimensional address space of bitstream words.  The mapping is as shown in the table below

+-------------------------+------------------------------+------------------------+
| most significant bits   | next most significant bits   | least significant bits |
+-------------------------+------------------------------+------------------------+
| Y coordinate            | X coordinate                 | word address           |
+-------------------------+------------------------------+------------------------+

When mapped into this address space, bitstream words are ordered from lowest address value to highest address value.

The binary format does not specify a word size; instead, this is dictated by the FPGA/eFPGA architecture.  Words are treated as binary strings that, when read left to right, are read MSB to LSB.  The packing of bitstream words into bytes in a binary file is dictated by Python's tofile() function.  Implementations of a binary bitstream file reader should account for this so that when the bitstream is read back word ordering in this address space is preserved.

To make this more concrete, consider the an example FPGA architecture with array size 30x30.  An array of this size requires five bits to represent the X coordinate to represent the Y coordinate.  The number of word addresses needed at each (X,Y) coordinate in the array may vary.  To make a uniform address space, the maximum required word address dictates the number of bits of word address used.   If the example FPGA architecture's maximum address is 141, eight bits of word address are needed.  The binary bitstream address format is thus eighteen bits wide and organized as follows:

+--------------+--------------+--------------+
| [17:13]      | [12:8]       | [7:0]        |
+--------------+--------------+--------------+
| Y coordinate | X coordinate | word address |
+--------------+--------------+--------------+

The ordering of the words in the binary file thus begins with word address 0 at array coordinate (0,0) and the last word is word address 141 at array coordinate (29, 29).


================================================
FILE: docs/source/conf.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import datetime

import logik


# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = "Logik"
copyright = (
    f"2024-{datetime.datetime.now(tz=datetime.timezone.utc).date().year}, Zero ASIC"
)
author = "Zero ASIC"
release = logik.__version__

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
    "sphinx.ext.autodoc",  # automatically generate documentation for modules
    "sphinx.ext.napoleon",  # to read Google-style or Numpy-style docstrings
    "sphinx.ext.viewcode",  # to allow vieing the source code in the web page
    "autodocsumm",  # to generate tables of functions, attributes, methods, etc.
]

templates_path = ["_templates"]
exclude_patterns = []

root_doc = "index"


# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = "sphinx_rtd_theme"

autodoc_inherit_docstrings = False
autodoc_typehints = "description"
# include __init__ docstrings
autoclass_content = "both"


================================================
FILE: docs/source/design_preparation.rst
================================================
Design Preparation
==================

Prior to running the RTL-to-bitstream flow, design data must be aggregated and organized so that it can be found during flow execution.  The effort to do this is minimal and outlined below.

Create a Working Directory
--------------------------

Because the flow is command-line driven, organization of files is performed at the command line rather than through an integrated development environment (IDE) project-based infrastructure.  It is strongly recommended that users create a dedicated directory tree in which to store HDL files, constraint files, and their Silicon Compiler run script.  It is also recommended (though not required) to execute the RTL-to-bitstream flow from the directory containing the Silicon Compiler run script.

Aggregate Input Files
---------------------

The following file types should be aggregated

* HDL files
* Timing Constraints
* Pin Constraints

With these in place, a Silicon Compiler run script will have all required input files for execution.



================================================
FILE: docs/source/execution.rst
================================================
RTL-to-Bitstream Flow Execution
===============================

Within your Python virtual environment or wherever you have installed Silicon Copmiler, simply execute your Silicon Compiler run script

::

   python3 <your_sc_run_script>


================================================
FILE: docs/source/external_links.rst
================================================
External Links for Open Source Tools
====================================

Below is a set of links to documentation for open source tools used by Logik.  For each tool, the "Github" to go to the project github page.  The "Documentation" link links to the project's online documentation/home page.  If a tool does not contain a documentation link below, please consult its Github repository README for documentation.

+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| F4PGA (FASM format authors)  | `F4PGA Github <https://github.com/chipsalliance/f4pga>`_                     | `F4PGA Documentation <https://f4pga.org/>`_                            |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| GHDL                         | `GHDL Github <https://github.com/ghdl/ghdl>`_                                | `GHDL Documentation <https://ghdl.github.io/ghdl/>`_                   |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| GTKWave                      | `Gtkwave Github <https://github.com/gtkwave/gtkwave>`_                       | `Gtkwave Documentation <https://gtkwave.sourceforge.net/>`_            |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| Icarus Verilog               | `Icarus Github <https://github.com/steveicarus/iverilog>`_                   | `Icarus Documentation <https://steveicarus.github.io/iverilog/>`_      |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| Silicon Compiler             | `SC Github <https://github.com/siliconcompiler/siliconcompiler>`_            | `SC Documentation <https://docs.siliconcompiler.com/en/stable>`_       |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| slang                        | `slang Github <https://github.com/MikePopoloski/slang>`_                     |                                                                        |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| Verilator                    | `Verilator Github <https://github.com/verilator/verilator>`_                 | `Verilator Documentation <https://verilator.org/guide/latest/>`_       |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| Verilog-to-Routing (VPR)     | `VPR Github <https://github.com/verilog-to-routing/vtr-verilog-to-routing>`_ | `VPR Documentation <https://docs.verilogtorouting.org/en/latest/>`_    |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| Wildebeest                   | `Wildebeest Github <https://github.com/zeroasiccorp/wildebeest>`_            |                                                                        |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+
| Yosys                        | `Yosys Github <https://github.com/YosysHQ/yosys>`_                           | `Yosys Documentation <https://yosyshq.readthedocs.io/en/latest/>`_     |
+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+


================================================
FILE: docs/source/index.rst
================================================
Logik Demo Edition
==================

Welcome to the demo edition of Logik.  In this edition, the following features are showcased:

* RTL to bitstream automation flow for FPGA/eFPGA architectures, powered by `Silicon Compiler <https://www.siliconcompiler.com>`_
* Integration with logiklib, a catalog repository of FPGA/eFPGA architectures

* Example designs for reference in adopting the flow
* Documentation providing step-by-step guidance for setup and execution of the flow
  
Documentation Table of Contents
===============================

.. toctree::
    :maxdepth: 2
    :caption: Usage
    
    prerequisites
    tool_installations
    design_preparation
    sc_preparation
    execution

.. toctree::
    :maxdepth: 1
    :caption: References

    timing_constraints	      
    pin_constraints
    bitstream_format
    external_links
    

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`


================================================
FILE: docs/source/pin_constraints.rst
================================================
Preparing Pin Constraints and Placement Constraints
===================================================

Execution of the placement and routing steps with VPR do not require specifying constraints for the location of top-level ports in the user RTL design.  When no constraints are specified, VPR will automatically choose locations for ports using its placement algorithm.

In some architectures (including the architecture supplied for the examples in this distribution), pin constraints are required in order to specify which of a subset of FPGA pins may be used as clock signals.  More practically, constraints are typically required on all ports so that signals are routed to the correct physical locations for interaction with other components.  Constraints may also be specified for the physical location of logic blocks.

The methods of supplying these constraints are described below.

VPR Placement Constraints
-------------------------

VPR natively supports pin constraint specification as a subset of its generic placement constraint settings.  VPR placement constraints are specified in XML format.  Complete documentation of this format is provided as part of `VPR documentation <https://docs.verilogtorouting.org/en/latest/vpr/placement_constraints/>`_.

To make use of these constraints it is necessary to have detailed information about the structure of the FPGA that is being targeted.  FPGA resources are mapped in VPR to a grid laid out on an (X,Y) coordinate system.

Use of this format is required in order to constrain the placement of logic blocks.  However, typically specifying placement constraints for logic blocks is not necessary in this RTL-to-bitstream flow.

If only pin constraints need to be specified, knowledge of this coordinate system is not necessary.  Instead, a port-to-port mapping between user ports and eFPGA ports/FPGA pins can be specified in JSON format.  This format is described below.


JSON Pin Constraints (PCF)
--------------------------
Specifying pin constraints in JSON format is supported so that users can specify a mapping between ports in their top-level RTL and port or pin names defined in the FPGA architecture.  The required structure of the JSON file is referred to within Silicon Compiler as PCF format to distinguish it from other JSON files, and the .pcf file extension is used as an indicator that a file is of this type.

The PCF file is organized as a dictionary of JSON objects where keys in the dictionary are user port names and values are two-element dictionaries containing the port direction and the FPGA top level port name to which that user port should be mapped.  The port direction is specified with the "direction" key and the the FPGA top level port name is specified with the "pin" key.  This syntax is shown in the example below:

Example Pin Constraint Syntax
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

::
   
  "resetn": {
    "direction": "input",
    "pin": "gpio_in[1]"
  },



================================================
FILE: docs/source/prerequisites.rst
================================================
System Software Requirements
============================

Supported Operating Systems
---------------------------

The following operating systems are supported without the requirement of running within a docker container:

* Ubuntu 20.04

Additional OS support is provided by running within a docker container.

General Purpose Software Requirements
-------------------------------------

The following general purpose software must be installed on your system to use this flow:

* Python 3.10 or higher
* git

Required EDA Software Tools
---------------------------

* Silicon Compiler
* Yosys
* VPR

For VHDL support, GHDL is also required.

For SystemVerilog support, slang is also required.

For links to all EDA software Github repositories and documentation pages, please consult the :doc:`external_links`.

Optional EDA Software Tools
---------------------------

While not required to run the RTL-to-bitstream flow, HDL simulation support is required to run HDL simulations on provided examples.

Either of the following open-source simulators may be used for HDL simulation:

* Icarus Verilog
* Verilator
  
For waveform viewing, there are a few open source viewers to choose from:

* Surfer
* GTKWave
  
For links to all EDA software Github repositories and documentation pages, please consult the :doc:`external_links`.



================================================
FILE: docs/source/sc_preparation.rst
================================================
===========================================
 Preparing the Silicon Compiler Run Script
===========================================

Developing a Silicon Compiler run script for RTL-to-bitstream flow execution follows the same fundamental approach as developing a script for any Silicon Compiler flow execution.
Additional resources for understanding Silicon Compiler fundamentals are available at `docs.siliconcompiler.com <https://docs.siliconcompiler.com/en/stable>`_

For most designs, the example Silicon Compiler run scripts provided with Logik can be used as templates for creating your own.
The commands used in these examples and the general method for constructing run scripts are described below.

Constructing a Silicon Compiler run script can be broken down into the following steps:

* :ref:`import_modules`
* :ref:`Create_main_function`
* :ref:`Create_design_object`
* :ref:`Select_part_name`
* :ref:`Import_libraries`
* :ref:`Set_timing_constraints`
* :ref:`Set_pin_constraints`
* :ref:`Create_project_object`
* :ref:`Select_part_name`
* :ref:`Select_flow`
* :ref:`Add_options`
* :ref:`Add_execution_calls`
  
.. _import_modules:

Import Modules
==============

All Silicon Compiler run scripts are pure Python scripts that import Silicon Compiler functionality like any other Python module.
Similarly, the Logik RTL-to-bitstream flow is enabled as a set of Python modules that integrate to Silicon Compiler.

The minimum import requirements in a Logik Silicon Compiler run script are:

::

   import siliconcompiler
   from logik.targets import logik_target


Additional module imports may be required depending on project-specific requirements.

.. _Create_main_function:

Create Main Function
====================

Since the Silicon Compiler run script is just a Python script, executing it from the command line requires the same infrastructure as any other Python script.
In most design flows, the most convenient way to enable this will be to simply encapsulate the script in a `main()` function:

In Python, an executable `main()` function is implemented with the following code:

::

   def main(<main_function_parameters (optional)>):

       #Insert your main function here

   if __name__ == "__main__":
       main()

Experienced Python programmers may prefer to use their own scripting methodology for executing the script instead of the above.
Any approach that conforms to both Python and Silicon Compiler requirements should work.

.. _Create_design_object:

Create Design Object
====================

Silicon Compiler design information is encapsulated in a Python class called Design.

The Design class constructor requires one parameter: the name of the top level module in your RTL design.
A complete Design instantiation takes the form

::

   design = siliconcompiler.Design('<your_top_module_name>')


All design-specific data is housed within this class; it should be the first (or nearly the first) line in your main function.

Throughout this documentation, "design" will be used to refer to the Design class instance.
However, there is no requirement that the instance be assigned to this variable name.

.. _Import_libraries:

Add Source Files
================

All HDL source files must be added to the Silicon Compiler design object for inclusion.  Adding source files is a two-step process:

1.  Set source file data root
2.  Add all source files located at the given data root

The procedure below may be repeated for as many data roots as required.

.. _Set_dataroot:

Setting a Source File Data Root
-------------------------------

Setting a source file data root achieves two goals:

1.  It defines a group of source files housed in a common directory tree as a named IP package in Silicon Compiler
2.  It tells Silicon Compiler where source files are located.  This location could be either a filesystem path or a web URL (e.g. Github repository).

To name a IP package and specify its data root, the `set_dataroot` member function of the Design class is called:
::

    design.set_dataroot(<package_name>, <package_location>, [version])

`<package_name>` is a unique string ID defining the IP package located at `<package_location>`.  `<package_location>` can be either a filesystem path or a URL.  `[version]` is optional, but may be used with package locations that are github repository URLs to specify a particular version (tag or commit hash) of that repository to check out.

.. _Set_input_source_files:

Adding Source Files
-------------------

For each HDL file, include the following call in your Silicon Compiler run script

::

   with design.active_dataroot(<package_name>):
       design.add_file(<your_hdl_file_name>, fileset=<fileset_name>)

Enclosing the `add_file()` call within a `with` statement ensures that, for designs with multiple data roots, the correct data root is applied to each file.  Any number of files with a common data root may be embedded in a single `with` statement.

Specifying a fileset ensures that files within a given IP package are organized and handled correctly by Silicon Compiler.  In the examples provided with Logik, filesets are used to distinguish HDL files from constraint files.  HDL files are assigned to the fileset `rtl`, SDC constraints are assigned to the fileset `sdc`, and pin constraint files to the `pcf` fileset.  For more implementation details concerning filesets, consult `Silicon Compiler fileset documentation <https://docs.siliconcompiler.com/en/latest/reference_manual/schema.html#param-fpgadevice-fileset>`_

.. note::

   Silicon Compiler supports multiple front end options, including flows for high-level synthesis.
   For all front end compilation considerations not described above, please consult `Silicon Compiler Frontend documentation <https://docs.siliconcompiler.com/en/stable/user_guide/tutorials/hw_frontends.html>`_

For large designs, the above calls can be integrated into loops that iterate over lists of files

.. _Set_timing_constraints:

Set Timing Constraints
======================

.. note::

   The demo architecture provided with this distrbution implements a unit delay model.
   Provided examples demonstrate the RTL-to-bitstream flow without an SDC file.

Timing constraints must be provided in a single SDC file.  The SDC file must be added to the Silicon Compiler design object for inclusion.  The API for inclusion is identical to that for adding source files:

::

   with design.active_dataroot(<package_name>):
       design.add_file('<your_sdc_file_name>', fileset=<sdc_fileset>)

.. note::

   If no SDC file is provided, the flow will still run to completion.
   Timing analysis will be disabled during the place and route steps.

.. _Set_pin_constraints:

Set Pin Constraints
===================

Pin constraints may be provided in one of two files:

* A JSON pin constraints file (PCF)
* A VPR XML placement constraints file

.. note::

   If you need to specify placement constraints for design logic blocks in addition to specifying pin constraints, the XML placement constraints file must be used.

JSON Pin Constraint Specification
---------------------------------

The JSON pin constraint file is unique to this flow.
For additional information on creating the JSON pin constraint file, see :doc:`pin_constraints`.

The JSON placement constraints file must be added to the Silicon Compiler design object for inclusion.  The API for inclusion is identical to that for adding source files:

::

   with design.active_dataroot(<package_name>):
      design.add_file('<your_pcf_file_name>', fileset=<pcf_fileset>)

.. note::

   The .pcf file extension must be used

VPR XML Placement Constraint Specification
------------------------------------------

VPR XML placement constraints are portable to any VPR-based place and route flow.
For additional information on creating a VPR XML placement constraint file, see `VPR's documentation for placement constraints <https://docs.verilogtorouting.org/en/latest/vpr/placement_constraints/>`_.

The XML placement constraints file must be added to the Silicon Compiler Design object for inclusion.

::
   
   with design.active_dataroot(<package_name>):
      design.add_file('<your_xml_file_name>', fileset=<xml_fileset>)

in your Silicon Compiler run script.

.. _Create_project_object:

Create Project Object
=====================

Silicon Compiler includes a Project object for encapsulating all aspects of how a design will be implemented.  Like the Design object, the Project is simply a Python class defined in Silicon Compiler.  The primary items encapsulated within the Project are the design data from the Design object described above, the target FPGA device to be used for the project, and settings to control Logik's RTL to bitstream flow.

When using Logik, a specialized Project object for FPGAs is used; this object is of type FPGA.

The FPGA class constructor requires one parameter: an instance of a Design object.  In your run script, you can instantiate this as follows:

::

   project = siliconcompiler.FPGA('<your_design_name>')


Following the variable names used above, `<your_design_name>` would be replaced with `design`.

Add filesets to Project
-----------------------

All filenet names used in specifying design data must be added to the project.  This is done with the Project class's `add_fileset` function.  Typically there will be three filesets to add:  one for HDL files, one for SDC, and one for pin constraints:

::

    project.add_fileset('rtl')
    project.add_fileset('sdc')
    project.add_fileset('pcf')

.. _Select_part_name:

Select Part Name
================

Silicon Compiler associates each FPGA/eFPGA architecture with an object called a part driver.  The part driver is a Python class tailored to that FPGA/eFPGA for housing metadata specific to its architecture.  This metadata includes architecture parameters, associated data files, and other architecture-specific information.

Because part drivers are just Python classes, they can be imported from anywhere.  However, the common case is that the part driver will be imported from `Logiklib <https://github.com/siliconcompiler/logiklib>`_, a dedicated open source Github repository of Logik part drivers and associated CAD files.

At the top of your Python run script, include an `import` statement to import the FPGA part for your project:

::

   from logiklib.<vendor>.<part_name> import <part_name>

The format above illustrates Logiklib's python package organization for part drivers, which is by vendor and then by part name.  For example, to import the Zero ASIC z1000 architecture, the call is

::

   from logiklib.zeroasic.z1000 import z1000

The presense of this `import` statement allows the z1000 FPGA to be selected for use in the project using the `set_fpga()` function:

::

   project.set_fpga(<part_name>)

.. _Select_flow:

Select Flow
===========

Logik's RTL-to-bitstream flow is encapsulated in a Python class called LogikFlow.  This class derives from Silicon Compiler's Flow class.  A project's tool execution flow is selected by passing a Flow object to the project via the `set_flow()` function.  This means that all Logik projects should import Logik's flow:

::

   from logik.flows.logik_flow import LogikFlow

and then set it accordingly:

::

   project.set_flow(LogikFlow())

.. _Add_options:

Add Design and Project Options
==============================

Numerous options can be added to your run script to control Silicon Compiler behavior or configure tools in the RTL-to-bitstream flow to behave as desired.

Some options are configured on a per-design basis; others on a per-project basis.
For complete Silicon Compiler option specifications, refer to `Silicon Compiler's documentation for supported option settings <https://docs.siliconcompiler.com/en/stable/reference_manual/schema.html#param-option-ref>`_.

In particular, any compiler directives that are required for HDL synthesis should be specified as Silicon Compiler options.
These are furnished with Design class member function calls of the form

::

   design.add_define(<compiler_directive>, fileset=<fileset>)


Similarly, any HDL parameters that must be set explicitly for synthesis can be set with the `set_param()` function:

::

   design.set_param(<parameter>, <value>, fileset=<fileset>)

In both cases, `<fileset>` should have the same value as that used for HDL files (e.g. `rtl`).
   
.. _Add_execution_calls:

Add Execution Calls
===================

The final two lines of every run script should be the same:

::
   
   project.run()
   project.summary()
   
The `run()` call invokes the RTL-to-bitstream flow with all settings specified.
The `summary()` call reports results of the run in tabular form.
Included in the summary results are key design metrics such as FPGA resource utilization and tool execution runtimes.


================================================
FILE: docs/source/timing_constraints.rst
================================================
Preparing Timing Constraints for VPR
====================================

.. note::

   The demo architecture provided with this distrbution implements a unit delay model.  Provided examples demonstrate the Logik without an SDC file.  Examples that include SDC files are planned for a future release.

VPR is the place and route engine used in the Logik RTL to bitstream flow.  To support VPR's timing-driven place and route flow, timing constraints are provided in a Synopsys Design Constraint (SDC) file.

The minimum requirement is to specify a target clock frequency using the `create_clock` constraint:

::
   
   create_clock -period <float> <name of clock port>

For specifics on VPR's supported timing constraints, please consult the `VPR SDC Commmand support page <https://docs.verilogtorouting.org/en/latest/vpr/sdc_commands/>`_


================================================
FILE: docs/source/tool_installations.rst
================================================
Installing Required Software
============================

There are two ways to install the above software tools:
    1. Run within the Silicon Compiler tools docker image
    2. Use Silicon Compiler's sc-install command
    3. Build from source yourself

Silicon Compiler Tools Docker Image Setup
-----------------------------------------

First, install Docker according to the instructions for your operating system:

* `Linux Docker installation <https://docs.docker.com/desktop/install/linux-install/>`_
* `macOS Docker installation <https://docs.docker.com/desktop/install/mac-install/>`_
* `Windows Docker installation <https://docs.docker.com/desktop/install/windows-install/>`_

Once Docker is installed, launch the Docker Desktop application.

* Ubuntu: `Ctrl`-`Alt`-`T` or run the Terminal application from the Dash
* macOS: `Cmd-Space` to open Spotlight, then type `Terminal` and press `Enter`
* Windows: Open `Windows PowerShell` from the Start menu.

::
   
   docker run -it -v "${PWD}/sc_work:/sc_work" ghcr.io/siliconcompiler/sc_runner:latest
       
Silicon Compiler sc-install Tool
--------------------------------

When Silicon Compiler has been installed in your Python virtual environment, all required software can be installed by running

::

   sc-install -group fpga
   sc-install opensta

Building Software From Source
-----------------------------

Several resources are offered to assist in the installation process when tools need to be built from source.

Silicon Compiler's documentation provides reference install scripts for tools used in its flows.  These can be used as startpoints for developing install scripts for your particular system and are available at `https://docs.siliconcompiler.com/en/stable/user_guide/installation.html#external-tools <https://docs.siliconcompiler.com/en/stable/user_guide/installation.html#external-tools>`_

Additionally, the :doc:`external_links` page in this documentation points to documentation for open source software used in the flow.  Each of these software tools maintains its own installation instructions.  For the most up-to-date information on each software's installation procedure, its own documentation should be consulted.






================================================
FILE: examples/__init__.py
================================================


================================================
FILE: examples/adder/adder.pcf
================================================
{
  "a[0]": {
    "direction": "input",
    "pin": "pad_in_0_1[0]"
  },
  "a[1]": {
    "direction": "input",
    "pin": "pad_in_0_1[1]"
  },
  "a[2]": {
    "direction": "input",
    "pin": "pad_in_0_1[2]"
  },
  "a[3]": {
    "direction": "input",
    "pin": "pad_in_0_1[3]"
  },
  "a[4]": {
    "direction": "input",
    "pin": "pad_in_0_1[4]"
  },
  "a[5]": {
    "direction": "input",
    "pin": "pad_in_0_1[5]"
  },
  "a[6]": {
    "direction": "input",
    "pin": "pad_in_0_1[6]"
  },
  "a[7]": {
    "direction": "input",
    "pin": "pad_in_0_1[7]"
  },
  "b[0]": {
    "direction": "input",
    "pin": "pad_in_0_2[0]"
  },
  "b[1]": {
    "direction": "input",
    "pin": "pad_in_0_2[1]"
  },
  "b[2]": {
    "direction": "input",
    "pin": "pad_in_0_2[2]"
  },
  "b[3]": {
    "direction": "input",
    "pin": "pad_in_0_2[3]"
  },
  "b[4]": {
    "direction": "input",
    "pin": "pad_in_0_2[4]"
  },
  "b[5]": {
    "direction": "input",
    "pin": "pad_in_0_2[5]"
  },
  "b[6]": {
    "direction": "input",
    "pin": "pad_in_0_2[6]"
  },
  "b[7]": {
    "direction": "input",
    "pin": "pad_in_0_2[7]"
  },
  "y[0]": {
    "direction": "output",
    "pin": "pad_out_1_0[0]"
  },
  "y[1]": {
    "direction": "output",
    "pin": "pad_out_1_0[1]"
  },
  "y[2]": {
    "direction": "output",
    "pin": "pad_out_1_0[2]"
  },
  "y[3]": {
    "direction": "output",
    "pin": "pad_out_1_0[3]"
  },
  "y[4]": {
    "direction": "output",
    "pin": "pad_out_1_0[4]"
  },
  "y[5]": {
    "direction": "output",
    "pin": "pad_out_1_0[5]"
  },
  "y[6]": {
    "direction": "output",
    "pin": "pad_out_1_0[6]"
  },
  "y[7]": {
    "direction": "output",
    "pin": "pad_out_1_0[7]"
  },
  "y[8]": {
    "direction": "output",
    "pin": "pad_out_2_0[0]"
  }
}


================================================
FILE: examples/adder/adder.py
================================================
#!/usr/bin/env python3

# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import siliconcompiler
from logiklib.zeroasic.z1000 import z1000

from logik.flows.logik_flow import LogikFlow


def hello_adder():
    # Create a Design object to hold source files and constraints.
    design = siliconcompiler.Design("adder")

    design.set_dataroot("adder", __file__)
    with design.active_dataroot("adder"):
        design.add_file("adder.v", fileset="rtl")
        design.set_topmodule("adder", fileset="rtl")

    # Create an FPGA object with a -remote command line option
    project = siliconcompiler.FPGA.create_cmdline(switchlist=["-remote"])
    project.set_design(design)

    project.add_fileset("rtl")

    # Create an FPGA object and associate the design with it.
    fpga = z1000.z1000()

    # Load the specific FPGA part, which also sets the default flow and libraries.
    project.set_fpga(fpga)

    #  Use the specific flow for this build.
    project.set_flow(LogikFlow())

    # Customize steps for this design
    project.option.set_quiet(True)

    # Run the compilation.
    project.run()

    # Display the results summary.
    project.summary()


if __name__ == "__main__":
    hello_adder()


================================================
FILE: examples/adder/adder.v
================================================
/*******************************************************************************
 * Copyright 2024 Zero ASIC Corporation
 *
 * Licensed under the MIT License (see LICENSE for details)
 ******************************************************************************/

module adder
  # (
     parameter DATA_WIDTH = 8
     )
   (
    input [(DATA_WIDTH-1):0] a,
    input [(DATA_WIDTH-1):0] b,
    output [(DATA_WIDTH):0] y
    );

   assign y = a + b;

endmodule // adder


================================================
FILE: examples/adder/pin_constraints.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import argparse
import json
import os


def main():
    option_parser = argparse.ArgumentParser()
    # Command-line options
    option_parser.add_argument(
        "part_name",
        help="specify part number to prep, or specify all to build all parts in parts catalog",
    )

    options = option_parser.parse_args()
    part_name = options.part_name

    if part_name == "raw":
        pin_constraints = generate_raw_constraints()
    else:
        pin_constraints = generate_mapped_constraints(part_name)

    write_json_constraints(
        pin_constraints,
        os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            f"pin_constraints_{part_name}.pcf",
        ),
    )


def generate_mapped_constraints(part_name):

    pin_constraints = {}

    if part_name == "logik_demo":
        for i in range(8):
            pin_constraints[f"a[{i}]"] = {"direction": "input", "pin": f"gpio_in[{i}]"}

        for i in range(8):
            pin_constraints[f"b[{i}]"] = {
                "direction": "input",
                "pin": f"gpio_in[{i + 8}]",
            }

        for i in range(9):
            pin_constraints[f"y[{i}]"] = {
                "direction": "output",
                "pin": f"gpio_out[{i + 16}]",
            }

    else:
        print(f"ERROR: unsupported part name {part_name}")

    return pin_constraints


def generate_raw_constraints():

    pin_constraints = {}

    for i in range(8):
        pin_constraints[f"a[{i}]"] = {"direction": "input", "pin": f"pad_in_1_2[{i}]"}

    for i in range(8):
        pin_constraints[f"b[{i}]"] = {"direction": "input", "pin": f"pad_in_1_3[{i}]"}

    for i in range(9):
        if i < 8:
            pin_constraints[f"y[{i}]"] = {
                "direction": "output",
                "pin": f"pad_out_1_4[{i}]",
            }
        else:
            pin_constraints[f"y[{i}]"] = {
                "direction": "output",
                "pin": f"pad_out_1_5[{i - 8}]",
            }

    return pin_constraints


def write_json_constraints(constraints, filename):

    with open(filename, "w") as json_file:
        json_file.write(json.dumps(constraints, indent=2))
        json_file.write("\n")
        json_file.close()


if __name__ == "__main__":
    main()


================================================
FILE: examples/eth_mac_1g/constraints/z1000/pin_constraints.pcf
================================================
{
  "rx_clk": {
    "direction": "input",
    "pin": "gpio_in_clk[0]"
  },
  "rx_rst": {
    "direction": "input",
    "pin": "gpio_in_west[0]"
  },
  "tx_clk": {
    "direction": "input",
    "pin": "gpio_in_clk[1]"
  },
  "tx_rst": {
    "direction": "input",
    "pin": "gpio_in_west[1]"
  },
  "tx_axis_tdata[0]": {
    "direction": "input",
    "pin": "gpio_in_west[2]"
  },
  "tx_axis_tdata[1]": {
    "direction": "input",
    "pin": "gpio_in_west[3]"
  },
  "tx_axis_tdata[2]": {
    "direction": "input",
    "pin": "gpio_in_west[4]"
  },
  "tx_axis_tdata[3]": {
    "direction": "input",
    "pin": "gpio_in_west[5]"
  },
  "tx_axis_tdata[4]": {
    "direction": "input",
    "pin": "gpio_in_west[6]"
  },
  "tx_axis_tdata[5]": {
    "direction": "input",
    "pin": "gpio_in_west[7]"
  },
  "tx_axis_tdata[6]": {
    "direction": "input",
    "pin": "gpio_in_west[8]"
  },
  "tx_axis_tdata[7]": {
    "direction": "input",
    "pin": "gpio_in_west[9]"
  },
  "tx_axis_tvalid": {
    "direction": "input",
    "pin": "gpio_in_west[10]"
  },
  "tx_axis_tlast": {
    "direction": "input",
    "pin": "gpio_in_west[11]"
  },
  "tx_axis_tuser": {
    "direction": "input",
    "pin": "gpio_in_west[12]"
  },
  "gmii_rxd[0]": {
    "direction": "input",
    "pin": "gpio_in_west[13]"
  },
  "gmii_rxd[1]": {
    "direction": "input",
    "pin": "gpio_in_west[14]"
  },
  "gmii_rxd[2]": {
    "direction": "input",
    "pin": "gpio_in_west[15]"
  },
  "gmii_rxd[3]": {
    "direction": "input",
    "pin": "gpio_in_west[16]"
  },
  "gmii_rxd[4]": {
    "direction": "input",
    "pin": "gpio_in_west[17]"
  },
  "gmii_rxd[5]": {
    "direction": "input",
    "pin": "gpio_in_west[18]"
  },
  "gmii_rxd[6]": {
    "direction": "input",
    "pin": "gpio_in_west[19]"
  },
  "gmii_rxd[7]": {
    "direction": "input",
    "pin": "gpio_in_west[20]"
  },
  "gmii_rx_dv": {
    "direction": "input",
    "pin": "gpio_in_west[21]"
  },
  "gmii_rx_er": {
    "direction": "input",
    "pin": "gpio_in_west[22]"
  },
  "tx_ptp_ts[0]": {
    "direction": "input",
    "pin": "gpio_in_west[23]"
  },
  "tx_ptp_ts[1]": {
    "direction": "input",
    "pin": "gpio_in_west[24]"
  },
  "tx_ptp_ts[2]": {
    "direction": "input",
    "pin": "gpio_in_west[25]"
  },
  "tx_ptp_ts[3]": {
    "direction": "input",
    "pin": "gpio_in_west[26]"
  },
  "tx_ptp_ts[4]": {
    "direction": "input",
    "pin": "gpio_in_west[27]"
  },
  "tx_ptp_ts[5]": {
    "direction": "input",
    "pin": "gpio_in_west[28]"
  },
  "tx_ptp_ts[6]": {
    "direction": "input",
    "pin": "gpio_in_west[29]"
  },
  "tx_ptp_ts[7]": {
    "direction": "input",
    "pin": "gpio_in_west[30]"
  },
  "tx_ptp_ts[8]": {
    "direction": "input",
    "pin": "gpio_in_west[31]"
  },
  "tx_ptp_ts[9]": {
    "direction": "input",
    "pin": "gpio_in_west[32]"
  },
  "tx_ptp_ts[10]": {
    "direction": "input",
    "pin": "gpio_in_west[33]"
  },
  "tx_ptp_ts[11]": {
    "direction": "input",
    "pin": "gpio_in_west[34]"
  },
  "tx_ptp_ts[12]": {
    "direction": "input",
    "pin": "gpio_in_west[35]"
  },
  "tx_ptp_ts[13]": {
    "direction": "input",
    "pin": "gpio_in_west[36]"
  },
  "tx_ptp_ts[14]": {
    "direction": "input",
    "pin": "gpio_in_west[37]"
  },
  "tx_ptp_ts[15]": {
    "direction": "input",
    "pin": "gpio_in_west[38]"
  },
  "tx_ptp_ts[16]": {
    "direction": "input",
    "pin": "gpio_in_west[39]"
  },
  "tx_ptp_ts[17]": {
    "direction": "input",
    "pin": "gpio_in_west[40]"
  },
  "tx_ptp_ts[18]": {
    "direction": "input",
    "pin": "gpio_in_west[41]"
  },
  "tx_ptp_ts[19]": {
    "direction": "input",
    "pin": "gpio_in_west[42]"
  },
  "tx_ptp_ts[20]": {
    "direction": "input",
    "pin": "gpio_in_west[43]"
  },
  "tx_ptp_ts[21]": {
    "direction": "input",
    "pin": "gpio_in_west[44]"
  },
  "tx_ptp_ts[22]": {
    "direction": "input",
    "pin": "gpio_in_west[45]"
  },
  "tx_ptp_ts[23]": {
    "direction": "input",
    "pin": "gpio_in_west[46]"
  },
  "tx_ptp_ts[24]": {
    "direction": "input",
    "pin": "gpio_in_west[47]"
  },
  "tx_ptp_ts[25]": {
    "direction": "input",
    "pin": "gpio_in_west[48]"
  },
  "tx_ptp_ts[26]": {
    "direction": "input",
    "pin": "gpio_in_west[49]"
  },
  "tx_ptp_ts[27]": {
    "direction": "input",
    "pin": "gpio_in_west[50]"
  },
  "tx_ptp_ts[28]": {
    "direction": "input",
    "pin": "gpio_in_west[51]"
  },
  "tx_ptp_ts[29]": {
    "direction": "input",
    "pin": "gpio_in_west[52]"
  },
  "tx_ptp_ts[30]": {
    "direction": "input",
    "pin": "gpio_in_west[53]"
  },
  "tx_ptp_ts[31]": {
    "direction": "input",
    "pin": "gpio_in_west[54]"
  },
  "tx_ptp_ts[32]": {
    "direction": "input",
    "pin": "gpio_in_west[55]"
  },
  "tx_ptp_ts[33]": {
    "direction": "input",
    "pin": "gpio_in_west[56]"
  },
  "tx_ptp_ts[34]": {
    "direction": "input",
    "pin": "gpio_in_west[57]"
  },
  "tx_ptp_ts[35]": {
    "direction": "input",
    "pin": "gpio_in_west[58]"
  },
  "tx_ptp_ts[36]": {
    "direction": "input",
    "pin": "gpio_in_west[59]"
  },
  "tx_ptp_ts[37]": {
    "direction": "input",
    "pin": "gpio_in_west[60]"
  },
  "tx_ptp_ts[38]": {
    "direction": "input",
    "pin": "gpio_in_west[61]"
  },
  "tx_ptp_ts[39]": {
    "direction": "input",
    "pin": "gpio_in_west[62]"
  },
  "tx_ptp_ts[40]": {
    "direction": "input",
    "pin": "gpio_in_west[63]"
  },
  "tx_ptp_ts[41]": {
    "direction": "input",
    "pin": "gpio_in_west[64]"
  },
  "tx_ptp_ts[42]": {
    "direction": "input",
    "pin": "gpio_in_west[65]"
  },
  "tx_ptp_ts[43]": {
    "direction": "input",
    "pin": "gpio_in_west[66]"
  },
  "tx_ptp_ts[44]": {
    "direction": "input",
    "pin": "gpio_in_west[67]"
  },
  "tx_ptp_ts[45]": {
    "direction": "input",
    "pin": "gpio_in_west[68]"
  },
  "tx_ptp_ts[46]": {
    "direction": "input",
    "pin": "gpio_in_west[69]"
  },
  "tx_ptp_ts[47]": {
    "direction": "input",
    "pin": "gpio_in_west[70]"
  },
  "tx_ptp_ts[48]": {
    "direction": "input",
    "pin": "gpio_in_west[71]"
  },
  "tx_ptp_ts[49]": {
    "direction": "input",
    "pin": "gpio_in_west[72]"
  },
  "tx_ptp_ts[50]": {
    "direction": "input",
    "pin": "gpio_in_west[73]"
  },
  "tx_ptp_ts[51]": {
    "direction": "input",
    "pin": "gpio_in_west[74]"
  },
  "tx_ptp_ts[52]": {
    "direction": "input",
    "pin": "gpio_in_west[75]"
  },
  "tx_ptp_ts[53]": {
    "direction": "input",
    "pin": "gpio_in_west[76]"
  },
  "tx_ptp_ts[54]": {
    "direction": "input",
    "pin": "gpio_in_west[77]"
  },
  "tx_ptp_ts[55]": {
    "direction": "input",
    "pin": "gpio_in_west[78]"
  },
  "tx_ptp_ts[56]": {
    "direction": "input",
    "pin": "gpio_in_west[79]"
  },
  "tx_ptp_ts[57]": {
    "direction": "input",
    "pin": "gpio_in_west[80]"
  },
  "tx_ptp_ts[58]": {
    "direction": "input",
    "pin": "gpio_in_west[81]"
  },
  "tx_ptp_ts[59]": {
    "direction": "input",
    "pin": "gpio_in_west[82]"
  },
  "tx_ptp_ts[60]": {
    "direction": "input",
    "pin": "gpio_in_west[83]"
  },
  "tx_ptp_ts[61]": {
    "direction": "input",
    "pin": "gpio_in_west[84]"
  },
  "tx_ptp_ts[62]": {
    "direction": "input",
    "pin": "gpio_in_west[85]"
  },
  "tx_ptp_ts[63]": {
    "direction": "input",
    "pin": "gpio_in_west[86]"
  },
  "tx_ptp_ts[64]": {
    "direction": "input",
    "pin": "gpio_in_west[87]"
  },
  "tx_ptp_ts[65]": {
    "direction": "input",
    "pin": "gpio_in_west[88]"
  },
  "tx_ptp_ts[66]": {
    "direction": "input",
    "pin": "gpio_in_west[89]"
  },
  "tx_ptp_ts[67]": {
    "direction": "input",
    "pin": "gpio_in_west[90]"
  },
  "tx_ptp_ts[68]": {
    "direction": "input",
    "pin": "gpio_in_west[91]"
  },
  "tx_ptp_ts[69]": {
    "direction": "input",
    "pin": "gpio_in_west[92]"
  },
  "tx_ptp_ts[70]": {
    "direction": "input",
    "pin": "gpio_in_west[93]"
  },
  "tx_ptp_ts[71]": {
    "direction": "input",
    "pin": "gpio_in_west[94]"
  },
  "tx_ptp_ts[72]": {
    "direction": "input",
    "pin": "gpio_in_west[95]"
  },
  "tx_ptp_ts[73]": {
    "direction": "input",
    "pin": "gpio_in_west[96]"
  },
  "tx_ptp_ts[74]": {
    "direction": "input",
    "pin": "gpio_in_west[97]"
  },
  "tx_ptp_ts[75]": {
    "direction": "input",
    "pin": "gpio_in_west[98]"
  },
  "tx_ptp_ts[76]": {
    "direction": "input",
    "pin": "gpio_in_west[99]"
  },
  "tx_ptp_ts[77]": {
    "direction": "input",
    "pin": "gpio_in_west[100]"
  },
  "tx_ptp_ts[78]": {
    "direction": "input",
    "pin": "gpio_in_west[101]"
  },
  "tx_ptp_ts[79]": {
    "direction": "input",
    "pin": "gpio_in_west[102]"
  },
  "tx_ptp_ts[80]": {
    "direction": "input",
    "pin": "gpio_in_west[103]"
  },
  "tx_ptp_ts[81]": {
    "direction": "input",
    "pin": "gpio_in_west[104]"
  },
  "tx_ptp_ts[82]": {
    "direction": "input",
    "pin": "gpio_in_west[105]"
  },
  "tx_ptp_ts[83]": {
    "direction": "input",
    "pin": "gpio_in_west[106]"
  },
  "tx_ptp_ts[84]": {
    "direction": "input",
    "pin": "gpio_in_west[107]"
  },
  "tx_ptp_ts[85]": {
    "direction": "input",
    "pin": "gpio_in_west[108]"
  },
  "tx_ptp_ts[86]": {
    "direction": "input",
    "pin": "gpio_in_west[109]"
  },
  "tx_ptp_ts[87]": {
    "direction": "input",
    "pin": "gpio_in_west[110]"
  },
  "tx_ptp_ts[88]": {
    "direction": "input",
    "pin": "gpio_in_west[111]"
  },
  "tx_ptp_ts[89]": {
    "direction": "input",
    "pin": "gpio_in_west[112]"
  },
  "tx_ptp_ts[90]": {
    "direction": "input",
    "pin": "gpio_in_west[113]"
  },
  "tx_ptp_ts[91]": {
    "direction": "input",
    "pin": "gpio_in_west[114]"
  },
  "tx_ptp_ts[92]": {
    "direction": "input",
    "pin": "gpio_in_west[115]"
  },
  "tx_ptp_ts[93]": {
    "direction": "input",
    "pin": "gpio_in_west[116]"
  },
  "tx_ptp_ts[94]": {
    "direction": "input",
    "pin": "gpio_in_west[117]"
  },
  "tx_ptp_ts[95]": {
    "direction": "input",
    "pin": "gpio_in_west[118]"
  },
  "rx_ptp_ts[0]": {
    "direction": "input",
    "pin": "gpio_in_west[119]"
  },
  "rx_ptp_ts[1]": {
    "direction": "input",
    "pin": "gpio_in_west[120]"
  },
  "rx_ptp_ts[2]": {
    "direction": "input",
    "pin": "gpio_in_west[121]"
  },
  "rx_ptp_ts[3]": {
    "direction": "input",
    "pin": "gpio_in_west[122]"
  },
  "rx_ptp_ts[4]": {
    "direction": "input",
    "pin": "gpio_in_west[123]"
  },
  "rx_ptp_ts[5]": {
    "direction": "input",
    "pin": "gpio_in_west[124]"
  },
  "rx_ptp_ts[6]": {
    "direction": "input",
    "pin": "gpio_in_west[125]"
  },
  "rx_ptp_ts[7]": {
    "direction": "input",
    "pin": "gpio_in_west[126]"
  },
  "rx_ptp_ts[8]": {
    "direction": "input",
    "pin": "gpio_in_west[127]"
  },
  "rx_ptp_ts[9]": {
    "direction": "input",
    "pin": "gpio_in_west[128]"
  },
  "rx_ptp_ts[10]": {
    "direction": "input",
    "pin": "gpio_in_west[129]"
  },
  "rx_ptp_ts[11]": {
    "direction": "input",
    "pin": "gpio_in_west[130]"
  },
  "rx_ptp_ts[12]": {
    "direction": "input",
    "pin": "gpio_in_west[131]"
  },
  "rx_ptp_ts[13]": {
    "direction": "input",
    "pin": "gpio_in_west[132]"
  },
  "rx_ptp_ts[14]": {
    "direction": "input",
    "pin": "gpio_in_west[133]"
  },
  "rx_ptp_ts[15]": {
    "direction": "input",
    "pin": "gpio_in_west[134]"
  },
  "rx_ptp_ts[16]": {
    "direction": "input",
    "pin": "gpio_in_west[135]"
  },
  "rx_ptp_ts[17]": {
    "direction": "input",
    "pin": "gpio_in_west[136]"
  },
  "rx_ptp_ts[18]": {
    "direction": "input",
    "pin": "gpio_in_west[137]"
  },
  "rx_ptp_ts[19]": {
    "direction": "input",
    "pin": "gpio_in_west[138]"
  },
  "rx_ptp_ts[20]": {
    "direction": "input",
    "pin": "gpio_in_west[139]"
  },
  "rx_ptp_ts[21]": {
    "direction": "input",
    "pin": "gpio_in_west[140]"
  },
  "rx_ptp_ts[22]": {
    "direction": "input",
    "pin": "gpio_in_west[141]"
  },
  "rx_ptp_ts[23]": {
    "direction": "input",
    "pin": "gpio_in_west[142]"
  },
  "rx_ptp_ts[24]": {
    "direction": "input",
    "pin": "gpio_in_west[143]"
  },
  "rx_ptp_ts[25]": {
    "direction": "input",
    "pin": "gpio_in_west[144]"
  },
  "rx_ptp_ts[26]": {
    "direction": "input",
    "pin": "gpio_in_west[145]"
  },
  "rx_ptp_ts[27]": {
    "direction": "input",
    "pin": "gpio_in_west[146]"
  },
  "rx_ptp_ts[28]": {
    "direction": "input",
    "pin": "gpio_in_west[147]"
  },
  "rx_ptp_ts[29]": {
    "direction": "input",
    "pin": "gpio_in_west[148]"
  },
  "rx_ptp_ts[30]": {
    "direction": "input",
    "pin": "gpio_in_west[149]"
  },
  "rx_ptp_ts[31]": {
    "direction": "input",
    "pin": "gpio_in_west[150]"
  },
  "rx_ptp_ts[32]": {
    "direction": "input",
    "pin": "gpio_in_west[151]"
  },
  "rx_ptp_ts[33]": {
    "direction": "input",
    "pin": "gpio_in_west[152]"
  },
  "rx_ptp_ts[34]": {
    "direction": "input",
    "pin": "gpio_in_west[153]"
  },
  "rx_ptp_ts[35]": {
    "direction": "input",
    "pin": "gpio_in_west[154]"
  },
  "rx_ptp_ts[36]": {
    "direction": "input",
    "pin": "gpio_in_west[155]"
  },
  "rx_ptp_ts[37]": {
    "direction": "input",
    "pin": "gpio_in_west[156]"
  },
  "rx_ptp_ts[38]": {
    "direction": "input",
    "pin": "gpio_in_west[157]"
  },
  "rx_ptp_ts[39]": {
    "direction": "input",
    "pin": "gpio_in_west[158]"
  },
  "rx_ptp_ts[40]": {
    "direction": "input",
    "pin": "gpio_in_west[159]"
  },
  "rx_ptp_ts[41]": {
    "direction": "input",
    "pin": "gpio_in_west[160]"
  },
  "rx_ptp_ts[42]": {
    "direction": "input",
    "pin": "gpio_in_west[161]"
  },
  "rx_ptp_ts[43]": {
    "direction": "input",
    "pin": "gpio_in_west[162]"
  },
  "rx_ptp_ts[44]": {
    "direction": "input",
    "pin": "gpio_in_west[163]"
  },
  "rx_ptp_ts[45]": {
    "direction": "input",
    "pin": "gpio_in_west[164]"
  },
  "rx_ptp_ts[46]": {
    "direction": "input",
    "pin": "gpio_in_west[165]"
  },
  "rx_ptp_ts[47]": {
    "direction": "input",
    "pin": "gpio_in_west[166]"
  },
  "rx_ptp_ts[48]": {
    "direction": "input",
    "pin": "gpio_in_west[167]"
  },
  "rx_ptp_ts[49]": {
    "direction": "input",
    "pin": "gpio_in_west[168]"
  },
  "rx_ptp_ts[50]": {
    "direction": "input",
    "pin": "gpio_in_west[169]"
  },
  "rx_ptp_ts[51]": {
    "direction": "input",
    "pin": "gpio_in_west[170]"
  },
  "rx_ptp_ts[52]": {
    "direction": "input",
    "pin": "gpio_in_west[171]"
  },
  "rx_ptp_ts[53]": {
    "direction": "input",
    "pin": "gpio_in_west[172]"
  },
  "rx_ptp_ts[54]": {
    "direction": "input",
    "pin": "gpio_in_west[173]"
  },
  "rx_ptp_ts[55]": {
    "direction": "input",
    "pin": "gpio_in_west[174]"
  },
  "rx_ptp_ts[56]": {
    "direction": "input",
    "pin": "gpio_in_west[175]"
  },
  "rx_ptp_ts[57]": {
    "direction": "input",
    "pin": "gpio_in_west[176]"
  },
  "rx_ptp_ts[58]": {
    "direction": "input",
    "pin": "gpio_in_west[177]"
  },
  "rx_ptp_ts[59]": {
    "direction": "input",
    "pin": "gpio_in_west[178]"
  },
  "rx_ptp_ts[60]": {
    "direction": "input",
    "pin": "gpio_in_west[179]"
  },
  "rx_ptp_ts[61]": {
    "direction": "input",
    "pin": "gpio_in_west[180]"
  },
  "rx_ptp_ts[62]": {
    "direction": "input",
    "pin": "gpio_in_west[181]"
  },
  "rx_ptp_ts[63]": {
    "direction": "input",
    "pin": "gpio_in_west[182]"
  },
  "rx_ptp_ts[64]": {
    "direction": "input",
    "pin": "gpio_in_west[183]"
  },
  "rx_ptp_ts[65]": {
    "direction": "input",
    "pin": "gpio_in_west[184]"
  },
  "rx_ptp_ts[66]": {
    "direction": "input",
    "pin": "gpio_in_west[185]"
  },
  "rx_ptp_ts[67]": {
    "direction": "input",
    "pin": "gpio_in_west[186]"
  },
  "rx_ptp_ts[68]": {
    "direction": "input",
    "pin": "gpio_in_west[187]"
  },
  "rx_ptp_ts[69]": {
    "direction": "input",
    "pin": "gpio_in_west[188]"
  },
  "rx_ptp_ts[70]": {
    "direction": "input",
    "pin": "gpio_in_west[189]"
  },
  "rx_ptp_ts[71]": {
    "direction": "input",
    "pin": "gpio_in_west[190]"
  },
  "rx_ptp_ts[72]": {
    "direction": "input",
    "pin": "gpio_in_west[191]"
  },
  "rx_ptp_ts[73]": {
    "direction": "input",
    "pin": "gpio_in_west[192]"
  },
  "rx_ptp_ts[74]": {
    "direction": "input",
    "pin": "gpio_in_west[193]"
  },
  "rx_ptp_ts[75]": {
    "direction": "input",
    "pin": "gpio_in_west[194]"
  },
  "rx_ptp_ts[76]": {
    "direction": "input",
    "pin": "gpio_in_west[195]"
  },
  "rx_ptp_ts[77]": {
    "direction": "input",
    "pin": "gpio_in_west[196]"
  },
  "rx_ptp_ts[78]": {
    "direction": "input",
    "pin": "gpio_in_west[197]"
  },
  "rx_ptp_ts[79]": {
    "direction": "input",
    "pin": "gpio_in_west[198]"
  },
  "rx_ptp_ts[80]": {
    "direction": "input",
    "pin": "gpio_in_west[199]"
  },
  "rx_ptp_ts[81]": {
    "direction": "input",
    "pin": "gpio_in_west[200]"
  },
  "rx_ptp_ts[82]": {
    "direction": "input",
    "pin": "gpio_in_west[201]"
  },
  "rx_ptp_ts[83]": {
    "direction": "input",
    "pin": "gpio_in_west[202]"
  },
  "rx_ptp_ts[84]": {
    "direction": "input",
    "pin": "gpio_in_west[203]"
  },
  "rx_ptp_ts[85]": {
    "direction": "input",
    "pin": "gpio_in_west[204]"
  },
  "rx_ptp_ts[86]": {
    "direction": "input",
    "pin": "gpio_in_west[205]"
  },
  "rx_ptp_ts[87]": {
    "direction": "input",
    "pin": "gpio_in_west[206]"
  },
  "rx_ptp_ts[88]": {
    "direction": "input",
    "pin": "gpio_in_west[207]"
  },
  "rx_ptp_ts[89]": {
    "direction": "input",
    "pin": "gpio_in_west[208]"
  },
  "rx_ptp_ts[90]": {
    "direction": "input",
    "pin": "gpio_in_west[209]"
  },
  "rx_ptp_ts[91]": {
    "direction": "input",
    "pin": "gpio_in_west[210]"
  },
  "rx_ptp_ts[92]": {
    "direction": "input",
    "pin": "gpio_in_west[211]"
  },
  "rx_ptp_ts[93]": {
    "direction": "input",
    "pin": "gpio_in_west[212]"
  },
  "rx_ptp_ts[94]": {
    "direction": "input",
    "pin": "gpio_in_west[213]"
  },
  "rx_ptp_ts[95]": {
    "direction": "input",
    "pin": "gpio_in_west[214]"
  },
  "tx_lfc_req": {
    "direction": "input",
    "pin": "gpio_in_west[215]"
  },
  "tx_lfc_resend": {
    "direction": "input",
    "pin": "gpio_in_west[216]"
  },
  "rx_lfc_en": {
    "direction": "input",
    "pin": "gpio_in_west[217]"
  },
  "rx_lfc_ack": {
    "direction": "input",
    "pin": "gpio_in_west[218]"
  },
  "tx_pfc_req[0]": {
    "direction": "input",
    "pin": "gpio_in_west[219]"
  },
  "tx_pfc_req[1]": {
    "direction": "input",
    "pin": "gpio_in_west[220]"
  },
  "tx_pfc_req[2]": {
    "direction": "input",
    "pin": "gpio_in_west[221]"
  },
  "tx_pfc_req[3]": {
    "direction": "input",
    "pin": "gpio_in_west[222]"
  },
  "tx_pfc_req[4]": {
    "direction": "input",
    "pin": "gpio_in_west[223]"
  },
  "tx_pfc_req[5]": {
    "direction": "input",
    "pin": "gpio_in_west[224]"
  },
  "tx_pfc_req[6]": {
    "direction": "input",
    "pin": "gpio_in_west[225]"
  },
  "tx_pfc_req[7]": {
    "direction": "input",
    "pin": "gpio_in_west[226]"
  },
  "tx_pfc_resend": {
    "direction": "input",
    "pin": "gpio_in_west[227]"
  },
  "rx_pfc_en[0]": {
    "direction": "input",
    "pin": "gpio_in_west[228]"
  },
  "rx_pfc_en[1]": {
    "direction": "input",
    "pin": "gpio_in_west[229]"
  },
  "rx_pfc_en[2]": {
    "direction": "input",
    "pin": "gpio_in_west[230]"
  },
  "rx_pfc_en[3]": {
    "direction": "input",
    "pin": "gpio_in_west[231]"
  },
  "rx_pfc_en[4]": {
    "direction": "input",
    "pin": "gpio_in_west[232]"
  },
  "rx_pfc_en[5]": {
    "direction": "input",
    "pin": "gpio_in_west[233]"
  },
  "rx_pfc_en[6]": {
    "direction": "input",
    "pin": "gpio_in_west[234]"
  },
  "rx_pfc_en[7]": {
    "direction": "input",
    "pin": "gpio_in_west[235]"
  },
  "rx_pfc_ack[0]": {
    "direction": "input",
    "pin": "gpio_in_west[236]"
  },
  "rx_pfc_ack[1]": {
    "direction": "input",
    "pin": "gpio_in_west[237]"
  },
  "rx_pfc_ack[2]": {
    "direction": "input",
    "pin": "gpio_in_west[238]"
  },
  "rx_pfc_ack[3]": {
    "direction": "input",
    "pin": "gpio_in_west[239]"
  },
  "rx_pfc_ack[4]": {
    "direction": "input",
    "pin": "gpio_in_west[240]"
  },
  "rx_pfc_ack[5]": {
    "direction": "input",
    "pin": "gpio_in_west[241]"
  },
  "rx_pfc_ack[6]": {
    "direction": "input",
    "pin": "gpio_in_west[242]"
  },
  "rx_pfc_ack[7]": {
    "direction": "input",
    "pin": "gpio_in_west[243]"
  },
  "tx_lfc_pause_en": {
    "direction": "input",
    "pin": "gpio_in_west[244]"
  },
  "tx_pause_req": {
    "direction": "input",
    "pin": "gpio_in_west[245]"
  },
  "rx_clk_enable": {
    "direction": "input",
    "pin": "gpio_in_west[246]"
  },
  "tx_clk_enable": {
    "direction": "input",
    "pin": "gpio_in_west[247]"
  },
  "rx_mii_select": {
    "direction": "input",
    "pin": "gpio_in_west[248]"
  },
  "tx_mii_select": {
    "direction": "input",
    "pin": "gpio_in_west[249]"
  },
  "cfg_ifg[0]": {
    "direction": "input",
    "pin": "gpio_in_west[250]"
  },
  "cfg_ifg[1]": {
    "direction": "input",
    "pin": "gpio_in_west[251]"
  },
  "cfg_ifg[2]": {
    "direction": "input",
    "pin": "gpio_in_west[252]"
  },
  "cfg_ifg[3]": {
    "direction": "input",
    "pin": "gpio_in_west[253]"
  },
  "cfg_ifg[4]": {
    "direction": "input",
    "pin": "gpio_in_west[254]"
  },
  "cfg_ifg[5]": {
    "direction": "input",
    "pin": "gpio_in_west[255]"
  },
  "cfg_ifg[6]": {
    "direction": "input",
    "pin": "gpio_in_south[0]"
  },
  "cfg_ifg[7]": {
    "direction": "input",
    "pin": "gpio_in_south[1]"
  },
  "cfg_tx_enable": {
    "direction": "input",
    "pin": "gpio_in_south[2]"
  },
  "cfg_rx_enable": {
    "direction": "input",
    "pin": "gpio_in_south[3]"
  }
}

================================================
FILE: examples/eth_mac_1g/eth_mac_1g.py
================================================
#!/usr/bin/env python3

# This is the logik run script for demonstrating RTL-to-bitstream
# with Alex Forencich's 1G Ethernet MAC

import siliconcompiler
from logiklib.zeroasic.z1000 import z1000

from logik.flows.logik_flow import LogikFlow


def build():
    design = siliconcompiler.Design("eth_mac_1g_wrapper")

    # Define source files from verilog-ethernet repo

    # First we need to register the verilog-ethernet repo
    # as a package
    design.set_dataroot(
        "verilog-ethernet",
        "git+https://github.com/alexforencich/verilog-ethernet.git",
        "77320a9471d19c7dd383914bc049e02d9f4f1ffb",
    )

    # Then we can pull in the specific RTL we need from that
    # repository -- Silicon Compiler will download and cache the files
    # for us
    with design.active_dataroot("verilog-ethernet"):
        for source_file in (
            "eth_mac_1g.v",
            "axis_gmii_rx.v",
            "axis_gmii_tx.v",
            "lfsr.v",
        ):
            design.add_file(f"rtl/{source_file}", fileset="rtl")

    # Add in our top-level wrapper, stored locally
    design.set_dataroot("ethmac_example", __file__)
    with design.active_dataroot("ethmac_example"):
        design.add_file("eth_mac_1g_wrapper.v", fileset="rtl")
        design.set_topmodule("eth_mac_1g_wrapper", fileset="rtl")

        # Add timing constraints
        design.add_file("eth_mac_1g.sdc", fileset="sdc")

        # Define pin constraints
        design.add_file("constraints/z1000/pin_constraints.pcf", fileset="pcf")

    project = siliconcompiler.FPGA(design)

    project.add_fileset("rtl")
    project.add_fileset("sdc")
    project.add_fileset("pcf")

    fpga = z1000.z1000()

    project.set_fpga(fpga)

    project.set_flow(LogikFlow())

    project.option.set_quiet(True)

    project.run()
    project.summary()


if __name__ == "__main__":
    build()


================================================
FILE: examples/eth_mac_1g/eth_mac_1g.sdc
================================================
create_clock -period 16 rx_clk
create_clock -period 16 tx_clk


================================================
FILE: examples/eth_mac_1g/eth_mac_1g_wrapper.v
================================================
//eth_mac_1g_wrapper.v
//Peter Grossmann
//5 March 2025

//This wraps up the eth_mac_1g module to hide the unused cfg pin interface
//on the block, reducing the port count by about a factor of 5.

module eth_mac_1g_wrapper
  # (
     parameter DATA_WIDTH = 8,
     parameter ENABLE_PADDING = 1,
     parameter MIN_FRAME_LENGTH = 64,
     parameter PTP_TS_ENABLE = 0,
     parameter PTP_TS_FMT_TOD = 1,
     parameter PTP_TS_WIDTH = PTP_TS_FMT_TOD ? 96 : 64,
     parameter TX_PTP_TS_CTRL_IN_TUSER = 0,
     parameter TX_PTP_TAG_ENABLE = PTP_TS_ENABLE,
     parameter TX_PTP_TAG_WIDTH = 16,
     parameter TX_USER_WIDTH = (PTP_TS_ENABLE ? (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + (TX_PTP_TS_CTRL_IN_TUSER ? 1 : 0) : 0) + 1,
     parameter RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1,
     parameter PFC_ENABLE = 0,
     parameter PAUSE_ENABLE = PFC_ENABLE
     )   
   (
    input  wire                         rx_clk,
    input  wire                         rx_rst,
    input  wire                         tx_clk,
    input  wire                         tx_rst,

    /*
     * AXI input
     */
    input  wire [DATA_WIDTH-1:0]        tx_axis_tdata,
    input  wire                         tx_axis_tvalid,
    output wire                         tx_axis_tready,
    input  wire                         tx_axis_tlast,
    input  wire [TX_USER_WIDTH-1:0]     tx_axis_tuser,

    /*
     * AXI output
     */
    output wire [DATA_WIDTH-1:0]        rx_axis_tdata,
    output wire                         rx_axis_tvalid,
    output wire                         rx_axis_tlast,
    output wire [RX_USER_WIDTH-1:0]     rx_axis_tuser,

    /*
     * GMII interface
     */
    input  wire [DATA_WIDTH-1:0]        gmii_rxd,
    input  wire                         gmii_rx_dv,
    input  wire                         gmii_rx_er,
    output wire [DATA_WIDTH-1:0]        gmii_txd,
    output wire                         gmii_tx_en,
    output wire                         gmii_tx_er,

    /*
     * PTP
     */
    input  wire [PTP_TS_WIDTH-1:0]      tx_ptp_ts,
    input  wire [PTP_TS_WIDTH-1:0]      rx_ptp_ts,
    output wire [PTP_TS_WIDTH-1:0]      tx_axis_ptp_ts,
    output wire [TX_PTP_TAG_WIDTH-1:0]  tx_axis_ptp_ts_tag,
    output wire                         tx_axis_ptp_ts_valid,

    /*
     * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
     */
    input  wire                         tx_lfc_req,
    input  wire                         tx_lfc_resend,
    input  wire                         rx_lfc_en,
    output wire                         rx_lfc_req,
    input  wire                         rx_lfc_ack,

    /*
     * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
     */
    input  wire [7:0]                   tx_pfc_req,
    input  wire                         tx_pfc_resend,
    input  wire [7:0]                   rx_pfc_en,
    output wire [7:0]                   rx_pfc_req,
    input  wire [7:0]                   rx_pfc_ack,

    /*
     * Pause interface
     */
    input  wire                         tx_lfc_pause_en,
    input  wire                         tx_pause_req,
    output wire                         tx_pause_ack,

    /*
     * Control
     */
    input  wire                         rx_clk_enable,
    input  wire                         tx_clk_enable,
    input  wire                         rx_mii_select,
    input  wire                         tx_mii_select,

    /*
     * Status
     */
    output wire                         tx_start_packet,
    output wire                         tx_error_underflow,
    output wire                         rx_start_packet,
    output wire                         rx_error_bad_frame,
    output wire                         rx_error_bad_fcs,
    output wire                         stat_tx_mcf,
    output wire                         stat_rx_mcf,
    output wire                         stat_tx_lfc_pkt,
    output wire                         stat_tx_lfc_xon,
    output wire                         stat_tx_lfc_xoff,
    output wire                         stat_tx_lfc_paused,
    output wire                         stat_tx_pfc_pkt,
    output wire [7:0]                   stat_tx_pfc_xon,
    output wire [7:0]                   stat_tx_pfc_xoff,
    output wire [7:0]                   stat_tx_pfc_paused,
    output wire                         stat_rx_lfc_pkt,
    output wire                         stat_rx_lfc_xon,
    output wire                         stat_rx_lfc_xoff,
    output wire                         stat_rx_lfc_paused,
    output wire                         stat_rx_pfc_pkt,
    output wire [7:0]                   stat_rx_pfc_xon,
    output wire [7:0]                   stat_rx_pfc_xoff,
    output wire [7:0]                   stat_rx_pfc_paused,

    /*
     * Configuration
     */
    input  wire [7:0]                   cfg_ifg,
    input  wire                         cfg_tx_enable,
    input  wire                         cfg_rx_enable
    );

   eth_mac_1g
     # (
        .DATA_WIDTH(DATA_WIDTH),
        .ENABLE_PADDING(ENABLE_PADDING),
        .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
        .PTP_TS_ENABLE(PTP_TS_ENABLE),
        .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
        .PTP_TS_WIDTH(PTP_TS_WIDTH),
        .TX_PTP_TS_CTRL_IN_TUSER(TX_PTP_TS_CTRL_IN_TUSER),
        .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
        .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
        .TX_USER_WIDTH(TX_USER_WIDTH),
        .RX_USER_WIDTH(RX_USER_WIDTH),
        .PFC_ENABLE(PFC_ENABLE),
        .PAUSE_ENABLE(PAUSE_ENABLE)
        )
   eth_mac_1g
     (
      .rx_clk(rx_clk),
      .rx_rst(rx_rst),
      .tx_clk(tx_clk),
      .tx_rst(tx_rst),
      .tx_axis_tdata(tx_axis_tdata),
      .tx_axis_tvalid(tx_axis_tvalid),
      .tx_axis_tready(tx_axis_tready),
      .tx_axis_tlast(tx_axis_tlast),
      .tx_axis_tuser(tx_axis_tuser),
      .rx_axis_tdata(rx_axis_tdata),
      .rx_axis_tvalid(rx_axis_tvalid),
      .rx_axis_tlast(rx_axis_tlast),
      .rx_axis_tuser(rx_axis_tuser),
      .gmii_rxd(gmii_rxd),
      .gmii_rx_dv(gmii_rx_dv),
      .gmii_rx_er(gmii_rx_er),
      .gmii_txd(gmii_txd),
      .gmii_tx_en(gmii_tx_en),
      .gmii_tx_er(gmii_tx_er),
      .tx_ptp_ts(tx_ptp_ts),
      .rx_ptp_ts(rx_ptp_ts),
      .tx_axis_ptp_ts(tx_axis_ptp_ts),
      .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
      .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
      .tx_lfc_req(tx_lfc_req),
      .tx_lfc_resend(tx_lfc_resend),
      .rx_lfc_en(rx_lfc_en),
      .rx_lfc_req(rx_lfc_req),
      .rx_lfc_ack(rx_lfc_ack),
      .tx_pfc_req(tx_pfc_req),
      .tx_pfc_resend(tx_pfc_resend),
      .rx_pfc_en(rx_pfc_en),
      .rx_pfc_req(rx_pfc_req),
      .rx_pfc_ack(rx_pfc_ack),
      .tx_lfc_pause_en(tx_lfc_pause_en),
      .tx_pause_req(tx_pause_req),
      .tx_pause_ack(tx_pause_ack),
      .rx_clk_enable(rx_clk_enable),
      .tx_clk_enable(tx_clk_enable),
      .rx_mii_select(rx_mii_select),
      .tx_mii_select(tx_mii_select),
      .tx_start_packet(tx_start_packet),
      .tx_error_underflow(tx_error_underflow),
      .rx_start_packet(rx_start_packet),
      .rx_error_bad_frame(rx_error_bad_frame),
      .rx_error_bad_fcs(rx_error_bad_fcs),
      .stat_tx_mcf(stat_tx_mcf),
      .stat_rx_mcf(stat_rx_mcf),
      .stat_tx_lfc_pkt(stat_tx_lfc_pkt),
      .stat_tx_lfc_xon(stat_tx_lfc_xon),
      .stat_tx_lfc_xoff(stat_tx_lfc_xoff),
      .stat_tx_lfc_paused(stat_tx_lfc_paused),
      .stat_tx_pfc_pkt(stat_tx_pfc_pkt),
      .stat_tx_pfc_xon(stat_tx_pfc_xon),
      .stat_tx_pfc_xoff(stat_tx_pfc_xoff),
      .stat_tx_pfc_paused(stat_tx_pfc_paused),
      .stat_rx_lfc_pkt(stat_rx_lfc_pkt),
      .stat_rx_lfc_xon(stat_rx_lfc_xon),
      .stat_rx_lfc_xoff(stat_rx_lfc_xoff),
      .stat_rx_lfc_paused(stat_rx_lfc_paused),
      .stat_rx_pfc_pkt(stat_rx_pfc_pkt),
      .stat_rx_pfc_xon(stat_rx_pfc_xon),
      .stat_rx_pfc_xoff(stat_rx_pfc_xoff),
      .stat_rx_pfc_paused(stat_rx_pfc_paused),
      .cfg_ifg(cfg_ifg),
      .cfg_tx_enable(cfg_tx_enable),
      .cfg_rx_enable(cfg_rx_enable),
      .cfg_mcf_rx_eth_dst_mcast('h0),
      .cfg_mcf_rx_check_eth_dst_mcast('h0),
      .cfg_mcf_rx_eth_dst_ucast('h0),
      .cfg_mcf_rx_check_eth_dst_ucast('h0),
      .cfg_mcf_rx_eth_src('h0),
      .cfg_mcf_rx_check_eth_src('h0),
      .cfg_mcf_rx_eth_type('h0),
      .cfg_mcf_rx_opcode_lfc('h0),
      .cfg_mcf_rx_check_opcode_lfc('h0),
      .cfg_mcf_rx_opcode_pfc('h0),
      .cfg_mcf_rx_check_opcode_pfc('h0),
      .cfg_mcf_rx_forward('h0),
      .cfg_mcf_rx_enable('h0),
      .cfg_tx_lfc_eth_dst('h0),
      .cfg_tx_lfc_eth_src('h0),
      .cfg_tx_lfc_eth_type('h0),
      .cfg_tx_lfc_opcode('h0),
      .cfg_tx_lfc_en('h0),
      .cfg_tx_lfc_quanta('h0),
      .cfg_tx_lfc_refresh('h0),
      .cfg_tx_pfc_eth_dst('h0),
      .cfg_tx_pfc_eth_src('h0),
      .cfg_tx_pfc_eth_type('h0),
      .cfg_tx_pfc_opcode('h0),
      .cfg_tx_pfc_en('h0),
      .cfg_tx_pfc_quanta('h0),
      .cfg_tx_pfc_refresh('h0),
      .cfg_rx_lfc_opcode('h0),
      .cfg_rx_lfc_en('h0),
      .cfg_rx_pfc_opcode('h0),
      .cfg_rx_pfc_en('h0)
      );
   

endmodule


================================================
FILE: examples/picorv32/constraints/z1062/picorv32.pcf
================================================
{
  "clk": {
    "pin": "gpio_in_clk[0]",
    "direction": "input"
  },
  "resetn": {
    "pin": "gpio_in_west[10]",
    "direction": "input"
  },
  "trap": {
    "pin": "gpio_out_north[10]",
    "direction": "output"
  },
  "mem_valid": {
    "pin": "gpio_out_north[11]",
    "direction": "output"
  },
  "mem_instr": {
    "pin": "gpio_out_north[12]",
    "direction": "output"
  },
  "mem_ready": {
    "pin": "gpio_in_west[11]",
    "direction": "input"
  },
  "mem_la_read": {
    "pin": "gpio_out_west[12]",
    "direction": "output"
  },
  "mem_la_write": {
    "pin": "gpio_out_west[13]",
    "direction": "output"
  },
  "pcpi_valid": {
    "pin": "gpio_out_south[10]",
    "direction": "output"
  },
  "pcpi_wr": {
    "pin": "gpio_in_east[10]",
    "direction": "input"
  },
  "pcpi_wait": {
    "pin": "gpio_in_east[11]",
    "direction": "input"
  },
  "pcpi_ready": {
    "pin": "gpio_in_east[12]",
    "direction": "input"
  },
  "trace_valid": {
    "pin": "gpio_out_west[14]",
    "direction": "output"
  },
  "mem_addr[0]": {
    "pin": "gpio_out_north[320]",
    "direction": "output"
  },
  "mem_addr[1]": {
    "pin": "gpio_out_north[321]",
    "direction": "output"
  },
  "mem_addr[2]": {
    "pin": "gpio_out_north[322]",
    "direction": "output"
  },
  "mem_addr[3]": {
    "pin": "gpio_out_north[323]",
    "direction": "output"
  },
  "mem_addr[4]": {
    "pin": "gpio_out_north[324]",
    "direction": "output"
  },
  "mem_addr[5]": {
    "pin": "gpio_out_north[325]",
    "direction": "output"
  },
  "mem_addr[6]": {
    "pin": "gpio_out_north[326]",
    "direction": "output"
  },
  "mem_addr[7]": {
    "pin": "gpio_out_north[327]",
    "direction": "output"
  },
  "mem_addr[8]": {
    "pin": "gpio_out_north[328]",
    "direction": "output"
  },
  "mem_addr[9]": {
    "pin": "gpio_out_north[329]",
    "direction": "output"
  },
  "mem_addr[10]": {
    "pin": "gpio_out_north[330]",
    "direction": "output"
  },
  "mem_addr[11]": {
    "pin": "gpio_out_north[331]",
    "direction": "output"
  },
  "mem_addr[12]": {
    "pin": "gpio_out_north[332]",
    "direction": "output"
  },
  "mem_addr[13]": {
    "pin": "gpio_out_north[333]",
    "direction": "output"
  },
  "mem_addr[14]": {
    "pin": "gpio_out_north[334]",
    "direction": "output"
  },
  "mem_addr[15]": {
    "pin": "gpio_out_north[335]",
    "direction": "output"
  },
  "mem_addr[16]": {
    "pin": "gpio_out_north[336]",
    "direction": "output"
  },
  "mem_addr[17]": {
    "pin": "gpio_out_north[337]",
    "direction": "output"
  },
  "mem_addr[18]": {
    "pin": "gpio_out_north[338]",
    "direction": "output"
  },
  "mem_addr[19]": {
    "pin": "gpio_out_north[339]",
    "direction": "output"
  },
  "mem_addr[20]": {
    "pin": "gpio_out_north[340]",
    "direction": "output"
  },
  "mem_addr[21]": {
    "pin": "gpio_out_north[341]",
    "direction": "output"
  },
  "mem_addr[22]": {
    "pin": "gpio_out_north[342]",
    "direction": "output"
  },
  "mem_addr[23]": {
    "pin": "gpio_out_north[343]",
    "direction": "output"
  },
  "mem_addr[24]": {
    "pin": "gpio_out_north[344]",
    "direction": "output"
  },
  "mem_addr[25]": {
    "pin": "gpio_out_north[345]",
    "direction": "output"
  },
  "mem_addr[26]": {
    "pin": "gpio_out_north[346]",
    "direction": "output"
  },
  "mem_addr[27]": {
    "pin": "gpio_out_north[347]",
    "direction": "output"
  },
  "mem_addr[28]": {
    "pin": "gpio_out_north[348]",
    "direction": "output"
  },
  "mem_addr[29]": {
    "pin": "gpio_out_north[349]",
    "direction": "output"
  },
  "mem_addr[30]": {
    "pin": "gpio_out_north[350]",
    "direction": "output"
  },
  "mem_addr[31]": {
    "pin": "gpio_out_north[351]",
    "direction": "output"
  },
  "mem_wdata[0]": {
    "pin": "gpio_out_east[400]",
    "direction": "output"
  },
  "mem_wdata[1]": {
    "pin": "gpio_out_east[401]",
    "direction": "output"
  },
  "mem_wdata[2]": {
    "pin": "gpio_out_east[402]",
    "direction": "output"
  },
  "mem_wdata[3]": {
    "pin": "gpio_out_east[403]",
    "direction": "output"
  },
  "mem_wdata[4]": {
    "pin": "gpio_out_east[404]",
    "direction": "output"
  },
  "mem_wdata[5]": {
    "pin": "gpio_out_east[405]",
    "direction": "output"
  },
  "mem_wdata[6]": {
    "pin": "gpio_out_east[406]",
    "direction": "output"
  },
  "mem_wdata[7]": {
    "pin": "gpio_out_east[407]",
    "direction": "output"
  },
  "mem_wdata[8]": {
    "pin": "gpio_out_east[408]",
    "direction": "output"
  },
  "mem_wdata[9]": {
    "pin": "gpio_out_east[409]",
    "direction": "output"
  },
  "mem_wdata[10]": {
    "pin": "gpio_out_east[410]",
    "direction": "output"
  },
  "mem_wdata[11]": {
    "pin": "gpio_out_east[411]",
    "direction": "output"
  },
  "mem_wdata[12]": {
    "pin": "gpio_out_east[412]",
    "direction": "output"
  },
  "mem_wdata[13]": {
    "pin": "gpio_out_east[413]",
    "direction": "output"
  },
  "mem_wdata[14]": {
    "pin": "gpio_out_east[414]",
    "direction": "output"
  },
  "mem_wdata[15]": {
    "pin": "gpio_out_east[415]",
    "direction": "output"
  },
  "mem_wdata[16]": {
    "pin": "gpio_out_east[416]",
    "direction": "output"
  },
  "mem_wdata[17]": {
    "pin": "gpio_out_east[417]",
    "direction": "output"
  },
  "mem_wdata[18]": {
    "pin": "gpio_out_east[418]",
    "direction": "output"
  },
  "mem_wdata[19]": {
    "pin": "gpio_out_east[419]",
    "direction": "output"
  },
  "mem_wdata[20]": {
    "pin": "gpio_out_east[420]",
    "direction": "output"
  },
  "mem_wdata[21]": {
    "pin": "gpio_out_east[421]",
    "direction": "output"
  },
  "mem_wdata[22]": {
    "pin": "gpio_out_east[422]",
    "direction": "output"
  },
  "mem_wdata[23]": {
    "pin": "gpio_out_east[423]",
    "direction": "output"
  },
  "mem_wdata[24]": {
    "pin": "gpio_out_east[424]",
    "direction": "output"
  },
  "mem_wdata[25]": {
    "pin": "gpio_out_east[425]",
    "direction": "output"
  },
  "mem_wdata[26]": {
    "pin": "gpio_out_east[426]",
    "direction": "output"
  },
  "mem_wdata[27]": {
    "pin": "gpio_out_east[427]",
    "direction": "output"
  },
  "mem_wdata[28]": {
    "pin": "gpio_out_east[428]",
    "direction": "output"
  },
  "mem_wdata[29]": {
    "pin": "gpio_out_east[429]",
    "direction": "output"
  },
  "mem_wdata[30]": {
    "pin": "gpio_out_east[430]",
    "direction": "output"
  },
  "mem_wdata[31]": {
    "pin": "gpio_out_east[431]",
    "direction": "output"
  },
  "mem_wstrb[0]": {
    "pin": "gpio_out_north[460]",
    "direction": "output"
  },
  "mem_wstrb[1]": {
    "pin": "gpio_out_north[461]",
    "direction": "output"
  },
  "mem_wstrb[2]": {
    "pin": "gpio_out_north[462]",
    "direction": "output"
  },
  "mem_wstrb[3]": {
    "pin": "gpio_out_north[463]",
    "direction": "output"
  },
  "mem_rdata[0]": {
    "pin": "gpio_in_west[320]",
    "direction": "input"
  },
  "mem_rdata[1]": {
    "pin": "gpio_in_west[321]",
    "direction": "input"
  },
  "mem_rdata[2]": {
    "pin": "gpio_in_west[322]",
    "direction": "input"
  },
  "mem_rdata[3]": {
    "pin": "gpio_in_west[323]",
    "direction": "input"
  },
  "mem_rdata[4]": {
    "pin": "gpio_in_west[324]",
    "direction": "input"
  },
  "mem_rdata[5]": {
    "pin": "gpio_in_west[325]",
    "direction": "input"
  },
  "mem_rdata[6]": {
    "pin": "gpio_in_west[326]",
    "direction": "input"
  },
  "mem_rdata[7]": {
    "pin": "gpio_in_west[327]",
    "direction": "input"
  },
  "mem_rdata[8]": {
    "pin": "gpio_in_west[328]",
    "direction": "input"
  },
  "mem_rdata[9]": {
    "pin": "gpio_in_west[329]",
    "direction": "input"
  },
  "mem_rdata[10]": {
    "pin": "gpio_in_west[330]",
    "direction": "input"
  },
  "mem_rdata[11]": {
    "pin": "gpio_in_west[331]",
    "direction": "input"
  },
  "mem_rdata[12]": {
    "pin": "gpio_in_west[332]",
    "direction": "input"
  },
  "mem_rdata[13]": {
    "pin": "gpio_in_west[333]",
    "direction": "input"
  },
  "mem_rdata[14]": {
    "pin": "gpio_in_west[334]",
    "direction": "input"
  },
  "mem_rdata[15]": {
    "pin": "gpio_in_west[335]",
    "direction": "input"
  },
  "mem_rdata[16]": {
    "pin": "gpio_in_west[336]",
    "direction": "input"
  },
  "mem_rdata[17]": {
    "pin": "gpio_in_west[337]",
    "direction": "input"
  },
  "mem_rdata[18]": {
    "pin": "gpio_in_west[338]",
    "direction": "input"
  },
  "mem_rdata[19]": {
    "pin": "gpio_in_west[339]",
    "direction": "input"
  },
  "mem_rdata[20]": {
    "pin": "gpio_in_west[340]",
    "direction": "input"
  },
  "mem_rdata[21]": {
    "pin": "gpio_in_west[341]",
    "direction": "input"
  },
  "mem_rdata[22]": {
    "pin": "gpio_in_west[342]",
    "direction": "input"
  },
  "mem_rdata[23]": {
    "pin": "gpio_in_west[343]",
    "direction": "input"
  },
  "mem_rdata[24]": {
    "pin": "gpio_in_west[344]",
    "direction": "input"
  },
  "mem_rdata[25]": {
    "pin": "gpio_in_west[345]",
    "direction": "input"
  },
  "mem_rdata[26]": {
    "pin": "gpio_in_west[346]",
    "direction": "input"
  },
  "mem_rdata[27]": {
    "pin": "gpio_in_west[347]",
    "direction": "input"
  },
  "mem_rdata[28]": {
    "pin": "gpio_in_west[348]",
    "direction": "input"
  },
  "mem_rdata[29]": {
    "pin": "gpio_in_west[349]",
    "direction": "input"
  },
  "mem_rdata[30]": {
    "pin": "gpio_in_west[350]",
    "direction": "input"
  },
  "mem_rdata[31]": {
    "pin": "gpio_in_west[351]",
    "direction": "input"
  },
  "mem_la_addr[0]": {
    "pin": "gpio_out_east[260]",
    "direction": "output"
  },
  "mem_la_addr[1]": {
    "pin": "gpio_out_east[261]",
    "direction": "output"
  },
  "mem_la_addr[2]": {
    "pin": "gpio_out_east[262]",
    "direction": "output"
  },
  "mem_la_addr[3]": {
    "pin": "gpio_out_east[263]",
    "direction": "output"
  },
  "mem_la_addr[4]": {
    "pin": "gpio_out_east[264]",
    "direction": "output"
  },
  "mem_la_addr[5]": {
    "pin": "gpio_out_east[265]",
    "direction": "output"
  },
  "mem_la_addr[6]": {
    "pin": "gpio_out_east[266]",
    "direction": "output"
  },
  "mem_la_addr[7]": {
    "pin": "gpio_out_east[267]",
    "direction": "output"
  },
  "mem_la_addr[8]": {
    "pin": "gpio_out_east[268]",
    "direction": "output"
  },
  "mem_la_addr[9]": {
    "pin": "gpio_out_east[269]",
    "direction": "output"
  },
  "mem_la_addr[10]": {
    "pin": "gpio_out_east[270]",
    "direction": "output"
  },
  "mem_la_addr[11]": {
    "pin": "gpio_out_east[271]",
    "direction": "output"
  },
  "mem_la_addr[12]": {
    "pin": "gpio_out_east[272]",
    "direction": "output"
  },
  "mem_la_addr[13]": {
    "pin": "gpio_out_east[273]",
    "direction": "output"
  },
  "mem_la_addr[14]": {
    "pin": "gpio_out_east[274]",
    "direction": "output"
  },
  "mem_la_addr[15]": {
    "pin": "gpio_out_east[275]",
    "direction": "output"
  },
  "mem_la_addr[16]": {
    "pin": "gpio_out_east[276]",
    "direction": "output"
  },
  "mem_la_addr[17]": {
    "pin": "gpio_out_east[277]",
    "direction": "output"
  },
  "mem_la_addr[18]": {
    "pin": "gpio_out_east[278]",
    "direction": "output"
  },
  "mem_la_addr[19]": {
    "pin": "gpio_out_east[279]",
    "direction": "output"
  },
  "mem_la_addr[20]": {
    "pin": "gpio_out_east[280]",
    "direction": "output"
  },
  "mem_la_addr[21]": {
    "pin": "gpio_out_east[281]",
    "direction": "output"
  },
  "mem_la_addr[22]": {
    "pin": "gpio_out_east[282]",
    "direction": "output"
  },
  "mem_la_addr[23]": {
    "pin": "gpio_out_east[283]",
    "direction": "output"
  },
  "mem_la_addr[24]": {
    "pin": "gpio_out_east[284]",
    "direction": "output"
  },
  "mem_la_addr[25]": {
    "pin": "gpio_out_east[285]",
    "direction": "output"
  },
  "mem_la_addr[26]": {
    "pin": "gpio_out_east[286]",
    "direction": "output"
  },
  "mem_la_addr[27]": {
    "pin": "gpio_out_east[287]",
    "direction": "output"
  },
  "mem_la_addr[28]": {
    "pin": "gpio_out_east[288]",
    "direction": "output"
  },
  "mem_la_addr[29]": {
    "pin": "gpio_out_east[289]",
    "direction": "output"
  },
  "mem_la_addr[30]": {
    "pin": "gpio_out_east[290]",
    "direction": "output"
  },
  "mem_la_addr[31]": {
    "pin": "gpio_out_east[291]",
    "direction": "output"
  },
  "mem_la_wdata[0]": {
    "pin": "gpio_out_south[20]",
    "direction": "output"
  },
  "mem_la_wdata[1]": {
    "pin": "gpio_out_south[21]",
    "direction": "output"
  },
  "mem_la_wdata[2]": {
    "pin": "gpio_out_south[22]",
    "direction": "output"
  },
  "mem_la_wdata[3]": {
    "pin": "gpio_out_south[23]",
    "direction": "output"
  },
  "mem_la_wdata[4]": {
    "pin": "gpio_out_south[24]",
    "direction": "output"
  },
  "mem_la_wdata[5]": {
    "pin": "gpio_out_south[25]",
    "direction": "output"
  },
  "mem_la_wdata[6]": {
    "pin": "gpio_out_south[26]",
    "direction": "output"
  },
  "mem_la_wdata[7]": {
    "pin": "gpio_out_south[27]",
    "direction": "output"
  },
  "mem_la_wdata[8]": {
    "pin": "gpio_out_south[28]",
    "direction": "output"
  },
  "mem_la_wdata[9]": {
    "pin": "gpio_out_south[29]",
    "direction": "output"
  },
  "mem_la_wdata[10]": {
    "pin": "gpio_out_south[30]",
    "direction": "output"
  },
  "mem_la_wdata[11]": {
    "pin": "gpio_out_south[31]",
    "direction": "output"
  },
  "mem_la_wdata[12]": {
    "pin": "gpio_out_south[32]",
    "direction": "output"
  },
  "mem_la_wdata[13]": {
    "pin": "gpio_out_south[33]",
    "direction": "output"
  },
  "mem_la_wdata[14]": {
    "pin": "gpio_out_south[34]",
    "direction": "output"
  },
  "mem_la_wdata[15]": {
    "pin": "gpio_out_south[35]",
    "direction": "output"
  },
  "mem_la_wdata[16]": {
    "pin": "gpio_out_south[36]",
    "direction": "output"
  },
  "mem_la_wdata[17]": {
    "pin": "gpio_out_south[37]",
    "direction": "output"
  },
  "mem_la_wdata[18]": {
    "pin": "gpio_out_south[38]",
    "direction": "output"
  },
  "mem_la_wdata[19]": {
    "pin": "gpio_out_south[39]",
    "direction": "output"
  },
  "mem_la_wdata[20]": {
    "pin": "gpio_out_south[40]",
    "direction": "output"
  },
  "mem_la_wdata[21]": {
    "pin": "gpio_out_south[41]",
    "direction": "output"
  },
  "mem_la_wdata[22]": {
    "pin": "gpio_out_south[42]",
    "direction": "output"
  },
  "mem_la_wdata[23]": {
    "pin": "gpio_out_south[43]",
    "direction": "output"
  },
  "mem_la_wdata[24]": {
    "pin": "gpio_out_south[44]",
    "direction": "output"
  },
  "mem_la_wdata[25]": {
    "pin": "gpio_out_south[45]",
    "direction": "output"
  },
  "mem_la_wdata[26]": {
    "pin": "gpio_out_south[46]",
    "direction": "output"
  },
  "mem_la_wdata[27]": {
    "pin": "gpio_out_south[47]",
    "direction": "output"
  },
  "mem_la_wdata[28]": {
    "pin": "gpio_out_south[48]",
    "direction": "output"
  },
  "mem_la_wdata[29]": {
    "pin": "gpio_out_south[49]",
    "direction": "output"
  },
  "mem_la_wdata[30]": {
    "pin": "gpio_out_south[50]",
    "direction": "output"
  },
  "mem_la_wdata[31]": {
    "pin": "gpio_out_south[51]",
    "direction": "output"
  },
  "mem_la_wstrb[0]": {
    "pin": "gpio_out_south[60]",
    "direction": "output"
  },
  "mem_la_wstrb[1]": {
    "pin": "gpio_out_south[61]",
    "direction": "output"
  },
  "mem_la_wstrb[2]": {
    "pin": "gpio_out_south[62]",
    "direction": "output"
  },
  "mem_la_wstrb[3]": {
    "pin": "gpio_out_south[63]",
    "direction": "output"
  },
  "pcpi_insn[0]": {
    "pin": "gpio_out_south[100]",
    "direction": "output"
  },
  "pcpi_insn[1]": {
    "pin": "gpio_out_south[101]",
    "direction": "output"
  },
  "pcpi_insn[2]": {
    "pin": "gpio_out_south[102]",
    "direction": "output"
  },
  "pcpi_insn[3]": {
    "pin": "gpio_out_south[103]",
    "direction": "output"
  },
  "pcpi_insn[4]": {
    "pin": "gpio_out_south[104]",
    "direction": "output"
  },
  "pcpi_insn[5]": {
    "pin": "gpio_out_south[105]",
    "direction": "output"
  },
  "pcpi_insn[6]": {
    "pin": "gpio_out_south[106]",
    "direction": "output"
  },
  "pcpi_insn[7]": {
    "pin": "gpio_out_south[107]",
    "direction": "output"
  },
  "pcpi_insn[8]": {
    "pin": "gpio_out_south[108]",
    "direction": "output"
  },
  "pcpi_insn[9]": {
    "pin": "gpio_out_south[109]",
    "direction": "output"
  },
  "pcpi_insn[10]": {
    "pin": "gpio_out_south[110]",
    "direction": "output"
  },
  "pcpi_insn[11]": {
    "pin": "gpio_out_south[111]",
    "direction": "output"
  },
  "pcpi_insn[12]": {
    "pin": "gpio_out_south[112]",
    "direction": "output"
  },
  "pcpi_insn[13]": {
    "pin": "gpio_out_south[113]",
    "direction": "output"
  },
  "pcpi_insn[14]": {
    "pin": "gpio_out_south[114]",
    "direction": "output"
  },
  "pcpi_insn[15]": {
    "pin": "gpio_out_south[115]",
    "direction": "output"
  },
  "pcpi_insn[16]": {
    "pin": "gpio_out_south[116]",
    "direction": "output"
  },
  "pcpi_insn[17]": {
    "pin": "gpio_out_south[117]",
    "direction": "output"
  },
  "pcpi_insn[18]": {
    "pin": "gpio_out_south[118]",
    "direction": "output"
  },
  "pcpi_insn[19]": {
    "pin": "gpio_out_south[119]",
    "direction": "output"
  },
  "pcpi_insn[20]": {
    "pin": "gpio_out_south[120]",
    "direction": "output"
  },
  "pcpi_insn[21]": {
    "pin": "gpio_out_south[121]",
    "direction": "output"
  },
  "pcpi_insn[22]": {
    "pin": "gpio_out_south[122]",
    "direction": "output"
  },
  "pcpi_insn[23]": {
    "pin": "gpio_out_south[123]",
    "direction": "output"
  },
  "pcpi_insn[24]": {
    "pin": "gpio_out_south[124]",
    "direction": "output"
  },
  "pcpi_insn[25]": {
    "pin": "gpio_out_south[125]",
    "direction": "output"
  },
  "pcpi_insn[26]": {
    "pin": "gpio_out_south[126]",
    "direction": "output"
  },
  "pcpi_insn[27]": {
    "pin": "gpio_out_south[127]",
    "direction": "output"
  },
  "pcpi_insn[28]": {
    "pin": "gpio_out_south[128]",
    "direction": "output"
  },
  "pcpi_insn[29]": {
    "pin": "gpio_out_south[129]",
    "direction": "output"
  },
  "pcpi_insn[30]": {
    "pin": "gpio_out_south[130]",
    "direction": "output"
  },
  "pcpi_insn[31]": {
    "pin": "gpio_out_south[131]",
    "direction": "output"
  },
  "pcpi_rs1[0]": {
    "pin": "gpio_out_south[140]",
    "direction": "output"
  },
  "pcpi_rs1[1]": {
    "pin": "gpio_out_south[141]",
    "direction": "output"
  },
  "pcpi_rs1[2]": {
    "pin": "gpio_out_south[142]",
    "direction": "output"
  },
  "pcpi_rs1[3]": {
    "pin": "gpio_out_south[143]",
    "direction": "output"
  },
  "pcpi_rs1[4]": {
    "pin": "gpio_out_south[144]",
    "direction": "output"
  },
  "pcpi_rs1[5]": {
    "pin": "gpio_out_south[145]",
    "direction": "output"
  },
  "pcpi_rs1[6]": {
    "pin": "gpio_out_south[146]",
    "direction": "output"
  },
  "pcpi_rs1[7]": {
    "pin": "gpio_out_south[147]",
    "direction": "output"
  },
  "pcpi_rs1[8]": {
    "pin": "gpio_out_south[148]",
    "direction": "output"
  },
  "pcpi_rs1[9]": {
    "pin": "gpio_out_south[149]",
    "direction": "output"
  },
  "pcpi_rs1[10]": {
    "pin": "gpio_out_south[150]",
    "direction": "output"
  },
  "pcpi_rs1[11]": {
    "pin": "gpio_out_south[151]",
    "direction": "output"
  },
  "pcpi_rs1[12]": {
    "pin": "gpio_out_south[152]",
    "direction": "output"
  },
  "pcpi_rs1[13]": {
    "pin": "gpio_out_south[153]",
    "direction": "output"
  },
  "pcpi_rs1[14]": {
    "pin": "gpio_out_south[154]",
    "direction": "output"
  },
  "pcpi_rs1[15]": {
    "pin": "gpio_out_south[155]",
    "direction": "output"
  },
  "pcpi_rs1[16]": {
    "pin": "gpio_out_south[156]",
    "direction": "output"
  },
  "pcpi_rs1[17]": {
    "pin": "gpio_out_south[157]",
    "direction": "output"
  },
  "pcpi_rs1[18]": {
    "pin": "gpio_out_south[158]",
    "direction": "output"
  },
  "pcpi_rs1[19]": {
    "pin": "gpio_out_south[159]",
    "direction": "output"
  },
  "pcpi_rs1[20]": {
    "pin": "gpio_out_south[160]",
    "direction": "output"
  },
  "pcpi_rs1[21]": {
    "pin": "gpio_out_south[161]",
    "direction": "output"
  },
  "pcpi_rs1[22]": {
    "pin": "gpio_out_south[162]",
    "direction": "output"
  },
  "pcpi_rs1[23]": {
    "pin": "gpio_out_south[163]",
    "direction": "output"
  },
  "pcpi_rs1[24]": {
    "pin": "gpio_out_south[164]",
    "direction": "output"
  },
  "pcpi_rs1[25]": {
    "pin": "gpio_out_south[165]",
    "direction": "output"
  },
  "pcpi_rs1[26]": {
    "pin": "gpio_out_south[166]",
    "direction": "output"
  },
  "pcpi_rs1[27]": {
    "pin": "gpio_out_south[167]",
    "direction": "output"
  },
  "pcpi_rs1[28]": {
    "pin": "gpio_out_south[168]",
    "direction": "output"
  },
  "pcpi_rs1[29]": {
    "pin": "gpio_out_south[169]",
    "direction": "output"
  },
  "pcpi_rs1[30]": {
    "pin": "gpio_out_south[170]",
    "direction": "output"
  },
  "pcpi_rs1[31]": {
    "pin": "gpio_out_south[171]",
    "direction": "output"
  },
  "pcpi_rs2[0]": {
    "pin": "gpio_out_south[180]",
    "direction": "output"
  },
  "pcpi_rs2[1]": {
    "pin": "gpio_out_south[181]",
    "direction": "output"
  },
  "pcpi_rs2[2]": {
    "pin": "gpio_out_south[182]",
    "direction": "output"
  },
  "pcpi_rs2[3]": {
    "pin": "gpio_out_south[183]",
    "direction": "output"
  },
  "pcpi_rs2[4]": {
    "pin": "gpio_out_south[184]",
    "direction": "output"
  },
  "pcpi_rs2[5]": {
    "pin": "gpio_out_south[185]",
    "direction": "output"
  },
  "pcpi_rs2[6]": {
    "pin": "gpio_out_south[186]",
    "direction": "output"
  },
  "pcpi_rs2[7]": {
    "pin": "gpio_out_south[187]",
    "direction": "output"
  },
  "pcpi_rs2[8]": {
    "pin": "gpio_out_south[188]",
    "direction": "output"
  },
  "pcpi_rs2[9]": {
    "pin": "gpio_out_south[189]",
    "direction": "output"
  },
  "pcpi_rs2[10]": {
    "pin": "gpio_out_south[190]",
    "direction": "output"
  },
  "pcpi_rs2[11]": {
    "pin": "gpio_out_south[191]",
    "direction": "output"
  },
  "pcpi_rs2[12]": {
    "pin": "gpio_out_south[192]",
    "direction": "output"
  },
  "pcpi_rs2[13]": {
    "pin": "gpio_out_south[193]",
    "direction": "output"
  },
  "pcpi_rs2[14]": {
    "pin": "gpio_out_south[194]",
    "direction": "output"
  },
  "pcpi_rs2[15]": {
    "pin": "gpio_out_south[195]",
    "direction": "output"
  },
  "pcpi_rs2[16]": {
    "pin": "gpio_out_south[196]",
    "direction": "output"
  },
  "pcpi_rs2[17]": {
    "pin": "gpio_out_south[197]",
    "direction": "output"
  },
  "pcpi_rs2[18]": {
    "pin": "gpio_out_south[198]",
    "direction": "output"
  },
  "pcpi_rs2[19]": {
    "pin": "gpio_out_south[199]",
    "direction": "output"
  },
  "pcpi_rs2[20]": {
    "pin": "gpio_out_south[200]",
    "direction": "output"
  },
  "pcpi_rs2[21]": {
    "pin": "gpio_out_south[201]",
    "direction": "output"
  },
  "pcpi_rs2[22]": {
    "pin": "gpio_out_south[202]",
    "direction": "output"
  },
  "pcpi_rs2[23]": {
    "pin": "gpio_out_south[203]",
    "direction": "output"
  },
  "pcpi_rs2[24]": {
    "pin": "gpio_out_south[204]",
    "direction": "output"
  },
  "pcpi_rs2[25]": {
    "pin": "gpio_out_south[205]",
    "direction": "output"
  },
  "pcpi_rs2[26]": {
    "pin": "gpio_out_south[206]",
    "direction": "output"
  },
  "pcpi_rs2[27]": {
    "pin": "gpio_out_south[207]",
    "direction": "output"
  },
  "pcpi_rs2[28]": {
    "pin": "gpio_out_south[208]",
    "direction": "output"
  },
  "pcpi_rs2[29]": {
    "pin": "gpio_out_south[209]",
    "direction": "output"
  },
  "pcpi_rs2[30]": {
    "pin": "gpio_out_south[210]",
    "direction": "output"
  },
  "pcpi_rs2[31]": {
    "pin": "gpio_out_south[211]",
    "direction": "output"
  },
  "pcpi_rd[0]": {
    "pin": "gpio_in_east[20]",
    "direction": "input"
  },
  "pcpi_rd[1]": {
    "pin": "gpio_in_east[21]",
    "direction": "input"
  },
  "pcpi_rd[2]": {
    "pin": "gpio_in_east[22]",
    "direction": "input"
  },
  "pcpi_rd[3]": {
    "pin": "gpio_in_east[23]",
    "direction": "input"
  },
  "pcpi_rd[4]": {
    "pin": "gpio_in_east[24]",
    "direction": "input"
  },
  "pcpi_rd[5]": {
    "pin": "gpio_in_east[25]",
    "direction": "input"
  },
  "pcpi_rd[6]": {
    "pin": "gpio_in_east[26]",
    "direction": "input"
  },
  "pcpi_rd[7]": {
    "pin": "gpio_in_east[27]",
    "direction": "input"
  },
  "pcpi_rd[8]": {
    "pin": "gpio_in_east[28]",
    "direction": "input"
  },
  "pcpi_rd[9]": {
    "pin": "gpio_in_east[29]",
    "direction": "input"
  },
  "pcpi_rd[10]": {
    "pin": "gpio_in_east[30]",
    "direction": "input"
  },
  "pcpi_rd[11]": {
    "pin": "gpio_in_east[31]",
    "direction": "input"
  },
  "pcpi_rd[12]": {
    "pin": "gpio_in_east[32]",
    "direction": "input"
  },
  "pcpi_rd[13]": {
    "pin": "gpio_in_east[33]",
    "direction": "input"
  },
  "pcpi_rd[14]": {
    "pin": "gpio_in_east[34]",
    "direction": "input"
  },
  "pcpi_rd[15]": {
    "pin": "gpio_in_east[35]",
    "direction": "input"
  },
  "pcpi_rd[16]": {
    "pin": "gpio_in_east[36]",
    "direction": "input"
  },
  "pcpi_rd[17]": {
    "pin": "gpio_in_east[37]",
    "direction": "input"
  },
  "pcpi_rd[18]": {
    "pin": "gpio_in_east[38]",
    "direction": "input"
  },
  "pcpi_rd[19]": {
    "pin": "gpio_in_east[39]",
    "direction": "input"
  },
  "pcpi_rd[20]": {
    "pin": "gpio_in_east[40]",
    "direction": "input"
  },
  "pcpi_rd[21]": {
    "pin": "gpio_in_east[41]",
    "direction": "input"
  },
  "pcpi_rd[22]": {
    "pin": "gpio_in_east[42]",
    "direction": "input"
  },
  "pcpi_rd[23]": {
    "pin": "gpio_in_east[43]",
    "direction": "input"
  },
  "pcpi_rd[24]": {
    "pin": "gpio_in_east[44]",
    "direction": "input"
  },
  "pcpi_rd[25]": {
    "pin": "gpio_in_east[45]",
    "direction": "input"
  },
  "pcpi_rd[26]": {
    "pin": "gpio_in_east[46]",
    "direction": "input"
  },
  "pcpi_rd[27]": {
    "pin": "gpio_in_east[47]",
    "direction": "input"
  },
  "pcpi_rd[28]": {
    "pin": "gpio_in_east[48]",
    "direction": "input"
  },
  "pcpi_rd[29]": {
    "pin": "gpio_in_east[49]",
    "direction": "input"
  },
  "pcpi_rd[30]": {
    "pin": "gpio_in_east[50]",
    "direction": "input"
  },
  "pcpi_rd[31]": {
    "pin": "gpio_in_east[51]",
    "direction": "input"
  },
  "eoi[0]": {
    "pin": "gpio_out_west[220]",
    "direction": "output"
  },
  "eoi[1]": {
    "pin": "gpio_out_west[221]",
    "direction": "output"
  },
  "eoi[2]": {
    "pin": "gpio_out_west[222]",
    "direction": "output"
  },
  "eoi[3]": {
    "pin": "gpio_out_west[223]",
    "direction": "output"
  },
  "eoi[4]": {
    "pin": "gpio_out_west[224]",
    "direction": "output"
  },
  "eoi[5]": {
    "pin": "gpio_out_west[225]",
    "direction": "output"
  },
  "eoi[6]": {
    "pin": "gpio_out_west[226]",
    "direction": "output"
  },
  "eoi[7]": {
    "pin": "gpio_out_west[227]",
    "direction": "output"
  },
  "eoi[8]": {
    "pin": "gpio_out_west[228]",
    "direction": "output"
  },
  "eoi[9]": {
    "pin": "gpio_out_west[229]",
    "direction": "output"
  },
  "eoi[10]": {
    "pin": "gpio_out_west[230]",
    "direction": "output"
  },
  "eoi[11]": {
    "pin": "gpio_out_west[231]",
    "direction": "output"
  },
  "eoi[12]": {
    "pin": "gpio_out_west[232]",
    "direction": "output"
  },
  "eoi[13]": {
    "pin": "gpio_out_west[233]",
    "direction": "output"
  },
  "eoi[14]": {
    "pin": "gpio_out_west[234]",
    "direction": "output"
  },
  "eoi[15]": {
    "pin": "gpio_out_west[235]",
    "direction": "output"
  },
  "eoi[16]": {
    "pin": "gpio_out_west[236]",
    "direction": "output"
  },
  "eoi[17]": {
    "pin": "gpio_out_west[237]",
    "direction": "output"
  },
  "eoi[18]": {
    "pin": "gpio_out_west[238]",
    "direction": "output"
  },
  "eoi[19]": {
    "pin": "gpio_out_west[239]",
    "direction": "output"
  },
  "eoi[20]": {
    "pin": "gpio_out_west[240]",
    "direction": "output"
  },
  "eoi[21]": {
    "pin": "gpio_out_west[241]",
    "direction": "output"
  },
  "eoi[22]": {
    "pin": "gpio_out_west[242]",
    "direction": "output"
  },
  "eoi[23]": {
    "pin": "gpio_out_west[243]",
    "direction": "output"
  },
  "eoi[24]": {
    "pin": "gpio_out_west[244]",
    "direction": "output"
  },
  "eoi[25]": {
    "pin": "gpio_out_west[245]",
    "direction": "output"
  },
  "eoi[26]": {
    "pin": "gpio_out_west[246]",
    "direction": "output"
  },
  "eoi[27]": {
    "pin": "gpio_out_west[247]",
    "direction": "output"
  },
  "eoi[28]": {
    "pin": "gpio_out_west[248]",
    "direction": "output"
  },
  "eoi[29]": {
    "pin": "gpio_out_west[249]",
    "direction": "output"
  },
  "eoi[30]": {
    "pin": "gpio_out_west[250]",
    "direction": "output"
  },
  "eoi[31]": {
    "pin": "gpio_out_west[251]",
    "direction": "output"
  },
  "irq[0]": {
    "pin": "gpio_in_west[60]",
    "direction": "input"
  },
  "irq[1]": {
    "pin": "gpio_in_west[61]",
    "direction": "input"
  },
  "irq[2]": {
    "pin": "gpio_in_west[62]",
    "direction": "input"
  },
  "irq[3]": {
    "pin": "gpio_in_west[63]",
    "direction": "input"
  },
  "irq[4]": {
    "pin": "gpio_in_west[64]",
    "direction": "input"
  },
  "irq[5]": {
    "pin": "gpio_in_west[65]",
    "direction": "input"
  },
  "irq[6]": {
    "pin": "gpio_in_west[66]",
    "direction": "input"
  },
  "irq[7]": {
    "pin": "gpio_in_west[67]",
    "direction": "input"
  },
  "irq[8]": {
    "pin": "gpio_in_west[68]",
    "direction": "input"
  },
  "irq[9]": {
    "pin": "gpio_in_west[69]",
    "direction": "input"
  },
  "irq[10]": {
    "pin": "gpio_in_west[70]",
    "direction": "input"
  },
  "irq[11]": {
    "pin": "gpio_in_west[71]",
    "direction": "input"
  },
  "irq[12]": {
    "pin": "gpio_in_west[72]",
    "direction": "input"
  },
  "irq[13]": {
    "pin": "gpio_in_west[73]",
    "direction": "input"
  },
  "irq[14]": {
    "pin": "gpio_in_west[74]",
    "direction": "input"
  },
  "irq[15]": {
    "pin": "gpio_in_west[75]",
    "direction": "input"
  },
  "irq[16]": {
    "pin": "gpio_in_west[76]",
    "direction": "input"
  },
  "irq[17]": {
    "pin": "gpio_in_west[77]",
    "direction": "input"
  },
  "irq[18]": {
    "pin": "gpio_in_west[78]",
    "direction": "input"
  },
  "irq[19]": {
    "pin": "gpio_in_west[79]",
    "direction": "input"
  },
  "irq[20]": {
    "pin": "gpio_in_west[80]",
    "direction": "input"
  },
  "irq[21]": {
    "pin": "gpio_in_west[81]",
    "direction": "input"
  },
  "irq[22]": {
    "pin": "gpio_in_west[82]",
    "direction": "input"
  },
  "irq[23]": {
    "pin": "gpio_in_west[83]",
    "direction": "input"
  },
  "irq[24]": {
    "pin": "gpio_in_west[84]",
    "direction": "input"
  },
  "irq[25]": {
    "pin": "gpio_in_west[85]",
    "direction": "input"
  },
  "irq[26]": {
    "pin": "gpio_in_west[86]",
    "direction": "input"
  },
  "irq[27]": {
    "pin": "gpio_in_west[87]",
    "direction": "input"
  },
  "irq[28]": {
    "pin": "gpio_in_west[88]",
    "direction": "input"
  },
  "irq[29]": {
    "pin": "gpio_in_west[89]",
    "direction": "input"
  },
  "irq[30]": {
    "pin": "gpio_in_west[90]",
    "direction": "input"
  },
  "irq[31]": {
    "pin": "gpio_in_west[91]",
    "direction": "input"
  },
  "trace_data[0]": {
    "pin": "gpio_out_west[260]",
    "direction": "output"
  },
  "trace_data[1]": {
    "pin": "gpio_out_west[261]",
    "direction": "output"
  },
  "trace_data[2]": {
    "pin": "gpio_out_west[262]",
    "direction": "output"
  },
  "trace_data[3]": {
    "pin": "gpio_out_west[263]",
    "direction": "output"
  },
  "trace_data[4]": {
    "pin": "gpio_out_west[264]",
    "direction": "output"
  },
  "trace_data[5]": {
    "pin": "gpio_out_west[265]",
    "direction": "output"
  },
  "trace_data[6]": {
    "pin": "gpio_out_west[266]",
    "direction": "output"
  },
  "trace_data[7]": {
    "pin": "gpio_out_west[267]",
    "direction": "output"
  },
  "trace_data[8]": {
    "pin": "gpio_out_west[268]",
    "direction": "output"
  },
  "trace_data[9]": {
    "pin": "gpio_out_west[269]",
    "direction": "output"
  },
  "trace_data[10]": {
    "pin": "gpio_out_west[270]",
    "direction": "output"
  },
  "trace_data[11]": {
    "pin": "gpio_out_west[271]",
    "direction": "output"
  },
  "trace_data[12]": {
    "pin": "gpio_out_west[272]",
    "direction": "output"
  },
  "trace_data[13]": {
    "pin": "gpio_out_west[273]",
    "direction": "output"
  },
  "trace_data[14]": {
    "pin": "gpio_out_west[274]",
    "direction": "output"
  },
  "trace_data[15]": {
    "pin": "gpio_out_west[275]",
    "direction": "output"
  },
  "trace_data[16]": {
    "pin": "gpio_out_west[276]",
    "direction": "output"
  },
  "trace_data[17]": {
    "pin": "gpio_out_west[277]",
    "direction": "output"
  },
  "trace_data[18]": {
    "pin": "gpio_out_west[278]",
    "direction": "output"
  },
  "trace_data[19]": {
    "pin": "gpio_out_west[279]",
    "direction": "output"
  },
  "trace_data[20]": {
    "pin": "gpio_out_west[280]",
    "direction": "output"
  },
  "trace_data[21]": {
    "pin": "gpio_out_west[281]",
    "direction": "output"
  },
  "trace_data[22]": {
    "pin": "gpio_out_west[282]",
    "direction": "output"
  },
  "trace_data[23]": {
    "pin": "gpio_out_west[283]",
    "direction": "output"
  },
  "trace_data[24]": {
    "pin": "gpio_out_west[284]",
    "direction": "output"
  },
  "trace_data[25]": {
    "pin": "gpio_out_west[285]",
    "direction": "output"
  },
  "trace_data[26]": {
    "pin": "gpio_out_west[286]",
    "direction": "output"
  },
  "trace_data[27]": {
    "pin": "gpio_out_west[287]",
    "direction": "output"
  },
  "trace_data[28]": {
    "pin": "gpio_out_west[288]",
    "direction": "output"
  },
  "trace_data[29]": {
    "pin": "gpio_out_west[289]",
    "direction": "output"
  },
  "trace_data[30]": {
    "pin": "gpio_out_west[290]",
    "direction": "output"
  },
  "trace_data[31]": {
    "pin": "gpio_out_west[291]",
    "direction": "output"
  },
  "trace_data[32]": {
    "pin": "gpio_out_west[292]",
    "direction": "output"
  },
  "trace_data[33]": {
    "pin": "gpio_out_west[293]",
    "direction": "output"
  },
  "trace_data[34]": {
    "pin": "gpio_out_west[294]",
    "direction": "output"
  },
  "trace_data[35]": {
    "pin": "gpio_out_west[295]",
    "direction": "output"
  }
}

================================================
FILE: examples/picorv32/picorv32.py
================================================
#!/usr/bin/env python3

import siliconcompiler
from logiklib.zeroasic.z1062 import z1062
from siliconcompiler.tools.yosys.syn_fpga import FPGASynthesis

from logik.flows.logik_flow import LogikFlow


def build():
    module_name = "picorv32"
    design = siliconcompiler.Design(module_name)

    # Fetch picorv32 from the logikbench repo
    # Silicon Compiler will download and cache the files for us
    design.set_dataroot(
        "picorv32-logikbench",
        "git+https://github.com/zeroasiccorp/logikbench.git",
        "db866c536340c071c563a063c9406888070dfbda",
    )

    with design.active_dataroot("picorv32-logikbench"):
        design.add_file(
            f"logikbench/blocks/{module_name}/rtl/{module_name}.v", fileset="rtl"
        )
        design.set_topmodule(module_name, fileset="rtl")

    design.set_dataroot("constraints", __file__)
    with design.active_dataroot("constraints"):
        # Add timing constraints
        design.add_file(f"{module_name}.sdc", fileset="sdc")

        # Define pin constraints
        design.add_file(f"constraints/z1062/{module_name}.pcf", fileset="pcf")

    project = siliconcompiler.FPGA(design)

    # add design files to the project
    project.add_fileset("rtl")
    project.add_fileset("sdc")
    project.add_fileset("pcf")

    fpga = z1062.z1062()
    project.set_fpga(fpga)

    project.set_flow(LogikFlow())

    # set synthesis mode to 'delay'
    FPGASynthesis.find_task(project=project).set_yosys_synthoptmode("delay")

    # Customize steps for this design
    project.option.set_quiet(True)

    project.run()
    project.summary()


if __name__ == "__main__":
    build()


================================================
FILE: examples/picorv32/picorv32.sdc
================================================
create_clock -period 12.5 clk


================================================
FILE: logik/__init__.py
================================================
try:
    from logik._version import __version__
except ImportError:
    # This only exists in installations
    __version__ = None


================================================
FILE: logik/devices/__init__.py
================================================


================================================
FILE: logik/devices/logik_fpga.py
================================================
from siliconcompiler.tools.opensta import OpenSTAFPGA
from siliconcompiler.tools.vpr import VPRFPGA
from siliconcompiler.tools.yosys import YosysFPGA


class LogikFPGA(YosysFPGA, VPRFPGA, OpenSTAFPGA):
    """
    Class for logik FPGA devices
    """

    def __init__(self) -> None:
        super().__init__()

    def set_convert_bitstream_bitstream_map(
        self, file: str, dataroot: str | None = None
    ):
        with self.active_dataroot(self._get_active_dataroot(dataroot)):
            return self.set("tool", "convert_bitstream", "bitstream_map", file)


================================================
FILE: logik/flows/__init__.py
================================================


================================================
FILE: logik/flows/logik_flow.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

from siliconcompiler.flows import fpgaflow

from logik.tools.fasm_to_bitstream import bitstream_finish


class LogikFlow(fpgaflow.FPGAVPROpenSTAFlow):
    """An open-source FPGA flow using Yosys, VPR, and GenFasm.

    This flow is designed for academic and research FPGAs, utilizing VPR
    (Versatile Place and Route) for placement and routing.

    The flow consists of the following steps:

    * **elaborate**: Elaborate the RTL design from sources.
    * **synthesis**: Synthesize the elaborated design into a netlist using Yosys.
    * **place**: Place the netlist components onto the FPGA architecture using VPR.
    * **route**: Route the connections between placed components using VPR.
    * **timing**: Perform static analysis using OpenSTA.
    * **bitstream**: Generate the final bitstream using GenFasm.
    * **convert_bitstream**: Format bitstream from fasm to bits.
    """

    def __init__(self, name: str = "logik_flow") -> None:
        """
        Initializes the FPGAVPRFlow.

        Args:
            name (str): The name of the flow.
        """
        super().__init__(name)

        self.node("convert_bitstream", bitstream_finish.BitstreamFinishTask())
        self.edge("bitstream", "convert_bitstream")


if __name__ == "__main__":
    LogikFlow().write_flowgraph(f"{LogikFlow().name}.png")


================================================
FILE: logik/tools/__init__.py
================================================


================================================
FILE: logik/tools/fasm_to_bitstream/__init__.py
================================================


================================================
FILE: logik/tools/fasm_to_bitstream/bitstream_bin_convert.py
================================================
#!/usr/bin/env python3

# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import argparse


def main() -> None:

    option_parser = argparse.ArgumentParser()

    option_parser.add_argument("binary_bitstream", help="binary bitstream file")
    option_parser.add_argument("ascii_bitstream", help="ascii bitstream file")

    options = option_parser.parse_args()

    bin_filename = options.binary_bitstream
    out_filename = options.ascii_bitstream

    words = []
    with open(bin_filename, "rb") as bin_file:
        for cur_byte in bin_file.read():
            formatted_word = format(cur_byte, "0x").zfill(2)
            words.append(formatted_word)

    with open(out_filename, "w") as out_file:
        for word in words:
            out_file.write(word)
            out_file.write("\n")


if __name__ == "__main__":
    main()


================================================
FILE: logik/tools/fasm_to_bitstream/bitstream_finish.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

from siliconcompiler.tool import Task

from logik.tools.fasm_to_bitstream import fasm_to_bitstream as fasm_utils


class BitstreamFinishTask(Task):
    def __init__(self) -> None:
        super().__init__()

    def tool(self) -> str:
        return "fasm_to_bitstream"

    def task(self) -> str:
        return "bitstream_finish"

    def setup(self) -> None:
        """
        Perform bitstream finishing
        """
        super().setup()

        fpga = self.project.get("fpga", "device")
        fpga_obj = self.project.get("library", fpga, field="schema")

        self.add_required_key(fpga_obj, "tool", "convert_bitstream", "bitstream_map")

        self.add_input_file(ext="fasm")
        self.add_output_file(ext="json")
        self.add_output_file(ext="bin")

    def run(self) -> int:
        fpga = self.project.get("fpga", "device")
        fpga_obj = self.project.get("library", fpga, field="schema")

        fasm_file = f"inputs/{self.design_topmodule}.fasm"

        bitstream_map = fpga_obj.find_files(
            "tool", "convert_bitstream", "bitstream_map"
        )

        json_outfile = f"outputs/{self.design_topmodule}.json"
        binary_outfile = f"outputs/{self.design_topmodule}.bin"

        # Finishing steps are as follows:
        # 1. Convert FASM to IR
        config_bitstream = fasm_utils.fasm2bitstream(fasm_file, bitstream_map)

        # 2.  Write IR to JSON for inspection purposes
        fasm_utils.write_bitstream_json(config_bitstream, json_outfile)

        # 3.  Flatten the IR to a 1D address space
        flattened_bitstream = fasm_utils.generate_flattened_bitstream(config_bitstream)

        # 4.  Format the flattened bitstream to binary
        binary_bitstream = fasm_utils.format_binary_bitstream(flattened_bitstream)

        # 5.  Write binary to file
        fasm_utils.write_bitstream_binary(binary_bitstream, binary_outfile)

        return 0


================================================
FILE: logik/tools/fasm_to_bitstream/fasm_to_bitstream.py
================================================
#!/usr/bin/env python3

# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import json
import math
import re
import sys
from typing import Any

import numpy as np
from numpy import dtype, ndarray


def main() -> None:
    fasm_file = sys.argv[1]
    bitstream_map_file = sys.argv[2]
    json_bitstream_file = sys.argv[3]
    dat_bitstream_file = sys.argv[4]
    bin_bitstream_file = sys.argv[5]

    config_bitstream = fasm2bitstream(fasm_file, bitstream_map_file)
    write_bitstream_json(config_bitstream, json_bitstream_file)
    flattened_bitstream = generate_flattened_bitstream(config_bitstream)
    write_bitstream_data(flattened_bitstream, dat_bitstream_file)
    binary_bitstream = format_binary_bitstream(flattened_bitstream)
    write_bitstream_binary(binary_bitstream, bin_bitstream_file)


def write_bitstream_json(config_bitstream, json_bitstream_file) -> None:
    with open(json_bitstream_file, "w") as json_out:
        json_out.write(json.dumps(config_bitstream))
        json_out.write("\n")


def write_bitstream_data(config_bitstream, dat_bitstream_file) -> None:
    with open(dat_bitstream_file, "w") as dat_out:
        dat_out.writelines(f"{entry}\n" for entry in config_bitstream)


def write_bitstream_binary(binary_bitstream, binary_bitstream_file) -> None:
    binary_bitstream.tofile(binary_bitstream_file)


def calculate_bitstream_columns(bitstream_map) -> int:

    return len(bitstream_map)


def calculate_bitstream_rows(bitstream_map) -> int:

    max_rows = -1
    # ***TO DO:  Add SC-compliant error checking that
    #            the row count is constant across columns
    #            (or eventually allow non-constant count
    #            for non-rectangular FPGAs)
    for i in range(len(bitstream_map)):
        max_rows = max(max_rows, len(bitstream_map[i]))

    return max_rows


def calculate_address_size(bitstream_map) -> int:

    max_length = 0

    for x in range(len(bitstream_map)):
        for y in range(len(bitstream_map[x])):
            max_length = max(max_length, len(bitstream_map[x][y]))

    return max_length


def calculate_config_data_width(bitstream_map) -> int:

    # ***TO DO:  The config data width is supposed to be
    #            constant for all addresses, so we should
    #            add error checking to see if it ever
    #            deviates.  Need an SC-compliant way to do
    #            this before implementing
    max_config_width = 0
    for x in range(len(bitstream_map)):
        for y in range(len(bitstream_map[x])):
            for address in range(len(bitstream_map[x][y])):
                if len(bitstream_map[x][y][address]) > max_config_width:
                    # To prevent runaway runtimes, assume that the config
                    # width is constant throughout the bitstream map
                    # and abort after we find a positive value
                    max_config_width = len(bitstream_map[x][y][address])
                    break

    return max_config_width


# In this converter, the bitstream address space is flattened
# into a vector; this is useful for prepping the bitstream for
# storage into a ROM that will be loaded over a serial interface
# To align to the bitstream ordering that is required by
# the bitstream loading circuit, it is necessary to do some
# arithmetic to pick which configuration words go in which
# order in the flattened vector; see below for details
def generate_flattened_bitstream(bitstream_map) -> list[str]:

    # Convert FPGA array dimensions into address space bit widths;
    # this will assist in flattening the address space:
    num_bitstream_columns = calculate_bitstream_columns(bitstream_map)
    num_bitstream_rows = calculate_bitstream_rows(bitstream_map)
    address_length = int.bit_length(calculate_address_size(bitstream_map))
    x_length = int.bit_length(num_bitstream_columns - 1)
    y_length = int.bit_length(num_bitstream_rows - 1)

    # Get the word size of the words in the bitstream
    config_data_width = calculate_config_data_width(bitstream_map)

    input_bus_width = x_length + y_length + address_length

    default_entry = format(0, "0x").zfill(int(config_data_width / 4))

    bitstream_vector = [default_entry] * pow(2, input_bus_width)

    for x in range(len(bitstream_map)):
        for y in range(len(bitstream_map[x])):
            for address in range(len(bitstream_map[x][y])):
                vector_address = y * pow(2, x_length + address_length)
                vector_address += x * pow(2, address_length)
                vector_address += address

                bitstream_data = concatenate_data(bitstream_map[x][y][address])
                formatted_data = format(bitstream_data, "0x").zfill(
                    int(config_data_width / 4)
                )
                bitstream_vector[vector_address] = formatted_data

    return bitstream_vector


def concatenate_data(data_array) -> int:

    data_sum = 0
    scale_factor = 1

    for i in range(len(data_array)):
        if data_array[i] == 1:
            data_sum += scale_factor
        scale_factor = scale_factor * 2

    return data_sum


def format_binary_bitstream(bitstream_data, word_size=8) -> ndarray[Any, dtype]:

    converted_data = []

    for element in bitstream_data:
        element_temp = int(element.rstrip(), 16)
        sub_element_count = math.ceil(word_size / 8)
        for i in range(sub_element_count):
            cur_data_word = element_temp & ((1 << 8) - 1)
            converted_data.append(cur_data_word)
            element_temp = element_temp >> 8

    bitstream_data_array = np.array(converted_data, np.uint8)

    return bitstream_data_array


def fasm2bitstream(
    fasm_file, bitstream_map_file) -> list[list[list[list[int]]]]:

    with open(bitstream_map_file, "r") as map_file:
        json_bitstream_map = json.load(map_file)
        bitstream_map = json_bitstream_map["bitstream"]

    fasm_features = load_fasm_data(
        fasm_file
    )

    config_bitstream = generate_bitstream_from_fasm(bitstream_map, fasm_features)

    return config_bitstream


def load_fasm_data(filename) -> list[str]:
    with open(filename, "r") as fasm_file:
        fasm_feature_list = fasm_file.readlines()

    # "Canonicalize" the feature list, as described here:
    # https://fasm.readthedocs.io/en/latest/specification/syntax.html

    canonical_fasm_feature_list = []

    for feature in fasm_feature_list:
        feature = feature.rstrip()
        if "=" in feature:
            feature_fields = feature.split("=")
            if len(feature_fields) == 2:
                feature_name = feature_fields[0]
                feature_value = feature_fields[1]

                # ***TO DO:  Select a more robust detector of a multibit feature
                #            than array index colon checking
                if ":" in feature_name:
                    errors = 0

                    feature_split_pattern = r"[\[\]:]"
                    feature_name_fields = re.split(feature_split_pattern, feature_name)

                    # ***ASSUMPTION: All FASM feature output will be binary
                    feature_array = feature_value.split("'b")

                    if len(feature_name_fields) < 2:
                        errors += 1

                    else:
                        base_feature_length = int(feature_array[0])
                        base_feature_value = feature_array[1]

                        if base_feature_length != len(base_feature_value):
                            errors += 1

                    if len(feature_name_fields) < 3:
                        errors += 1

                    if errors == 0:
                        base_feature_name = feature_name_fields[0]
                        base_feature_name_msb = int(feature_name_fields[1])

                        for i in range(len(base_feature_value)):
                            # multi-bit fasm features are represented big-endian, so:
                            if base_feature_value[i] == "1":
                                cur_index = base_feature_name_msb - i
                                indexed_feature_name = (
                                    f"{base_feature_name}[{cur_index}]"
                                )
                                canonical_fasm_feature_list.append(indexed_feature_name)

                else:
                    if feature_value != 0:
                        canonical_fasm_feature_list.append(feature_name)

        else:
            canonical_fasm_feature_list.append(feature)

    return canonical_fasm_feature_list


def generate_bitstream_from_fasm(
    address_map, fasm_data,
) -> list[list[list[list[int]]]]:

    feature_index = invert_address_map(address_map)
    bitstream = []
    for x in range(len(address_map)):
        bitstream.append([])
        for y in range(len(address_map[x])):
            bitstream[x].append([])
            for address in range(len(address_map[x][y])):
                bitstream[x][y].append([0] * len(address_map[x][y][address]))

    for fasm_feature in fasm_data:
        if fasm_feature not in feature_index:
            print(f"fasm feature '{fasm_feature}' not found in address map")
            continue
        x_i = feature_index[fasm_feature]["x"]
        y_i = feature_index[fasm_feature]["y"]
        addr_i = feature_index[fasm_feature]["address"]
        bit_i = feature_index[fasm_feature]["bit"]
        bitstream[x_i][y_i][addr_i][bit_i] = 1

    return bitstream


def invert_address_map(address_map) -> dict[Any, dict[str, int]]:

    feature_index = {}
    for x in range(len(address_map)):
        for y in range(len(address_map[x])):
            for address in range(len(address_map[x][y])):
                for bit in range(len(address_map[x][y][address])):
                    feature_index[address_map[x][y][address][bit]] = {}
                    feature_index[address_map[x][y][address][bit]]["x"] = x
                    feature_index[address_map[x][y][address][bit]]["y"] = y
                    feature_index[address_map[x][y][address][bit]]["address"] = address
                    feature_index[address_map[x][y][address][bit]]["bit"] = bit

    return feature_index


if __name__ == "__main__":
    main()


================================================
FILE: pyproject.toml
================================================
[build-system]
requires = [
    "setuptools >= 80",
    "setuptools_scm[toml] >= 8"
]

build-backend = "setuptools.build_meta"

[project]
name = "logik"
authors = [{name = "Zero ASIC"}]
description = "Logik is a light weight FPGA tool chain based on mature open source technologies."
readme = "README.md"
urls = {Homepage = "https://github.com/siliconcompiler/logik"}
requires-python = ">= 3.10"
dependencies = [
    # Use ~= to allow users to pull in bug fixes and compatible future releases (>= current, < next minor)
    "logiklib ~= 0.2.0",
    "siliconcompiler ~= 0.37.2"
]

license = "Apache-2.0"
license-files = ["LICENSE"]

dynamic = ["version"]

[tool.setuptools_scm]
write_to = "logik/_version.py"
write_to_template = '''
# This file is automatically generated by setuptools_scm.
# Do not edit it directly.
__version__ = "{version}"
__base_version__ = "{scm_version.tag}"
'''

[project.optional-dependencies]
test = [
    "pytest == 9.0.3",
    "pytest-timeout == 2.4.0",
    "flake8 == 7.3.0"
]
docs = [
    "Sphinx == 8.1.3",
    "sphinx-rtd-theme == 3.1.0",
    "autodocsumm == 0.2.15"
]

[tool.setuptools]
include-package-data = true
packages = [
    "logik"
]

[tool.pytest.ini_options]
testpaths = "tests"
timeout = "180"
markers = [
    "quick: always run this test on push"
]
filterwarnings = [
    "ignore::DeprecationWarning:pip._internal"
]


================================================
FILE: tests/conftest.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import os

import pytest
import siliconcompiler


@pytest.fixture
def setup_example_test(monkeypatch):
    """
    This file is cloned from Silicon Compiler.  We follow its convention
    for organizing CI tests with pytest, so that all testing can be done with
    similar efficiency.  See Silicon Compiler documentation for details
    """

    def setup(directory):
        cad_root = ebrick_fpga_cad_root()
        ex_dir = os.path.join(cad_root, "examples", directory)

        def _mock_show(chip, filename=None, screenshot=False):
            pass

        # pytest's monkeypatch lets us modify sys.path for this test only.
        monkeypatch.syspath_prepend(ex_dir)
        # Mock chip.show() so it doesn't run.
        monkeypatch.setattr(siliconcompiler.Project, "show", _mock_show)

        return ex_dir

    return setup


def ebrick_fpga_cad_root():
    return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


================================================
FILE: tests/data/z1000.py
================================================
# Copyright 2024 Zero ASIC Corporation

from logik.devices.logik_fpga import LogikFPGA


class z1000(LogikFPGA):
    """
    Logik driver for z1000
    """

    def __init__(self):
        super().__init__()
        part_name = "z1000"
        self.set_name(part_name)

        self.define_tool_parameter(
            "convert_bitstream",
            "bitstream_map",
            "file",
            "map for fasm->bitstream conversion",
        )

        self.set_dataroot(
            part_name,
            f"github://siliconcompiler/logiklib/v0.1.0/{part_name}_cad.tar.gz",
            "0.1.0",
        )

        self.package.set_vendor("ZeroASIC")
        self.set_lutsize(4)

        self.add_yosys_registertype(["dff", "dffr", "dffe", "dffer"])
        self.add_yosys_featureset(["async_reset", "enable"])
        with self.active_dataroot(part_name):
            self.set_yosys_flipfloptechmap("techlib/tech_flops.v")

        self.set_vpr_devicecode(part_name)
        self.set_vpr_clockmodel("route")
        self.set_vpr_channelwidth(50)
        self.add_vpr_registertype(["dff", "dffr", "dffe", "dffer"])
        with self.active_dataroot(part_name):
            self.set_vpr_archfile("cad/z1000.xml")
            self.set_vpr_graphfile("cad/z1000_rr_graph.xml")
            self.set_vpr_constraintsmap("cad/z1000_constraint_map.json")

        with self.active_dataroot(part_name):
            self.set_convert_bitstream_bitstream_map("cad/z1000_bitstream_map.json")

        self.set_vpr_router_lookahead("classic")


================================================
FILE: tests/examples/test_adder.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import os
import subprocess

import pytest


@pytest.mark.timeout(300)
def test_py(setup_example_test, monkeypatch):
    adder_dir = setup_example_test("adder")

    monkeypatch.chdir(adder_dir)
    # create_cmdline() parses sys.argv directly; without this, pytest's own
    # arguments (e.g. -v matching argparse's -version prefix) cause it to exit.
    monkeypatch.setattr('sys.argv', ['adder.py'])

    import adder

    adder.hello_adder()


@pytest.mark.timeout(300)
def test_cli(setup_example_test):
    adder_dir = setup_example_test("adder")

    proc = subprocess.run(
        [os.path.join(adder_dir, "adder.py")], cwd=adder_dir, check=False
    )
    assert proc.returncode == 0


================================================
FILE: tests/examples/test_eth_mac_1g.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import os
import subprocess

import pytest


@pytest.mark.timeout(720)
def test_py(setup_example_test, monkeypatch):
    eth_mac_1g_dir = setup_example_test("eth_mac_1g")

    monkeypatch.chdir(eth_mac_1g_dir)

    import eth_mac_1g

    eth_mac_1g.build()


@pytest.mark.timeout(720)
def test_cli(setup_example_test):
    eth_mac_1g_dir = setup_example_test("eth_mac_1g")

    proc = subprocess.run(
        [os.path.join(eth_mac_1g_dir, "eth_mac_1g.py")], cwd=eth_mac_1g_dir, check=False
    )
    assert proc.returncode == 0


================================================
FILE: tests/examples/test_files.py
================================================
# Copyright 2024 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import siliconcompiler
from data.z1000 import z1000


def test_file_paths():
    project = siliconcompiler.FPGA("test")
    project.set_fpga(z1000())
    project.set("option", "builddir", ".")
    assert project.check_filepaths()


================================================
FILE: tests/examples/test_picorv32.py
================================================
# Copyright 2025 Zero ASIC Corporation
# Licensed under the MIT License (see LICENSE for details)

import os
import subprocess

import pytest


@pytest.mark.timeout(360)
def test_py(setup_example_test, monkeypatch):
    picorv32_dir = setup_example_test("picorv32")

    monkeypatch.chdir(picorv32_dir)

    import picorv32

    picorv32.build()


@pytest.mark.timeout(360)
def test_cli(setup_example_test):
    picorv32_dir = setup_example_test("picorv32")

    proc = subprocess.run(
        [os.path.join(picorv32_dir, "picorv32.py")], cwd=picorv32_dir, check=False
    )
    assert proc.returncode == 0
Download .txt
gitextract_iw5zrkjd/

├── .flake8
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── lint.yml
│       ├── regression.yml
│       └── wheels.yml
├── .gitignore
├── .readthedocs.yaml
├── LICENSE
├── README.md
├── docs/
│   ├── Makefile
│   ├── make.bat
│   └── source/
│       ├── bitstream_format.rst
│       ├── conf.py
│       ├── design_preparation.rst
│       ├── execution.rst
│       ├── external_links.rst
│       ├── index.rst
│       ├── pin_constraints.rst
│       ├── prerequisites.rst
│       ├── sc_preparation.rst
│       ├── timing_constraints.rst
│       └── tool_installations.rst
├── examples/
│   ├── __init__.py
│   ├── adder/
│   │   ├── adder.pcf
│   │   ├── adder.py
│   │   ├── adder.v
│   │   └── pin_constraints.py
│   ├── eth_mac_1g/
│   │   ├── constraints/
│   │   │   └── z1000/
│   │   │       └── pin_constraints.pcf
│   │   ├── eth_mac_1g.py
│   │   ├── eth_mac_1g.sdc
│   │   └── eth_mac_1g_wrapper.v
│   └── picorv32/
│       ├── constraints/
│       │   └── z1062/
│       │       └── picorv32.pcf
│       ├── picorv32.py
│       └── picorv32.sdc
├── logik/
│   ├── __init__.py
│   ├── devices/
│   │   ├── __init__.py
│   │   └── logik_fpga.py
│   ├── flows/
│   │   ├── __init__.py
│   │   └── logik_flow.py
│   └── tools/
│       ├── __init__.py
│       └── fasm_to_bitstream/
│           ├── __init__.py
│           ├── bitstream_bin_convert.py
│           ├── bitstream_finish.py
│           └── fasm_to_bitstream.py
├── pyproject.toml
└── tests/
    ├── conftest.py
    ├── data/
    │   └── z1000.py
    └── examples/
        ├── test_adder.py
        ├── test_eth_mac_1g.py
        ├── test_files.py
        └── test_picorv32.py
Download .txt
SYMBOL INDEX (45 symbols across 15 files)

FILE: examples/adder/adder.py
  function hello_adder (line 12) | def hello_adder():

FILE: examples/adder/pin_constraints.py
  function main (line 9) | def main():
  function generate_mapped_constraints (line 34) | def generate_mapped_constraints(part_name):
  function generate_raw_constraints (line 60) | def generate_raw_constraints():
  function write_json_constraints (line 85) | def write_json_constraints(constraints, filename):

FILE: examples/eth_mac_1g/eth_mac_1g.py
  function build (line 12) | def build():

FILE: examples/picorv32/picorv32.py
  function build (line 10) | def build():

FILE: logik/devices/logik_fpga.py
  class LogikFPGA (line 6) | class LogikFPGA(YosysFPGA, VPRFPGA, OpenSTAFPGA):
    method __init__ (line 11) | def __init__(self) -> None:
    method set_convert_bitstream_bitstream_map (line 14) | def set_convert_bitstream_bitstream_map(

FILE: logik/flows/logik_flow.py
  class LogikFlow (line 9) | class LogikFlow(fpgaflow.FPGAVPROpenSTAFlow):
    method __init__ (line 26) | def __init__(self, name: str = "logik_flow") -> None:

FILE: logik/tools/fasm_to_bitstream/bitstream_bin_convert.py
  function main (line 9) | def main() -> None:

FILE: logik/tools/fasm_to_bitstream/bitstream_finish.py
  class BitstreamFinishTask (line 9) | class BitstreamFinishTask(Task):
    method __init__ (line 10) | def __init__(self) -> None:
    method tool (line 13) | def tool(self) -> str:
    method task (line 16) | def task(self) -> str:
    method setup (line 19) | def setup(self) -> None:
    method run (line 34) | def run(self) -> int:

FILE: logik/tools/fasm_to_bitstream/fasm_to_bitstream.py
  function main (line 16) | def main() -> None:
  function write_bitstream_json (line 31) | def write_bitstream_json(config_bitstream, json_bitstream_file) -> None:
  function write_bitstream_data (line 37) | def write_bitstream_data(config_bitstream, dat_bitstream_file) -> None:
  function write_bitstream_binary (line 42) | def write_bitstream_binary(binary_bitstream, binary_bitstream_file) -> N...
  function calculate_bitstream_columns (line 46) | def calculate_bitstream_columns(bitstream_map) -> int:
  function calculate_bitstream_rows (line 51) | def calculate_bitstream_rows(bitstream_map) -> int:
  function calculate_address_size (line 64) | def calculate_address_size(bitstream_map) -> int:
  function calculate_config_data_width (line 75) | def calculate_config_data_width(bitstream_map) -> int:
  function generate_flattened_bitstream (line 103) | def generate_flattened_bitstream(bitstream_map) -> list[str]:
  function concatenate_data (line 138) | def concatenate_data(data_array) -> int:
  function format_binary_bitstream (line 151) | def format_binary_bitstream(bitstream_data, word_size=8) -> ndarray[Any,...
  function fasm2bitstream (line 168) | def fasm2bitstream(
  function load_fasm_data (line 184) | def load_fasm_data(filename) -> list[str]:
  function generate_bitstream_from_fasm (line 248) | def generate_bitstream_from_fasm(
  function invert_address_map (line 274) | def invert_address_map(address_map) -> dict[Any, dict[str, int]]:

FILE: tests/conftest.py
  function setup_example_test (line 11) | def setup_example_test(monkeypatch):
  function ebrick_fpga_cad_root (line 35) | def ebrick_fpga_cad_root():

FILE: tests/data/z1000.py
  class z1000 (line 6) | class z1000(LogikFPGA):
    method __init__ (line 11) | def __init__(self):

FILE: tests/examples/test_adder.py
  function test_py (line 11) | def test_py(setup_example_test, monkeypatch):
  function test_cli (line 25) | def test_cli(setup_example_test):

FILE: tests/examples/test_eth_mac_1g.py
  function test_py (line 11) | def test_py(setup_example_test, monkeypatch):
  function test_cli (line 22) | def test_cli(setup_example_test):

FILE: tests/examples/test_files.py
  function test_file_paths (line 8) | def test_file_paths():

FILE: tests/examples/test_picorv32.py
  function test_py (line 11) | def test_py(setup_example_test, monkeypatch):
  function test_cli (line 22) | def test_cli(setup_example_test):
Condensed preview — 51 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (172K chars).
[
  {
    "path": ".flake8",
    "chars": 124,
    "preview": "[flake8]\nextend-exclude = testbench/build,build,.venv\nmax-line-length = 100\nignore =\n    E125,\n    E129,\n    E128,\n    W"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 414,
    "preview": "version: 2\nupdates:\n  # Maintain dependencies for GitHub Actions\n  - package-ecosystem: \"github-actions\"\n    directory: "
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 1066,
    "preview": "# Copyright (c) 2024 Zero ASIC Corporation\n# This code is licensed under Apache License 2.0 (see LICENSE for details)\n\n#"
  },
  {
    "path": ".github/workflows/regression.yml",
    "chars": 2812,
    "preview": "---\n\nname: Regression\non:\n  workflow_dispatch:\n  pull_request:\n  push:\n    branches:\n      - main\n\njobs:\n  version-compa"
  },
  {
    "path": ".github/workflows/wheels.yml",
    "chars": 999,
    "preview": "name: Wheels\n\non:\n  workflow_dispatch:\n  release:\n    types:\n      - published\n\njobs:\n  build_wheels:\n    name: Wheels\n "
  },
  {
    "path": ".gitignore",
    "chars": 3155,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
  },
  {
    "path": ".readthedocs.yaml",
    "chars": 429,
    "preview": "# .readthedocs.yaml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
  },
  {
    "path": "LICENSE",
    "chars": 11351,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 5166,
    "preview": "Logik\n-------------------------------------------------------------\n\n[![Regression](https://github.com/siliconcompiler/l"
  },
  {
    "path": "docs/Makefile",
    "chars": 737,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\n# Minimal makefile fo"
  },
  {
    "path": "docs/make.bat",
    "chars": 804,
    "preview": "@ECHO OFF\r\n\r\npushd %~dp0\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sp"
  },
  {
    "path": "docs/source/bitstream_format.rst",
    "chars": 4898,
    "preview": "Bitstream Formatting\n====================\n\nBitstream data is generated in this flow in multiple formats:\n\n* `FASM <https"
  },
  {
    "path": "docs/source/conf.py",
    "chars": 1568,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\n# Configuration file "
  },
  {
    "path": "docs/source/design_preparation.rst",
    "chars": 1027,
    "preview": "Design Preparation\n==================\n\nPrior to running the RTL-to-bitstream flow, design data must be aggregated and or"
  },
  {
    "path": "docs/source/execution.rst",
    "chars": 238,
    "preview": "RTL-to-Bitstream Flow Execution\n===============================\n\nWithin your Python virtual environment or wherever you "
  },
  {
    "path": "docs/source/external_links.rst",
    "chars": 4302,
    "preview": "External Links for Open Source Tools\n====================================\n\nBelow is a set of links to documentation for "
  },
  {
    "path": "docs/source/index.rst",
    "chars": 944,
    "preview": "Logik Demo Edition\n==================\n\nWelcome to the demo edition of Logik.  In this edition, the following features ar"
  },
  {
    "path": "docs/source/pin_constraints.rst",
    "chars": 2957,
    "preview": "Preparing Pin Constraints and Placement Constraints\n===================================================\n\nExecution of th"
  },
  {
    "path": "docs/source/prerequisites.rst",
    "chars": 1334,
    "preview": "System Software Requirements\n============================\n\nSupported Operating Systems\n---------------------------\n\nThe "
  },
  {
    "path": "docs/source/sc_preparation.rst",
    "chars": 12853,
    "preview": "===========================================\n Preparing the Silicon Compiler Run Script\n================================="
  },
  {
    "path": "docs/source/timing_constraints.rst",
    "chars": 840,
    "preview": "Preparing Timing Constraints for VPR\n====================================\n\n.. note::\n\n   The demo architecture provided "
  },
  {
    "path": "docs/source/tool_installations.rst",
    "chars": 2214,
    "preview": "Installing Required Software\n============================\n\nThere are two ways to install the above software tools:\n    1"
  },
  {
    "path": "examples/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/adder/adder.pcf",
    "chars": 1771,
    "preview": "{\n  \"a[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[0]\"\n  },\n  \"a[1]\": {\n    \"direction\": \"input\",\n    \"pin\":"
  },
  {
    "path": "examples/adder/adder.py",
    "chars": 1261,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details"
  },
  {
    "path": "examples/adder/adder.v",
    "chars": 470,
    "preview": "/*******************************************************************************\n * Copyright 2024 Zero ASIC Corporation"
  },
  {
    "path": "examples/adder/pin_constraints.py",
    "chars": 2367,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport argparse\nimpor"
  },
  {
    "path": "examples/eth_mac_1g/constraints/z1000/pin_constraints.pcf",
    "chars": 21542,
    "preview": "{\n  \"rx_clk\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_clk[0]\"\n  },\n  \"rx_rst\": {\n    \"direction\": \"input\",\n    \""
  },
  {
    "path": "examples/eth_mac_1g/eth_mac_1g.py",
    "chars": 1875,
    "preview": "#!/usr/bin/env python3\n\n# This is the logik run script for demonstrating RTL-to-bitstream\n# with Alex Forencich's 1G Eth"
  },
  {
    "path": "examples/eth_mac_1g/eth_mac_1g.sdc",
    "chars": 62,
    "preview": "create_clock -period 16 rx_clk\ncreate_clock -period 16 tx_clk\n"
  },
  {
    "path": "examples/eth_mac_1g/eth_mac_1g_wrapper.v",
    "chars": 9091,
    "preview": "//eth_mac_1g_wrapper.v\n//Peter Grossmann\n//5 March 2025\n\n//This wraps up the eth_mac_1g module to hide the unused cfg pi"
  },
  {
    "path": "examples/picorv32/constraints/z1062/picorv32.pcf",
    "chars": 34097,
    "preview": "{\n  \"clk\": {\n    \"pin\": \"gpio_in_clk[0]\",\n    \"direction\": \"input\"\n  },\n  \"resetn\": {\n    \"pin\": \"gpio_in_west[10]\",\n   "
  },
  {
    "path": "examples/picorv32/picorv32.py",
    "chars": 1648,
    "preview": "#!/usr/bin/env python3\n\nimport siliconcompiler\nfrom logiklib.zeroasic.z1062 import z1062\nfrom siliconcompiler.tools.yosy"
  },
  {
    "path": "examples/picorv32/picorv32.sdc",
    "chars": 30,
    "preview": "create_clock -period 12.5 clk\n"
  },
  {
    "path": "logik/__init__.py",
    "chars": 131,
    "preview": "try:\n    from logik._version import __version__\nexcept ImportError:\n    # This only exists in installations\n    __versio"
  },
  {
    "path": "logik/devices/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "logik/devices/logik_fpga.py",
    "chars": 569,
    "preview": "from siliconcompiler.tools.opensta import OpenSTAFPGA\nfrom siliconcompiler.tools.vpr import VPRFPGA\nfrom siliconcompiler"
  },
  {
    "path": "logik/flows/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "logik/flows/logik_flow.py",
    "chars": 1423,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nfrom siliconcompiler."
  },
  {
    "path": "logik/tools/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "logik/tools/fasm_to_bitstream/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "logik/tools/fasm_to_bitstream/bitstream_bin_convert.py",
    "chars": 885,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details"
  },
  {
    "path": "logik/tools/fasm_to_bitstream/bitstream_finish.py",
    "chars": 2012,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nfrom siliconcompiler."
  },
  {
    "path": "logik/tools/fasm_to_bitstream/fasm_to_bitstream.py",
    "chars": 10292,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details"
  },
  {
    "path": "pyproject.toml",
    "chars": 1362,
    "preview": "[build-system]\nrequires = [\n    \"setuptools >= 80\",\n    \"setuptools_scm[toml] >= 8\"\n]\n\nbuild-backend = \"setuptools.build"
  },
  {
    "path": "tests/conftest.py",
    "chars": 1035,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\n\nimport pyt"
  },
  {
    "path": "tests/data/z1000.py",
    "chars": 1532,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n\nfrom logik.devices.logik_fpga import LogikFPGA\n\n\nclass z1000(LogikFPGA):\n    \"\"\""
  },
  {
    "path": "tests/examples/test_adder.py",
    "chars": 789,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\nimport subp"
  },
  {
    "path": "tests/examples/test_eth_mac_1g.py",
    "chars": 627,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\nimport subp"
  },
  {
    "path": "tests/examples/test_files.py",
    "chars": 329,
    "preview": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport siliconcompile"
  },
  {
    "path": "tests/examples/test_picorv32.py",
    "chars": 607,
    "preview": "# Copyright 2025 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\nimport subp"
  }
]

About this extraction

This page contains the full source code of the zeroasiccorp/logik GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 51 files (152.4 KB), approximately 45.6k tokens, and a symbol index with 45 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!