[
  {
    "path": ".flake8",
    "content": "[flake8]\nextend-exclude = testbench/build,build,.venv\nmax-line-length = 100\nignore =\n    E125,\n    E129,\n    E128,\n    W503\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  # Maintain dependencies for GitHub Actions\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      actions:\n        patterns:\n          - \"*\"\n  # Maintain dependencies for Python\n  - package-ecosystem: pip\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n    groups:\n      python-packages:\n        patterns:\n          - \"*\"\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "# Copyright (c) 2024 Zero ASIC Corporation\n# This code is licensed under Apache License 2.0 (see LICENSE for details)\n\n# modified from https://github.com/siliconcompiler/siliconcompiler/blob/main/.github/workflows/lint.yml\n\nname: Lint\non:\n  pull_request:\n  workflow_dispatch:\n  push:\n    branches:\n      - main\n\njobs:\n  lint_python:\n    name: Lint Python Code\n    runs-on: ubuntu-latest\n    timeout-minutes: 5\n\n    steps:\n      - name: Check out Git repository\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Set up Python 3.10\n        uses: actions/setup-python@v6\n        with:\n          python-version: '3.10'\n\n      - name: Setup permissions\n        run: |\n          echo ${{ secrets.ZA_TOKEN }} | gh auth login --with-token\n          gh auth setup-git\n          git config --global url.\"https://github\".insteadOf git://github\n\n      - name: Install Requirements\n        run: |\n          python3 -m pip install --upgrade pip\n          pip install .[test]\n\n      - name: Lint with Flake8\n        run: flake8 --statistics .\n"
  },
  {
    "path": ".github/workflows/regression.yml",
    "content": "---\n\nname: Regression\non:\n  workflow_dispatch:\n  pull_request:\n  push:\n    branches:\n      - main\n\njobs:\n  version-compatibility:\n    name: Test Python ${{ matrix.python-version }} with ${{ matrix.resolution }} deps\n\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [\"3.10\", \"3.14\"]\n        resolution: [\"highest\", \"lowest-direct\"]\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n\n      - name: Install uv\n        uses: astral-sh/setup-uv@v7\n\n      - name: Install dependencies with ${{ matrix.resolution }} resolution\n        run: |\n          uv pip install --system --resolution ${{ matrix.resolution }} -e .[test]\n\n      - name: Verify installation and imports\n        run: |\n          python -c \"import logik; import siliconcompiler; print('✓ Imports successful')\"\n          python -c \"from logik.flows.logik_flow import LogikFlow; print('✓ LogikFlow imported')\"\n\n      - name: Run basic tests (no CAD tools)\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          pytest tests/examples/test_files.py -v\n\n  pytest:\n    name: Run CAD flow tests\n\n    runs-on: ubuntu-latest\n    container:\n      image: ghcr.io/siliconcompiler/sc_runner:latest\n\n    env:\n      GIT_TOKEN: ${{ secrets.ZA_TOKEN }}\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Setup permissions\n        run: |\n          apt update && apt install sudo -y\n          type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)\n          curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \\\n          && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \\\n          && 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 \\\n          && sudo apt update \\\n          && sudo apt install gh -y\n\n          echo ${{ secrets.ZA_TOKEN }} | gh auth login --with-token\n          gh auth setup-git\n\n      - name: Setup git access\n        run: |\n          git config --global --add url.\"https://github.com/\".insteadOf git@github.com:\n          git config --global --add safe.directory \"$GITHUB_WORKSPACE\"\n\n      - name: Setup python\n        run: |\n          python3 -m venv --system-site-packages .logik\n          . .logik/bin/activate\n          python3 -m pip install --upgrade pip\n          pip3 install -e .[test]\n\n      - name: Run tests\n        run: |\n          . .logik/bin/activate\n          pytest\n"
  },
  {
    "path": ".github/workflows/wheels.yml",
    "content": "name: Wheels\n\non:\n  workflow_dispatch:\n  release:\n    types:\n      - published\n\njobs:\n  build_wheels:\n    name: Wheels\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v6\n      with:\n        submodules: true\n        fetch-depth: 0\n\n    - uses: hynek/build-and-inspect-python-package@v2\n\n  publish:\n    needs: [build_wheels]\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n    if: github.event_name == 'release' && github.event.action == 'published'\n\n    steps:\n    - uses: actions/download-artifact@v8\n      with:\n        name: Packages\n        path: dist\n\n    - name: Publish\n      uses: pypa/gh-action-pypi-publish@v1.14.0\n\n  save:\n    needs: [publish]\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: write\n\n    steps:\n    - uses: actions/download-artifact@v8\n      with:\n        name: Packages\n        path: dist\n\n    - name: Add wheels to GitHub release artifacts\n      uses: softprops/action-gh-release@v3\n      with:\n        files: dist/*.whl\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n#   For a library or package, you might want to ignore these files since the code is\n#   intended to run in multiple environments; otherwise, check them in:\n# .python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# poetry\n#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.\n#   This is especially recommended for binary packages to ensure reproducibility, and is more\n#   commonly ignored for libraries.\n#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control\n#poetry.lock\n\n# pdm\n#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.\n#pdm.lock\n#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it\n#   in version control.\n#   https://pdm.fming.dev/#use-with-ide\n.pdm.toml\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# PyCharm\n#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can\n#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore\n#  and can be added to the global gitignore or merged into this file.  For a more nuclear\n#  option (not recommended) you can uncomment the following to ignore the entire idea folder.\n#.idea/\n\n# Emacs backup files\n*~\n\n# Switchboard\n*.q\n\n# scm version\nlogik/_version.py\n"
  },
  {
    "path": ".readthedocs.yaml",
    "content": "# .readthedocs.yaml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details\n\n# Required\nversion: 2\n\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.11\"\n    \n# Build documentation in the docs/ directory with Sphinx\nsphinx:\n  configuration: docs/source/conf.py\n\nformats:\n  - pdf\n\npython:\n    install:\n    - method: pip\n      path: .\n      extra_requirements:\n        - docs\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2025 Zero ASIC Corporation\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "Logik\n-------------------------------------------------------------\n\n[![Regression](https://github.com/siliconcompiler/logik/actions/workflows/regression.yml/badge.svg)](https://github.com/siliconcompiler/logik/actions/workflows/regression.yml)\n[![Lint](https://github.com/siliconcompiler/logik/actions/workflows/lint.yml/badge.svg)](https://github.com/siliconcompiler/logik/actions/workflows/lint.yml)\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\nLogik 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.\n\n![logik_flow](images/logik-plus-open-sta-flow.png)\n\nLogik supports most of the features you would expect in a commercial proprietary FPGA tool chain.\n\n| Feature                  | Status |\n|--------------------------|--------|\n| Design languages         | SystemVerilog, Verilog, VHDL\n| DSP synthesis            | Supported\n| RAM synthesis            | Supported\n| Timing constraints (SDC) | Supported\n| Pin Constraints (PCF)    | Supported\n| Bitstream generation     | Supported\n| IP management            | Supported\n| Remote compilation       | Supported\n| Multi-clock designs      | Supported\n| Supported devices        | Logiklib devices\n\n## Getting Started\n\nThe Logik tool chain is available through PyPi and can be installed using pip.\n\n```sh\npython -m pip install --upgrade logik\n```\n\nAll open source FPGA pre-requisites can be installed via the SiliconCompiler `sc-install` utility.\n\n```sh\nsc-install -group fpga\n```\n\nThe 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).\n\n```python\n\nimport siliconcompiler\nfrom logik.flows.logik_flow import LogikFlow\nfrom logiklib.zeroasic.z1000 import z1000\n\n# 1. Create a Design object to hold source files and constraints.\ndesign = siliconcompiler.Design('adder')\ndesign.add_file('adder.v', fileset=\"rtl\")\ndesign.set_topmodule('adder', fileset=\"rtl\")\n\n# Create an FPGA project\nproject = siliconcompiler.FPGA(design)\n\n# Assign file sets to use for elaboration\nproject.add_fileset('rtl')\n\n# Select the rtl2bits flow to use\nproject.set_flow(LogikFlow())\n\n# Load FPGA part settings and associated flow and libraries.\nproject.set_fpga(z1000.z1000())\n\n# User defined options\nproject.option.set_quiet(True)\n\n# Run compilation\nproject.run()\n\n# Display summary of results\nproject.summary()\n\n```\n\n> [!NOTE]\n> The required files can be found [here](https://github.com/siliconcompiler/logik/tree/main/examples/adder)\n\n## Examples\n\n* [Ethernet](./examples/eth_mac_1g/eth_mac_1g.py): Ethernet MAC compiled for the `z1000` architecture.\n* [Adder](examples/adder/adder.py): Small adder example compiled for the `z1000` architecture.\n* [Picorv32](examples/picorv32/picorv32.py): picorv32 RISC-V CPU example compiled for the `z1062` architecture.\n\n## Documentation\n\n* [Logik Documentation](https://logik.readthedocs.io/en/latest/)\n* [SiliconCompiler Documentation](https://docs.siliconcompiler.com/en/stable/)\n\n\n## Installation\n\nLogik is available as wheel packages on PyPI for macOS, Windows and Linux platforms. For working Python >= 3.10 environments, just use `pip` to install.\n\n```sh\npython -m pip install --upgrade logik\n```\n\nRunning natively on your local machine will require installing a number of prerequisites:\n\n* [Silicon Compiler](https://github.com/siliconcompiler/siliconcompiler): Hardware compiler framework\n* [Slang](https://github.com/MikePopoloski/slang): SystemVerilog Parser\n* [Yosys](https://github.com/YosysHQ/yosys): Logic synthesis platform\n* [Wildebeest](https://github.com/zeroasiccorp/wildebeest): High-performance synthesis yosys plugin\n* [VPR](https://github.com/verilog-to-routing/vtr-verilog-to-routing): FPGA place and route\n* [FASM](https://github.com/chipsalliance/fasm): FPGA assembly parser and generator\n* [OpenSTA](https://github.com/The-OpenROAD-Project/OpenSTA): Production-grade static timing analysis engine\n\nWe recommend using the SiliconCompiler `sc-install` utility to automatically install the correct versions of all open source FPGA tool dependencies.\n\n```sh\nsc-install -group fpga\n```\n\nDetailed installation instructions can be found in the [SiliconCompiler Installation Guide](https://docs.siliconcompiler.com/en/stable/user_guide/installation.html#external-tools).\n\n\n## License\n\nThe Logik project is licensed under the open source [Apache License 2.0](LICENSE). For licensing terms of all dependencies, visit dependency repository.\n\n## Issues / Bugs\nWe use [GitHub Issues](https://github.com/siliconcompiler/logik/issues) for tracking requests and bugs.\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\n# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = source\nBUILDDIR      = build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs/make.bat",
    "content": "@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=sphinx-build\r\n)\r\nset SOURCEDIR=source\r\nset BUILDDIR=build\r\n\r\n%SPHINXBUILD% >NUL 2>NUL\r\nif errorlevel 9009 (\r\n\techo.\r\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r\n\techo.installed, then set the SPHINXBUILD environment variable to point\r\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\r\n\techo.may add the Sphinx directory to PATH.\r\n\techo.\r\n\techo.If you don't have Sphinx installed, grab it from\r\n\techo.https://www.sphinx-doc.org/\r\n\texit /b 1\r\n)\r\n\r\nif \"%1\" == \"\" goto help\r\n\r\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r\ngoto end\r\n\r\n:help\r\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r\n\r\n:end\r\npopd\r\n"
  },
  {
    "path": "docs/source/bitstream_format.rst",
    "content": "Bitstream Formatting\n====================\n\nBitstream data is generated in this flow in multiple formats:\n\n* `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.\n* 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.\n* 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.\n\nUnderstanding the details of bitstream formatting is typically necessary only for writing software drivers to perform bitstream loading for particular FPGA chips.\n\nThe following sections outline how bitstreams are organized in a general sense without specifying the bitstream format for a particular FPGA or eFPGA architecture.\n\nWorking with FASM Bitstream Data\n--------------------------------\n\nA 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.\n\nEnd 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/>`_\n\nWorking with JSON Bitstream Data\n--------------------------------\n\nJSON is used as the file format for storing an intermediate representation (IR) of bitstream data between FASM and binary formats.\n\nThe 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.\n\nFor 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.\n\n.. note::\n\n   Architecture bitstream map files are cached by Silicon Compiler for use within the flow and may not be easily accessible by end users.\n\nWorking with Binary Bitstream Data\n----------------------------------\n\nThe 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\n\n+-------------------------+------------------------------+------------------------+\n| most significant bits   | next most significant bits   | least significant bits |\n+-------------------------+------------------------------+------------------------+\n| Y coordinate            | X coordinate                 | word address           |\n+-------------------------+------------------------------+------------------------+\n\nWhen mapped into this address space, bitstream words are ordered from lowest address value to highest address value.\n\nThe 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.\n\nTo 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:\n\n+--------------+--------------+--------------+\n| [17:13]      | [12:8]       | [7:0]        |\n+--------------+--------------+--------------+\n| Y coordinate | X coordinate | word address |\n+--------------+--------------+--------------+\n\nThe 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).\n"
  },
  {
    "path": "docs/source/conf.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\n# Configuration file for the Sphinx documentation builder.\n#\n# For the full list of built-in configuration values, see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\nimport datetime\n\nimport logik\n\n\n# -- Project information -----------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information\n\nproject = \"Logik\"\ncopyright = (\n    f\"2024-{datetime.datetime.now(tz=datetime.timezone.utc).date().year}, Zero ASIC\"\n)\nauthor = \"Zero ASIC\"\nrelease = logik.__version__\n\n# -- General configuration ---------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration\n\nextensions = [\n    \"sphinx.ext.autodoc\",  # automatically generate documentation for modules\n    \"sphinx.ext.napoleon\",  # to read Google-style or Numpy-style docstrings\n    \"sphinx.ext.viewcode\",  # to allow vieing the source code in the web page\n    \"autodocsumm\",  # to generate tables of functions, attributes, methods, etc.\n]\n\ntemplates_path = [\"_templates\"]\nexclude_patterns = []\n\nroot_doc = \"index\"\n\n\n# -- Options for HTML output -------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output\n\nhtml_theme = \"sphinx_rtd_theme\"\n\nautodoc_inherit_docstrings = False\nautodoc_typehints = \"description\"\n# include __init__ docstrings\nautoclass_content = \"both\"\n"
  },
  {
    "path": "docs/source/design_preparation.rst",
    "content": "Design Preparation\n==================\n\nPrior 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.\n\nCreate a Working Directory\n--------------------------\n\nBecause 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.\n\nAggregate Input Files\n---------------------\n\nThe following file types should be aggregated\n\n* HDL files\n* Timing Constraints\n* Pin Constraints\n\nWith these in place, a Silicon Compiler run script will have all required input files for execution.\n\n"
  },
  {
    "path": "docs/source/execution.rst",
    "content": "RTL-to-Bitstream Flow Execution\n===============================\n\nWithin your Python virtual environment or wherever you have installed Silicon Copmiler, simply execute your Silicon Compiler run script\n\n::\n\n   python3 <your_sc_run_script>\n"
  },
  {
    "path": "docs/source/external_links.rst",
    "content": "External Links for Open Source Tools\n====================================\n\nBelow 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.\n\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| F4PGA (FASM format authors)  | `F4PGA Github <https://github.com/chipsalliance/f4pga>`_                     | `F4PGA Documentation <https://f4pga.org/>`_                            |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| GHDL                         | `GHDL Github <https://github.com/ghdl/ghdl>`_                                | `GHDL Documentation <https://ghdl.github.io/ghdl/>`_                   |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| GTKWave                      | `Gtkwave Github <https://github.com/gtkwave/gtkwave>`_                       | `Gtkwave Documentation <https://gtkwave.sourceforge.net/>`_            |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| Icarus Verilog               | `Icarus Github <https://github.com/steveicarus/iverilog>`_                   | `Icarus Documentation <https://steveicarus.github.io/iverilog/>`_      |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| Silicon Compiler             | `SC Github <https://github.com/siliconcompiler/siliconcompiler>`_            | `SC Documentation <https://docs.siliconcompiler.com/en/stable>`_       |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| slang                        | `slang Github <https://github.com/MikePopoloski/slang>`_                     |                                                                        |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| Verilator                    | `Verilator Github <https://github.com/verilator/verilator>`_                 | `Verilator Documentation <https://verilator.org/guide/latest/>`_       |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| Verilog-to-Routing (VPR)     | `VPR Github <https://github.com/verilog-to-routing/vtr-verilog-to-routing>`_ | `VPR Documentation <https://docs.verilogtorouting.org/en/latest/>`_    |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| Wildebeest                   | `Wildebeest Github <https://github.com/zeroasiccorp/wildebeest>`_            |                                                                        |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n| Yosys                        | `Yosys Github <https://github.com/YosysHQ/yosys>`_                           | `Yosys Documentation <https://yosyshq.readthedocs.io/en/latest/>`_     |\n+------------------------------+------------------------------------------------------------------------------+------------------------------------------------------------------------+\n"
  },
  {
    "path": "docs/source/index.rst",
    "content": "Logik Demo Edition\n==================\n\nWelcome to the demo edition of Logik.  In this edition, the following features are showcased:\n\n* RTL to bitstream automation flow for FPGA/eFPGA architectures, powered by `Silicon Compiler <https://www.siliconcompiler.com>`_\n* Integration with logiklib, a catalog repository of FPGA/eFPGA architectures\n\n* Example designs for reference in adopting the flow\n* Documentation providing step-by-step guidance for setup and execution of the flow\n  \nDocumentation Table of Contents\n===============================\n\n.. toctree::\n    :maxdepth: 2\n    :caption: Usage\n    \n    prerequisites\n    tool_installations\n    design_preparation\n    sc_preparation\n    execution\n\n.. toctree::\n    :maxdepth: 1\n    :caption: References\n\n    timing_constraints\t      \n    pin_constraints\n    bitstream_format\n    external_links\n    \n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n"
  },
  {
    "path": "docs/source/pin_constraints.rst",
    "content": "Preparing Pin Constraints and Placement Constraints\n===================================================\n\nExecution 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.\n\nIn 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.\n\nThe methods of supplying these constraints are described below.\n\nVPR Placement Constraints\n-------------------------\n\nVPR 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/>`_.\n\nTo 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.\n\nUse 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.\n\nIf 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.\n\n\nJSON Pin Constraints (PCF)\n--------------------------\nSpecifying 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.\n\nThe 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:\n\nExample Pin Constraint Syntax\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n   \n  \"resetn\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in[1]\"\n  },\n\n"
  },
  {
    "path": "docs/source/prerequisites.rst",
    "content": "System Software Requirements\n============================\n\nSupported Operating Systems\n---------------------------\n\nThe following operating systems are supported without the requirement of running within a docker container:\n\n* Ubuntu 20.04\n\nAdditional OS support is provided by running within a docker container.\n\nGeneral Purpose Software Requirements\n-------------------------------------\n\nThe following general purpose software must be installed on your system to use this flow:\n\n* Python 3.10 or higher\n* git\n\nRequired EDA Software Tools\n---------------------------\n\n* Silicon Compiler\n* Yosys\n* VPR\n\nFor VHDL support, GHDL is also required.\n\nFor SystemVerilog support, slang is also required.\n\nFor links to all EDA software Github repositories and documentation pages, please consult the :doc:`external_links`.\n\nOptional EDA Software Tools\n---------------------------\n\nWhile not required to run the RTL-to-bitstream flow, HDL simulation support is required to run HDL simulations on provided examples.\n\nEither of the following open-source simulators may be used for HDL simulation:\n\n* Icarus Verilog\n* Verilator\n  \nFor waveform viewing, there are a few open source viewers to choose from:\n\n* Surfer\n* GTKWave\n  \nFor links to all EDA software Github repositories and documentation pages, please consult the :doc:`external_links`.\n\n"
  },
  {
    "path": "docs/source/sc_preparation.rst",
    "content": "===========================================\n Preparing the Silicon Compiler Run Script\n===========================================\n\nDeveloping 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.\nAdditional resources for understanding Silicon Compiler fundamentals are available at `docs.siliconcompiler.com <https://docs.siliconcompiler.com/en/stable>`_\n\nFor most designs, the example Silicon Compiler run scripts provided with Logik can be used as templates for creating your own.\nThe commands used in these examples and the general method for constructing run scripts are described below.\n\nConstructing a Silicon Compiler run script can be broken down into the following steps:\n\n* :ref:`import_modules`\n* :ref:`Create_main_function`\n* :ref:`Create_design_object`\n* :ref:`Select_part_name`\n* :ref:`Import_libraries`\n* :ref:`Set_timing_constraints`\n* :ref:`Set_pin_constraints`\n* :ref:`Create_project_object`\n* :ref:`Select_part_name`\n* :ref:`Select_flow`\n* :ref:`Add_options`\n* :ref:`Add_execution_calls`\n  \n.. _import_modules:\n\nImport Modules\n==============\n\nAll Silicon Compiler run scripts are pure Python scripts that import Silicon Compiler functionality like any other Python module.\nSimilarly, the Logik RTL-to-bitstream flow is enabled as a set of Python modules that integrate to Silicon Compiler.\n\nThe minimum import requirements in a Logik Silicon Compiler run script are:\n\n::\n\n   import siliconcompiler\n   from logik.targets import logik_target\n\n\nAdditional module imports may be required depending on project-specific requirements.\n\n.. _Create_main_function:\n\nCreate Main Function\n====================\n\nSince 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.\nIn most design flows, the most convenient way to enable this will be to simply encapsulate the script in a `main()` function:\n\nIn Python, an executable `main()` function is implemented with the following code:\n\n::\n\n   def main(<main_function_parameters (optional)>):\n\n       #Insert your main function here\n\n   if __name__ == \"__main__\":\n       main()\n\nExperienced Python programmers may prefer to use their own scripting methodology for executing the script instead of the above.\nAny approach that conforms to both Python and Silicon Compiler requirements should work.\n\n.. _Create_design_object:\n\nCreate Design Object\n====================\n\nSilicon Compiler design information is encapsulated in a Python class called Design.\n\nThe Design class constructor requires one parameter: the name of the top level module in your RTL design.\nA complete Design instantiation takes the form\n\n::\n\n   design = siliconcompiler.Design('<your_top_module_name>')\n\n\nAll design-specific data is housed within this class; it should be the first (or nearly the first) line in your main function.\n\nThroughout this documentation, \"design\" will be used to refer to the Design class instance.\nHowever, there is no requirement that the instance be assigned to this variable name.\n\n.. _Import_libraries:\n\nAdd Source Files\n================\n\nAll HDL source files must be added to the Silicon Compiler design object for inclusion.  Adding source files is a two-step process:\n\n1.  Set source file data root\n2.  Add all source files located at the given data root\n\nThe procedure below may be repeated for as many data roots as required.\n\n.. _Set_dataroot:\n\nSetting a Source File Data Root\n-------------------------------\n\nSetting a source file data root achieves two goals:\n\n1.  It defines a group of source files housed in a common directory tree as a named IP package in Silicon Compiler\n2.  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).\n\nTo name a IP package and specify its data root, the `set_dataroot` member function of the Design class is called:\n::\n\n    design.set_dataroot(<package_name>, <package_location>, [version])\n\n`<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.\n\n.. _Set_input_source_files:\n\nAdding Source Files\n-------------------\n\nFor each HDL file, include the following call in your Silicon Compiler run script\n\n::\n\n   with design.active_dataroot(<package_name>):\n       design.add_file(<your_hdl_file_name>, fileset=<fileset_name>)\n\nEnclosing 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.\n\nSpecifying 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>`_\n\n.. note::\n\n   Silicon Compiler supports multiple front end options, including flows for high-level synthesis.\n   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>`_\n\nFor large designs, the above calls can be integrated into loops that iterate over lists of files\n\n.. _Set_timing_constraints:\n\nSet Timing Constraints\n======================\n\n.. note::\n\n   The demo architecture provided with this distrbution implements a unit delay model.\n   Provided examples demonstrate the RTL-to-bitstream flow without an SDC file.\n\nTiming 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:\n\n::\n\n   with design.active_dataroot(<package_name>):\n       design.add_file('<your_sdc_file_name>', fileset=<sdc_fileset>)\n\n.. note::\n\n   If no SDC file is provided, the flow will still run to completion.\n   Timing analysis will be disabled during the place and route steps.\n\n.. _Set_pin_constraints:\n\nSet Pin Constraints\n===================\n\nPin constraints may be provided in one of two files:\n\n* A JSON pin constraints file (PCF)\n* A VPR XML placement constraints file\n\n.. note::\n\n   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.\n\nJSON Pin Constraint Specification\n---------------------------------\n\nThe JSON pin constraint file is unique to this flow.\nFor additional information on creating the JSON pin constraint file, see :doc:`pin_constraints`.\n\nThe 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:\n\n::\n\n   with design.active_dataroot(<package_name>):\n      design.add_file('<your_pcf_file_name>', fileset=<pcf_fileset>)\n\n.. note::\n\n   The .pcf file extension must be used\n\nVPR XML Placement Constraint Specification\n------------------------------------------\n\nVPR XML placement constraints are portable to any VPR-based place and route flow.\nFor 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/>`_.\n\nThe XML placement constraints file must be added to the Silicon Compiler Design object for inclusion.\n\n::\n   \n   with design.active_dataroot(<package_name>):\n      design.add_file('<your_xml_file_name>', fileset=<xml_fileset>)\n\nin your Silicon Compiler run script.\n\n.. _Create_project_object:\n\nCreate Project Object\n=====================\n\nSilicon 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.\n\nWhen using Logik, a specialized Project object for FPGAs is used; this object is of type FPGA.\n\nThe FPGA class constructor requires one parameter: an instance of a Design object.  In your run script, you can instantiate this as follows:\n\n::\n\n   project = siliconcompiler.FPGA('<your_design_name>')\n\n\nFollowing the variable names used above, `<your_design_name>` would be replaced with `design`.\n\nAdd filesets to Project\n-----------------------\n\nAll 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:\n\n::\n\n    project.add_fileset('rtl')\n    project.add_fileset('sdc')\n    project.add_fileset('pcf')\n\n.. _Select_part_name:\n\nSelect Part Name\n================\n\nSilicon 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.\n\nBecause 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.\n\nAt the top of your Python run script, include an `import` statement to import the FPGA part for your project:\n\n::\n\n   from logiklib.<vendor>.<part_name> import <part_name>\n\nThe 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\n\n::\n\n   from logiklib.zeroasic.z1000 import z1000\n\nThe presense of this `import` statement allows the z1000 FPGA to be selected for use in the project using the `set_fpga()` function:\n\n::\n\n   project.set_fpga(<part_name>)\n\n.. _Select_flow:\n\nSelect Flow\n===========\n\nLogik'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:\n\n::\n\n   from logik.flows.logik_flow import LogikFlow\n\nand then set it accordingly:\n\n::\n\n   project.set_flow(LogikFlow())\n\n.. _Add_options:\n\nAdd Design and Project Options\n==============================\n\nNumerous 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.\n\nSome options are configured on a per-design basis; others on a per-project basis.\nFor 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>`_.\n\nIn particular, any compiler directives that are required for HDL synthesis should be specified as Silicon Compiler options.\nThese are furnished with Design class member function calls of the form\n\n::\n\n   design.add_define(<compiler_directive>, fileset=<fileset>)\n\n\nSimilarly, any HDL parameters that must be set explicitly for synthesis can be set with the `set_param()` function:\n\n::\n\n   design.set_param(<parameter>, <value>, fileset=<fileset>)\n\nIn both cases, `<fileset>` should have the same value as that used for HDL files (e.g. `rtl`).\n   \n.. _Add_execution_calls:\n\nAdd Execution Calls\n===================\n\nThe final two lines of every run script should be the same:\n\n::\n   \n   project.run()\n   project.summary()\n   \nThe `run()` call invokes the RTL-to-bitstream flow with all settings specified.\nThe `summary()` call reports results of the run in tabular form.\nIncluded in the summary results are key design metrics such as FPGA resource utilization and tool execution runtimes.\n"
  },
  {
    "path": "docs/source/timing_constraints.rst",
    "content": "Preparing Timing Constraints for VPR\n====================================\n\n.. note::\n\n   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.\n\nVPR 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.\n\nThe minimum requirement is to specify a target clock frequency using the `create_clock` constraint:\n\n::\n   \n   create_clock -period <float> <name of clock port>\n\nFor specifics on VPR's supported timing constraints, please consult the `VPR SDC Commmand support page <https://docs.verilogtorouting.org/en/latest/vpr/sdc_commands/>`_\n"
  },
  {
    "path": "docs/source/tool_installations.rst",
    "content": "Installing Required Software\n============================\n\nThere are two ways to install the above software tools:\n    1. Run within the Silicon Compiler tools docker image\n    2. Use Silicon Compiler's sc-install command\n    3. Build from source yourself\n\nSilicon Compiler Tools Docker Image Setup\n-----------------------------------------\n\nFirst, install Docker according to the instructions for your operating system:\n\n* `Linux Docker installation <https://docs.docker.com/desktop/install/linux-install/>`_\n* `macOS Docker installation <https://docs.docker.com/desktop/install/mac-install/>`_\n* `Windows Docker installation <https://docs.docker.com/desktop/install/windows-install/>`_\n\nOnce Docker is installed, launch the Docker Desktop application.\n\n* Ubuntu: `Ctrl`-`Alt`-`T` or run the Terminal application from the Dash\n* macOS: `Cmd-Space` to open Spotlight, then type `Terminal` and press `Enter`\n* Windows: Open `Windows PowerShell` from the Start menu.\n\n::\n   \n   docker run -it -v \"${PWD}/sc_work:/sc_work\" ghcr.io/siliconcompiler/sc_runner:latest\n       \nSilicon Compiler sc-install Tool\n--------------------------------\n\nWhen Silicon Compiler has been installed in your Python virtual environment, all required software can be installed by running\n\n::\n\n   sc-install -group fpga\n   sc-install opensta\n\nBuilding Software From Source\n-----------------------------\n\nSeveral resources are offered to assist in the installation process when tools need to be built from source.\n\nSilicon 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>`_\n\nAdditionally, 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.\n\n\n\n\n"
  },
  {
    "path": "examples/__init__.py",
    "content": ""
  },
  {
    "path": "examples/adder/adder.pcf",
    "content": "{\n  \"a[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[0]\"\n  },\n  \"a[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[1]\"\n  },\n  \"a[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[2]\"\n  },\n  \"a[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[3]\"\n  },\n  \"a[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[4]\"\n  },\n  \"a[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[5]\"\n  },\n  \"a[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[6]\"\n  },\n  \"a[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_1[7]\"\n  },\n  \"b[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[0]\"\n  },\n  \"b[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[1]\"\n  },\n  \"b[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[2]\"\n  },\n  \"b[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[3]\"\n  },\n  \"b[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[4]\"\n  },\n  \"b[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[5]\"\n  },\n  \"b[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[6]\"\n  },\n  \"b[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"pad_in_0_2[7]\"\n  },\n  \"y[0]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[0]\"\n  },\n  \"y[1]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[1]\"\n  },\n  \"y[2]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[2]\"\n  },\n  \"y[3]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[3]\"\n  },\n  \"y[4]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[4]\"\n  },\n  \"y[5]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[5]\"\n  },\n  \"y[6]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[6]\"\n  },\n  \"y[7]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_1_0[7]\"\n  },\n  \"y[8]\": {\n    \"direction\": \"output\",\n    \"pin\": \"pad_out_2_0[0]\"\n  }\n}\n"
  },
  {
    "path": "examples/adder/adder.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport siliconcompiler\nfrom logiklib.zeroasic.z1000 import z1000\n\nfrom logik.flows.logik_flow import LogikFlow\n\n\ndef hello_adder():\n    # Create a Design object to hold source files and constraints.\n    design = siliconcompiler.Design(\"adder\")\n\n    design.set_dataroot(\"adder\", __file__)\n    with design.active_dataroot(\"adder\"):\n        design.add_file(\"adder.v\", fileset=\"rtl\")\n        design.set_topmodule(\"adder\", fileset=\"rtl\")\n\n    # Create an FPGA object with a -remote command line option\n    project = siliconcompiler.FPGA.create_cmdline(switchlist=[\"-remote\"])\n    project.set_design(design)\n\n    project.add_fileset(\"rtl\")\n\n    # Create an FPGA object and associate the design with it.\n    fpga = z1000.z1000()\n\n    # Load the specific FPGA part, which also sets the default flow and libraries.\n    project.set_fpga(fpga)\n\n    #  Use the specific flow for this build.\n    project.set_flow(LogikFlow())\n\n    # Customize steps for this design\n    project.option.set_quiet(True)\n\n    # Run the compilation.\n    project.run()\n\n    # Display the results summary.\n    project.summary()\n\n\nif __name__ == \"__main__\":\n    hello_adder()\n"
  },
  {
    "path": "examples/adder/adder.v",
    "content": "/*******************************************************************************\n * Copyright 2024 Zero ASIC Corporation\n *\n * Licensed under the MIT License (see LICENSE for details)\n ******************************************************************************/\n\nmodule adder\n  # (\n     parameter DATA_WIDTH = 8\n     )\n   (\n    input [(DATA_WIDTH-1):0] a,\n    input [(DATA_WIDTH-1):0] b,\n    output [(DATA_WIDTH):0] y\n    );\n\n   assign y = a + b;\n\nendmodule // adder\n"
  },
  {
    "path": "examples/adder/pin_constraints.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport argparse\nimport json\nimport os\n\n\ndef main():\n    option_parser = argparse.ArgumentParser()\n    # Command-line options\n    option_parser.add_argument(\n        \"part_name\",\n        help=\"specify part number to prep, or specify all to build all parts in parts catalog\",\n    )\n\n    options = option_parser.parse_args()\n    part_name = options.part_name\n\n    if part_name == \"raw\":\n        pin_constraints = generate_raw_constraints()\n    else:\n        pin_constraints = generate_mapped_constraints(part_name)\n\n    write_json_constraints(\n        pin_constraints,\n        os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            f\"pin_constraints_{part_name}.pcf\",\n        ),\n    )\n\n\ndef generate_mapped_constraints(part_name):\n\n    pin_constraints = {}\n\n    if part_name == \"logik_demo\":\n        for i in range(8):\n            pin_constraints[f\"a[{i}]\"] = {\"direction\": \"input\", \"pin\": f\"gpio_in[{i}]\"}\n\n        for i in range(8):\n            pin_constraints[f\"b[{i}]\"] = {\n                \"direction\": \"input\",\n                \"pin\": f\"gpio_in[{i + 8}]\",\n            }\n\n        for i in range(9):\n            pin_constraints[f\"y[{i}]\"] = {\n                \"direction\": \"output\",\n                \"pin\": f\"gpio_out[{i + 16}]\",\n            }\n\n    else:\n        print(f\"ERROR: unsupported part name {part_name}\")\n\n    return pin_constraints\n\n\ndef generate_raw_constraints():\n\n    pin_constraints = {}\n\n    for i in range(8):\n        pin_constraints[f\"a[{i}]\"] = {\"direction\": \"input\", \"pin\": f\"pad_in_1_2[{i}]\"}\n\n    for i in range(8):\n        pin_constraints[f\"b[{i}]\"] = {\"direction\": \"input\", \"pin\": f\"pad_in_1_3[{i}]\"}\n\n    for i in range(9):\n        if i < 8:\n            pin_constraints[f\"y[{i}]\"] = {\n                \"direction\": \"output\",\n                \"pin\": f\"pad_out_1_4[{i}]\",\n            }\n        else:\n            pin_constraints[f\"y[{i}]\"] = {\n                \"direction\": \"output\",\n                \"pin\": f\"pad_out_1_5[{i - 8}]\",\n            }\n\n    return pin_constraints\n\n\ndef write_json_constraints(constraints, filename):\n\n    with open(filename, \"w\") as json_file:\n        json_file.write(json.dumps(constraints, indent=2))\n        json_file.write(\"\\n\")\n        json_file.close()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/eth_mac_1g/constraints/z1000/pin_constraints.pcf",
    "content": "{\n  \"rx_clk\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_clk[0]\"\n  },\n  \"rx_rst\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[0]\"\n  },\n  \"tx_clk\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_clk[1]\"\n  },\n  \"tx_rst\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[1]\"\n  },\n  \"tx_axis_tdata[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[2]\"\n  },\n  \"tx_axis_tdata[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[3]\"\n  },\n  \"tx_axis_tdata[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[4]\"\n  },\n  \"tx_axis_tdata[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[5]\"\n  },\n  \"tx_axis_tdata[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[6]\"\n  },\n  \"tx_axis_tdata[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[7]\"\n  },\n  \"tx_axis_tdata[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[8]\"\n  },\n  \"tx_axis_tdata[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[9]\"\n  },\n  \"tx_axis_tvalid\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[10]\"\n  },\n  \"tx_axis_tlast\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[11]\"\n  },\n  \"tx_axis_tuser\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[12]\"\n  },\n  \"gmii_rxd[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[13]\"\n  },\n  \"gmii_rxd[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[14]\"\n  },\n  \"gmii_rxd[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[15]\"\n  },\n  \"gmii_rxd[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[16]\"\n  },\n  \"gmii_rxd[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[17]\"\n  },\n  \"gmii_rxd[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[18]\"\n  },\n  \"gmii_rxd[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[19]\"\n  },\n  \"gmii_rxd[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[20]\"\n  },\n  \"gmii_rx_dv\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[21]\"\n  },\n  \"gmii_rx_er\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[22]\"\n  },\n  \"tx_ptp_ts[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[23]\"\n  },\n  \"tx_ptp_ts[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[24]\"\n  },\n  \"tx_ptp_ts[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[25]\"\n  },\n  \"tx_ptp_ts[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[26]\"\n  },\n  \"tx_ptp_ts[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[27]\"\n  },\n  \"tx_ptp_ts[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[28]\"\n  },\n  \"tx_ptp_ts[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[29]\"\n  },\n  \"tx_ptp_ts[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[30]\"\n  },\n  \"tx_ptp_ts[8]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[31]\"\n  },\n  \"tx_ptp_ts[9]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[32]\"\n  },\n  \"tx_ptp_ts[10]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[33]\"\n  },\n  \"tx_ptp_ts[11]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[34]\"\n  },\n  \"tx_ptp_ts[12]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[35]\"\n  },\n  \"tx_ptp_ts[13]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[36]\"\n  },\n  \"tx_ptp_ts[14]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[37]\"\n  },\n  \"tx_ptp_ts[15]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[38]\"\n  },\n  \"tx_ptp_ts[16]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[39]\"\n  },\n  \"tx_ptp_ts[17]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[40]\"\n  },\n  \"tx_ptp_ts[18]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[41]\"\n  },\n  \"tx_ptp_ts[19]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[42]\"\n  },\n  \"tx_ptp_ts[20]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[43]\"\n  },\n  \"tx_ptp_ts[21]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[44]\"\n  },\n  \"tx_ptp_ts[22]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[45]\"\n  },\n  \"tx_ptp_ts[23]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[46]\"\n  },\n  \"tx_ptp_ts[24]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[47]\"\n  },\n  \"tx_ptp_ts[25]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[48]\"\n  },\n  \"tx_ptp_ts[26]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[49]\"\n  },\n  \"tx_ptp_ts[27]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[50]\"\n  },\n  \"tx_ptp_ts[28]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[51]\"\n  },\n  \"tx_ptp_ts[29]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[52]\"\n  },\n  \"tx_ptp_ts[30]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[53]\"\n  },\n  \"tx_ptp_ts[31]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[54]\"\n  },\n  \"tx_ptp_ts[32]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[55]\"\n  },\n  \"tx_ptp_ts[33]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[56]\"\n  },\n  \"tx_ptp_ts[34]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[57]\"\n  },\n  \"tx_ptp_ts[35]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[58]\"\n  },\n  \"tx_ptp_ts[36]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[59]\"\n  },\n  \"tx_ptp_ts[37]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[60]\"\n  },\n  \"tx_ptp_ts[38]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[61]\"\n  },\n  \"tx_ptp_ts[39]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[62]\"\n  },\n  \"tx_ptp_ts[40]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[63]\"\n  },\n  \"tx_ptp_ts[41]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[64]\"\n  },\n  \"tx_ptp_ts[42]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[65]\"\n  },\n  \"tx_ptp_ts[43]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[66]\"\n  },\n  \"tx_ptp_ts[44]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[67]\"\n  },\n  \"tx_ptp_ts[45]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[68]\"\n  },\n  \"tx_ptp_ts[46]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[69]\"\n  },\n  \"tx_ptp_ts[47]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[70]\"\n  },\n  \"tx_ptp_ts[48]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[71]\"\n  },\n  \"tx_ptp_ts[49]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[72]\"\n  },\n  \"tx_ptp_ts[50]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[73]\"\n  },\n  \"tx_ptp_ts[51]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[74]\"\n  },\n  \"tx_ptp_ts[52]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[75]\"\n  },\n  \"tx_ptp_ts[53]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[76]\"\n  },\n  \"tx_ptp_ts[54]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[77]\"\n  },\n  \"tx_ptp_ts[55]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[78]\"\n  },\n  \"tx_ptp_ts[56]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[79]\"\n  },\n  \"tx_ptp_ts[57]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[80]\"\n  },\n  \"tx_ptp_ts[58]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[81]\"\n  },\n  \"tx_ptp_ts[59]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[82]\"\n  },\n  \"tx_ptp_ts[60]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[83]\"\n  },\n  \"tx_ptp_ts[61]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[84]\"\n  },\n  \"tx_ptp_ts[62]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[85]\"\n  },\n  \"tx_ptp_ts[63]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[86]\"\n  },\n  \"tx_ptp_ts[64]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[87]\"\n  },\n  \"tx_ptp_ts[65]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[88]\"\n  },\n  \"tx_ptp_ts[66]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[89]\"\n  },\n  \"tx_ptp_ts[67]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[90]\"\n  },\n  \"tx_ptp_ts[68]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[91]\"\n  },\n  \"tx_ptp_ts[69]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[92]\"\n  },\n  \"tx_ptp_ts[70]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[93]\"\n  },\n  \"tx_ptp_ts[71]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[94]\"\n  },\n  \"tx_ptp_ts[72]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[95]\"\n  },\n  \"tx_ptp_ts[73]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[96]\"\n  },\n  \"tx_ptp_ts[74]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[97]\"\n  },\n  \"tx_ptp_ts[75]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[98]\"\n  },\n  \"tx_ptp_ts[76]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[99]\"\n  },\n  \"tx_ptp_ts[77]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[100]\"\n  },\n  \"tx_ptp_ts[78]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[101]\"\n  },\n  \"tx_ptp_ts[79]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[102]\"\n  },\n  \"tx_ptp_ts[80]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[103]\"\n  },\n  \"tx_ptp_ts[81]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[104]\"\n  },\n  \"tx_ptp_ts[82]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[105]\"\n  },\n  \"tx_ptp_ts[83]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[106]\"\n  },\n  \"tx_ptp_ts[84]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[107]\"\n  },\n  \"tx_ptp_ts[85]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[108]\"\n  },\n  \"tx_ptp_ts[86]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[109]\"\n  },\n  \"tx_ptp_ts[87]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[110]\"\n  },\n  \"tx_ptp_ts[88]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[111]\"\n  },\n  \"tx_ptp_ts[89]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[112]\"\n  },\n  \"tx_ptp_ts[90]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[113]\"\n  },\n  \"tx_ptp_ts[91]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[114]\"\n  },\n  \"tx_ptp_ts[92]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[115]\"\n  },\n  \"tx_ptp_ts[93]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[116]\"\n  },\n  \"tx_ptp_ts[94]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[117]\"\n  },\n  \"tx_ptp_ts[95]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[118]\"\n  },\n  \"rx_ptp_ts[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[119]\"\n  },\n  \"rx_ptp_ts[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[120]\"\n  },\n  \"rx_ptp_ts[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[121]\"\n  },\n  \"rx_ptp_ts[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[122]\"\n  },\n  \"rx_ptp_ts[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[123]\"\n  },\n  \"rx_ptp_ts[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[124]\"\n  },\n  \"rx_ptp_ts[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[125]\"\n  },\n  \"rx_ptp_ts[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[126]\"\n  },\n  \"rx_ptp_ts[8]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[127]\"\n  },\n  \"rx_ptp_ts[9]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[128]\"\n  },\n  \"rx_ptp_ts[10]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[129]\"\n  },\n  \"rx_ptp_ts[11]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[130]\"\n  },\n  \"rx_ptp_ts[12]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[131]\"\n  },\n  \"rx_ptp_ts[13]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[132]\"\n  },\n  \"rx_ptp_ts[14]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[133]\"\n  },\n  \"rx_ptp_ts[15]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[134]\"\n  },\n  \"rx_ptp_ts[16]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[135]\"\n  },\n  \"rx_ptp_ts[17]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[136]\"\n  },\n  \"rx_ptp_ts[18]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[137]\"\n  },\n  \"rx_ptp_ts[19]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[138]\"\n  },\n  \"rx_ptp_ts[20]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[139]\"\n  },\n  \"rx_ptp_ts[21]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[140]\"\n  },\n  \"rx_ptp_ts[22]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[141]\"\n  },\n  \"rx_ptp_ts[23]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[142]\"\n  },\n  \"rx_ptp_ts[24]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[143]\"\n  },\n  \"rx_ptp_ts[25]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[144]\"\n  },\n  \"rx_ptp_ts[26]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[145]\"\n  },\n  \"rx_ptp_ts[27]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[146]\"\n  },\n  \"rx_ptp_ts[28]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[147]\"\n  },\n  \"rx_ptp_ts[29]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[148]\"\n  },\n  \"rx_ptp_ts[30]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[149]\"\n  },\n  \"rx_ptp_ts[31]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[150]\"\n  },\n  \"rx_ptp_ts[32]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[151]\"\n  },\n  \"rx_ptp_ts[33]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[152]\"\n  },\n  \"rx_ptp_ts[34]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[153]\"\n  },\n  \"rx_ptp_ts[35]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[154]\"\n  },\n  \"rx_ptp_ts[36]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[155]\"\n  },\n  \"rx_ptp_ts[37]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[156]\"\n  },\n  \"rx_ptp_ts[38]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[157]\"\n  },\n  \"rx_ptp_ts[39]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[158]\"\n  },\n  \"rx_ptp_ts[40]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[159]\"\n  },\n  \"rx_ptp_ts[41]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[160]\"\n  },\n  \"rx_ptp_ts[42]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[161]\"\n  },\n  \"rx_ptp_ts[43]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[162]\"\n  },\n  \"rx_ptp_ts[44]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[163]\"\n  },\n  \"rx_ptp_ts[45]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[164]\"\n  },\n  \"rx_ptp_ts[46]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[165]\"\n  },\n  \"rx_ptp_ts[47]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[166]\"\n  },\n  \"rx_ptp_ts[48]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[167]\"\n  },\n  \"rx_ptp_ts[49]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[168]\"\n  },\n  \"rx_ptp_ts[50]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[169]\"\n  },\n  \"rx_ptp_ts[51]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[170]\"\n  },\n  \"rx_ptp_ts[52]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[171]\"\n  },\n  \"rx_ptp_ts[53]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[172]\"\n  },\n  \"rx_ptp_ts[54]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[173]\"\n  },\n  \"rx_ptp_ts[55]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[174]\"\n  },\n  \"rx_ptp_ts[56]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[175]\"\n  },\n  \"rx_ptp_ts[57]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[176]\"\n  },\n  \"rx_ptp_ts[58]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[177]\"\n  },\n  \"rx_ptp_ts[59]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[178]\"\n  },\n  \"rx_ptp_ts[60]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[179]\"\n  },\n  \"rx_ptp_ts[61]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[180]\"\n  },\n  \"rx_ptp_ts[62]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[181]\"\n  },\n  \"rx_ptp_ts[63]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[182]\"\n  },\n  \"rx_ptp_ts[64]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[183]\"\n  },\n  \"rx_ptp_ts[65]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[184]\"\n  },\n  \"rx_ptp_ts[66]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[185]\"\n  },\n  \"rx_ptp_ts[67]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[186]\"\n  },\n  \"rx_ptp_ts[68]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[187]\"\n  },\n  \"rx_ptp_ts[69]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[188]\"\n  },\n  \"rx_ptp_ts[70]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[189]\"\n  },\n  \"rx_ptp_ts[71]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[190]\"\n  },\n  \"rx_ptp_ts[72]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[191]\"\n  },\n  \"rx_ptp_ts[73]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[192]\"\n  },\n  \"rx_ptp_ts[74]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[193]\"\n  },\n  \"rx_ptp_ts[75]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[194]\"\n  },\n  \"rx_ptp_ts[76]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[195]\"\n  },\n  \"rx_ptp_ts[77]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[196]\"\n  },\n  \"rx_ptp_ts[78]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[197]\"\n  },\n  \"rx_ptp_ts[79]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[198]\"\n  },\n  \"rx_ptp_ts[80]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[199]\"\n  },\n  \"rx_ptp_ts[81]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[200]\"\n  },\n  \"rx_ptp_ts[82]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[201]\"\n  },\n  \"rx_ptp_ts[83]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[202]\"\n  },\n  \"rx_ptp_ts[84]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[203]\"\n  },\n  \"rx_ptp_ts[85]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[204]\"\n  },\n  \"rx_ptp_ts[86]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[205]\"\n  },\n  \"rx_ptp_ts[87]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[206]\"\n  },\n  \"rx_ptp_ts[88]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[207]\"\n  },\n  \"rx_ptp_ts[89]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[208]\"\n  },\n  \"rx_ptp_ts[90]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[209]\"\n  },\n  \"rx_ptp_ts[91]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[210]\"\n  },\n  \"rx_ptp_ts[92]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[211]\"\n  },\n  \"rx_ptp_ts[93]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[212]\"\n  },\n  \"rx_ptp_ts[94]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[213]\"\n  },\n  \"rx_ptp_ts[95]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[214]\"\n  },\n  \"tx_lfc_req\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[215]\"\n  },\n  \"tx_lfc_resend\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[216]\"\n  },\n  \"rx_lfc_en\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[217]\"\n  },\n  \"rx_lfc_ack\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[218]\"\n  },\n  \"tx_pfc_req[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[219]\"\n  },\n  \"tx_pfc_req[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[220]\"\n  },\n  \"tx_pfc_req[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[221]\"\n  },\n  \"tx_pfc_req[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[222]\"\n  },\n  \"tx_pfc_req[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[223]\"\n  },\n  \"tx_pfc_req[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[224]\"\n  },\n  \"tx_pfc_req[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[225]\"\n  },\n  \"tx_pfc_req[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[226]\"\n  },\n  \"tx_pfc_resend\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[227]\"\n  },\n  \"rx_pfc_en[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[228]\"\n  },\n  \"rx_pfc_en[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[229]\"\n  },\n  \"rx_pfc_en[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[230]\"\n  },\n  \"rx_pfc_en[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[231]\"\n  },\n  \"rx_pfc_en[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[232]\"\n  },\n  \"rx_pfc_en[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[233]\"\n  },\n  \"rx_pfc_en[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[234]\"\n  },\n  \"rx_pfc_en[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[235]\"\n  },\n  \"rx_pfc_ack[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[236]\"\n  },\n  \"rx_pfc_ack[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[237]\"\n  },\n  \"rx_pfc_ack[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[238]\"\n  },\n  \"rx_pfc_ack[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[239]\"\n  },\n  \"rx_pfc_ack[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[240]\"\n  },\n  \"rx_pfc_ack[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[241]\"\n  },\n  \"rx_pfc_ack[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[242]\"\n  },\n  \"rx_pfc_ack[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[243]\"\n  },\n  \"tx_lfc_pause_en\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[244]\"\n  },\n  \"tx_pause_req\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[245]\"\n  },\n  \"rx_clk_enable\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[246]\"\n  },\n  \"tx_clk_enable\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[247]\"\n  },\n  \"rx_mii_select\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[248]\"\n  },\n  \"tx_mii_select\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[249]\"\n  },\n  \"cfg_ifg[0]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[250]\"\n  },\n  \"cfg_ifg[1]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[251]\"\n  },\n  \"cfg_ifg[2]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[252]\"\n  },\n  \"cfg_ifg[3]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[253]\"\n  },\n  \"cfg_ifg[4]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[254]\"\n  },\n  \"cfg_ifg[5]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_west[255]\"\n  },\n  \"cfg_ifg[6]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_south[0]\"\n  },\n  \"cfg_ifg[7]\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_south[1]\"\n  },\n  \"cfg_tx_enable\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_south[2]\"\n  },\n  \"cfg_rx_enable\": {\n    \"direction\": \"input\",\n    \"pin\": \"gpio_in_south[3]\"\n  }\n}"
  },
  {
    "path": "examples/eth_mac_1g/eth_mac_1g.py",
    "content": "#!/usr/bin/env python3\n\n# This is the logik run script for demonstrating RTL-to-bitstream\n# with Alex Forencich's 1G Ethernet MAC\n\nimport siliconcompiler\nfrom logiklib.zeroasic.z1000 import z1000\n\nfrom logik.flows.logik_flow import LogikFlow\n\n\ndef build():\n    design = siliconcompiler.Design(\"eth_mac_1g_wrapper\")\n\n    # Define source files from verilog-ethernet repo\n\n    # First we need to register the verilog-ethernet repo\n    # as a package\n    design.set_dataroot(\n        \"verilog-ethernet\",\n        \"git+https://github.com/alexforencich/verilog-ethernet.git\",\n        \"77320a9471d19c7dd383914bc049e02d9f4f1ffb\",\n    )\n\n    # Then we can pull in the specific RTL we need from that\n    # repository -- Silicon Compiler will download and cache the files\n    # for us\n    with design.active_dataroot(\"verilog-ethernet\"):\n        for source_file in (\n            \"eth_mac_1g.v\",\n            \"axis_gmii_rx.v\",\n            \"axis_gmii_tx.v\",\n            \"lfsr.v\",\n        ):\n            design.add_file(f\"rtl/{source_file}\", fileset=\"rtl\")\n\n    # Add in our top-level wrapper, stored locally\n    design.set_dataroot(\"ethmac_example\", __file__)\n    with design.active_dataroot(\"ethmac_example\"):\n        design.add_file(\"eth_mac_1g_wrapper.v\", fileset=\"rtl\")\n        design.set_topmodule(\"eth_mac_1g_wrapper\", fileset=\"rtl\")\n\n        # Add timing constraints\n        design.add_file(\"eth_mac_1g.sdc\", fileset=\"sdc\")\n\n        # Define pin constraints\n        design.add_file(\"constraints/z1000/pin_constraints.pcf\", fileset=\"pcf\")\n\n    project = siliconcompiler.FPGA(design)\n\n    project.add_fileset(\"rtl\")\n    project.add_fileset(\"sdc\")\n    project.add_fileset(\"pcf\")\n\n    fpga = z1000.z1000()\n\n    project.set_fpga(fpga)\n\n    project.set_flow(LogikFlow())\n\n    project.option.set_quiet(True)\n\n    project.run()\n    project.summary()\n\n\nif __name__ == \"__main__\":\n    build()\n"
  },
  {
    "path": "examples/eth_mac_1g/eth_mac_1g.sdc",
    "content": "create_clock -period 16 rx_clk\ncreate_clock -period 16 tx_clk\n"
  },
  {
    "path": "examples/eth_mac_1g/eth_mac_1g_wrapper.v",
    "content": "//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 pin interface\n//on the block, reducing the port count by about a factor of 5.\n\nmodule eth_mac_1g_wrapper\n  # (\n     parameter DATA_WIDTH = 8,\n     parameter ENABLE_PADDING = 1,\n     parameter MIN_FRAME_LENGTH = 64,\n     parameter PTP_TS_ENABLE = 0,\n     parameter PTP_TS_FMT_TOD = 1,\n     parameter PTP_TS_WIDTH = PTP_TS_FMT_TOD ? 96 : 64,\n     parameter TX_PTP_TS_CTRL_IN_TUSER = 0,\n     parameter TX_PTP_TAG_ENABLE = PTP_TS_ENABLE,\n     parameter TX_PTP_TAG_WIDTH = 16,\n     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,\n     parameter RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1,\n     parameter PFC_ENABLE = 0,\n     parameter PAUSE_ENABLE = PFC_ENABLE\n     )   \n   (\n    input  wire                         rx_clk,\n    input  wire                         rx_rst,\n    input  wire                         tx_clk,\n    input  wire                         tx_rst,\n\n    /*\n     * AXI input\n     */\n    input  wire [DATA_WIDTH-1:0]        tx_axis_tdata,\n    input  wire                         tx_axis_tvalid,\n    output wire                         tx_axis_tready,\n    input  wire                         tx_axis_tlast,\n    input  wire [TX_USER_WIDTH-1:0]     tx_axis_tuser,\n\n    /*\n     * AXI output\n     */\n    output wire [DATA_WIDTH-1:0]        rx_axis_tdata,\n    output wire                         rx_axis_tvalid,\n    output wire                         rx_axis_tlast,\n    output wire [RX_USER_WIDTH-1:0]     rx_axis_tuser,\n\n    /*\n     * GMII interface\n     */\n    input  wire [DATA_WIDTH-1:0]        gmii_rxd,\n    input  wire                         gmii_rx_dv,\n    input  wire                         gmii_rx_er,\n    output wire [DATA_WIDTH-1:0]        gmii_txd,\n    output wire                         gmii_tx_en,\n    output wire                         gmii_tx_er,\n\n    /*\n     * PTP\n     */\n    input  wire [PTP_TS_WIDTH-1:0]      tx_ptp_ts,\n    input  wire [PTP_TS_WIDTH-1:0]      rx_ptp_ts,\n    output wire [PTP_TS_WIDTH-1:0]      tx_axis_ptp_ts,\n    output wire [TX_PTP_TAG_WIDTH-1:0]  tx_axis_ptp_ts_tag,\n    output wire                         tx_axis_ptp_ts_valid,\n\n    /*\n     * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)\n     */\n    input  wire                         tx_lfc_req,\n    input  wire                         tx_lfc_resend,\n    input  wire                         rx_lfc_en,\n    output wire                         rx_lfc_req,\n    input  wire                         rx_lfc_ack,\n\n    /*\n     * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)\n     */\n    input  wire [7:0]                   tx_pfc_req,\n    input  wire                         tx_pfc_resend,\n    input  wire [7:0]                   rx_pfc_en,\n    output wire [7:0]                   rx_pfc_req,\n    input  wire [7:0]                   rx_pfc_ack,\n\n    /*\n     * Pause interface\n     */\n    input  wire                         tx_lfc_pause_en,\n    input  wire                         tx_pause_req,\n    output wire                         tx_pause_ack,\n\n    /*\n     * Control\n     */\n    input  wire                         rx_clk_enable,\n    input  wire                         tx_clk_enable,\n    input  wire                         rx_mii_select,\n    input  wire                         tx_mii_select,\n\n    /*\n     * Status\n     */\n    output wire                         tx_start_packet,\n    output wire                         tx_error_underflow,\n    output wire                         rx_start_packet,\n    output wire                         rx_error_bad_frame,\n    output wire                         rx_error_bad_fcs,\n    output wire                         stat_tx_mcf,\n    output wire                         stat_rx_mcf,\n    output wire                         stat_tx_lfc_pkt,\n    output wire                         stat_tx_lfc_xon,\n    output wire                         stat_tx_lfc_xoff,\n    output wire                         stat_tx_lfc_paused,\n    output wire                         stat_tx_pfc_pkt,\n    output wire [7:0]                   stat_tx_pfc_xon,\n    output wire [7:0]                   stat_tx_pfc_xoff,\n    output wire [7:0]                   stat_tx_pfc_paused,\n    output wire                         stat_rx_lfc_pkt,\n    output wire                         stat_rx_lfc_xon,\n    output wire                         stat_rx_lfc_xoff,\n    output wire                         stat_rx_lfc_paused,\n    output wire                         stat_rx_pfc_pkt,\n    output wire [7:0]                   stat_rx_pfc_xon,\n    output wire [7:0]                   stat_rx_pfc_xoff,\n    output wire [7:0]                   stat_rx_pfc_paused,\n\n    /*\n     * Configuration\n     */\n    input  wire [7:0]                   cfg_ifg,\n    input  wire                         cfg_tx_enable,\n    input  wire                         cfg_rx_enable\n    );\n\n   eth_mac_1g\n     # (\n        .DATA_WIDTH(DATA_WIDTH),\n        .ENABLE_PADDING(ENABLE_PADDING),\n        .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),\n        .PTP_TS_ENABLE(PTP_TS_ENABLE),\n        .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),\n        .PTP_TS_WIDTH(PTP_TS_WIDTH),\n        .TX_PTP_TS_CTRL_IN_TUSER(TX_PTP_TS_CTRL_IN_TUSER),\n        .TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),\n        .TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),\n        .TX_USER_WIDTH(TX_USER_WIDTH),\n        .RX_USER_WIDTH(RX_USER_WIDTH),\n        .PFC_ENABLE(PFC_ENABLE),\n        .PAUSE_ENABLE(PAUSE_ENABLE)\n        )\n   eth_mac_1g\n     (\n      .rx_clk(rx_clk),\n      .rx_rst(rx_rst),\n      .tx_clk(tx_clk),\n      .tx_rst(tx_rst),\n      .tx_axis_tdata(tx_axis_tdata),\n      .tx_axis_tvalid(tx_axis_tvalid),\n      .tx_axis_tready(tx_axis_tready),\n      .tx_axis_tlast(tx_axis_tlast),\n      .tx_axis_tuser(tx_axis_tuser),\n      .rx_axis_tdata(rx_axis_tdata),\n      .rx_axis_tvalid(rx_axis_tvalid),\n      .rx_axis_tlast(rx_axis_tlast),\n      .rx_axis_tuser(rx_axis_tuser),\n      .gmii_rxd(gmii_rxd),\n      .gmii_rx_dv(gmii_rx_dv),\n      .gmii_rx_er(gmii_rx_er),\n      .gmii_txd(gmii_txd),\n      .gmii_tx_en(gmii_tx_en),\n      .gmii_tx_er(gmii_tx_er),\n      .tx_ptp_ts(tx_ptp_ts),\n      .rx_ptp_ts(rx_ptp_ts),\n      .tx_axis_ptp_ts(tx_axis_ptp_ts),\n      .tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),\n      .tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),\n      .tx_lfc_req(tx_lfc_req),\n      .tx_lfc_resend(tx_lfc_resend),\n      .rx_lfc_en(rx_lfc_en),\n      .rx_lfc_req(rx_lfc_req),\n      .rx_lfc_ack(rx_lfc_ack),\n      .tx_pfc_req(tx_pfc_req),\n      .tx_pfc_resend(tx_pfc_resend),\n      .rx_pfc_en(rx_pfc_en),\n      .rx_pfc_req(rx_pfc_req),\n      .rx_pfc_ack(rx_pfc_ack),\n      .tx_lfc_pause_en(tx_lfc_pause_en),\n      .tx_pause_req(tx_pause_req),\n      .tx_pause_ack(tx_pause_ack),\n      .rx_clk_enable(rx_clk_enable),\n      .tx_clk_enable(tx_clk_enable),\n      .rx_mii_select(rx_mii_select),\n      .tx_mii_select(tx_mii_select),\n      .tx_start_packet(tx_start_packet),\n      .tx_error_underflow(tx_error_underflow),\n      .rx_start_packet(rx_start_packet),\n      .rx_error_bad_frame(rx_error_bad_frame),\n      .rx_error_bad_fcs(rx_error_bad_fcs),\n      .stat_tx_mcf(stat_tx_mcf),\n      .stat_rx_mcf(stat_rx_mcf),\n      .stat_tx_lfc_pkt(stat_tx_lfc_pkt),\n      .stat_tx_lfc_xon(stat_tx_lfc_xon),\n      .stat_tx_lfc_xoff(stat_tx_lfc_xoff),\n      .stat_tx_lfc_paused(stat_tx_lfc_paused),\n      .stat_tx_pfc_pkt(stat_tx_pfc_pkt),\n      .stat_tx_pfc_xon(stat_tx_pfc_xon),\n      .stat_tx_pfc_xoff(stat_tx_pfc_xoff),\n      .stat_tx_pfc_paused(stat_tx_pfc_paused),\n      .stat_rx_lfc_pkt(stat_rx_lfc_pkt),\n      .stat_rx_lfc_xon(stat_rx_lfc_xon),\n      .stat_rx_lfc_xoff(stat_rx_lfc_xoff),\n      .stat_rx_lfc_paused(stat_rx_lfc_paused),\n      .stat_rx_pfc_pkt(stat_rx_pfc_pkt),\n      .stat_rx_pfc_xon(stat_rx_pfc_xon),\n      .stat_rx_pfc_xoff(stat_rx_pfc_xoff),\n      .stat_rx_pfc_paused(stat_rx_pfc_paused),\n      .cfg_ifg(cfg_ifg),\n      .cfg_tx_enable(cfg_tx_enable),\n      .cfg_rx_enable(cfg_rx_enable),\n      .cfg_mcf_rx_eth_dst_mcast('h0),\n      .cfg_mcf_rx_check_eth_dst_mcast('h0),\n      .cfg_mcf_rx_eth_dst_ucast('h0),\n      .cfg_mcf_rx_check_eth_dst_ucast('h0),\n      .cfg_mcf_rx_eth_src('h0),\n      .cfg_mcf_rx_check_eth_src('h0),\n      .cfg_mcf_rx_eth_type('h0),\n      .cfg_mcf_rx_opcode_lfc('h0),\n      .cfg_mcf_rx_check_opcode_lfc('h0),\n      .cfg_mcf_rx_opcode_pfc('h0),\n      .cfg_mcf_rx_check_opcode_pfc('h0),\n      .cfg_mcf_rx_forward('h0),\n      .cfg_mcf_rx_enable('h0),\n      .cfg_tx_lfc_eth_dst('h0),\n      .cfg_tx_lfc_eth_src('h0),\n      .cfg_tx_lfc_eth_type('h0),\n      .cfg_tx_lfc_opcode('h0),\n      .cfg_tx_lfc_en('h0),\n      .cfg_tx_lfc_quanta('h0),\n      .cfg_tx_lfc_refresh('h0),\n      .cfg_tx_pfc_eth_dst('h0),\n      .cfg_tx_pfc_eth_src('h0),\n      .cfg_tx_pfc_eth_type('h0),\n      .cfg_tx_pfc_opcode('h0),\n      .cfg_tx_pfc_en('h0),\n      .cfg_tx_pfc_quanta('h0),\n      .cfg_tx_pfc_refresh('h0),\n      .cfg_rx_lfc_opcode('h0),\n      .cfg_rx_lfc_en('h0),\n      .cfg_rx_pfc_opcode('h0),\n      .cfg_rx_pfc_en('h0)\n      );\n   \n\nendmodule\n"
  },
  {
    "path": "examples/picorv32/constraints/z1062/picorv32.pcf",
    "content": "{\n  \"clk\": {\n    \"pin\": \"gpio_in_clk[0]\",\n    \"direction\": \"input\"\n  },\n  \"resetn\": {\n    \"pin\": \"gpio_in_west[10]\",\n    \"direction\": \"input\"\n  },\n  \"trap\": {\n    \"pin\": \"gpio_out_north[10]\",\n    \"direction\": \"output\"\n  },\n  \"mem_valid\": {\n    \"pin\": \"gpio_out_north[11]\",\n    \"direction\": \"output\"\n  },\n  \"mem_instr\": {\n    \"pin\": \"gpio_out_north[12]\",\n    \"direction\": \"output\"\n  },\n  \"mem_ready\": {\n    \"pin\": \"gpio_in_west[11]\",\n    \"direction\": \"input\"\n  },\n  \"mem_la_read\": {\n    \"pin\": \"gpio_out_west[12]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_write\": {\n    \"pin\": \"gpio_out_west[13]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_valid\": {\n    \"pin\": \"gpio_out_south[10]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_wr\": {\n    \"pin\": \"gpio_in_east[10]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_wait\": {\n    \"pin\": \"gpio_in_east[11]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_ready\": {\n    \"pin\": \"gpio_in_east[12]\",\n    \"direction\": \"input\"\n  },\n  \"trace_valid\": {\n    \"pin\": \"gpio_out_west[14]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[0]\": {\n    \"pin\": \"gpio_out_north[320]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[1]\": {\n    \"pin\": \"gpio_out_north[321]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[2]\": {\n    \"pin\": \"gpio_out_north[322]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[3]\": {\n    \"pin\": \"gpio_out_north[323]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[4]\": {\n    \"pin\": \"gpio_out_north[324]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[5]\": {\n    \"pin\": \"gpio_out_north[325]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[6]\": {\n    \"pin\": \"gpio_out_north[326]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[7]\": {\n    \"pin\": \"gpio_out_north[327]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[8]\": {\n    \"pin\": \"gpio_out_north[328]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[9]\": {\n    \"pin\": \"gpio_out_north[329]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[10]\": {\n    \"pin\": \"gpio_out_north[330]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[11]\": {\n    \"pin\": \"gpio_out_north[331]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[12]\": {\n    \"pin\": \"gpio_out_north[332]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[13]\": {\n    \"pin\": \"gpio_out_north[333]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[14]\": {\n    \"pin\": \"gpio_out_north[334]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[15]\": {\n    \"pin\": \"gpio_out_north[335]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[16]\": {\n    \"pin\": \"gpio_out_north[336]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[17]\": {\n    \"pin\": \"gpio_out_north[337]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[18]\": {\n    \"pin\": \"gpio_out_north[338]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[19]\": {\n    \"pin\": \"gpio_out_north[339]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[20]\": {\n    \"pin\": \"gpio_out_north[340]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[21]\": {\n    \"pin\": \"gpio_out_north[341]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[22]\": {\n    \"pin\": \"gpio_out_north[342]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[23]\": {\n    \"pin\": \"gpio_out_north[343]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[24]\": {\n    \"pin\": \"gpio_out_north[344]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[25]\": {\n    \"pin\": \"gpio_out_north[345]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[26]\": {\n    \"pin\": \"gpio_out_north[346]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[27]\": {\n    \"pin\": \"gpio_out_north[347]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[28]\": {\n    \"pin\": \"gpio_out_north[348]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[29]\": {\n    \"pin\": \"gpio_out_north[349]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[30]\": {\n    \"pin\": \"gpio_out_north[350]\",\n    \"direction\": \"output\"\n  },\n  \"mem_addr[31]\": {\n    \"pin\": \"gpio_out_north[351]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[0]\": {\n    \"pin\": \"gpio_out_east[400]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[1]\": {\n    \"pin\": \"gpio_out_east[401]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[2]\": {\n    \"pin\": \"gpio_out_east[402]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[3]\": {\n    \"pin\": \"gpio_out_east[403]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[4]\": {\n    \"pin\": \"gpio_out_east[404]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[5]\": {\n    \"pin\": \"gpio_out_east[405]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[6]\": {\n    \"pin\": \"gpio_out_east[406]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[7]\": {\n    \"pin\": \"gpio_out_east[407]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[8]\": {\n    \"pin\": \"gpio_out_east[408]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[9]\": {\n    \"pin\": \"gpio_out_east[409]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[10]\": {\n    \"pin\": \"gpio_out_east[410]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[11]\": {\n    \"pin\": \"gpio_out_east[411]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[12]\": {\n    \"pin\": \"gpio_out_east[412]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[13]\": {\n    \"pin\": \"gpio_out_east[413]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[14]\": {\n    \"pin\": \"gpio_out_east[414]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[15]\": {\n    \"pin\": \"gpio_out_east[415]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[16]\": {\n    \"pin\": \"gpio_out_east[416]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[17]\": {\n    \"pin\": \"gpio_out_east[417]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[18]\": {\n    \"pin\": \"gpio_out_east[418]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[19]\": {\n    \"pin\": \"gpio_out_east[419]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[20]\": {\n    \"pin\": \"gpio_out_east[420]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[21]\": {\n    \"pin\": \"gpio_out_east[421]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[22]\": {\n    \"pin\": \"gpio_out_east[422]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[23]\": {\n    \"pin\": \"gpio_out_east[423]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[24]\": {\n    \"pin\": \"gpio_out_east[424]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[25]\": {\n    \"pin\": \"gpio_out_east[425]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[26]\": {\n    \"pin\": \"gpio_out_east[426]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[27]\": {\n    \"pin\": \"gpio_out_east[427]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[28]\": {\n    \"pin\": \"gpio_out_east[428]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[29]\": {\n    \"pin\": \"gpio_out_east[429]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[30]\": {\n    \"pin\": \"gpio_out_east[430]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wdata[31]\": {\n    \"pin\": \"gpio_out_east[431]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wstrb[0]\": {\n    \"pin\": \"gpio_out_north[460]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wstrb[1]\": {\n    \"pin\": \"gpio_out_north[461]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wstrb[2]\": {\n    \"pin\": \"gpio_out_north[462]\",\n    \"direction\": \"output\"\n  },\n  \"mem_wstrb[3]\": {\n    \"pin\": \"gpio_out_north[463]\",\n    \"direction\": \"output\"\n  },\n  \"mem_rdata[0]\": {\n    \"pin\": \"gpio_in_west[320]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[1]\": {\n    \"pin\": \"gpio_in_west[321]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[2]\": {\n    \"pin\": \"gpio_in_west[322]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[3]\": {\n    \"pin\": \"gpio_in_west[323]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[4]\": {\n    \"pin\": \"gpio_in_west[324]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[5]\": {\n    \"pin\": \"gpio_in_west[325]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[6]\": {\n    \"pin\": \"gpio_in_west[326]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[7]\": {\n    \"pin\": \"gpio_in_west[327]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[8]\": {\n    \"pin\": \"gpio_in_west[328]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[9]\": {\n    \"pin\": \"gpio_in_west[329]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[10]\": {\n    \"pin\": \"gpio_in_west[330]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[11]\": {\n    \"pin\": \"gpio_in_west[331]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[12]\": {\n    \"pin\": \"gpio_in_west[332]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[13]\": {\n    \"pin\": \"gpio_in_west[333]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[14]\": {\n    \"pin\": \"gpio_in_west[334]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[15]\": {\n    \"pin\": \"gpio_in_west[335]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[16]\": {\n    \"pin\": \"gpio_in_west[336]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[17]\": {\n    \"pin\": \"gpio_in_west[337]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[18]\": {\n    \"pin\": \"gpio_in_west[338]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[19]\": {\n    \"pin\": \"gpio_in_west[339]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[20]\": {\n    \"pin\": \"gpio_in_west[340]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[21]\": {\n    \"pin\": \"gpio_in_west[341]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[22]\": {\n    \"pin\": \"gpio_in_west[342]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[23]\": {\n    \"pin\": \"gpio_in_west[343]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[24]\": {\n    \"pin\": \"gpio_in_west[344]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[25]\": {\n    \"pin\": \"gpio_in_west[345]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[26]\": {\n    \"pin\": \"gpio_in_west[346]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[27]\": {\n    \"pin\": \"gpio_in_west[347]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[28]\": {\n    \"pin\": \"gpio_in_west[348]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[29]\": {\n    \"pin\": \"gpio_in_west[349]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[30]\": {\n    \"pin\": \"gpio_in_west[350]\",\n    \"direction\": \"input\"\n  },\n  \"mem_rdata[31]\": {\n    \"pin\": \"gpio_in_west[351]\",\n    \"direction\": \"input\"\n  },\n  \"mem_la_addr[0]\": {\n    \"pin\": \"gpio_out_east[260]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[1]\": {\n    \"pin\": \"gpio_out_east[261]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[2]\": {\n    \"pin\": \"gpio_out_east[262]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[3]\": {\n    \"pin\": \"gpio_out_east[263]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[4]\": {\n    \"pin\": \"gpio_out_east[264]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[5]\": {\n    \"pin\": \"gpio_out_east[265]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[6]\": {\n    \"pin\": \"gpio_out_east[266]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[7]\": {\n    \"pin\": \"gpio_out_east[267]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[8]\": {\n    \"pin\": \"gpio_out_east[268]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[9]\": {\n    \"pin\": \"gpio_out_east[269]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[10]\": {\n    \"pin\": \"gpio_out_east[270]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[11]\": {\n    \"pin\": \"gpio_out_east[271]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[12]\": {\n    \"pin\": \"gpio_out_east[272]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[13]\": {\n    \"pin\": \"gpio_out_east[273]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[14]\": {\n    \"pin\": \"gpio_out_east[274]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[15]\": {\n    \"pin\": \"gpio_out_east[275]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[16]\": {\n    \"pin\": \"gpio_out_east[276]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[17]\": {\n    \"pin\": \"gpio_out_east[277]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[18]\": {\n    \"pin\": \"gpio_out_east[278]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[19]\": {\n    \"pin\": \"gpio_out_east[279]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[20]\": {\n    \"pin\": \"gpio_out_east[280]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[21]\": {\n    \"pin\": \"gpio_out_east[281]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[22]\": {\n    \"pin\": \"gpio_out_east[282]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[23]\": {\n    \"pin\": \"gpio_out_east[283]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[24]\": {\n    \"pin\": \"gpio_out_east[284]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[25]\": {\n    \"pin\": \"gpio_out_east[285]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[26]\": {\n    \"pin\": \"gpio_out_east[286]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[27]\": {\n    \"pin\": \"gpio_out_east[287]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[28]\": {\n    \"pin\": \"gpio_out_east[288]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[29]\": {\n    \"pin\": \"gpio_out_east[289]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[30]\": {\n    \"pin\": \"gpio_out_east[290]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_addr[31]\": {\n    \"pin\": \"gpio_out_east[291]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[0]\": {\n    \"pin\": \"gpio_out_south[20]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[1]\": {\n    \"pin\": \"gpio_out_south[21]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[2]\": {\n    \"pin\": \"gpio_out_south[22]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[3]\": {\n    \"pin\": \"gpio_out_south[23]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[4]\": {\n    \"pin\": \"gpio_out_south[24]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[5]\": {\n    \"pin\": \"gpio_out_south[25]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[6]\": {\n    \"pin\": \"gpio_out_south[26]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[7]\": {\n    \"pin\": \"gpio_out_south[27]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[8]\": {\n    \"pin\": \"gpio_out_south[28]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[9]\": {\n    \"pin\": \"gpio_out_south[29]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[10]\": {\n    \"pin\": \"gpio_out_south[30]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[11]\": {\n    \"pin\": \"gpio_out_south[31]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[12]\": {\n    \"pin\": \"gpio_out_south[32]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[13]\": {\n    \"pin\": \"gpio_out_south[33]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[14]\": {\n    \"pin\": \"gpio_out_south[34]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[15]\": {\n    \"pin\": \"gpio_out_south[35]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[16]\": {\n    \"pin\": \"gpio_out_south[36]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[17]\": {\n    \"pin\": \"gpio_out_south[37]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[18]\": {\n    \"pin\": \"gpio_out_south[38]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[19]\": {\n    \"pin\": \"gpio_out_south[39]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[20]\": {\n    \"pin\": \"gpio_out_south[40]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[21]\": {\n    \"pin\": \"gpio_out_south[41]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[22]\": {\n    \"pin\": \"gpio_out_south[42]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[23]\": {\n    \"pin\": \"gpio_out_south[43]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[24]\": {\n    \"pin\": \"gpio_out_south[44]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[25]\": {\n    \"pin\": \"gpio_out_south[45]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[26]\": {\n    \"pin\": \"gpio_out_south[46]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[27]\": {\n    \"pin\": \"gpio_out_south[47]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[28]\": {\n    \"pin\": \"gpio_out_south[48]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[29]\": {\n    \"pin\": \"gpio_out_south[49]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[30]\": {\n    \"pin\": \"gpio_out_south[50]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wdata[31]\": {\n    \"pin\": \"gpio_out_south[51]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wstrb[0]\": {\n    \"pin\": \"gpio_out_south[60]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wstrb[1]\": {\n    \"pin\": \"gpio_out_south[61]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wstrb[2]\": {\n    \"pin\": \"gpio_out_south[62]\",\n    \"direction\": \"output\"\n  },\n  \"mem_la_wstrb[3]\": {\n    \"pin\": \"gpio_out_south[63]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[0]\": {\n    \"pin\": \"gpio_out_south[100]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[1]\": {\n    \"pin\": \"gpio_out_south[101]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[2]\": {\n    \"pin\": \"gpio_out_south[102]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[3]\": {\n    \"pin\": \"gpio_out_south[103]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[4]\": {\n    \"pin\": \"gpio_out_south[104]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[5]\": {\n    \"pin\": \"gpio_out_south[105]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[6]\": {\n    \"pin\": \"gpio_out_south[106]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[7]\": {\n    \"pin\": \"gpio_out_south[107]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[8]\": {\n    \"pin\": \"gpio_out_south[108]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[9]\": {\n    \"pin\": \"gpio_out_south[109]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[10]\": {\n    \"pin\": \"gpio_out_south[110]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[11]\": {\n    \"pin\": \"gpio_out_south[111]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[12]\": {\n    \"pin\": \"gpio_out_south[112]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[13]\": {\n    \"pin\": \"gpio_out_south[113]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[14]\": {\n    \"pin\": \"gpio_out_south[114]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[15]\": {\n    \"pin\": \"gpio_out_south[115]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[16]\": {\n    \"pin\": \"gpio_out_south[116]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[17]\": {\n    \"pin\": \"gpio_out_south[117]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[18]\": {\n    \"pin\": \"gpio_out_south[118]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[19]\": {\n    \"pin\": \"gpio_out_south[119]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[20]\": {\n    \"pin\": \"gpio_out_south[120]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[21]\": {\n    \"pin\": \"gpio_out_south[121]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[22]\": {\n    \"pin\": \"gpio_out_south[122]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[23]\": {\n    \"pin\": \"gpio_out_south[123]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[24]\": {\n    \"pin\": \"gpio_out_south[124]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[25]\": {\n    \"pin\": \"gpio_out_south[125]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[26]\": {\n    \"pin\": \"gpio_out_south[126]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[27]\": {\n    \"pin\": \"gpio_out_south[127]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[28]\": {\n    \"pin\": \"gpio_out_south[128]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[29]\": {\n    \"pin\": \"gpio_out_south[129]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[30]\": {\n    \"pin\": \"gpio_out_south[130]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_insn[31]\": {\n    \"pin\": \"gpio_out_south[131]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[0]\": {\n    \"pin\": \"gpio_out_south[140]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[1]\": {\n    \"pin\": \"gpio_out_south[141]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[2]\": {\n    \"pin\": \"gpio_out_south[142]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[3]\": {\n    \"pin\": \"gpio_out_south[143]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[4]\": {\n    \"pin\": \"gpio_out_south[144]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[5]\": {\n    \"pin\": \"gpio_out_south[145]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[6]\": {\n    \"pin\": \"gpio_out_south[146]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[7]\": {\n    \"pin\": \"gpio_out_south[147]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[8]\": {\n    \"pin\": \"gpio_out_south[148]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[9]\": {\n    \"pin\": \"gpio_out_south[149]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[10]\": {\n    \"pin\": \"gpio_out_south[150]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[11]\": {\n    \"pin\": \"gpio_out_south[151]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[12]\": {\n    \"pin\": \"gpio_out_south[152]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[13]\": {\n    \"pin\": \"gpio_out_south[153]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[14]\": {\n    \"pin\": \"gpio_out_south[154]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[15]\": {\n    \"pin\": \"gpio_out_south[155]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[16]\": {\n    \"pin\": \"gpio_out_south[156]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[17]\": {\n    \"pin\": \"gpio_out_south[157]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[18]\": {\n    \"pin\": \"gpio_out_south[158]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[19]\": {\n    \"pin\": \"gpio_out_south[159]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[20]\": {\n    \"pin\": \"gpio_out_south[160]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[21]\": {\n    \"pin\": \"gpio_out_south[161]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[22]\": {\n    \"pin\": \"gpio_out_south[162]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[23]\": {\n    \"pin\": \"gpio_out_south[163]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[24]\": {\n    \"pin\": \"gpio_out_south[164]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[25]\": {\n    \"pin\": \"gpio_out_south[165]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[26]\": {\n    \"pin\": \"gpio_out_south[166]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[27]\": {\n    \"pin\": \"gpio_out_south[167]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[28]\": {\n    \"pin\": \"gpio_out_south[168]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[29]\": {\n    \"pin\": \"gpio_out_south[169]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[30]\": {\n    \"pin\": \"gpio_out_south[170]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs1[31]\": {\n    \"pin\": \"gpio_out_south[171]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[0]\": {\n    \"pin\": \"gpio_out_south[180]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[1]\": {\n    \"pin\": \"gpio_out_south[181]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[2]\": {\n    \"pin\": \"gpio_out_south[182]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[3]\": {\n    \"pin\": \"gpio_out_south[183]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[4]\": {\n    \"pin\": \"gpio_out_south[184]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[5]\": {\n    \"pin\": \"gpio_out_south[185]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[6]\": {\n    \"pin\": \"gpio_out_south[186]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[7]\": {\n    \"pin\": \"gpio_out_south[187]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[8]\": {\n    \"pin\": \"gpio_out_south[188]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[9]\": {\n    \"pin\": \"gpio_out_south[189]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[10]\": {\n    \"pin\": \"gpio_out_south[190]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[11]\": {\n    \"pin\": \"gpio_out_south[191]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[12]\": {\n    \"pin\": \"gpio_out_south[192]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[13]\": {\n    \"pin\": \"gpio_out_south[193]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[14]\": {\n    \"pin\": \"gpio_out_south[194]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[15]\": {\n    \"pin\": \"gpio_out_south[195]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[16]\": {\n    \"pin\": \"gpio_out_south[196]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[17]\": {\n    \"pin\": \"gpio_out_south[197]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[18]\": {\n    \"pin\": \"gpio_out_south[198]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[19]\": {\n    \"pin\": \"gpio_out_south[199]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[20]\": {\n    \"pin\": \"gpio_out_south[200]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[21]\": {\n    \"pin\": \"gpio_out_south[201]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[22]\": {\n    \"pin\": \"gpio_out_south[202]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[23]\": {\n    \"pin\": \"gpio_out_south[203]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[24]\": {\n    \"pin\": \"gpio_out_south[204]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[25]\": {\n    \"pin\": \"gpio_out_south[205]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[26]\": {\n    \"pin\": \"gpio_out_south[206]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[27]\": {\n    \"pin\": \"gpio_out_south[207]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[28]\": {\n    \"pin\": \"gpio_out_south[208]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[29]\": {\n    \"pin\": \"gpio_out_south[209]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[30]\": {\n    \"pin\": \"gpio_out_south[210]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rs2[31]\": {\n    \"pin\": \"gpio_out_south[211]\",\n    \"direction\": \"output\"\n  },\n  \"pcpi_rd[0]\": {\n    \"pin\": \"gpio_in_east[20]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[1]\": {\n    \"pin\": \"gpio_in_east[21]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[2]\": {\n    \"pin\": \"gpio_in_east[22]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[3]\": {\n    \"pin\": \"gpio_in_east[23]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[4]\": {\n    \"pin\": \"gpio_in_east[24]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[5]\": {\n    \"pin\": \"gpio_in_east[25]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[6]\": {\n    \"pin\": \"gpio_in_east[26]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[7]\": {\n    \"pin\": \"gpio_in_east[27]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[8]\": {\n    \"pin\": \"gpio_in_east[28]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[9]\": {\n    \"pin\": \"gpio_in_east[29]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[10]\": {\n    \"pin\": \"gpio_in_east[30]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[11]\": {\n    \"pin\": \"gpio_in_east[31]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[12]\": {\n    \"pin\": \"gpio_in_east[32]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[13]\": {\n    \"pin\": \"gpio_in_east[33]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[14]\": {\n    \"pin\": \"gpio_in_east[34]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[15]\": {\n    \"pin\": \"gpio_in_east[35]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[16]\": {\n    \"pin\": \"gpio_in_east[36]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[17]\": {\n    \"pin\": \"gpio_in_east[37]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[18]\": {\n    \"pin\": \"gpio_in_east[38]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[19]\": {\n    \"pin\": \"gpio_in_east[39]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[20]\": {\n    \"pin\": \"gpio_in_east[40]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[21]\": {\n    \"pin\": \"gpio_in_east[41]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[22]\": {\n    \"pin\": \"gpio_in_east[42]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[23]\": {\n    \"pin\": \"gpio_in_east[43]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[24]\": {\n    \"pin\": \"gpio_in_east[44]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[25]\": {\n    \"pin\": \"gpio_in_east[45]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[26]\": {\n    \"pin\": \"gpio_in_east[46]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[27]\": {\n    \"pin\": \"gpio_in_east[47]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[28]\": {\n    \"pin\": \"gpio_in_east[48]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[29]\": {\n    \"pin\": \"gpio_in_east[49]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[30]\": {\n    \"pin\": \"gpio_in_east[50]\",\n    \"direction\": \"input\"\n  },\n  \"pcpi_rd[31]\": {\n    \"pin\": \"gpio_in_east[51]\",\n    \"direction\": \"input\"\n  },\n  \"eoi[0]\": {\n    \"pin\": \"gpio_out_west[220]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[1]\": {\n    \"pin\": \"gpio_out_west[221]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[2]\": {\n    \"pin\": \"gpio_out_west[222]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[3]\": {\n    \"pin\": \"gpio_out_west[223]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[4]\": {\n    \"pin\": \"gpio_out_west[224]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[5]\": {\n    \"pin\": \"gpio_out_west[225]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[6]\": {\n    \"pin\": \"gpio_out_west[226]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[7]\": {\n    \"pin\": \"gpio_out_west[227]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[8]\": {\n    \"pin\": \"gpio_out_west[228]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[9]\": {\n    \"pin\": \"gpio_out_west[229]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[10]\": {\n    \"pin\": \"gpio_out_west[230]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[11]\": {\n    \"pin\": \"gpio_out_west[231]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[12]\": {\n    \"pin\": \"gpio_out_west[232]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[13]\": {\n    \"pin\": \"gpio_out_west[233]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[14]\": {\n    \"pin\": \"gpio_out_west[234]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[15]\": {\n    \"pin\": \"gpio_out_west[235]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[16]\": {\n    \"pin\": \"gpio_out_west[236]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[17]\": {\n    \"pin\": \"gpio_out_west[237]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[18]\": {\n    \"pin\": \"gpio_out_west[238]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[19]\": {\n    \"pin\": \"gpio_out_west[239]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[20]\": {\n    \"pin\": \"gpio_out_west[240]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[21]\": {\n    \"pin\": \"gpio_out_west[241]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[22]\": {\n    \"pin\": \"gpio_out_west[242]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[23]\": {\n    \"pin\": \"gpio_out_west[243]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[24]\": {\n    \"pin\": \"gpio_out_west[244]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[25]\": {\n    \"pin\": \"gpio_out_west[245]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[26]\": {\n    \"pin\": \"gpio_out_west[246]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[27]\": {\n    \"pin\": \"gpio_out_west[247]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[28]\": {\n    \"pin\": \"gpio_out_west[248]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[29]\": {\n    \"pin\": \"gpio_out_west[249]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[30]\": {\n    \"pin\": \"gpio_out_west[250]\",\n    \"direction\": \"output\"\n  },\n  \"eoi[31]\": {\n    \"pin\": \"gpio_out_west[251]\",\n    \"direction\": \"output\"\n  },\n  \"irq[0]\": {\n    \"pin\": \"gpio_in_west[60]\",\n    \"direction\": \"input\"\n  },\n  \"irq[1]\": {\n    \"pin\": \"gpio_in_west[61]\",\n    \"direction\": \"input\"\n  },\n  \"irq[2]\": {\n    \"pin\": \"gpio_in_west[62]\",\n    \"direction\": \"input\"\n  },\n  \"irq[3]\": {\n    \"pin\": \"gpio_in_west[63]\",\n    \"direction\": \"input\"\n  },\n  \"irq[4]\": {\n    \"pin\": \"gpio_in_west[64]\",\n    \"direction\": \"input\"\n  },\n  \"irq[5]\": {\n    \"pin\": \"gpio_in_west[65]\",\n    \"direction\": \"input\"\n  },\n  \"irq[6]\": {\n    \"pin\": \"gpio_in_west[66]\",\n    \"direction\": \"input\"\n  },\n  \"irq[7]\": {\n    \"pin\": \"gpio_in_west[67]\",\n    \"direction\": \"input\"\n  },\n  \"irq[8]\": {\n    \"pin\": \"gpio_in_west[68]\",\n    \"direction\": \"input\"\n  },\n  \"irq[9]\": {\n    \"pin\": \"gpio_in_west[69]\",\n    \"direction\": \"input\"\n  },\n  \"irq[10]\": {\n    \"pin\": \"gpio_in_west[70]\",\n    \"direction\": \"input\"\n  },\n  \"irq[11]\": {\n    \"pin\": \"gpio_in_west[71]\",\n    \"direction\": \"input\"\n  },\n  \"irq[12]\": {\n    \"pin\": \"gpio_in_west[72]\",\n    \"direction\": \"input\"\n  },\n  \"irq[13]\": {\n    \"pin\": \"gpio_in_west[73]\",\n    \"direction\": \"input\"\n  },\n  \"irq[14]\": {\n    \"pin\": \"gpio_in_west[74]\",\n    \"direction\": \"input\"\n  },\n  \"irq[15]\": {\n    \"pin\": \"gpio_in_west[75]\",\n    \"direction\": \"input\"\n  },\n  \"irq[16]\": {\n    \"pin\": \"gpio_in_west[76]\",\n    \"direction\": \"input\"\n  },\n  \"irq[17]\": {\n    \"pin\": \"gpio_in_west[77]\",\n    \"direction\": \"input\"\n  },\n  \"irq[18]\": {\n    \"pin\": \"gpio_in_west[78]\",\n    \"direction\": \"input\"\n  },\n  \"irq[19]\": {\n    \"pin\": \"gpio_in_west[79]\",\n    \"direction\": \"input\"\n  },\n  \"irq[20]\": {\n    \"pin\": \"gpio_in_west[80]\",\n    \"direction\": \"input\"\n  },\n  \"irq[21]\": {\n    \"pin\": \"gpio_in_west[81]\",\n    \"direction\": \"input\"\n  },\n  \"irq[22]\": {\n    \"pin\": \"gpio_in_west[82]\",\n    \"direction\": \"input\"\n  },\n  \"irq[23]\": {\n    \"pin\": \"gpio_in_west[83]\",\n    \"direction\": \"input\"\n  },\n  \"irq[24]\": {\n    \"pin\": \"gpio_in_west[84]\",\n    \"direction\": \"input\"\n  },\n  \"irq[25]\": {\n    \"pin\": \"gpio_in_west[85]\",\n    \"direction\": \"input\"\n  },\n  \"irq[26]\": {\n    \"pin\": \"gpio_in_west[86]\",\n    \"direction\": \"input\"\n  },\n  \"irq[27]\": {\n    \"pin\": \"gpio_in_west[87]\",\n    \"direction\": \"input\"\n  },\n  \"irq[28]\": {\n    \"pin\": \"gpio_in_west[88]\",\n    \"direction\": \"input\"\n  },\n  \"irq[29]\": {\n    \"pin\": \"gpio_in_west[89]\",\n    \"direction\": \"input\"\n  },\n  \"irq[30]\": {\n    \"pin\": \"gpio_in_west[90]\",\n    \"direction\": \"input\"\n  },\n  \"irq[31]\": {\n    \"pin\": \"gpio_in_west[91]\",\n    \"direction\": \"input\"\n  },\n  \"trace_data[0]\": {\n    \"pin\": \"gpio_out_west[260]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[1]\": {\n    \"pin\": \"gpio_out_west[261]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[2]\": {\n    \"pin\": \"gpio_out_west[262]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[3]\": {\n    \"pin\": \"gpio_out_west[263]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[4]\": {\n    \"pin\": \"gpio_out_west[264]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[5]\": {\n    \"pin\": \"gpio_out_west[265]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[6]\": {\n    \"pin\": \"gpio_out_west[266]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[7]\": {\n    \"pin\": \"gpio_out_west[267]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[8]\": {\n    \"pin\": \"gpio_out_west[268]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[9]\": {\n    \"pin\": \"gpio_out_west[269]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[10]\": {\n    \"pin\": \"gpio_out_west[270]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[11]\": {\n    \"pin\": \"gpio_out_west[271]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[12]\": {\n    \"pin\": \"gpio_out_west[272]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[13]\": {\n    \"pin\": \"gpio_out_west[273]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[14]\": {\n    \"pin\": \"gpio_out_west[274]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[15]\": {\n    \"pin\": \"gpio_out_west[275]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[16]\": {\n    \"pin\": \"gpio_out_west[276]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[17]\": {\n    \"pin\": \"gpio_out_west[277]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[18]\": {\n    \"pin\": \"gpio_out_west[278]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[19]\": {\n    \"pin\": \"gpio_out_west[279]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[20]\": {\n    \"pin\": \"gpio_out_west[280]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[21]\": {\n    \"pin\": \"gpio_out_west[281]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[22]\": {\n    \"pin\": \"gpio_out_west[282]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[23]\": {\n    \"pin\": \"gpio_out_west[283]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[24]\": {\n    \"pin\": \"gpio_out_west[284]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[25]\": {\n    \"pin\": \"gpio_out_west[285]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[26]\": {\n    \"pin\": \"gpio_out_west[286]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[27]\": {\n    \"pin\": \"gpio_out_west[287]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[28]\": {\n    \"pin\": \"gpio_out_west[288]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[29]\": {\n    \"pin\": \"gpio_out_west[289]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[30]\": {\n    \"pin\": \"gpio_out_west[290]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[31]\": {\n    \"pin\": \"gpio_out_west[291]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[32]\": {\n    \"pin\": \"gpio_out_west[292]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[33]\": {\n    \"pin\": \"gpio_out_west[293]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[34]\": {\n    \"pin\": \"gpio_out_west[294]\",\n    \"direction\": \"output\"\n  },\n  \"trace_data[35]\": {\n    \"pin\": \"gpio_out_west[295]\",\n    \"direction\": \"output\"\n  }\n}"
  },
  {
    "path": "examples/picorv32/picorv32.py",
    "content": "#!/usr/bin/env python3\n\nimport siliconcompiler\nfrom logiklib.zeroasic.z1062 import z1062\nfrom siliconcompiler.tools.yosys.syn_fpga import FPGASynthesis\n\nfrom logik.flows.logik_flow import LogikFlow\n\n\ndef build():\n    module_name = \"picorv32\"\n    design = siliconcompiler.Design(module_name)\n\n    # Fetch picorv32 from the logikbench repo\n    # Silicon Compiler will download and cache the files for us\n    design.set_dataroot(\n        \"picorv32-logikbench\",\n        \"git+https://github.com/zeroasiccorp/logikbench.git\",\n        \"db866c536340c071c563a063c9406888070dfbda\",\n    )\n\n    with design.active_dataroot(\"picorv32-logikbench\"):\n        design.add_file(\n            f\"logikbench/blocks/{module_name}/rtl/{module_name}.v\", fileset=\"rtl\"\n        )\n        design.set_topmodule(module_name, fileset=\"rtl\")\n\n    design.set_dataroot(\"constraints\", __file__)\n    with design.active_dataroot(\"constraints\"):\n        # Add timing constraints\n        design.add_file(f\"{module_name}.sdc\", fileset=\"sdc\")\n\n        # Define pin constraints\n        design.add_file(f\"constraints/z1062/{module_name}.pcf\", fileset=\"pcf\")\n\n    project = siliconcompiler.FPGA(design)\n\n    # add design files to the project\n    project.add_fileset(\"rtl\")\n    project.add_fileset(\"sdc\")\n    project.add_fileset(\"pcf\")\n\n    fpga = z1062.z1062()\n    project.set_fpga(fpga)\n\n    project.set_flow(LogikFlow())\n\n    # set synthesis mode to 'delay'\n    FPGASynthesis.find_task(project=project).set_yosys_synthoptmode(\"delay\")\n\n    # Customize steps for this design\n    project.option.set_quiet(True)\n\n    project.run()\n    project.summary()\n\n\nif __name__ == \"__main__\":\n    build()\n"
  },
  {
    "path": "examples/picorv32/picorv32.sdc",
    "content": "create_clock -period 12.5 clk\n"
  },
  {
    "path": "logik/__init__.py",
    "content": "try:\n    from logik._version import __version__\nexcept ImportError:\n    # This only exists in installations\n    __version__ = None\n"
  },
  {
    "path": "logik/devices/__init__.py",
    "content": ""
  },
  {
    "path": "logik/devices/logik_fpga.py",
    "content": "from siliconcompiler.tools.opensta import OpenSTAFPGA\nfrom siliconcompiler.tools.vpr import VPRFPGA\nfrom siliconcompiler.tools.yosys import YosysFPGA\n\n\nclass LogikFPGA(YosysFPGA, VPRFPGA, OpenSTAFPGA):\n    \"\"\"\n    Class for logik FPGA devices\n    \"\"\"\n\n    def __init__(self) -> None:\n        super().__init__()\n\n    def set_convert_bitstream_bitstream_map(\n        self, file: str, dataroot: str | None = None\n    ):\n        with self.active_dataroot(self._get_active_dataroot(dataroot)):\n            return self.set(\"tool\", \"convert_bitstream\", \"bitstream_map\", file)\n"
  },
  {
    "path": "logik/flows/__init__.py",
    "content": ""
  },
  {
    "path": "logik/flows/logik_flow.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nfrom siliconcompiler.flows import fpgaflow\n\nfrom logik.tools.fasm_to_bitstream import bitstream_finish\n\n\nclass LogikFlow(fpgaflow.FPGAVPROpenSTAFlow):\n    \"\"\"An open-source FPGA flow using Yosys, VPR, and GenFasm.\n\n    This flow is designed for academic and research FPGAs, utilizing VPR\n    (Versatile Place and Route) for placement and routing.\n\n    The flow consists of the following steps:\n\n    * **elaborate**: Elaborate the RTL design from sources.\n    * **synthesis**: Synthesize the elaborated design into a netlist using Yosys.\n    * **place**: Place the netlist components onto the FPGA architecture using VPR.\n    * **route**: Route the connections between placed components using VPR.\n    * **timing**: Perform static analysis using OpenSTA.\n    * **bitstream**: Generate the final bitstream using GenFasm.\n    * **convert_bitstream**: Format bitstream from fasm to bits.\n    \"\"\"\n\n    def __init__(self, name: str = \"logik_flow\") -> None:\n        \"\"\"\n        Initializes the FPGAVPRFlow.\n\n        Args:\n            name (str): The name of the flow.\n        \"\"\"\n        super().__init__(name)\n\n        self.node(\"convert_bitstream\", bitstream_finish.BitstreamFinishTask())\n        self.edge(\"bitstream\", \"convert_bitstream\")\n\n\nif __name__ == \"__main__\":\n    LogikFlow().write_flowgraph(f\"{LogikFlow().name}.png\")\n"
  },
  {
    "path": "logik/tools/__init__.py",
    "content": ""
  },
  {
    "path": "logik/tools/fasm_to_bitstream/__init__.py",
    "content": ""
  },
  {
    "path": "logik/tools/fasm_to_bitstream/bitstream_bin_convert.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport argparse\n\n\ndef main() -> None:\n\n    option_parser = argparse.ArgumentParser()\n\n    option_parser.add_argument(\"binary_bitstream\", help=\"binary bitstream file\")\n    option_parser.add_argument(\"ascii_bitstream\", help=\"ascii bitstream file\")\n\n    options = option_parser.parse_args()\n\n    bin_filename = options.binary_bitstream\n    out_filename = options.ascii_bitstream\n\n    words = []\n    with open(bin_filename, \"rb\") as bin_file:\n        for cur_byte in bin_file.read():\n            formatted_word = format(cur_byte, \"0x\").zfill(2)\n            words.append(formatted_word)\n\n    with open(out_filename, \"w\") as out_file:\n        for word in words:\n            out_file.write(word)\n            out_file.write(\"\\n\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "logik/tools/fasm_to_bitstream/bitstream_finish.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nfrom siliconcompiler.tool import Task\n\nfrom logik.tools.fasm_to_bitstream import fasm_to_bitstream as fasm_utils\n\n\nclass BitstreamFinishTask(Task):\n    def __init__(self) -> None:\n        super().__init__()\n\n    def tool(self) -> str:\n        return \"fasm_to_bitstream\"\n\n    def task(self) -> str:\n        return \"bitstream_finish\"\n\n    def setup(self) -> None:\n        \"\"\"\n        Perform bitstream finishing\n        \"\"\"\n        super().setup()\n\n        fpga = self.project.get(\"fpga\", \"device\")\n        fpga_obj = self.project.get(\"library\", fpga, field=\"schema\")\n\n        self.add_required_key(fpga_obj, \"tool\", \"convert_bitstream\", \"bitstream_map\")\n\n        self.add_input_file(ext=\"fasm\")\n        self.add_output_file(ext=\"json\")\n        self.add_output_file(ext=\"bin\")\n\n    def run(self) -> int:\n        fpga = self.project.get(\"fpga\", \"device\")\n        fpga_obj = self.project.get(\"library\", fpga, field=\"schema\")\n\n        fasm_file = f\"inputs/{self.design_topmodule}.fasm\"\n\n        bitstream_map = fpga_obj.find_files(\n            \"tool\", \"convert_bitstream\", \"bitstream_map\"\n        )\n\n        json_outfile = f\"outputs/{self.design_topmodule}.json\"\n        binary_outfile = f\"outputs/{self.design_topmodule}.bin\"\n\n        # Finishing steps are as follows:\n        # 1. Convert FASM to IR\n        config_bitstream = fasm_utils.fasm2bitstream(fasm_file, bitstream_map)\n\n        # 2.  Write IR to JSON for inspection purposes\n        fasm_utils.write_bitstream_json(config_bitstream, json_outfile)\n\n        # 3.  Flatten the IR to a 1D address space\n        flattened_bitstream = fasm_utils.generate_flattened_bitstream(config_bitstream)\n\n        # 4.  Format the flattened bitstream to binary\n        binary_bitstream = fasm_utils.format_binary_bitstream(flattened_bitstream)\n\n        # 5.  Write binary to file\n        fasm_utils.write_bitstream_binary(binary_bitstream, binary_outfile)\n\n        return 0\n"
  },
  {
    "path": "logik/tools/fasm_to_bitstream/fasm_to_bitstream.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport json\nimport math\nimport re\nimport sys\nfrom typing import Any\n\nimport numpy as np\nfrom numpy import dtype, ndarray\n\n\ndef main() -> None:\n    fasm_file = sys.argv[1]\n    bitstream_map_file = sys.argv[2]\n    json_bitstream_file = sys.argv[3]\n    dat_bitstream_file = sys.argv[4]\n    bin_bitstream_file = sys.argv[5]\n\n    config_bitstream = fasm2bitstream(fasm_file, bitstream_map_file)\n    write_bitstream_json(config_bitstream, json_bitstream_file)\n    flattened_bitstream = generate_flattened_bitstream(config_bitstream)\n    write_bitstream_data(flattened_bitstream, dat_bitstream_file)\n    binary_bitstream = format_binary_bitstream(flattened_bitstream)\n    write_bitstream_binary(binary_bitstream, bin_bitstream_file)\n\n\ndef write_bitstream_json(config_bitstream, json_bitstream_file) -> None:\n    with open(json_bitstream_file, \"w\") as json_out:\n        json_out.write(json.dumps(config_bitstream))\n        json_out.write(\"\\n\")\n\n\ndef write_bitstream_data(config_bitstream, dat_bitstream_file) -> None:\n    with open(dat_bitstream_file, \"w\") as dat_out:\n        dat_out.writelines(f\"{entry}\\n\" for entry in config_bitstream)\n\n\ndef write_bitstream_binary(binary_bitstream, binary_bitstream_file) -> None:\n    binary_bitstream.tofile(binary_bitstream_file)\n\n\ndef calculate_bitstream_columns(bitstream_map) -> int:\n\n    return len(bitstream_map)\n\n\ndef calculate_bitstream_rows(bitstream_map) -> int:\n\n    max_rows = -1\n    # ***TO DO:  Add SC-compliant error checking that\n    #            the row count is constant across columns\n    #            (or eventually allow non-constant count\n    #            for non-rectangular FPGAs)\n    for i in range(len(bitstream_map)):\n        max_rows = max(max_rows, len(bitstream_map[i]))\n\n    return max_rows\n\n\ndef calculate_address_size(bitstream_map) -> int:\n\n    max_length = 0\n\n    for x in range(len(bitstream_map)):\n        for y in range(len(bitstream_map[x])):\n            max_length = max(max_length, len(bitstream_map[x][y]))\n\n    return max_length\n\n\ndef calculate_config_data_width(bitstream_map) -> int:\n\n    # ***TO DO:  The config data width is supposed to be\n    #            constant for all addresses, so we should\n    #            add error checking to see if it ever\n    #            deviates.  Need an SC-compliant way to do\n    #            this before implementing\n    max_config_width = 0\n    for x in range(len(bitstream_map)):\n        for y in range(len(bitstream_map[x])):\n            for address in range(len(bitstream_map[x][y])):\n                if len(bitstream_map[x][y][address]) > max_config_width:\n                    # To prevent runaway runtimes, assume that the config\n                    # width is constant throughout the bitstream map\n                    # and abort after we find a positive value\n                    max_config_width = len(bitstream_map[x][y][address])\n                    break\n\n    return max_config_width\n\n\n# In this converter, the bitstream address space is flattened\n# into a vector; this is useful for prepping the bitstream for\n# storage into a ROM that will be loaded over a serial interface\n# To align to the bitstream ordering that is required by\n# the bitstream loading circuit, it is necessary to do some\n# arithmetic to pick which configuration words go in which\n# order in the flattened vector; see below for details\ndef generate_flattened_bitstream(bitstream_map) -> list[str]:\n\n    # Convert FPGA array dimensions into address space bit widths;\n    # this will assist in flattening the address space:\n    num_bitstream_columns = calculate_bitstream_columns(bitstream_map)\n    num_bitstream_rows = calculate_bitstream_rows(bitstream_map)\n    address_length = int.bit_length(calculate_address_size(bitstream_map))\n    x_length = int.bit_length(num_bitstream_columns - 1)\n    y_length = int.bit_length(num_bitstream_rows - 1)\n\n    # Get the word size of the words in the bitstream\n    config_data_width = calculate_config_data_width(bitstream_map)\n\n    input_bus_width = x_length + y_length + address_length\n\n    default_entry = format(0, \"0x\").zfill(int(config_data_width / 4))\n\n    bitstream_vector = [default_entry] * pow(2, input_bus_width)\n\n    for x in range(len(bitstream_map)):\n        for y in range(len(bitstream_map[x])):\n            for address in range(len(bitstream_map[x][y])):\n                vector_address = y * pow(2, x_length + address_length)\n                vector_address += x * pow(2, address_length)\n                vector_address += address\n\n                bitstream_data = concatenate_data(bitstream_map[x][y][address])\n                formatted_data = format(bitstream_data, \"0x\").zfill(\n                    int(config_data_width / 4)\n                )\n                bitstream_vector[vector_address] = formatted_data\n\n    return bitstream_vector\n\n\ndef concatenate_data(data_array) -> int:\n\n    data_sum = 0\n    scale_factor = 1\n\n    for i in range(len(data_array)):\n        if data_array[i] == 1:\n            data_sum += scale_factor\n        scale_factor = scale_factor * 2\n\n    return data_sum\n\n\ndef format_binary_bitstream(bitstream_data, word_size=8) -> ndarray[Any, dtype]:\n\n    converted_data = []\n\n    for element in bitstream_data:\n        element_temp = int(element.rstrip(), 16)\n        sub_element_count = math.ceil(word_size / 8)\n        for i in range(sub_element_count):\n            cur_data_word = element_temp & ((1 << 8) - 1)\n            converted_data.append(cur_data_word)\n            element_temp = element_temp >> 8\n\n    bitstream_data_array = np.array(converted_data, np.uint8)\n\n    return bitstream_data_array\n\n\ndef fasm2bitstream(\n    fasm_file, bitstream_map_file) -> list[list[list[list[int]]]]:\n\n    with open(bitstream_map_file, \"r\") as map_file:\n        json_bitstream_map = json.load(map_file)\n        bitstream_map = json_bitstream_map[\"bitstream\"]\n\n    fasm_features = load_fasm_data(\n        fasm_file\n    )\n\n    config_bitstream = generate_bitstream_from_fasm(bitstream_map, fasm_features)\n\n    return config_bitstream\n\n\ndef load_fasm_data(filename) -> list[str]:\n    with open(filename, \"r\") as fasm_file:\n        fasm_feature_list = fasm_file.readlines()\n\n    # \"Canonicalize\" the feature list, as described here:\n    # https://fasm.readthedocs.io/en/latest/specification/syntax.html\n\n    canonical_fasm_feature_list = []\n\n    for feature in fasm_feature_list:\n        feature = feature.rstrip()\n        if \"=\" in feature:\n            feature_fields = feature.split(\"=\")\n            if len(feature_fields) == 2:\n                feature_name = feature_fields[0]\n                feature_value = feature_fields[1]\n\n                # ***TO DO:  Select a more robust detector of a multibit feature\n                #            than array index colon checking\n                if \":\" in feature_name:\n                    errors = 0\n\n                    feature_split_pattern = r\"[\\[\\]:]\"\n                    feature_name_fields = re.split(feature_split_pattern, feature_name)\n\n                    # ***ASSUMPTION: All FASM feature output will be binary\n                    feature_array = feature_value.split(\"'b\")\n\n                    if len(feature_name_fields) < 2:\n                        errors += 1\n\n                    else:\n                        base_feature_length = int(feature_array[0])\n                        base_feature_value = feature_array[1]\n\n                        if base_feature_length != len(base_feature_value):\n                            errors += 1\n\n                    if len(feature_name_fields) < 3:\n                        errors += 1\n\n                    if errors == 0:\n                        base_feature_name = feature_name_fields[0]\n                        base_feature_name_msb = int(feature_name_fields[1])\n\n                        for i in range(len(base_feature_value)):\n                            # multi-bit fasm features are represented big-endian, so:\n                            if base_feature_value[i] == \"1\":\n                                cur_index = base_feature_name_msb - i\n                                indexed_feature_name = (\n                                    f\"{base_feature_name}[{cur_index}]\"\n                                )\n                                canonical_fasm_feature_list.append(indexed_feature_name)\n\n                else:\n                    if feature_value != 0:\n                        canonical_fasm_feature_list.append(feature_name)\n\n        else:\n            canonical_fasm_feature_list.append(feature)\n\n    return canonical_fasm_feature_list\n\n\ndef generate_bitstream_from_fasm(\n    address_map, fasm_data,\n) -> list[list[list[list[int]]]]:\n\n    feature_index = invert_address_map(address_map)\n    bitstream = []\n    for x in range(len(address_map)):\n        bitstream.append([])\n        for y in range(len(address_map[x])):\n            bitstream[x].append([])\n            for address in range(len(address_map[x][y])):\n                bitstream[x][y].append([0] * len(address_map[x][y][address]))\n\n    for fasm_feature in fasm_data:\n        if fasm_feature not in feature_index:\n            print(f\"fasm feature '{fasm_feature}' not found in address map\")\n            continue\n        x_i = feature_index[fasm_feature][\"x\"]\n        y_i = feature_index[fasm_feature][\"y\"]\n        addr_i = feature_index[fasm_feature][\"address\"]\n        bit_i = feature_index[fasm_feature][\"bit\"]\n        bitstream[x_i][y_i][addr_i][bit_i] = 1\n\n    return bitstream\n\n\ndef invert_address_map(address_map) -> dict[Any, dict[str, int]]:\n\n    feature_index = {}\n    for x in range(len(address_map)):\n        for y in range(len(address_map[x])):\n            for address in range(len(address_map[x][y])):\n                for bit in range(len(address_map[x][y][address])):\n                    feature_index[address_map[x][y][address][bit]] = {}\n                    feature_index[address_map[x][y][address][bit]][\"x\"] = x\n                    feature_index[address_map[x][y][address][bit]][\"y\"] = y\n                    feature_index[address_map[x][y][address][bit]][\"address\"] = address\n                    feature_index[address_map[x][y][address][bit]][\"bit\"] = bit\n\n    return feature_index\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\n    \"setuptools >= 80\",\n    \"setuptools_scm[toml] >= 8\"\n]\n\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"logik\"\nauthors = [{name = \"Zero ASIC\"}]\ndescription = \"Logik is a light weight FPGA tool chain based on mature open source technologies.\"\nreadme = \"README.md\"\nurls = {Homepage = \"https://github.com/siliconcompiler/logik\"}\nrequires-python = \">= 3.10\"\ndependencies = [\n    # Use ~= to allow users to pull in bug fixes and compatible future releases (>= current, < next minor)\n    \"logiklib ~= 0.2.0\",\n    \"siliconcompiler ~= 0.37.2\"\n]\n\nlicense = \"Apache-2.0\"\nlicense-files = [\"LICENSE\"]\n\ndynamic = [\"version\"]\n\n[tool.setuptools_scm]\nwrite_to = \"logik/_version.py\"\nwrite_to_template = '''\n# This file is automatically generated by setuptools_scm.\n# Do not edit it directly.\n__version__ = \"{version}\"\n__base_version__ = \"{scm_version.tag}\"\n'''\n\n[project.optional-dependencies]\ntest = [\n    \"pytest == 9.0.3\",\n    \"pytest-timeout == 2.4.0\",\n    \"flake8 == 7.3.0\"\n]\ndocs = [\n    \"Sphinx == 8.1.3\",\n    \"sphinx-rtd-theme == 3.1.0\",\n    \"autodocsumm == 0.2.15\"\n]\n\n[tool.setuptools]\ninclude-package-data = true\npackages = [\n    \"logik\"\n]\n\n[tool.pytest.ini_options]\ntestpaths = \"tests\"\ntimeout = \"180\"\nmarkers = [\n    \"quick: always run this test on push\"\n]\nfilterwarnings = [\n    \"ignore::DeprecationWarning:pip._internal\"\n]\n"
  },
  {
    "path": "tests/conftest.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\n\nimport pytest\nimport siliconcompiler\n\n\n@pytest.fixture\ndef setup_example_test(monkeypatch):\n    \"\"\"\n    This file is cloned from Silicon Compiler.  We follow its convention\n    for organizing CI tests with pytest, so that all testing can be done with\n    similar efficiency.  See Silicon Compiler documentation for details\n    \"\"\"\n\n    def setup(directory):\n        cad_root = ebrick_fpga_cad_root()\n        ex_dir = os.path.join(cad_root, \"examples\", directory)\n\n        def _mock_show(chip, filename=None, screenshot=False):\n            pass\n\n        # pytest's monkeypatch lets us modify sys.path for this test only.\n        monkeypatch.syspath_prepend(ex_dir)\n        # Mock chip.show() so it doesn't run.\n        monkeypatch.setattr(siliconcompiler.Project, \"show\", _mock_show)\n\n        return ex_dir\n\n    return setup\n\n\ndef ebrick_fpga_cad_root():\n    return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n"
  },
  {
    "path": "tests/data/z1000.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n\nfrom logik.devices.logik_fpga import LogikFPGA\n\n\nclass z1000(LogikFPGA):\n    \"\"\"\n    Logik driver for z1000\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        part_name = \"z1000\"\n        self.set_name(part_name)\n\n        self.define_tool_parameter(\n            \"convert_bitstream\",\n            \"bitstream_map\",\n            \"file\",\n            \"map for fasm->bitstream conversion\",\n        )\n\n        self.set_dataroot(\n            part_name,\n            f\"github://siliconcompiler/logiklib/v0.1.0/{part_name}_cad.tar.gz\",\n            \"0.1.0\",\n        )\n\n        self.package.set_vendor(\"ZeroASIC\")\n        self.set_lutsize(4)\n\n        self.add_yosys_registertype([\"dff\", \"dffr\", \"dffe\", \"dffer\"])\n        self.add_yosys_featureset([\"async_reset\", \"enable\"])\n        with self.active_dataroot(part_name):\n            self.set_yosys_flipfloptechmap(\"techlib/tech_flops.v\")\n\n        self.set_vpr_devicecode(part_name)\n        self.set_vpr_clockmodel(\"route\")\n        self.set_vpr_channelwidth(50)\n        self.add_vpr_registertype([\"dff\", \"dffr\", \"dffe\", \"dffer\"])\n        with self.active_dataroot(part_name):\n            self.set_vpr_archfile(\"cad/z1000.xml\")\n            self.set_vpr_graphfile(\"cad/z1000_rr_graph.xml\")\n            self.set_vpr_constraintsmap(\"cad/z1000_constraint_map.json\")\n\n        with self.active_dataroot(part_name):\n            self.set_convert_bitstream_bitstream_map(\"cad/z1000_bitstream_map.json\")\n\n        self.set_vpr_router_lookahead(\"classic\")\n"
  },
  {
    "path": "tests/examples/test_adder.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\nimport subprocess\n\nimport pytest\n\n\n@pytest.mark.timeout(300)\ndef test_py(setup_example_test, monkeypatch):\n    adder_dir = setup_example_test(\"adder\")\n\n    monkeypatch.chdir(adder_dir)\n    # create_cmdline() parses sys.argv directly; without this, pytest's own\n    # arguments (e.g. -v matching argparse's -version prefix) cause it to exit.\n    monkeypatch.setattr('sys.argv', ['adder.py'])\n\n    import adder\n\n    adder.hello_adder()\n\n\n@pytest.mark.timeout(300)\ndef test_cli(setup_example_test):\n    adder_dir = setup_example_test(\"adder\")\n\n    proc = subprocess.run(\n        [os.path.join(adder_dir, \"adder.py\")], cwd=adder_dir, check=False\n    )\n    assert proc.returncode == 0\n"
  },
  {
    "path": "tests/examples/test_eth_mac_1g.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\nimport subprocess\n\nimport pytest\n\n\n@pytest.mark.timeout(720)\ndef test_py(setup_example_test, monkeypatch):\n    eth_mac_1g_dir = setup_example_test(\"eth_mac_1g\")\n\n    monkeypatch.chdir(eth_mac_1g_dir)\n\n    import eth_mac_1g\n\n    eth_mac_1g.build()\n\n\n@pytest.mark.timeout(720)\ndef test_cli(setup_example_test):\n    eth_mac_1g_dir = setup_example_test(\"eth_mac_1g\")\n\n    proc = subprocess.run(\n        [os.path.join(eth_mac_1g_dir, \"eth_mac_1g.py\")], cwd=eth_mac_1g_dir, check=False\n    )\n    assert proc.returncode == 0\n"
  },
  {
    "path": "tests/examples/test_files.py",
    "content": "# Copyright 2024 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport siliconcompiler\nfrom data.z1000 import z1000\n\n\ndef test_file_paths():\n    project = siliconcompiler.FPGA(\"test\")\n    project.set_fpga(z1000())\n    project.set(\"option\", \"builddir\", \".\")\n    assert project.check_filepaths()\n"
  },
  {
    "path": "tests/examples/test_picorv32.py",
    "content": "# Copyright 2025 Zero ASIC Corporation\n# Licensed under the MIT License (see LICENSE for details)\n\nimport os\nimport subprocess\n\nimport pytest\n\n\n@pytest.mark.timeout(360)\ndef test_py(setup_example_test, monkeypatch):\n    picorv32_dir = setup_example_test(\"picorv32\")\n\n    monkeypatch.chdir(picorv32_dir)\n\n    import picorv32\n\n    picorv32.build()\n\n\n@pytest.mark.timeout(360)\ndef test_cli(setup_example_test):\n    picorv32_dir = setup_example_test(\"picorv32\")\n\n    proc = subprocess.run(\n        [os.path.join(picorv32_dir, \"picorv32.py\")], cwd=picorv32_dir, check=False\n    )\n    assert proc.returncode == 0\n"
  }
]