├── pypi-ecp5 ├── README.md ├── yowasp_nextpnr_ecp5 │ ├── ecpbram.wasm │ ├── ecppack.wasm │ ├── ecppll.wasm │ ├── share │ │ ├── ecp5 │ │ └── trellis │ │ │ └── database │ │ │ ├── ECP5 │ │ │ └── devices.json │ ├── ecpmulti.wasm │ ├── ecpunpack.wasm │ ├── nextpnr-ecp5.wasm │ └── __init__.py ├── .gitignore ├── setup.py └── pyproject.toml ├── pypi-ice40 ├── README.md ├── yowasp_nextpnr_ice40 │ ├── share │ │ └── ice40 │ ├── icebram.wasm │ ├── icepack.wasm │ ├── icepll.wasm │ ├── icemulti.wasm │ ├── nextpnr-ice40.wasm │ └── __init__.py ├── .gitignore ├── setup.py └── pyproject.toml ├── pypi-nexus ├── README.md ├── yowasp_nextpnr_nexus │ ├── share │ │ └── nexus │ ├── nextpnr-nexus.wasm │ ├── prjoxide.wasm │ └── __init__.py ├── .gitignore ├── setup.py └── pyproject.toml ├── pypi-machxo2 ├── README.md ├── yowasp_nextpnr_machxo2 │ ├── ecpbram.wasm │ ├── ecppack.wasm │ ├── ecppll.wasm │ ├── ecpmulti.wasm │ ├── ecpunpack.wasm │ ├── share │ │ ├── machxo2 │ │ └── trellis │ │ │ └── database │ │ │ ├── MachXO │ │ │ ├── MachXO2 │ │ │ ├── MachXO3 │ │ │ ├── MachXO3D │ │ │ └── devices.json │ ├── nextpnr-machxo2.wasm │ └── __init__.py ├── .gitignore ├── setup.py └── pyproject.toml ├── .github ├── FUNDING.yml └── workflows │ ├── track-upstream.yml │ └── package.yml ├── pypi-himbaechel-gowin ├── README.md ├── dependencies.txt ├── dependencies-apycula.txt ├── .gitignore ├── yowasp_nextpnr_himbaechel_gowin │ ├── share │ │ └── himbaechel │ │ │ └── gowin │ ├── nextpnr-himbaechel-gowin.wasm │ └── __init__.py ├── setup.py └── pyproject.toml ├── apycula-meta └── requirements.txt ├── npmjs-ecp5 ├── prepare.py ├── share │ ├── ecp5 │ └── trellis │ │ └── database │ │ ├── ECP5 │ │ └── devices.json ├── package-in.json ├── .gitignore ├── package-local.json └── lib │ ├── api.d.ts │ └── api.js ├── npmjs-ice40 ├── prepare.py ├── package-in.json ├── share │ └── ice40 ├── .gitignore ├── package-local.json └── lib │ ├── api.d.ts │ └── api.js ├── npmjs-nexus ├── prepare.py ├── package-in.json ├── share │ └── nexus ├── .gitignore ├── package-local.json └── lib │ ├── api.js │ └── api.d.ts ├── npmjs-machxo2 ├── prepare.py ├── package-in.json ├── share │ ├── machxo2 │ └── trellis │ │ └── database │ │ ├── MachXO │ │ ├── MachXO2 │ │ ├── MachXO3 │ │ ├── MachXO3D │ │ └── devices.json ├── .gitignore ├── package-local.json └── lib │ ├── api.d.ts │ └── api.js ├── npmjs-himbaechel-gowin ├── prepare.py ├── package-in.json ├── share │ └── himbaechel │ │ └── gowin ├── .gitignore ├── package-local.json └── lib │ ├── api.d.ts │ ├── api.js │ └── pyodide.js ├── npmjs-common ├── .gitignore ├── package-in.json └── prepare.py ├── .gitignore ├── package-pypi-ecp5.sh ├── package-pypi-ice40.sh ├── package-pypi-machxo2.sh ├── package-pypi-nexus.sh ├── package-pypi-himbaechel-gowin.sh ├── package-npmjs-ecp5.sh ├── package-npmjs-ice40.sh ├── package-npmjs-nexus.sh ├── package-npmjs-machxo2.sh ├── .gitmodules ├── CONTRIBUTING.md ├── pypi-common └── yowasp_nextpnr_version.py ├── LICENSE.txt ├── package-npmjs-himbaechel-gowin.sh ├── purge-test-pypi-releases.py └── README.md /pypi-ecp5/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /pypi-ice40/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /pypi-nexus/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /pypi-machxo2/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: whitequark 2 | -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /apycula-meta/requirements.txt: -------------------------------------------------------------------------------- 1 | Apycula==0.28 2 | -------------------------------------------------------------------------------- /npmjs-ecp5/prepare.py: -------------------------------------------------------------------------------- 1 | ../npmjs-common/prepare.py -------------------------------------------------------------------------------- /npmjs-ice40/prepare.py: -------------------------------------------------------------------------------- 1 | ../npmjs-common/prepare.py -------------------------------------------------------------------------------- /npmjs-nexus/prepare.py: -------------------------------------------------------------------------------- 1 | ../npmjs-common/prepare.py -------------------------------------------------------------------------------- /npmjs-ecp5/share/ecp5: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/share/ecp5/ -------------------------------------------------------------------------------- /npmjs-machxo2/prepare.py: -------------------------------------------------------------------------------- 1 | ../npmjs-common/prepare.py -------------------------------------------------------------------------------- /npmjs-ecp5/package-in.json: -------------------------------------------------------------------------------- 1 | ../npmjs-common/package-in.json -------------------------------------------------------------------------------- /npmjs-ice40/package-in.json: -------------------------------------------------------------------------------- 1 | ../npmjs-common/package-in.json -------------------------------------------------------------------------------- /npmjs-ice40/share/ice40: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/share/ice40/ -------------------------------------------------------------------------------- /npmjs-nexus/package-in.json: -------------------------------------------------------------------------------- 1 | ../npmjs-common/package-in.json -------------------------------------------------------------------------------- /npmjs-nexus/share/nexus: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/share/nexus/ -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/prepare.py: -------------------------------------------------------------------------------- 1 | ../npmjs-common/prepare.py -------------------------------------------------------------------------------- /npmjs-machxo2/package-in.json: -------------------------------------------------------------------------------- 1 | ../npmjs-common/package-in.json -------------------------------------------------------------------------------- /npmjs-machxo2/share/machxo2: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/share/machxo2/ -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/dependencies.txt: -------------------------------------------------------------------------------- 1 | yowasp-runtime~=1.1 2 | -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/package-in.json: -------------------------------------------------------------------------------- 1 | ../npmjs-common/package-in.json -------------------------------------------------------------------------------- /npmjs-ecp5/share/trellis/database/ECP5: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/ECP5 -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/ecpbram.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecpbram.wasm -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/ecppack.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecppack.wasm -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/ecppll.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecppll.wasm -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/share/ecp5: -------------------------------------------------------------------------------- 1 | ../../../nextpnr-build/share/ecp5/ -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/dependencies-apycula.txt: -------------------------------------------------------------------------------- 1 | ../apycula-meta/requirements.txt -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/share/ice40: -------------------------------------------------------------------------------- 1 | ../../../nextpnr-build/share/ice40 -------------------------------------------------------------------------------- /pypi-nexus/yowasp_nextpnr_nexus/share/nexus: -------------------------------------------------------------------------------- 1 | ../../../nextpnr-build/share/nexus -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/ecpmulti.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecpmulti.wasm -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/ecpunpack.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecpunpack.wasm -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/icebram.wasm: -------------------------------------------------------------------------------- 1 | ../../icestorm-prefix/bin/icebram.wasm -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/icepack.wasm: -------------------------------------------------------------------------------- 1 | ../../icestorm-prefix/bin/icepack.wasm -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/icepll.wasm: -------------------------------------------------------------------------------- 1 | ../../icestorm-prefix/bin/icepll.wasm -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/ecpbram.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecpbram.wasm -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/ecppack.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecppack.wasm -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/ecppll.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecppll.wasm -------------------------------------------------------------------------------- /npmjs-machxo2/share/trellis/database/MachXO: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/MachXO -------------------------------------------------------------------------------- /npmjs-machxo2/share/trellis/database/MachXO2: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/MachXO2 -------------------------------------------------------------------------------- /npmjs-machxo2/share/trellis/database/MachXO3: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/MachXO3 -------------------------------------------------------------------------------- /pypi-ecp5/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | /*.egg-info 3 | /.eggs 4 | /build 5 | /dist 6 | -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/nextpnr-ecp5.wasm: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/nextpnr-ecp5.wasm -------------------------------------------------------------------------------- /pypi-ice40/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | /*.egg-info 3 | /.eggs 4 | /build 5 | /dist 6 | -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/icemulti.wasm: -------------------------------------------------------------------------------- 1 | ../../icestorm-prefix/bin/icemulti.wasm -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/nextpnr-ice40.wasm: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/nextpnr-ice40.wasm -------------------------------------------------------------------------------- /pypi-machxo2/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | /*.egg-info 3 | /.eggs 4 | /build 5 | /dist 6 | -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/ecpmulti.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecpmulti.wasm -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/ecpunpack.wasm: -------------------------------------------------------------------------------- 1 | ../../prjtrellis-build/ecpunpack.wasm -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/share/machxo2: -------------------------------------------------------------------------------- 1 | ../../../nextpnr-build/share/machxo2 -------------------------------------------------------------------------------- /pypi-nexus/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | /*.egg-info 3 | /.eggs 4 | /build 5 | /dist 6 | -------------------------------------------------------------------------------- /pypi-nexus/yowasp_nextpnr_nexus/nextpnr-nexus.wasm: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/nextpnr-nexus.wasm -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/share/himbaechel/gowin: -------------------------------------------------------------------------------- 1 | ../../../nextpnr-build/share/himbaechel/gowin/ -------------------------------------------------------------------------------- /npmjs-machxo2/share/trellis/database/MachXO3D: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/MachXO3D -------------------------------------------------------------------------------- /npmjs-ecp5/share/trellis/database/devices.json: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/devices.json -------------------------------------------------------------------------------- /npmjs-machxo2/share/trellis/database/devices.json: -------------------------------------------------------------------------------- 1 | ../../../../prjtrellis-src/database/devices.json -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | /*.egg-info 3 | /.eggs 4 | /build 5 | /dist 6 | -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/nextpnr-machxo2.wasm: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/nextpnr-machxo2.wasm -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/share/trellis/database/ECP5: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/ECP5/ -------------------------------------------------------------------------------- /pypi-nexus/yowasp_nextpnr_nexus/prjoxide.wasm: -------------------------------------------------------------------------------- 1 | ../../prjoxide-build/wasm32-wasip1/release/prjoxide.wasm -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/share/trellis/database/MachXO: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/MachXO -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/share/trellis/database/MachXO2: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/MachXO2 -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/share/trellis/database/MachXO3: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/MachXO3 -------------------------------------------------------------------------------- /npmjs-common/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | -------------------------------------------------------------------------------- /npmjs-ecp5/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | -------------------------------------------------------------------------------- /npmjs-ice40/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | -------------------------------------------------------------------------------- /npmjs-nexus/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/share/trellis/database/devices.json: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/devices.json -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/share/trellis/database/MachXO3D: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/MachXO3D -------------------------------------------------------------------------------- /npmjs-machxo2/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/share/trellis/database/devices.json: -------------------------------------------------------------------------------- 1 | ../../../../../prjtrellis-src/database/devices.json -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/yowasp_nextpnr_himbaechel_gowin/share/himbaechel/gowin: -------------------------------------------------------------------------------- 1 | ../../../../nextpnr-build/share/himbaechel/gowin/ -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/yowasp_nextpnr_himbaechel_gowin/nextpnr-himbaechel-gowin.wasm: -------------------------------------------------------------------------------- 1 | ../../nextpnr-build/nextpnr-himbaechel-gowin.wasm -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /wasi-sdk-* 2 | 3 | /boost-* 4 | /eigen-* 5 | /*-build 6 | /*-prefix 7 | /Toolchain-WASI.cmake 8 | 9 | .venv*/ 10 | -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | /share/python 9 | -------------------------------------------------------------------------------- /package-pypi-ecp5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | cd $(dirname $0) 6 | 7 | cd pypi-ecp5 8 | rm -rf build && ${PYTHON} -m build -w 9 | sha256sum dist/*.whl 10 | -------------------------------------------------------------------------------- /package-pypi-ice40.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | cd $(dirname $0) 6 | 7 | cd pypi-ice40 8 | rm -rf build && ${PYTHON} -m build -w 9 | sha256sum dist/*.whl 10 | -------------------------------------------------------------------------------- /package-pypi-machxo2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | cd $(dirname $0) 6 | 7 | cd pypi-machxo2 8 | rm -rf build && ${PYTHON} -m build -w 9 | sha256sum dist/*.whl 10 | -------------------------------------------------------------------------------- /package-pypi-nexus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | cd $(dirname $0) 6 | 7 | cd pypi-nexus 8 | rm -rf build && ${PYTHON} -m build -w 9 | sha256sum dist/*.whl 10 | -------------------------------------------------------------------------------- /package-pypi-himbaechel-gowin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | cd $(dirname $0) 6 | 7 | cd pypi-himbaechel-gowin 8 | rm -rf build && ${PYTHON} -m build -w 9 | sha256sum dist/*.whl 10 | -------------------------------------------------------------------------------- /npmjs-nexus/package-local.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "transpile": [ 4 | "../prjoxide-build/wasm32-wasip1/release/prjoxide.wasm", 5 | "../nextpnr-build/nextpnr-nexus.wasm" 6 | ] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package-npmjs-ecp5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | PYTHON=${PYTHON:-python} 6 | 7 | cd npmjs-ecp5 8 | ${PYTHON} prepare.py ecp5 9 | npm install 10 | npm run all 11 | 12 | mkdir -p dist 13 | npm pack --pack-destination dist 14 | -------------------------------------------------------------------------------- /package-npmjs-ice40.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | PYTHON=${PYTHON:-python} 6 | 7 | cd npmjs-ice40 8 | ${PYTHON} prepare.py ice40 9 | npm install 10 | npm run all 11 | 12 | mkdir -p dist 13 | npm pack --pack-destination dist 14 | -------------------------------------------------------------------------------- /package-npmjs-nexus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | PYTHON=${PYTHON:-python} 6 | 7 | cd npmjs-nexus 8 | ${PYTHON} prepare.py nexus 9 | npm install 10 | npm run all 11 | 12 | mkdir -p dist 13 | npm pack --pack-destination dist 14 | -------------------------------------------------------------------------------- /package-npmjs-machxo2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | PYTHON=${PYTHON:-python} 6 | 7 | cd npmjs-machxo2 8 | ${PYTHON} prepare.py machxo2 9 | npm install 10 | npm run all 11 | 12 | mkdir -p dist 13 | npm pack --pack-destination dist 14 | -------------------------------------------------------------------------------- /pypi-ecp5/setup.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.append(os.path.join(os.path.dirname(__file__), "..", "pypi-common")) 3 | 4 | from setuptools import setup 5 | from yowasp_nextpnr_version import version 6 | 7 | 8 | setup( 9 | version=version(), 10 | ) 11 | -------------------------------------------------------------------------------- /pypi-ice40/setup.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.append(os.path.join(os.path.dirname(__file__), "..", "pypi-common")) 3 | 4 | from setuptools import setup 5 | from yowasp_nextpnr_version import version 6 | 7 | 8 | setup( 9 | version=version(), 10 | ) 11 | -------------------------------------------------------------------------------- /pypi-machxo2/setup.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.append(os.path.join(os.path.dirname(__file__), "..", "pypi-common")) 3 | 4 | from setuptools import setup 5 | from yowasp_nextpnr_version import version 6 | 7 | 8 | setup( 9 | version=version(), 10 | ) 11 | -------------------------------------------------------------------------------- /pypi-nexus/setup.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.append(os.path.join(os.path.dirname(__file__), "..", "pypi-common")) 3 | 4 | from setuptools import setup 5 | from yowasp_nextpnr_version import version 6 | 7 | 8 | setup( 9 | version=version(), 10 | ) 11 | -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/setup.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | sys.path.append(os.path.join(os.path.dirname(__file__), "..", "pypi-common")) 3 | 4 | from setuptools import setup 5 | from yowasp_nextpnr_version import version 6 | 7 | 8 | setup( 9 | version=version(), 10 | ) 11 | -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/package-local.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "transpile": [ 4 | "../nextpnr-build/nextpnr-himbaechel-gowin.wasm" 5 | ], 6 | "build": "--external:pyodide" 7 | }, 8 | "devDependencies": { 9 | "pyodide": "0.27" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /npmjs-ice40/package-local.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "transpile": [ 4 | "../icestorm-prefix/bin/icepll.wasm", 5 | "../icestorm-prefix/bin/icebram.wasm", 6 | "../icestorm-prefix/bin/icemulti.wasm", 7 | "../icestorm-prefix/bin/icepack.wasm", 8 | "../nextpnr-build/nextpnr-ice40.wasm" 9 | ] 10 | } 11 | } -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "icestorm"] 2 | path = icestorm-src 3 | url = https://github.com/YosysHQ/icestorm 4 | [submodule "nextpnr"] 5 | path = nextpnr-src 6 | url = https://github.com/YosysHQ/nextpnr 7 | [submodule "prjtrellis-src"] 8 | path = prjtrellis-src 9 | url = https://github.com/YosysHQ/prjtrellis 10 | [submodule "prjoxide-src"] 11 | path = prjoxide-src 12 | url = https://github.com/gatecat/prjoxide.git 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | YoWASP nextpnr packages 2 | ======================= 3 | 4 | Building 5 | -------- 6 | 7 | The primary build environment for this repository is the `ubuntu-latest` GitHub CI runner; packages are built on every push and automatically published from the `release` branch to PyPI. 8 | 9 | To reduce maintenance overhead, the only development environment we will support for this repository is x86_64 Linux. 10 | -------------------------------------------------------------------------------- /npmjs-ecp5/package-local.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "transpile": [ 4 | "../prjtrellis-build/ecppll.wasm", 5 | "../prjtrellis-build/ecpbram.wasm", 6 | "../prjtrellis-build/ecpmulti.wasm", 7 | "../prjtrellis-build/ecppack.wasm", 8 | "../prjtrellis-build/ecpunpack.wasm", 9 | "../nextpnr-build/nextpnr-ecp5.wasm" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /npmjs-machxo2/package-local.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "transpile": [ 4 | "../prjtrellis-build/ecppll.wasm", 5 | "../prjtrellis-build/ecpbram.wasm", 6 | "../prjtrellis-build/ecpmulti.wasm", 7 | "../prjtrellis-build/ecppack.wasm", 8 | "../prjtrellis-build/ecpunpack.wasm", 9 | "../nextpnr-build/nextpnr-machxo2.wasm" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/yowasp_nextpnr_himbaechel_gowin/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import yowasp_runtime 3 | 4 | 5 | def run_nextpnr_himbaechel_gowin(argv): 6 | return yowasp_runtime.run_wasm(__package__, "nextpnr-himbaechel-gowin.wasm", resources=["share"], 7 | argv=["yowasp-nextpnr-himbaechel-gowin", *argv]) 8 | 9 | 10 | def _run_nextpnr_himbaechel_gowin_argv(): 11 | sys.exit(run_nextpnr_himbaechel_gowin(sys.argv[1:])) 12 | -------------------------------------------------------------------------------- /pypi-nexus/yowasp_nextpnr_nexus/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import yowasp_runtime 3 | 4 | 5 | def run_prjoxide(argv): 6 | return yowasp_runtime.run_wasm(__package__, "prjoxide.wasm", 7 | argv=["yowasp-prjoxide", *argv]) 8 | 9 | 10 | def _run_prjoxide_argv(): 11 | sys.exit(run_prjoxide(sys.argv[1:])) 12 | 13 | 14 | def run_nextpnr_nexus(argv): 15 | return yowasp_runtime.run_wasm(__package__, "nextpnr-nexus.wasm", resources=["share"], 16 | argv=["yowasp-nextpnr-nexus", *argv]) 17 | 18 | 19 | def _run_nextpnr_nexus_argv(): 20 | sys.exit(run_nextpnr_nexus(sys.argv[1:])) 21 | -------------------------------------------------------------------------------- /pypi-common/yowasp_nextpnr_version.py: -------------------------------------------------------------------------------- 1 | from setuptools_scm.git import parse as parse_git 2 | 3 | 4 | def version(): 5 | upstream_git = parse_git("../nextpnr-src") 6 | package_git = parse_git("..") 7 | 8 | version = f"{upstream_git.tag.major}.{upstream_git.tag.minor}.{upstream_git.tag.micro}" 9 | if upstream_git.exact: # release 10 | version += f".0" 11 | else: # snapshot 12 | version += f".{upstream_git.distance}" 13 | version += f".post{package_git.distance}" 14 | if not upstream_git.exact: # snapshot 15 | version += f".dev0" 16 | if upstream_git.dirty or package_git.dirty: 17 | version += f"+dirty" 18 | return version 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (C) 2020 whitequark 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /package-npmjs-himbaechel-gowin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | cd $(dirname $0) 4 | 5 | PYTHON=${PYTHON:-python} 6 | 7 | PYTHON_LIBNAME=$(basename $(readlink -f apycula-prefix/bin/python)) 8 | rm -rf npmjs-himbaechel-gowin/share/python 9 | mkdir -p npmjs-himbaechel-gowin/share/python/apycula 10 | cp -r apycula-prefix/lib/${PYTHON_LIBNAME}/site-packages/apycula/*.py \ 11 | npmjs-himbaechel-gowin/share/python/apycula 12 | cp -r apycula-prefix/lib/${PYTHON_LIBNAME}/site-packages/apycula/*.pickle \ 13 | npmjs-himbaechel-gowin/share/python/apycula 14 | cp -r apycula-prefix/lib/${PYTHON_LIBNAME}/site-packages/crc/_crc.py \ 15 | npmjs-himbaechel-gowin/share/python/crc.py 16 | 17 | cd npmjs-himbaechel-gowin 18 | ${PYTHON} prepare.py himbaechel-gowin 19 | npm install 20 | npm run all 21 | 22 | mkdir -p dist 23 | npm pack --pack-destination dist 24 | -------------------------------------------------------------------------------- /npmjs-nexus/lib/api.js: -------------------------------------------------------------------------------- 1 | import { Application } from '@yowasp/runtime'; 2 | import * as resources from '../gen/nextpnr-nexus-resources.js'; 3 | import { instantiate as instantiatePrjoxide } from '../gen/prjoxide.js'; 4 | import { instantiate as instantiateNextpnrNexus } from '../gen/nextpnr-nexus.js'; 5 | 6 | export { Exit } from '@yowasp/runtime'; 7 | 8 | const prjoxide = new Application(resources, instantiatePrjoxide, 'yowasp-prjoxide'); 9 | const runPrjoxide = prjoxide.run.bind(prjoxide); 10 | 11 | const nextpnrNexus = new Application(resources, instantiateNextpnrNexus, 'yowasp-nextpnr-nexus'); 12 | const runNextpnrNexus = nextpnrNexus.run.bind(nextpnrNexus); 13 | 14 | export { 15 | runPrjoxide, 16 | runNextpnrNexus, 17 | }; 18 | 19 | export const commands = { 20 | 'prjoxide': runPrjoxide, 21 | 'nextpnr-nexus': runNextpnrNexus, 22 | }; 23 | 24 | export const version = VERSION; 25 | -------------------------------------------------------------------------------- /pypi-nexus/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools~=78.0", "setuptools_scm~=6.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | dynamic = ["version"] 7 | 8 | name = "yowasp-nextpnr-nexus" 9 | description = "nextpnr-nexus FPGA place and route tool" 10 | readme = "README.md" 11 | authors = [{name = "Catherine", email = "whitequark@whitequark.org"}] 12 | license = "ISC" 13 | 14 | dependencies = [ 15 | "yowasp-runtime~=1.1" 16 | ] 17 | 18 | [project.scripts] 19 | yowasp-prjoxide = "yowasp_nextpnr_nexus:_run_prjoxide_argv" 20 | yowasp-nextpnr-nexus = "yowasp_nextpnr_nexus:_run_nextpnr_nexus_argv" 21 | 22 | [project.urls] 23 | "Homepage" = "https://yowasp.org/" 24 | "Source Code" = "https://github.com/YoWASP/nextpnr" 25 | "Bug Tracker" = "https://github.com/YoWASP/nextpnr/issues" 26 | 27 | [tool.setuptools.package-data] 28 | yowasp_nextpnr_nexus = [ 29 | "*.wasm", 30 | "share/nexus/chipdb-*.bin", 31 | ] 32 | -------------------------------------------------------------------------------- /pypi-himbaechel-gowin/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools~=78.0", "setuptools_scm~=6.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | dynamic = ["version", "dependencies"] 7 | 8 | name = "yowasp-nextpnr-himbaechel-gowin" 9 | description = "nextpnr-himbaechel-gowin FPGA place and route tool" 10 | readme = "README.md" 11 | authors = [{name = "Catherine", email = "whitequark@whitequark.org"}] 12 | license = "ISC" 13 | 14 | [project.scripts] 15 | yowasp-nextpnr-himbaechel-gowin = "yowasp_nextpnr_himbaechel_gowin:_run_nextpnr_himbaechel_gowin_argv" 16 | 17 | [project.urls] 18 | "Homepage" = "https://yowasp.org/" 19 | "Source Code" = "https://github.com/YoWASP/nextpnr" 20 | "Bug Tracker" = "https://github.com/YoWASP/nextpnr/issues" 21 | 22 | [tool.setuptools.package-data] 23 | yowasp_nextpnr_himbaechel_gowin = [ 24 | "*.wasm", 25 | "share/himbaechel/gowin/chipdb-*.bin", 26 | ] 27 | 28 | [tool.setuptools.dynamic] 29 | dependencies = {file = ["dependencies.txt", "dependencies-apycula.txt"]} 30 | -------------------------------------------------------------------------------- /purge-test-pypi-releases.py: -------------------------------------------------------------------------------- 1 | # If TestPyPI complains about size of packages reaching the quota, use Developer Tools to find out 2 | # the session ID (in `Cookie:` header) and CSRF token (in any form submission), and use this script 3 | # to trim old files. THIS OPERATION CANNOT BE UNDONE. 4 | 5 | session_id = "" 6 | csrf_token = "" 7 | 8 | projects = [] 9 | versions = [] 10 | 11 | import urllib.parse 12 | import urllib.request 13 | 14 | for version in versions: 15 | for project in projects: 16 | request = urllib.request.Request( 17 | f"https://test.pypi.org/manage/project/{project}/release/{version}/", 18 | method="POST", 19 | headers={ 20 | "Cookie": f"session_id={session_id}", 21 | "Origin": "https://test.pypi.org", 22 | }, 23 | data=urllib.parse.urlencode({ 24 | "csrf_token": csrf_token, 25 | "confirm_delete_version": version, 26 | }).encode() 27 | ) 28 | urllib.request.urlopen(request) 29 | print(f"deleted {project} {version}") 30 | -------------------------------------------------------------------------------- /pypi-ice40/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools~=78.0", "setuptools_scm~=6.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | dynamic = ["version"] 7 | 8 | name = "yowasp-nextpnr-ice40" 9 | description = "nextpnr-ice40 FPGA place and route tool" 10 | readme = "README.md" 11 | authors = [{name = "Catherine", email = "whitequark@whitequark.org"}] 12 | license = "ISC" 13 | 14 | dependencies = [ 15 | "yowasp-runtime~=1.1" 16 | ] 17 | 18 | [project.scripts] 19 | yowasp-icepll = "yowasp_nextpnr_ice40:_run_icepll_argv" 20 | yowasp-icebram = "yowasp_nextpnr_ice40:_run_icebram_argv" 21 | yowasp-icemulti = "yowasp_nextpnr_ice40:_run_icemulti_argv" 22 | yowasp-icepack = "yowasp_nextpnr_ice40:_run_icepack_argv" 23 | yowasp-iceunpack = "yowasp_nextpnr_ice40:_run_iceunpack_argv" 24 | yowasp-nextpnr-ice40 = "yowasp_nextpnr_ice40:_run_nextpnr_ice40_argv" 25 | 26 | [project.urls] 27 | "Homepage" = "https://yowasp.org/" 28 | "Source Code" = "https://github.com/YoWASP/nextpnr" 29 | "Bug Tracker" = "https://github.com/YoWASP/nextpnr/issues" 30 | 31 | [tool.setuptools.package-data] 32 | yowasp_nextpnr_ice40 = [ 33 | "*.wasm", 34 | "share/ice40/chipdb-*.bin" 35 | ] 36 | -------------------------------------------------------------------------------- /npmjs-nexus/lib/api.d.ts: -------------------------------------------------------------------------------- 1 | export type Tree = { 2 | [name: string]: Tree | string | Uint8Array 3 | }; 4 | 5 | export type InputStream = 6 | (byteLength: number) => Uint8Array | null; 7 | 8 | export type OutputStream = 9 | (bytes: Uint8Array | null) => void; 10 | 11 | export type ProgressCallback = 12 | (event: { source: object, totalLength: number, doneLength: number }) => void; 13 | 14 | export type RunOptions = { 15 | stdin?: InputStream | null; 16 | stdout?: OutputStream | null; 17 | stderr?: OutputStream | null; 18 | decodeASCII?: boolean; 19 | synchronously?: boolean; 20 | fetchProgress?: ProgressCallback; 21 | }; 22 | 23 | export type Command = 24 | (args?: string[], files?: Tree, options?: RunOptions) => Promise | Tree | undefined; 25 | 26 | export class Exit extends Error { 27 | code: number; 28 | files: Tree; 29 | } 30 | 31 | //--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<-------- 32 | 33 | export const runPrjoxide: Command; 34 | export const runNextpnrNexus: Command; 35 | 36 | export const commands: { 37 | 'prjoxide': Command, 38 | 'nextpnr-nexus': Command, 39 | }; 40 | 41 | export const version: string; 42 | -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/lib/api.d.ts: -------------------------------------------------------------------------------- 1 | export type Tree = { 2 | [name: string]: Tree | string | Uint8Array 3 | }; 4 | 5 | export type InputStream = 6 | (byteLength: number) => Uint8Array | null; 7 | 8 | export type OutputStream = 9 | (bytes: Uint8Array | null) => void; 10 | 11 | export type ProgressCallback = 12 | (event: { source: object, totalLength: number, doneLength: number }) => void; 13 | 14 | export type RunOptions = { 15 | stdin?: InputStream | null; 16 | stdout?: OutputStream | null; 17 | stderr?: OutputStream | null; 18 | decodeASCII?: boolean; 19 | synchronously?: boolean; 20 | fetchProgress?: ProgressCallback; 21 | }; 22 | 23 | export type Command = 24 | (args?: string[], files?: Tree, options?: RunOptions) => Promise | Tree | undefined; 25 | 26 | export class Exit extends Error { 27 | code: number; 28 | files: Tree; 29 | } 30 | 31 | //--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<-------- 32 | 33 | export const runNextpnrHimbaechelGowin: Command; 34 | 35 | export const commands: { 36 | 'gowin_pll': Command, 37 | 'gowin_pack': Command, 38 | 'gowin_unpack': Command, 39 | 'nextpnr-himbaechel-gowin': Command, 40 | }; 41 | 42 | export const version: string; 43 | -------------------------------------------------------------------------------- /pypi-ecp5/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools~=78.0", "setuptools_scm~=6.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | dynamic = ["version"] 7 | 8 | name = "yowasp-nextpnr-ecp5" 9 | description = "nextpnr-ecp5 FPGA place and route tool" 10 | readme = "README.md" 11 | authors = [{name = "Catherine", email = "whitequark@whitequark.org"}] 12 | license = "ISC" 13 | 14 | dependencies = [ 15 | "yowasp-runtime~=1.1" 16 | ] 17 | 18 | [project.scripts] 19 | yowasp-ecppll = "yowasp_nextpnr_ecp5:_run_ecppll_argv" 20 | yowasp-ecpbram = "yowasp_nextpnr_ecp5:_run_ecpbram_argv" 21 | yowasp-ecpmulti = "yowasp_nextpnr_ecp5:_run_ecpmulti_argv" 22 | yowasp-ecppack = "yowasp_nextpnr_ecp5:_run_ecppack_argv" 23 | yowasp-ecpunpack = "yowasp_nextpnr_ecp5:_run_ecpunpack_argv" 24 | yowasp-nextpnr-ecp5 = "yowasp_nextpnr_ecp5:_run_nextpnr_ecp5_argv" 25 | 26 | [project.urls] 27 | "Homepage" = "https://yowasp.org/" 28 | "Source Code" = "https://github.com/YoWASP/nextpnr" 29 | "Bug Tracker" = "https://github.com/YoWASP/nextpnr/issues" 30 | 31 | [tool.setuptools.package-data] 32 | yowasp_nextpnr_ecp5 = [ 33 | "*.wasm", 34 | "share/trellis/database/devices.json", 35 | "share/trellis/database/ECP5/tiledata/**/*", 36 | "share/trellis/database/ECP5/timing/**/*", 37 | "share/trellis/database/ECP5/LFE5*/*", 38 | "share/ecp5/chipdb-*.bin" 39 | ] 40 | -------------------------------------------------------------------------------- /npmjs-ecp5/lib/api.d.ts: -------------------------------------------------------------------------------- 1 | export type Tree = { 2 | [name: string]: Tree | string | Uint8Array 3 | }; 4 | 5 | export type InputStream = 6 | (byteLength: number) => Uint8Array | null; 7 | 8 | export type OutputStream = 9 | (bytes: Uint8Array | null) => void; 10 | 11 | export type ProgressCallback = 12 | (event: { source: object, totalLength: number, doneLength: number }) => void; 13 | 14 | export type RunOptions = { 15 | stdin?: InputStream | null; 16 | stdout?: OutputStream | null; 17 | stderr?: OutputStream | null; 18 | decodeASCII?: boolean; 19 | synchronously?: boolean; 20 | fetchProgress?: ProgressCallback; 21 | }; 22 | 23 | export type Command = 24 | (args?: string[], files?: Tree, options?: RunOptions) => Promise | Tree | undefined; 25 | 26 | export class Exit extends Error { 27 | code: number; 28 | files: Tree; 29 | } 30 | 31 | //--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<-------- 32 | 33 | export const runEcppll: Command; 34 | export const runEcpbram: Command; 35 | export const runEcpmulti: Command; 36 | export const runEcppack: Command; 37 | export const runEcpunpack: Command; 38 | export const runNextpnrEcp5: Command; 39 | 40 | export const commands: { 41 | 'ecppll': Command, 42 | 'ecpbram': Command, 43 | 'ecpmulti': Command, 44 | 'ecppack': Command, 45 | 'ecpunpack': Command, 46 | 'nextpnr-ecp5': Command, 47 | }; 48 | 49 | export const version: string; 50 | -------------------------------------------------------------------------------- /npmjs-ice40/lib/api.d.ts: -------------------------------------------------------------------------------- 1 | export type Tree = { 2 | [name: string]: Tree | string | Uint8Array 3 | }; 4 | 5 | export type InputStream = 6 | (byteLength: number) => Uint8Array | null; 7 | 8 | export type OutputStream = 9 | (bytes: Uint8Array | null) => void; 10 | 11 | export type ProgressCallback = 12 | (event: { source: object, totalLength: number, doneLength: number }) => void; 13 | 14 | export type RunOptions = { 15 | stdin?: InputStream | null; 16 | stdout?: OutputStream | null; 17 | stderr?: OutputStream | null; 18 | decodeASCII?: boolean; 19 | synchronously?: boolean; 20 | fetchProgress?: ProgressCallback; 21 | }; 22 | 23 | export type Command = 24 | (args?: string[], files?: Tree, options?: RunOptions) => Promise | Tree | undefined; 25 | 26 | export class Exit extends Error { 27 | code: number; 28 | files: Tree; 29 | } 30 | 31 | //--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<-------- 32 | 33 | export const runIcepll: Command; 34 | export const runIcebram: Command; 35 | export const runIcemulti: Command; 36 | export const runIcepack: Command; 37 | export const runIceunpack: Command; 38 | export const runNextpnrIce40: Command; 39 | 40 | export const commands: { 41 | 'icepll': Command, 42 | 'icebram': Command, 43 | 'icemulti': Command, 44 | 'icepack': Command, 45 | 'iceunpack': Command, 46 | 'nextpnr-ice40': Command, 47 | }; 48 | 49 | export const version: string; 50 | -------------------------------------------------------------------------------- /npmjs-machxo2/lib/api.d.ts: -------------------------------------------------------------------------------- 1 | export type Tree = { 2 | [name: string]: Tree | string | Uint8Array 3 | }; 4 | 5 | export type InputStream = 6 | (byteLength: number) => Uint8Array | null; 7 | 8 | export type OutputStream = 9 | (bytes: Uint8Array | null) => void; 10 | 11 | export type ProgressCallback = 12 | (event: { source: object, totalLength: number, doneLength: number }) => void; 13 | 14 | export type RunOptions = { 15 | stdin?: InputStream | null; 16 | stdout?: OutputStream | null; 17 | stderr?: OutputStream | null; 18 | decodeASCII?: boolean; 19 | synchronously?: boolean; 20 | fetchProgress?: ProgressCallback; 21 | }; 22 | 23 | export type Command = 24 | (args?: string[], files?: Tree, options?: RunOptions) => Promise | Tree | undefined; 25 | 26 | export class Exit extends Error { 27 | code: number; 28 | files: Tree; 29 | } 30 | 31 | //--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<-------- 32 | 33 | export const runEcppll: Command; 34 | export const runEcpbram: Command; 35 | export const runEcpmulti: Command; 36 | export const runEcppack: Command; 37 | export const runEcpunpack: Command; 38 | export const runNextpnrMachxo2: Command; 39 | 40 | export const commands: { 41 | 'ecppll': Command, 42 | 'ecpbram': Command, 43 | 'ecpmulti': Command, 44 | 'ecppack': Command, 45 | 'ecpunpack': Command, 46 | 'nextpnr-machxo2': Command, 47 | }; 48 | 49 | export const version: string; 50 | -------------------------------------------------------------------------------- /pypi-ecp5/yowasp_nextpnr_ecp5/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import yowasp_runtime 3 | 4 | 5 | def run_ecppll(argv): 6 | return yowasp_runtime.run_wasm(__package__, "ecppll.wasm", 7 | argv=["yowasp-ecppll", *argv]) 8 | 9 | 10 | def _run_ecppll_argv(): 11 | sys.exit(run_ecppll(sys.argv[1:])) 12 | 13 | 14 | def run_ecpbram(argv): 15 | return yowasp_runtime.run_wasm(__package__, "ecpbram.wasm", 16 | argv=["yowasp-ecpbram", *argv]) 17 | 18 | 19 | def _run_ecpbram_argv(): 20 | sys.exit(run_ecpbram(sys.argv[1:])) 21 | 22 | 23 | def run_ecpmulti(argv): 24 | return yowasp_runtime.run_wasm(__package__, "ecpmulti.wasm", 25 | argv=["yowasp-ecpmulti", *argv]) 26 | 27 | 28 | def _run_ecpmulti_argv(): 29 | sys.exit(run_ecpmulti(sys.argv[1:])) 30 | 31 | 32 | def run_ecppack(argv): 33 | return yowasp_runtime.run_wasm(__package__, "ecppack.wasm", resources=["share"], 34 | argv=["yowasp-ecppack", *argv]) 35 | 36 | 37 | def _run_ecppack_argv(): 38 | sys.exit(run_ecppack(sys.argv[1:])) 39 | 40 | 41 | def run_ecpunpack(argv): 42 | return yowasp_runtime.run_wasm(__package__, "ecpunpack.wasm", resources=["share"], 43 | argv=["yowasp-ecpunpack", *argv]) 44 | 45 | 46 | def _run_ecpunpack_argv(): 47 | sys.exit(run_ecpunpack(sys.argv[1:])) 48 | 49 | 50 | def run_nextpnr_ecp5(argv): 51 | return yowasp_runtime.run_wasm(__package__, "nextpnr-ecp5.wasm", resources=["share"], 52 | argv=["yowasp-nextpnr-ecp5", *argv]) 53 | 54 | 55 | def _run_nextpnr_ecp5_argv(): 56 | sys.exit(run_nextpnr_ecp5(sys.argv[1:])) 57 | -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/lib/api.js: -------------------------------------------------------------------------------- 1 | import { Application } from '@yowasp/runtime'; 2 | import { PythonApplication } from './pyodide.js'; 3 | import * as resources from '../gen/nextpnr-himbaechel-gowin-resources.js'; 4 | import { instantiate as instantiateNextpnrHimbaechelGowin } from '../gen/nextpnr-himbaechel-gowin.js'; 5 | 6 | export { Exit } from '@yowasp/runtime'; 7 | 8 | const executeApycula = (pyodide, argv0) => pyodide.runPython(` 9 | import sys; sys.path.append('/share/python') 10 | from apycula.${argv0} import main; main() 11 | `); 12 | 13 | const gowinPll = new PythonApplication(resources, executeApycula, 'gowin_pll'); 14 | const runGowinPll = gowinPll.run.bind(gowinPll); 15 | 16 | const gowinPack = new PythonApplication(resources, executeApycula, 'gowin_pack'); 17 | const runGowinPack = gowinPack.run.bind(gowinPack); 18 | 19 | const gowinUnpack = new PythonApplication(resources, executeApycula, 'gowin_unpack'); 20 | const runGowinUnpack = gowinUnpack.run.bind(gowinUnpack); 21 | 22 | const nextpnrHimbaechelGowin = new Application(resources, instantiateNextpnrHimbaechelGowin, 'yowasp-nextpnr-himbaechel-gowin'); 23 | const runNextpnrHimbaechelGowin = nextpnrHimbaechelGowin.run.bind(nextpnrHimbaechelGowin); 24 | 25 | export { 26 | runGowinPll, 27 | runGowinPack, 28 | runGowinUnpack, 29 | runNextpnrHimbaechelGowin, 30 | }; 31 | 32 | export const commands = { 33 | 'gowin_pll': runGowinPll, 34 | 'gowin_pack': runGowinPack, 35 | 'gowin_unpack': runGowinUnpack, 36 | 'nextpnr-himbaechel-gowin': runNextpnrHimbaechelGowin, 37 | }; 38 | 39 | export const version = VERSION; 40 | -------------------------------------------------------------------------------- /pypi-machxo2/yowasp_nextpnr_machxo2/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import yowasp_runtime 3 | 4 | 5 | def run_ecppll(argv): 6 | return yowasp_runtime.run_wasm(__package__, "ecppll.wasm", 7 | argv=["yowasp-ecppll", *argv]) 8 | 9 | 10 | def _run_ecppll_argv(): 11 | sys.exit(run_ecppll(sys.argv[1:])) 12 | 13 | 14 | def run_ecpbram(argv): 15 | return yowasp_runtime.run_wasm(__package__, "ecpbram.wasm", 16 | argv=["yowasp-ecpbram", *argv]) 17 | 18 | 19 | def _run_ecpbram_argv(): 20 | sys.exit(run_ecpbram(sys.argv[1:])) 21 | 22 | 23 | def run_ecpmulti(argv): 24 | return yowasp_runtime.run_wasm(__package__, "ecpmulti.wasm", 25 | argv=["yowasp-ecpmulti", *argv]) 26 | 27 | 28 | def _run_ecpmulti_argv(): 29 | sys.exit(run_ecpmulti(sys.argv[1:])) 30 | 31 | 32 | def run_ecppack(argv): 33 | return yowasp_runtime.run_wasm(__package__, "ecppack.wasm", resources=["share"], 34 | argv=["yowasp-ecppack", *argv]) 35 | 36 | 37 | def _run_ecppack_argv(): 38 | sys.exit(run_ecppack(sys.argv[1:])) 39 | 40 | 41 | def run_ecpunpack(argv): 42 | return yowasp_runtime.run_wasm(__package__, "ecpunpack.wasm", resources=["share"], 43 | argv=["yowasp-ecpunpack", *argv]) 44 | 45 | 46 | def _run_ecpunpack_argv(): 47 | sys.exit(run_ecpunpack(sys.argv[1:])) 48 | 49 | 50 | def run_nextpnr_machxo2(argv): 51 | return yowasp_runtime.run_wasm(__package__, "nextpnr-machxo2.wasm", resources=["share"], 52 | argv=["yowasp-nextpnr-machxo2", *argv]) 53 | 54 | 55 | def _run_nextpnr_machxo2_argv(): 56 | sys.exit(run_nextpnr_machxo2(sys.argv[1:])) 57 | -------------------------------------------------------------------------------- /pypi-ice40/yowasp_nextpnr_ice40/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import yowasp_runtime 3 | 4 | 5 | def run_icepll(argv): 6 | return yowasp_runtime.run_wasm(__package__, "icepll.wasm", 7 | argv=["yowasp-icepll", *argv]) 8 | 9 | 10 | def _run_icepll_argv(): 11 | sys.exit(run_icepll(sys.argv[1:])) 12 | 13 | 14 | def run_icebram(argv): 15 | return yowasp_runtime.run_wasm(__package__, "icebram.wasm", 16 | argv=["yowasp-icebram", *argv]) 17 | 18 | 19 | def _run_icebram_argv(): 20 | sys.exit(run_icebram(sys.argv[1:])) 21 | 22 | 23 | def run_icemulti(argv): 24 | return yowasp_runtime.run_wasm(__package__, "icemulti.wasm", 25 | argv=["yowasp-icemulti", *argv]) 26 | 27 | 28 | def _run_icemulti_argv(): 29 | sys.exit(run_icemulti(sys.argv[1:])) 30 | 31 | 32 | def run_icepack(argv): 33 | return yowasp_runtime.run_wasm(__package__, "icepack.wasm", 34 | argv=["yowasp-icepack", *argv]) 35 | 36 | 37 | def _run_icepack_argv(): 38 | sys.exit(run_icepack(sys.argv[1:])) 39 | 40 | 41 | def run_iceunpack(argv): 42 | # same binary as icepack, operation distinguished with argv[0] 43 | return yowasp_runtime.run_wasm(__package__, "icepack.wasm", 44 | argv=["yowasp-iceunpack", *argv]) 45 | 46 | 47 | def _run_iceunpack_argv(): 48 | sys.exit(run_iceunpack(sys.argv[1:])) 49 | 50 | 51 | def run_nextpnr_ice40(argv): 52 | return yowasp_runtime.run_wasm(__package__, "nextpnr-ice40.wasm", resources=["share"], 53 | argv=["yowasp-nextpnr-ice40", *argv]) 54 | 55 | 56 | def _run_nextpnr_ice40_argv(): 57 | sys.exit(run_nextpnr_ice40(sys.argv[1:])) 58 | -------------------------------------------------------------------------------- /pypi-machxo2/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools~=78.0", "setuptools_scm~=6.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | dynamic = ["version"] 7 | 8 | name = "yowasp-nextpnr-machxo2" 9 | description = "nextpnr-machxo2 FPGA place and route tool" 10 | readme = "README.md" 11 | authors = [{name = "Catherine", email = "whitequark@whitequark.org"}] 12 | license = "ISC" 13 | 14 | dependencies = [ 15 | "yowasp-runtime~=1.1" 16 | ] 17 | 18 | [project.scripts] 19 | # If two packages install scripts under the same name, the first package that is removed also 20 | # removes the script launcher. This is undesirable, and to resolve the conflict with 21 | # yowasp-nextpnr-ecp5, the scripts in yowasp-nextpnr-machxo2 are renamed. 22 | yowasp-xo2pll = "yowasp_nextpnr_machxo2:_run_ecppll_argv" 23 | yowasp-xo2bram = "yowasp_nextpnr_machxo2:_run_ecpbram_argv" 24 | yowasp-xo2multi = "yowasp_nextpnr_machxo2:_run_ecpmulti_argv" 25 | yowasp-xo2pack = "yowasp_nextpnr_machxo2:_run_ecppack_argv" 26 | yowasp-xo2unpack = "yowasp_nextpnr_machxo2:_run_ecpunpack_argv" 27 | yowasp-nextpnr-machxo2 = "yowasp_nextpnr_machxo2:_run_nextpnr_machxo2_argv" 28 | 29 | [project.urls] 30 | "Homepage" = "https://yowasp.org/" 31 | "Source Code" = "https://github.com/YoWASP/nextpnr" 32 | "Bug Tracker" = "https://github.com/YoWASP/nextpnr/issues" 33 | 34 | [tool.setuptools.package-data] 35 | yowasp_nextpnr_machxo2 = [ 36 | "*.wasm", 37 | "share/trellis/database/devices.json", 38 | "share/trellis/database/MachXO2/tiledata/**/*", 39 | "share/trellis/database/MachXO2/timing/**/*", 40 | "share/trellis/database/MachXO2/LCMXO2*/*", 41 | "share/machxo2/chipdb-*.bin" 42 | ] 43 | -------------------------------------------------------------------------------- /npmjs-common/package-in.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@yowasp/nextpnr-__ARCH__", 3 | "version": "__VERSION__", 4 | "description": "nextpnr-__ARCH__ FPGA place and route tool", 5 | "author": "Catherine ", 6 | "license": "ISC", 7 | "homepage": "https://yowasp.org/", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/YoWASP/nextpnr.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/YoWASP/nextpnr/issues" 14 | }, 15 | "type": "module", 16 | "files": [ 17 | "lib/api.d.ts", 18 | "gen/bundle.js", 19 | "gen/*.wasm", 20 | "gen/*-resources*.tar" 21 | ], 22 | "exports": { 23 | "types": "./lib/api.d.ts", 24 | "default": "./gen/bundle.js" 25 | }, 26 | "types": "./lib/api.d.ts", 27 | "devDependencies": { 28 | "@bytecodealliance/jco": "1.3.0", 29 | "@yowasp/runtime": "11.0.69", 30 | "esbuild": "^0.25.11" 31 | }, 32 | "scripts": { 33 | "transpile": "jco new __FILENAME__ --wasi-command --output __BASENAME__ && jco transpile __BASENAME__ --instantiation async --no-typescript --no-namespaced-exports --map 'wasi:io/*=runtime#io' --map 'wasi:cli/*=runtime#cli' --map 'wasi:clocks/*=runtime#*' --map 'wasi:filesystem/*=runtime#fs' --map 'wasi:random/*=runtime#random' --out-dir gen/", 34 | "pack": "yowasp-pack-resources gen/nextpnr-__ARCH__-resources.js gen share", 35 | "build": "esbuild --bundle lib/api.js --outfile=gen/bundle.js --format=esm --platform=node --external:./resources-*.js", 36 | "all": "npm run transpile && npm run pack && npm run build" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /npmjs-ice40/lib/api.js: -------------------------------------------------------------------------------- 1 | import { Application } from '@yowasp/runtime'; 2 | import * as resources from '../gen/nextpnr-ice40-resources.js'; 3 | import { instantiate as instantiateIcepll } from '../gen/icepll.js'; 4 | import { instantiate as instantiateIcebram } from '../gen/icebram.js'; 5 | import { instantiate as instantiateIcemulti } from '../gen/icemulti.js'; 6 | import { instantiate as instantiateIcepack } from '../gen/icepack.js'; 7 | import { instantiate as instantiateNextpnrIce40 } from '../gen/nextpnr-ice40.js'; 8 | 9 | export { Exit } from '@yowasp/runtime'; 10 | 11 | const icepll = new Application(resources, instantiateIcepll, 'yowasp-icepll'); 12 | const runIcepll = icepll.run.bind(icepll); 13 | 14 | const icebram = new Application(resources, instantiateIcebram, 'yowasp-icebram'); 15 | const runIcebram = icebram.run.bind(icebram); 16 | 17 | const icemulti = new Application(resources, instantiateIcemulti, 'yowasp-icemulti'); 18 | const runIcemulti = icemulti.run.bind(icemulti); 19 | 20 | const icepack = new Application(resources, instantiateIcepack, 'yowasp-icepack'); 21 | const runIcepack = icepack.run.bind(icepack); 22 | 23 | const iceunpack = new Application(resources, instantiateIcepack, 'yowasp-iceunpack'); 24 | const runIceunpack = iceunpack.run.bind(iceunpack); 25 | 26 | const nextpnrIce40 = new Application(resources, instantiateNextpnrIce40, 'yowasp-nextpnr-ice40'); 27 | const runNextpnrIce40 = nextpnrIce40.run.bind(nextpnrIce40); 28 | 29 | export { 30 | runIcepll, 31 | runIcebram, 32 | runIcemulti, 33 | runIcepack, 34 | runIceunpack, 35 | runNextpnrIce40, 36 | }; 37 | 38 | export const commands = { 39 | 'icepll': runIcepll, 40 | 'icebram': runIcebram, 41 | 'icemulti': runIcemulti, 42 | 'icepack': runIcepack, 43 | 'iceunpack': runIceunpack, 44 | 'nextpnr-ice40': runNextpnrIce40, 45 | }; 46 | 47 | export const version = VERSION; 48 | -------------------------------------------------------------------------------- /npmjs-ecp5/lib/api.js: -------------------------------------------------------------------------------- 1 | import { Application } from '@yowasp/runtime'; 2 | import * as resources from '../gen/nextpnr-ecp5-resources.js'; 3 | import { instantiate as instantiateEcppll } from '../gen/ecppll.js'; 4 | import { instantiate as instantiateEcpbram } from '../gen/ecpbram.js'; 5 | import { instantiate as instantiateEcpmulti } from '../gen/ecpmulti.js'; 6 | import { instantiate as instantiateEcppack } from '../gen/ecppack.js'; 7 | import { instantiate as instantiateEcpunpack } from '../gen/ecpunpack.js'; 8 | import { instantiate as instantiateNextpnrEcp5 } from '../gen/nextpnr-ecp5.js'; 9 | 10 | export { Exit } from '@yowasp/runtime'; 11 | 12 | const ecppll = new Application(resources, instantiateEcppll, 'yowasp-ecppll'); 13 | const runEcppll = ecppll.run.bind(ecppll); 14 | 15 | const ecpbram = new Application(resources, instantiateEcpbram, 'yowasp-ecpbram'); 16 | const runEcpbram = ecpbram.run.bind(ecpbram); 17 | 18 | const ecpmulti = new Application(resources, instantiateEcpmulti, 'yowasp-ecpmulti'); 19 | const runEcpmulti = ecpmulti.run.bind(ecpmulti); 20 | 21 | const ecppack = new Application(resources, instantiateEcppack, 'yowasp-ecppack'); 22 | const runEcppack = ecppack.run.bind(ecppack); 23 | 24 | const ecpunpack = new Application(resources, instantiateEcpunpack, 'yowasp-ecpunpack'); 25 | const runEcpunpack = ecpunpack.run.bind(ecpunpack); 26 | 27 | const nextpnrEcp5 = new Application(resources, instantiateNextpnrEcp5, 'yowasp-nextpnr-ecp5'); 28 | const runNextpnrEcp5 = nextpnrEcp5.run.bind(nextpnrEcp5); 29 | 30 | export { 31 | runEcppll, 32 | runEcpbram, 33 | runEcpmulti, 34 | runEcppack, 35 | runEcpunpack, 36 | runNextpnrEcp5, 37 | }; 38 | 39 | export const commands = { 40 | 'ecppll': runEcppll, 41 | 'ecpbram': runEcpbram, 42 | 'ecpmulti': runEcpmulti, 43 | 'ecppack': runEcppack, 44 | 'ecpunpack': runEcpunpack, 45 | 'nextpnr-ecp5': runNextpnrEcp5, 46 | }; 47 | 48 | export const version = VERSION; 49 | -------------------------------------------------------------------------------- /npmjs-machxo2/lib/api.js: -------------------------------------------------------------------------------- 1 | import { Application } from '@yowasp/runtime'; 2 | import * as resources from '../gen/nextpnr-machxo2-resources.js'; 3 | import { instantiate as instantiateEcppll } from '../gen/ecppll.js'; 4 | import { instantiate as instantiateEcpbram } from '../gen/ecpbram.js'; 5 | import { instantiate as instantiateEcpmulti } from '../gen/ecpmulti.js'; 6 | import { instantiate as instantiateEcppack } from '../gen/ecppack.js'; 7 | import { instantiate as instantiateEcpunpack } from '../gen/ecpunpack.js'; 8 | import { instantiate as instantiateNextpnrMachxo2 } from '../gen/nextpnr-machxo2.js'; 9 | 10 | export { Exit } from '@yowasp/runtime'; 11 | 12 | const ecppll = new Application(resources, instantiateEcppll, 'yowasp-ecppll'); 13 | const runEcppll = ecppll.run.bind(ecppll); 14 | 15 | const ecpbram = new Application(resources, instantiateEcpbram, 'yowasp-ecpbram'); 16 | const runEcpbram = ecpbram.run.bind(ecpbram); 17 | 18 | const ecpmulti = new Application(resources, instantiateEcpmulti, 'yowasp-ecpmulti'); 19 | const runEcpmulti = ecpmulti.run.bind(ecpmulti); 20 | 21 | const ecppack = new Application(resources, instantiateEcppack, 'yowasp-ecppack'); 22 | const runEcppack = ecppack.run.bind(ecppack); 23 | 24 | const ecpunpack = new Application(resources, instantiateEcpunpack, 'yowasp-ecpunpack'); 25 | const runEcpunpack = ecpunpack.run.bind(ecpunpack); 26 | 27 | const nextpnrMachxo2 = new Application(resources, instantiateNextpnrMachxo2, 'yowasp-nextpnr-machxo2'); 28 | const runNextpnrMachxo2 = nextpnrMachxo2.run.bind(nextpnrMachxo2); 29 | 30 | export { 31 | runEcppll, 32 | runEcpbram, 33 | runEcpmulti, 34 | runEcppack, 35 | runEcpunpack, 36 | runNextpnrMachxo2, 37 | }; 38 | 39 | export const commands = { 40 | 'ecppll': runEcppll, 41 | 'ecpbram': runEcpbram, 42 | 'ecpmulti': runEcpmulti, 43 | 'ecppack': runEcppack, 44 | 'ecpunpack': runEcpunpack, 45 | 'nextpnr-machxo2': runNextpnrMachxo2, 46 | }; 47 | 48 | export const version = VERSION; 49 | -------------------------------------------------------------------------------- /npmjs-common/prepare.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import sys 4 | import json 5 | import subprocess 6 | 7 | 8 | arch = sys.argv[1] 9 | 10 | 11 | nextpnr_version_raw = subprocess.check_output([ 12 | "git", "-C", "../nextpnr-src", "describe", "--tags", "HEAD" 13 | ], encoding="utf-8").strip() 14 | 15 | git_rev_list_raw = subprocess.check_output([ 16 | "git", "rev-list", "HEAD" 17 | ], encoding="utf-8").split() 18 | 19 | nextpnr_version = re.match(r"^nextpnr-(\d+).(\d+)(?:-(\d+)-)?", nextpnr_version_raw) 20 | nextpnr_major = int(nextpnr_version[1]) 21 | nextpnr_minor = int(nextpnr_version[2]) 22 | nextpnr_node = int(nextpnr_version[3] or "0") 23 | 24 | distance = len(git_rev_list_raw) - 1 25 | 26 | if os.environ.get("RELEASE_BRANCH", "false") in ("true", "1", "yes"): 27 | version = f"{nextpnr_major}.{nextpnr_minor}.{distance}" 28 | else: 29 | version = f"{nextpnr_major}.{nextpnr_minor + 1}.{nextpnr_node}-dev.{distance}" 30 | print(f"version {version}") 31 | 32 | 33 | with open("package-local.json", "rt") as f: 34 | package_local = json.load(f) 35 | with open("package-in.json", "rt") as f: 36 | package_json = json.load(f) 37 | package_json["version"] = version 38 | package_json["name"] = package_json["name"].replace("__ARCH__", arch) 39 | package_json["description"] = package_json["description"].replace("__ARCH__", arch) 40 | if "devDependencies" in package_local: 41 | package_json["devDependencies"] |= package_local["devDependencies"] 42 | package_json["scripts"]["pack"] = package_json["scripts"]["pack"].replace("__ARCH__", arch) 43 | transpile_commands = [] 44 | for transpile_file in package_local["scripts"]["transpile"]: 45 | transpile_commands.append(package_json["scripts"]["transpile"] 46 | .replace("__FILENAME__", transpile_file) 47 | .replace("__BASENAME__", os.path.basename(transpile_file))) 48 | package_json["scripts"]["transpile"] = " && ".join(transpile_commands) 49 | package_json["scripts"]["build"] += f" --define:VERSION=\\\"{version}\\\"" 50 | if "build" in package_local["scripts"]: 51 | package_json["scripts"]["build"] += " " + package_local["scripts"]["build"] 52 | with open("package.json", "wt") as f: 53 | json.dump(package_json, f, indent=2) 54 | -------------------------------------------------------------------------------- /.github/workflows/track-upstream.yml: -------------------------------------------------------------------------------- 1 | on: 2 | schedule: 3 | - cron: '0 0 * * *' 4 | workflow_dispatch: 5 | name: Track upstream activity 6 | jobs: 7 | track-commits: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Check out source code 11 | uses: actions/checkout@v4 12 | with: 13 | fetch-depth: 0 14 | submodules: true 15 | token: ${{ secrets.PUSH_TOKEN }} 16 | - name: Install dependencies 17 | run: | 18 | pip install packaging 19 | - name: Update upstream code 20 | run: | 21 | git -C icestorm-src pull --ff-only origin master 22 | git -C prjtrellis-src pull --ff-only origin master 23 | git -C prjoxide-src pull --ff-only origin master 24 | git -C nextpnr-src pull --ff-only origin master 25 | python -c 'import urllib.request, json, packaging.version; print("Apycula==" + max(json.load(urllib.request.urlopen("https://pypi.org/pypi/Apycula/json"))["releases"], key=packaging.version.Version))' >apycula-meta/requirements.txt 26 | - name: Push updated code 27 | uses: stefanzweifel/git-auto-commit-action@v6 28 | with: 29 | commit_message: Update dependencies. 30 | track-releases: 31 | runs-on: ubuntu-latest 32 | steps: 33 | - name: Check out source code 34 | uses: actions/checkout@v4 35 | with: 36 | fetch-depth: 0 37 | submodules: true 38 | token: ${{ secrets.PUSH_TOKEN }} 39 | - name: Check out new upstream tag 40 | id: checkout-tag 41 | run: | 42 | for tag in $(git -C nextpnr-src tag -l 'nextpnr-*' | sort -rV); do 43 | ref=$(git -C nextpnr-src rev-parse $tag) 44 | branch=develop-${tag/nextpnr-/} 45 | if ! git rev-parse -q --verify remotes/origin/${branch} >/dev/null; then 46 | echo "New branch ${branch} with nextpnr-src ${ref}" 47 | git -C nextpnr-src checkout ${ref} 48 | echo "version=${tag/nextpnr-/}" >> $GITHUB_OUTPUT 49 | break 50 | fi; 51 | done 52 | - name: Push new branch 53 | uses: stefanzweifel/git-auto-commit-action@v6 54 | if: steps.checkout-tag.outputs.version 55 | with: 56 | commit_message: "[autorelease] nextpnr ${{ steps.checkout-tag.outputs.version }}." 57 | branch: develop-${{ steps.checkout-tag.outputs.version }} 58 | create_branch: true 59 | skip_dirty_check: true 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | YoWASP nextpnr packages 2 | ======================= 3 | 4 | The YoWASP nextpnr suite of packages provides [nextpnr][] and related tools for several FPGA families built for [WebAssembly][]. See the [overview of the YoWASP project][yowasp] for details. 5 | 6 | The supported FPGA families are: 7 | * Lattice iCE40 (via [Project IceStorm][icestorm]); 8 | * Lattice ECP5 (via [Project Trellis][trellis]); 9 | * Lattice MachXO2 (via [Project Trellis][trellis]; **experimental**); 10 | * Lattice Nexus (via [Project Oxide][oxide]; **experimental**); 11 | * Gowin (via [Project Apicula][apicula]; **experimental**). 12 | 13 | [nextpnr]: https://github.com/YosysHQ/nextpnr/ 14 | [webassembly]: https://webassembly.org/ 15 | [yowasp]: https://yowasp.github.io/ 16 | [icestorm]: https://github.com/YosysHQ/icestorm/ 17 | [trellis]: https://github.com/YosysHQ/prjtrellis/ 18 | [oxide]: https://github.com/gatecat/prjoxide 19 | [apicula]: https://github.com/YosysHQ/apicula 20 | 21 | 22 | Notes 23 | ----- 24 | 25 | For technical reasons, the `ecppack`, `ecpunpack`, `ecpbram`, `ecppll`, and `ecpmulti` tools from the MachXO2 toolchain shipped in the `yowasp-nextpnr-machxo2` PyPI package are installed under the names `yowasp-xo2pack`, `yowasp-xo2unpack`, `yowasp-xo2bram`, `yowasp-xo2pll`, and `yowasp-xo2multi` respectively. These commands run bit-for-bit identical code as their `yowasp-ecp*` prefixed brethren from the `yowasp-nextpnr-ecp5` PyPI package of the same version. 26 | 27 | 28 | Versioning 29 | ---------- 30 | 31 | The version of this package is derived from the upstream nextpnr package version in the ``X.Y[.Z]`` format, and is comprised of five or six parts in a ``X.Y.Z.N.postM[.dev]`` format: 32 | 33 | 1. ``X``: nextpnr major version 34 | 2. ``Y``: nextpnr minor version 35 | 3. ``Z``: nextpnr patch version; reserved as nextpnr currently does not do patch releases 36 | 4. ``N``: zero for packages built from nextpnr releases, ``N`` for packages built from unreleased nextpnr snapshots; ``N`` is the amount of commits since the latest release 37 | 5. ``postM``: package build version; disambiguates different builds produced from the same nextpnr source tree 38 | 6. ``dev``: present only for packages built from unreleased nextpnr snapshots; marks these packages as pre-releases 39 | 40 | With this scheme, there is a direct correspondence between upstream versions and [PEP 440][pep440] Python package versions. Packages built from unreleased snapshots are ignored by pip by default, but can be still installed explicitly. (These packages are uploaded daily to [TestPyPI][], but only occasionally to [PyPI][].) 41 | 42 | A different versioning scheme was used earlier, where the package build version was denoted by a ``.devM`` suffix. This scheme did not work well with [PEP 440 version specifiers][pep440-vs] and was retired. 43 | 44 | [testpypi]: https://test.pypi.org/ 45 | [pypi]: https://pypi.org/ 46 | [pep440]: https://peps.python.org/pep-0440/ 47 | [pep440-vs]: https://peps.python.org/pep-0440/#version-specifiers 48 | 49 | 50 | Configuration 51 | ------------- 52 | 53 | See the documentation for [yowasp-runtime](https://github.com/YoWASP/runtime#configuration). 54 | 55 | 56 | License 57 | ------- 58 | 59 | This package is covered by the [ISC license](LICENSE.txt), which is the same as the [nextpnr license](https://github.com/YosysHQ/nextpnr/blob/master/COPYING). 60 | -------------------------------------------------------------------------------- /npmjs-himbaechel-gowin/lib/pyodide.js: -------------------------------------------------------------------------------- 1 | // This file duplicates a *lot* of code from `@yowasp/runtime`, but since it is only useful for 2 | // Gowin tools, this is likely fine. If more Python-based tools are added then this should be 3 | // moved to `YoWASP/runtime-js` repository. 4 | 5 | import { Exit } from '@yowasp/runtime'; 6 | import { lineBuffered } from '@yowasp/runtime/util'; 7 | 8 | let fetch; 9 | if (typeof process === 'object' && process.release?.name === 'node') { 10 | // Node doesn't have a usable `fetch()`. 11 | fetch = async function(url, options) { 12 | if (url.protocol === 'file:') { 13 | const { readFile } = await import('fs/promises'); 14 | let contentType = 'application/octet-stream'; 15 | if (url.pathname.endsWith('.wasm')) 16 | contentType = 'application/wasm'; 17 | return new Response(await readFile(url), { headers: { "Content-Type": contentType } }); 18 | } else { 19 | return globalThis.fetch(url, options); 20 | } 21 | }; 22 | } else { 23 | fetch = globalThis.fetch; 24 | } 25 | 26 | function writeTree(FS, tree, path = '/') { 27 | path = path.endsWith('/') ? path : `${path}/`; 28 | 29 | for(const [filename, data] of Object.entries(tree)) { 30 | const filepath = `${path}${filename}`; 31 | if (typeof data === 'string' || data instanceof Uint8Array) { 32 | FS.writeFile(filepath, data); 33 | } else { 34 | FS.mkdir(filepath); 35 | writeTree(FS, data, `${filepath}/`); 36 | } 37 | } 38 | } 39 | 40 | function readTree(FS, path = '/') { 41 | path = path.endsWith('/') ? path : `${path}/`; 42 | 43 | const tree = {}; 44 | for (const filename of FS.readdir(path)) { 45 | const filepath = `${path}${filename}`; 46 | if (filename === '.' || filename === '..') 47 | continue; 48 | if (['/tmp', '/dev', '/proc'].includes(filepath)) 49 | continue; 50 | const stat = FS.stat(filepath); 51 | if (FS.isFile(stat.mode)) { 52 | tree[filename] = FS.readFile(filepath, { encoding: 'binary' }); 53 | } else if (FS.isDir(stat.mode)) { 54 | tree[filename] = readTree(FS, `${filepath}/`); 55 | } 56 | } 57 | return tree; 58 | } 59 | 60 | async function fetchObject(obj, fetchFn) { 61 | // Mutate the object being fetched, to avoid re-fetches within the same session. 62 | // Do this in parallel to avoid head-of-line blocking. 63 | const promises = []; 64 | for (const [key, value] of Object.entries(obj)) { 65 | if (typeof value === "string" || value instanceof Uint8Array) { 66 | promises.push(Promise.resolve([key, value])); 67 | } else if (value instanceof URL) { 68 | promises.push(fetchFn(value).then((fetched) => [key, fetched])); 69 | } else { 70 | promises.push(fetchObject(value, fetchFn).then((fetched) => [key, fetched])); 71 | } 72 | } 73 | for (const [key, value] of await Promise.all(promises)) 74 | obj[key] = value; 75 | return obj; 76 | } 77 | 78 | function fetchUint8Array(url) { 79 | return fetch(url).then((resp) => resp.arrayBuffer()).then((buf) => new Uint8Array(buf)); 80 | } 81 | 82 | function fetchResources({ filesystem }) { 83 | return Promise.all([ 84 | fetchObject(filesystem, fetchUint8Array) 85 | ]).then(([filesystem]) => { 86 | return { filesystem }; 87 | }); 88 | } 89 | 90 | export class PythonApplication { 91 | constructor(resources, execute, argv0) { 92 | this.resources = resources; 93 | this.resourceData = null; 94 | this.execute = execute; 95 | this.argv0 = argv0; 96 | } 97 | 98 | async run(args = null, files = {}, options = {}) { 99 | if (options.synchronously) 100 | throw new Error("Cannot run a Python application synchronously"); 101 | 102 | if (this.resourceData === null) { 103 | this.resourceData = await this.resources().then(fetchResources); 104 | } 105 | 106 | const loadPyodide = options.loadPyodide ?? (await import('pyodide')).loadPyodide; 107 | const pyodide = await loadPyodide({ args: [this.argv0, ...args ?? []] }); 108 | 109 | if (args === null) 110 | return; // prefetch resources, but do not actually run 111 | 112 | const lineBufferedConsole = lineBuffered(options.printLine ?? console.log); 113 | const makeWriter = (output) => { 114 | return { write(buffer) { output(buffer); return buffer.length; } } 115 | }; 116 | pyodide.setStdout(makeWriter(options.stdout === undefined ? lineBufferedConsole : options.stdout)); 117 | pyodide.setStderr(makeWriter(options.stderr === undefined ? lineBufferedConsole : options.stderr)); 118 | 119 | writeTree(pyodide.FS, this.resourceData.filesystem); 120 | writeTree(pyodide.FS, {root: files}); 121 | pyodide.FS.chdir('/root'); 122 | 123 | let error; 124 | try { 125 | this.execute(pyodide, this.argv0); 126 | } catch (e) { 127 | if (e instanceof pyodide.ffi.PythonError) { 128 | error = e; 129 | } else { 130 | throw e; 131 | } 132 | } 133 | 134 | let exitCode = 0; 135 | if (error !== undefined) { 136 | if (error.type === 'SystemExit') { 137 | exitCode = pyodide.pyimport('sys').last_value.code; 138 | } else { 139 | exitCode = 2; 140 | } 141 | } 142 | 143 | const filesOut = readTree(pyodide.FS, '/root'); 144 | console.log(exitCode); 145 | if (exitCode == 0) { 146 | return filesOut; 147 | } else { 148 | throw new Exit(exitCode, filesOut) 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Build & publish 3 | jobs: 4 | build: 5 | if: ${{ !contains(github.event.head_commit.message, 'skip ci') }} 6 | runs-on: ubuntu-latest 7 | env: 8 | RELEASE_BRANCH: ${{ startsWith(github.event.ref, 'refs/heads/develop-') || startsWith(github.event.ref, 'refs/heads/release-') }} 9 | steps: 10 | - name: Check out source code 11 | uses: actions/checkout@v4 12 | with: 13 | fetch-depth: 0 14 | submodules: recursive 15 | - name: Set up Python 16 | uses: actions/setup-python@v5 17 | with: 18 | python-version: '3.11' 19 | - name: Set up Rust 20 | uses: dtolnay/rust-toolchain@nightly 21 | with: 22 | targets: wasm32-wasip1 23 | - name: Install dependencies 24 | run: | 25 | python -m pip install --upgrade pip build 26 | sudo apt-get update 27 | sudo apt-get install flex bison ccache cmake libboost-program-options-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-python-dev 28 | - name: Set up caching 29 | uses: actions/cache@v4 30 | with: 31 | path: ~/.cache/ccache 32 | key: nextpnr-${{ hashFiles('nextpnr-src', 'icestorm-src', 'prjtrellis-src', 'prjoxide-src', 'apycula-meta', 'build.sh') }} 33 | restore-keys: | 34 | nextpnr-${{ hashFiles('nextpnr-src', 'icestorm-src', 'prjtrellis-src', 'prjoxide-src', 'apycula-meta', 'build.sh') }} 35 | nextpnr- 36 | - name: Set up ccache 37 | run: | 38 | ccache --max-size=2G -z 39 | - name: Build WASM binaries 40 | run: | 41 | MAKEFLAGS=-j$(nproc) ./build.sh 42 | - name: Build Python artifacts 43 | run: | 44 | ./package-pypi-ice40.sh 45 | ./package-pypi-ecp5.sh 46 | ./package-pypi-machxo2.sh 47 | ./package-pypi-nexus.sh 48 | ./package-pypi-himbaechel-gowin.sh 49 | - name: Upload Python artifact 50 | uses: actions/upload-artifact@v4 51 | with: 52 | name: dist-pypi 53 | path: pypi-*/dist/ 54 | - name: Build JavaScript artifacts 55 | run: | 56 | ./package-npmjs-ice40.sh 57 | ./package-npmjs-ecp5.sh 58 | ./package-npmjs-machxo2.sh 59 | ./package-npmjs-nexus.sh 60 | ./package-npmjs-himbaechel-gowin.sh 61 | - name: Upload JavaScript artifact 62 | uses: actions/upload-artifact@v4 63 | with: 64 | name: dist-npmjs 65 | path: npmjs-*/dist/ 66 | - name: Print ccache statistics 67 | run: | 68 | ccache -s 69 | test-python: 70 | needs: build 71 | runs-on: ubuntu-latest 72 | steps: 73 | - name: Set up Python 74 | uses: actions/setup-python@v5 75 | with: 76 | python-version: '3.11' 77 | - name: Download Python artifacts 78 | uses: actions/download-artifact@v4 79 | with: 80 | name: dist-pypi 81 | - name: Test iCE40 Python artifact 82 | run: | 83 | pip install pypi-ice40/dist/*.whl 84 | yowasp-icepll -h || true 85 | yowasp-icebram -h || true 86 | yowasp-icemulti -h || true 87 | yowasp-icepack -h || true 88 | yowasp-iceunpack -h || true 89 | yowasp-nextpnr-ice40 --help 90 | yowasp-nextpnr-ice40 --hx8k --package ct256 --test 91 | yowasp-nextpnr-ice40 --up5k --package sg48 --test 92 | - name: Test ECP5 Python artifact 93 | run: | 94 | pip install pypi-ecp5/dist/*.whl 95 | yowasp-ecppll --help || true 96 | yowasp-ecpbram --help 97 | yowasp-ecpmulti --help || true 98 | yowasp-ecppack --help || true 99 | yowasp-ecpunpack --help || true 100 | yowasp-nextpnr-ecp5 --help 101 | yowasp-nextpnr-ecp5 --um5g-25k --package CABGA381 --test 102 | - name: Test MachXO2 Python artifact 103 | run: | 104 | pip install pypi-machxo2/dist/*.whl 105 | yowasp-xo2pll --help || true 106 | yowasp-xo2bram --help 107 | yowasp-xo2multi --help || true 108 | yowasp-xo2pack --help || true 109 | yowasp-xo2unpack --help || true 110 | yowasp-nextpnr-machxo2 --help 111 | yowasp-nextpnr-machxo2 --device LCMXO2-1200HC-4SG32C --test 112 | - name: Test Nexus Python artifact 113 | run: | 114 | pip install pypi-nexus/dist/*.whl 115 | yowasp-prjoxide --help 116 | yowasp-nextpnr-nexus --help 117 | yowasp-nextpnr-nexus --device LIFCL-40-9BG400CES --test 118 | - name: Test Himbächel Gowin Python artifact 119 | run: | 120 | pip install pypi-himbaechel-gowin/dist/*.whl 121 | yowasp-nextpnr-himbaechel-gowin --help 122 | yowasp-nextpnr-himbaechel-gowin --device GW1NR-LV9QN88PC6/I5 --vopt family=GW1N-9C --test 123 | check: # group all `test (*)` workflows into one for the required status check 124 | needs: [test-python] 125 | if: ${{ always() && !contains(needs.*.result, 'cancelled') }} 126 | runs-on: ubuntu-latest 127 | steps: 128 | - run: ${{ contains(needs.*.result, 'failure') && 'false' || 'true' }} 129 | publish-python: 130 | needs: check 131 | runs-on: ubuntu-latest 132 | environment: publish 133 | permissions: 134 | id-token: write 135 | if: ${{ !contains(github.event.head_commit.message, 'skip py') }} 136 | steps: 137 | - name: Download Python artifacts 138 | uses: actions/download-artifact@v4 139 | with: 140 | name: dist-pypi 141 | path: dist-tree/ 142 | - name: Prepare artifacts for publishing 143 | run: | 144 | mkdir dist 145 | find dist-tree -name '*.whl' -exec mv {} dist/ \; 146 | - name: Publish wheels to Test PyPI 147 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop') }} 148 | uses: pypa/gh-action-pypi-publish@release/v1 149 | with: 150 | repository-url: https://test.pypi.org/legacy/ 151 | verbose: true 152 | - name: Publish wheels to PyPI 153 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/release') }} 154 | uses: pypa/gh-action-pypi-publish@release/v1 155 | with: 156 | verbose: true 157 | publish-javascript: 158 | needs: check 159 | runs-on: ubuntu-latest 160 | environment: publish 161 | permissions: 162 | id-token: write 163 | if: ${{ !contains(github.event.head_commit.message, 'skip js') }} 164 | steps: 165 | - name: Set up Node.js 166 | uses: actions/setup-node@v4 167 | with: 168 | node-version: '20' 169 | registry-url: 'https://registry.npmjs.org' 170 | - name: Update npm 171 | run: npm install -g npm@latest 172 | - name: Download JavaScript artifacts 173 | uses: actions/download-artifact@v4 174 | with: 175 | name: dist-npmjs 176 | path: dist/ 177 | - name: Publish package to NPM (dry run) 178 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop') }} 179 | run: for pkg in $(find dist -name '*.tgz'); do npm publish file:$pkg ${{ github.event.ref == 'refs/heads/release' && '--tag latest' || '--tag release' }} --dry-run; done 180 | - name: Publish package to NPM 181 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/release') }} 182 | run: for pkg in $(find dist -name '*.tgz'); do npm publish file:$pkg ${{ github.event.ref == 'refs/heads/release' && '--tag latest' || '--tag release' }}; done 183 | release: 184 | needs: check 185 | runs-on: ubuntu-latest 186 | if: ${{ contains(github.event.head_commit.message, 'autorelease') && github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop') }} 187 | steps: 188 | - name: Check out source code 189 | uses: actions/checkout@v4 190 | with: 191 | fetch-depth: 0 192 | token: ${{ secrets.PUSH_TOKEN }} 193 | - name: Update release branch 194 | run: | 195 | release_branch=${{ github.event.ref }} 196 | release_branch=${release_branch/develop/release} 197 | git push origin HEAD:${release_branch} 198 | --------------------------------------------------------------------------------