├── npmjs ├── gen │ └── .gitkeep ├── .gitignore ├── lib │ ├── api.js │ └── api.d.ts ├── prepare.py ├── package-in.json ├── test │ └── test_api.mjs └── README.md ├── .github ├── FUNDING.yml └── workflows │ ├── track-upstream.yml │ └── package.yml ├── .gitignore ├── pypi ├── .gitignore ├── pyproject.toml ├── yowasp_yosys │ └── __init__.py ├── setup.py └── README.md ├── package-npmjs.sh ├── .gitmodules ├── CONTRIBUTING.md ├── package-pypi.sh ├── README.md └── LICENSE.txt /npmjs/gen/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: whitequark 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /wasi-sdk-* 2 | *.wasm 3 | 4 | /flex-* 5 | 6 | /*-build 7 | /*-prefix 8 | 9 | /flex-* 10 | -------------------------------------------------------------------------------- /npmjs/.gitignore: -------------------------------------------------------------------------------- 1 | /package-lock.json 2 | /package.json 3 | /node_modules 4 | /dist 5 | 6 | /*.wasm 7 | /gen 8 | -------------------------------------------------------------------------------- /pypi/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | /*.egg-info 3 | /.eggs 4 | /build 5 | /dist 6 | /yowasp_yosys/share 7 | /yowasp_yosys/smtbmc.py 8 | /yowasp_yosys/ywio.py 9 | /yowasp_yosys/witness.py 10 | /yowasp_yosys/sby.py 11 | -------------------------------------------------------------------------------- /package-npmjs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | cd $(dirname $0)/npmjs 6 | 7 | ${PYTHON} prepare.py 8 | npm install 9 | npm run all 10 | 11 | mkdir -p dist 12 | npm pack --pack-destination dist -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "yosys-src"] 2 | path = yosys-src 3 | url = https://github.com/YosysHQ/yosys 4 | branch = master 5 | [submodule "SymbiYosys-src"] 6 | path = SymbiYosys-src 7 | url = https://github.com/YosysHQ/SymbiYosys 8 | [submodule "yosys-slang-src"] 9 | path = yosys-slang-src 10 | url = https://github.com/povik/yosys-slang 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | YoWASP Yosys 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/lib/api.js: -------------------------------------------------------------------------------- 1 | import { Application } from '@yowasp/runtime'; 2 | import * as resources from '../gen/yosys-resources.js'; 3 | import { instantiate } from '../gen/yosys.js'; 4 | 5 | export { Exit } from '@yowasp/runtime'; 6 | 7 | const yosys = new Application(resources, instantiate, 'yowasp-yosys'); 8 | const runYosys = yosys.run.bind(yosys); 9 | 10 | export { runYosys }; 11 | export const commands = { 'yosys': runYosys }; 12 | export const version = VERSION; 13 | -------------------------------------------------------------------------------- /package-pypi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | PYTHON=${PYTHON:-python} 4 | 5 | rm -rf pypi/yowasp_yosys/share 6 | cp -r \ 7 | yosys-build/yosys.wasm \ 8 | yosys-build/share \ 9 | yosys-src/backends/smt2/smtbmc.py \ 10 | yosys-src/backends/smt2/witness.py \ 11 | SymbiYosys-src/sbysrc/sby.py \ 12 | pypi/yowasp_yosys/ 13 | cp SymbiYosys-src/sbysrc/sby_*.py \ 14 | pypi/yowasp_yosys/share/python3 15 | 16 | cd pypi 17 | rm -rf build && ${PYTHON} -m build -w 18 | sha256sum dist/*.whl 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | YoWASP Yosys packages 2 | ===================== 3 | 4 | This package provides [Yosys][] binaries built for [WebAssembly][]. See the [overview of the YoWASP project][yowasp] for details. 5 | 6 | Two embeddings are provided: [Python](pypi/README.md) and [JavaScript](npmjs/README.md). 7 | 8 | [yosys]: https://github.com/YosysHQ/yosys/ 9 | [webassembly]: https://webassembly.org/ 10 | [yowasp]: https://yowasp.github.io/ 11 | 12 | 13 | License 14 | ------- 15 | 16 | This package is covered by the [ISC license](LICENSE.txt), which is the same as the [Yosys license](https://github.com/YosysHQ/yosys/blob/master/COPYING). 17 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (C) Catherine 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 | -------------------------------------------------------------------------------- /pypi/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-yosys" 9 | description = "Yosys Open SYnthesis Suite" 10 | readme = "README.md" 11 | authors = [{name = "Catherine", email = "whitequark@whitequark.org"}] 12 | license = "ISC" 13 | 14 | requires-python = "~=3.9" 15 | dependencies = [ 16 | "yowasp-runtime~=1.12", 17 | "click" # for sby 18 | ] 19 | 20 | [project.scripts] 21 | yowasp-yosys = "yowasp_yosys:_run_yosys_argv" 22 | yowasp-yosys-smtbmc = "yowasp_yosys:_run_yosys_smtbmc_argv" 23 | yowasp-yosys-witness = "yowasp_yosys:_run_yosys_witness_argv" 24 | yowasp-sby = "yowasp_yosys:_run_sby_argv" 25 | 26 | [project.urls] 27 | "Homepage" = "https://yowasp.org/" 28 | "Source Code" = "https://github.com/YoWASP/yosys" 29 | "Bug Tracker" = "https://github.com/YoWASP/yosys/issues" 30 | 31 | [tool.setuptools.package-data] 32 | yowasp_yosys = ["*.wasm", "share/*", "share/**/*", "share/**/**/*", "share/**/**/**/*"] 33 | -------------------------------------------------------------------------------- /npmjs/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 runYosys: Command; 34 | 35 | export const commands: { 36 | 'yosys': Command, 37 | }; 38 | 39 | export const version: string; 40 | -------------------------------------------------------------------------------- /npmjs/prepare.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import json 4 | import subprocess 5 | 6 | 7 | yosys_version_raw = subprocess.check_output([ 8 | "make", "-s", "-C", "../yosys-src", "echo-yosys-ver" 9 | ], encoding="utf-8").strip() 10 | 11 | git_rev_list_raw = subprocess.check_output([ 12 | "git", "rev-list", "HEAD" 13 | ], encoding="utf-8").split() 14 | 15 | # Yosys can't figure out if it should have a patch version or not. 16 | # Match one, and add one below in our version just in case. 17 | yosys_version = re.match(r"^(\d+)\.(\d+)(?:\.(\d+))?(?:\+(\d+))?$", yosys_version_raw) 18 | yosys_major = int(yosys_version[1]) 19 | yosys_minor = int(yosys_version[2]) 20 | _yosys_patch = int(yosys_version[3] or "0") 21 | yosys_node = int(yosys_version[4] or "0") 22 | 23 | distance = len(git_rev_list_raw) - 1 24 | 25 | if os.environ.get("RELEASE_BRANCH", "false") in ("true", "1", "yes"): 26 | version = f"{yosys_major}.{yosys_minor}.{distance}" 27 | else: 28 | version = f"{yosys_major}.{yosys_minor + 1}.{yosys_node}-dev.{distance}" 29 | print(f"version {version}") 30 | 31 | with open("package-in.json", "rt") as f: 32 | package_json = json.load(f) 33 | package_json["version"] = version 34 | package_json["scripts"]["build"] += f" --define:VERSION=\\\"{version}\\\"" 35 | with open("package.json", "wt") as f: 36 | json.dump(package_json, f, indent=2) 37 | -------------------------------------------------------------------------------- /pypi/yowasp_yosys/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import importlib.resources 3 | import yowasp_runtime 4 | 5 | 6 | def run_yosys(argv): 7 | return yowasp_runtime.run_wasm(__package__, "yosys.wasm", resources=["share"], 8 | argv=["yowasp-yosys", *argv]) 9 | 10 | 11 | def _run_yosys_argv(): 12 | sys.exit(run_yosys(sys.argv[1:])) 13 | 14 | 15 | def _run_yosys_smtbmc_argv(): 16 | prefix = importlib.resources.files(__package__) 17 | sys.path[0:0] = [str(prefix / "share" / "python3")] 18 | smtbmc_py = prefix / "smtbmc.py" 19 | with open(smtbmc_py) as f: 20 | globals = {"__name__": "__main__"} 21 | exec(compile(f.read(), smtbmc_py, "exec"), globals, globals) 22 | 23 | 24 | def _run_yosys_witness_argv(): 25 | prefix = importlib.resources.files(__package__) 26 | sys.path[0:0] = [str(prefix / "share" / "python3")] 27 | witness_py = prefix / "witness.py" 28 | with open(witness_py) as f: 29 | globals = {"__name__": "__main__"} 30 | exec(compile(f.read(), witness_py, "exec"), globals, globals) 31 | 32 | 33 | def _run_sby_argv(): 34 | prefix = importlib.resources.files(__package__) 35 | sys.path[0:0] = [str(prefix / "share" / "python3")] 36 | sby_py = prefix / "sby.py" 37 | with open(sby_py) as f: 38 | globals = {} 39 | exec(compile(f.read(), sby_py, "exec"), globals, globals) 40 | -------------------------------------------------------------------------------- /pypi/setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import subprocess 4 | from setuptools import setup 5 | from setuptools_scm.git import parse as parse_git 6 | 7 | 8 | def version(): 9 | upstream_git = parse_git("../yosys-src") 10 | package_git = parse_git("..") 11 | 12 | yosys_version_raw = subprocess.check_output([ 13 | "make", "-s", "-C", "../yosys-src", "echo-yosys-ver" 14 | ], encoding="utf-8").strip() 15 | 16 | # Yosys can't figure out if it should have a patch version or not. 17 | # Match one, and add one below in our version just in case. 18 | yosys_version = re.match(r"^(\d+)\.(\d+)(?:\.(\d+))?(?:\+(\d+))?$", yosys_version_raw) 19 | yosys_major = int(yosys_version[1]) 20 | yosys_minor = int(yosys_version[2]) 21 | yosys_patch = int(yosys_version[3] or "0") 22 | yosys_node = int(yosys_version[4]) if yosys_version[4] else None 23 | 24 | version = f"{yosys_major}.{yosys_minor}.{yosys_patch}" 25 | if yosys_node is None: # Yosys release 26 | version += f".0" 27 | else: # Yosys snapshot 28 | version += f".{yosys_node}" 29 | version += f".post{package_git.distance}" 30 | if os.environ.get("RELEASE_BRANCH", "false") in ("true", "1", "yes"): 31 | pass # PyPI release (installable normally) 32 | elif yosys_node is not None: 33 | version += f".dev0" # PyPI snapshot (installable by exact version) 34 | if upstream_git.dirty or package_git.dirty: 35 | version += f"+dirty" 36 | return version 37 | 38 | 39 | setup( 40 | version=version(), 41 | ) 42 | -------------------------------------------------------------------------------- /npmjs/package-in.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@yowasp/yosys", 3 | "version": "__VERSION__", 4 | "description": "Yosys Open SYnthesis Suite", 5 | "author": "Catherine ", 6 | "license": "ISC", 7 | "homepage": "https://yowasp.org/", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/YoWASP/yosys.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/YoWASP/yosys/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.66", 30 | "esbuild": "^0.25.11" 31 | }, 32 | "scripts": { 33 | "transpile": "jco new ../yosys-build/yosys.wasm --wasi-command --output yosys.wasm && jco transpile yosys.wasm --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/yosys-resources.js gen ../yosys-build/share", 35 | "build": "esbuild --bundle lib/api.js --outfile=gen/bundle.js --format=esm --platform=node", 36 | "all": "npm run transpile && npm run pack && npm run build" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.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: Update upstream code 17 | run: | 18 | git -C yosys-src pull --ff-only origin main 19 | git -C SymbiYosys-src pull --ff-only origin main 20 | git -C yosys-slang-src pull --ff-only origin master 21 | - name: Push updated code 22 | uses: stefanzweifel/git-auto-commit-action@v4 23 | with: 24 | commit_message: Update dependencies. 25 | track-releases: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: Check out source code 29 | uses: actions/checkout@v4 30 | with: 31 | fetch-depth: 0 32 | submodules: true 33 | token: ${{ secrets.PUSH_TOKEN }} 34 | - name: Check out new upstream tag 35 | id: checkout-tag 36 | run: | 37 | for tag in $(git -C yosys-src tag -l 'v*.*' | sort -rV); do 38 | ref=$(git -C yosys-src rev-parse $tag) 39 | branch=develop-${tag/v/} 40 | if ! git rev-parse -q --verify remotes/origin/${branch} >/dev/null; then 41 | echo "New branch ${branch} with yosys-src ${ref}" 42 | git -C yosys-src checkout ${ref} 43 | # 2023-02-06: https://github.com/YosysHQ/sby/issues/229 44 | echo "version=${tag/v/}" >> $GITHUB_OUTPUT 45 | break 46 | fi; 47 | done 48 | - name: Push new branch 49 | uses: stefanzweifel/git-auto-commit-action@v5 50 | if: steps.checkout-tag.outputs.version 51 | with: 52 | commit_message: "[autorelease] Yosys ${{ steps.checkout-tag.outputs.version }}." 53 | branch: develop-${{ steps.checkout-tag.outputs.version }} 54 | create_branch: true 55 | -------------------------------------------------------------------------------- /pypi/README.md: -------------------------------------------------------------------------------- 1 | YoWASP Yosys package 2 | ==================== 3 | 4 | This package provides [Yosys][] binaries built for [WebAssembly][]. See the [overview of the YoWASP project][yowasp] for details. 5 | 6 | [yosys]: https://github.com/YosysHQ/yosys/ 7 | [webassembly]: https://webassembly.org/ 8 | [yowasp]: https://yowasp.github.io/ 9 | 10 | 11 | Versioning 12 | ---------- 13 | 14 | The version of this package is derived from the upstream Yosys package version in the `X.Y[.Z][+N]` format, and is comprised of five or six parts in a `X.Y.Z.N.postM[.dev]` format, where the symbols are: 15 | 16 | 1. `X`: Yosys major version 17 | 2. `Y`: Yosys minor version 18 | 3. `Z`: Yosys patch version; only present for some Yosys releases, zero if not present 19 | 4. `N`: zero for packages built from Yosys releases, `N` for packages built from unreleased Yosys snapshots; matches the `N` in the `X.Y+N` upstream version 20 | 5. `postM`: package build version; disambiguates different builds produced from the same Yosys source tree 21 | 6. `dev`: present only for packages built from unreleased Yosys snapshots; marks these packages as pre-releases 22 | 23 | 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][].) 24 | 25 | 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. 26 | 27 | [testpypi]: https://test.pypi.org/ 28 | [pypi]: https://pypi.org/ 29 | [pep440]: https://peps.python.org/pep-0440/ 30 | [pep440-vs]: https://peps.python.org/pep-0440/#version-specifiers 31 | 32 | 33 | Configuration 34 | ------------- 35 | 36 | See the documentation for [the Python YoWASP runtime](https://github.com/YoWASP/runtime-py#configuration). 37 | 38 | 39 | License 40 | ------- 41 | 42 | This package is covered by the [ISC license](LICENSE.txt), which is the same as the [Yosys license](https://github.com/YosysHQ/yosys/blob/master/COPYING). 43 | -------------------------------------------------------------------------------- /npmjs/test/test_api.mjs: -------------------------------------------------------------------------------- 1 | import { runYosys } from '@yowasp/yosys'; 2 | 3 | runYosys(["--version"]); 4 | 5 | const files = await runYosys( 6 | ["inv.v", "-p", "hierarchy -auto-top", "-o", "top.json"], 7 | {"inv.v": "module inv(input a, output o); assign o = ~a; endmodule"}); 8 | const actual = JSON.parse(files["top.json"]); 9 | const expected = { 10 | "creator": actual["creator"], 11 | "modules": { 12 | "inv": { 13 | "attributes": { 14 | "hdlname": "inv", 15 | "top": "00000000000000000000000000000001", 16 | "src": "inv.v:1.1-1.56" 17 | }, 18 | "ports": { 19 | "a": { 20 | "direction": "input", 21 | "bits": [ 2 ] 22 | }, 23 | "o": { 24 | "direction": "output", 25 | "bits": [ 3 ] 26 | } 27 | }, 28 | "cells": { 29 | "$not$inv.v:1$1": { 30 | "hide_name": 1, 31 | "type": "$not", 32 | "parameters": { 33 | "A_SIGNED": "00000000000000000000000000000000", 34 | "A_WIDTH": "00000000000000000000000000000001", 35 | "Y_WIDTH": "00000000000000000000000000000001" 36 | }, 37 | "attributes": { 38 | "src": "inv.v:1.43-1.45" 39 | }, 40 | "port_directions": { 41 | "A": "input", 42 | "Y": "output" 43 | }, 44 | "connections": { 45 | "A": [ 2 ], 46 | "Y": [ 3 ] 47 | } 48 | } 49 | }, 50 | "netnames": { 51 | "$not$inv.v:1$1_Y": { 52 | "hide_name": 1, 53 | "bits": [ 3 ], 54 | "attributes": { 55 | "src": "inv.v:1.43-1.45" 56 | } 57 | }, 58 | "a": { 59 | "hide_name": 0, 60 | "bits": [ 2 ], 61 | "attributes": { 62 | "src": "inv.v:1.18-1.19" 63 | } 64 | }, 65 | "o": { 66 | "hide_name": 0, 67 | "bits": [ 3 ], 68 | "attributes": { 69 | "src": "inv.v:1.28-1.29" 70 | } 71 | } 72 | } 73 | } 74 | } 75 | }; 76 | if (JSON.stringify(actual) !== JSON.stringify(expected)) { 77 | console.log(JSON.stringify(actual)); 78 | throw 'test failed'; 79 | } -------------------------------------------------------------------------------- /npmjs/README.md: -------------------------------------------------------------------------------- 1 | YoWASP Yosys package 2 | ==================== 3 | 4 | This package provides [Yosys][] binaries built for [WebAssembly][]. See the [overview of the YoWASP project][yowasp] for details. 5 | 6 | At the moment, this package only provides an API allowing to run Yosys in a virtual filesystem; no binaries are provided. 7 | 8 | This package does not provide access to `sby`, `yowasp-yosys-smtbmc`, and `yowasp-yosys-witness`; only the main `yosys` application is available. 9 | 10 | [yosys]: https://github.com/YosysHQ/yosys/ 11 | [webassembly]: https://webassembly.org/ 12 | [yowasp]: https://yowasp.github.io/ 13 | 14 | 15 | API reference 16 | ------------- 17 | 18 | This package provides one function: 19 | 20 | - `runYosys` 21 | 22 | For more detail, see the documentation for [the JavaScript YoWASP runtime](https://github.com/YoWASP/runtime-js#api-reference). 23 | 24 | 25 | Versioning 26 | ---------- 27 | 28 | The version of this package is derived from the upstream Yosys package version in the `X.Y[.Z][+N]` format, and can be in one of the two formats, `X.Y.M` (for builds from release branches) or `X.(Y+1).N-dev.M` (for development builds), where the symbols are: 29 | 30 | 1. `X`: Yosys major version 31 | 2. `Y`: Yosys minor version 32 | 3. `Z`: Yosys patch version; ignored if present 33 | 4. `N`: matches the `N` in the `X.Y+N` upstream version, if present 34 | 5. `-dev`: present only for packages built from unreleased Yosys snapshots; marks these packages as pre-releases 35 | 6. `M`: package build version; disambiguates different builds produced from the same Yosys source tree 36 | 37 | With this scheme, there is a direct correspondence between upstream versions and [SemVer][semver] NPM package versions. 38 | 39 | Note that for development builds, the minor version is incremented as required by the SemVer comparison order. This means that an NPM package built from the upstream version `0.45+12` and the 120th commit in this repository will have the version `0.46.12-dev.120`. Because this is a pre-release package, it will not be matched by version specifiers such as `^0.46` or `>=0.46`. 40 | 41 | [semver]: https://semver.org/ 42 | 43 | 44 | License 45 | ------- 46 | 47 | This package is covered by the [ISC license](LICENSE.txt), which is the same as the [Yosys license](https://github.com/YosysHQ/yosys/blob/master/COPYING). 48 | -------------------------------------------------------------------------------- /.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.x' 19 | - name: Install dependencies 20 | run: | 21 | python -m pip install --upgrade pip build 22 | sudo apt update 23 | sudo apt-get install flex bison ccache 24 | - name: Set up caching 25 | uses: actions/cache@v4 26 | with: 27 | path: ~/.cache/ccache 28 | key: yosys-${{ hashFiles('yosys-src', 'SymbiYosys-src', 'build.sh') }} 29 | restore-keys: | 30 | yosys-${{ hashFiles('yosys-src', 'SymbiYosys-src', 'build.sh') }} 31 | yosys- 32 | - name: Set up ccache 33 | run: | 34 | ccache --max-size=5G -z 35 | - name: Build WASM binaries 36 | run: | 37 | MAKEFLAGS=-j$(nproc) ./build.sh 38 | - name: Build Python artifact 39 | run: | 40 | ./package-pypi.sh 41 | - name: Upload Python artifact 42 | uses: actions/upload-artifact@v4 43 | with: 44 | name: dist-pypi 45 | path: pypi/dist/ 46 | - name: Build JavaScript artifact 47 | run: | 48 | ./package-npmjs.sh 49 | cp npmjs/test/test_api.mjs npmjs/dist/ 50 | - name: Upload JavaScript artifact 51 | uses: actions/upload-artifact@v4 52 | with: 53 | name: dist-npmjs 54 | path: npmjs/dist/ 55 | - name: Print ccache statistics 56 | run: | 57 | ccache -s 58 | test-python: 59 | needs: build 60 | runs-on: ubuntu-latest 61 | strategy: 62 | matrix: 63 | python-version: 64 | - '3.9' 65 | - '3.10' 66 | - '3.11' 67 | - '3.12' 68 | - '3.13' 69 | - '3.14-dev' 70 | steps: 71 | - name: Set up Python 72 | uses: actions/setup-python@v5 73 | with: 74 | python-version: ${{ matrix.python-version }} 75 | - name: Download Python artifact 76 | uses: actions/download-artifact@v4 77 | with: 78 | name: dist-pypi 79 | path: dist/ 80 | - name: Test Python artifact 81 | run: | 82 | pip install dist/*.whl 83 | yowasp-yosys --help 84 | yowasp-yosys -p 'slang_version' 85 | yowasp-sby --help 86 | yowasp-yosys-smtbmc --help 87 | yowasp-yosys-witness --help 88 | test-javascript: 89 | needs: build 90 | runs-on: ubuntu-latest 91 | strategy: 92 | matrix: 93 | node-version: 94 | - 'v18.x' 95 | - 'v20.x' 96 | steps: 97 | - name: Set up Node.js 98 | uses: actions/setup-node@v4 99 | with: 100 | node-version: ${{ matrix.node-version }} 101 | - name: Download JavaScript artifact 102 | uses: actions/download-artifact@v4 103 | with: 104 | name: dist-npmjs 105 | path: dist/ 106 | - name: Test JavaScript artifact 107 | run: | 108 | npm install ./dist/*.tgz 109 | node dist/test_api.mjs 110 | check: # group all `test (*)` workflows into one for the required status check 111 | needs: [test-python, test-javascript] 112 | if: ${{ always() && !contains(needs.*.result, 'cancelled') }} 113 | runs-on: ubuntu-latest 114 | steps: 115 | - run: ${{ contains(needs.*.result, 'failure') && 'false' || 'true' }} 116 | publish-python: 117 | needs: check 118 | runs-on: ubuntu-latest 119 | environment: publish 120 | permissions: 121 | id-token: write 122 | if: ${{ !contains(github.event.head_commit.message, 'skip py') }} 123 | steps: 124 | - name: Download Python artifact 125 | uses: actions/download-artifact@v4 126 | with: 127 | name: dist-pypi 128 | path: dist/ 129 | - name: Publish wheels to Test PyPI 130 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop') }} 131 | uses: pypa/gh-action-pypi-publish@release/v1 132 | with: 133 | repository-url: https://test.pypi.org/legacy/ 134 | - name: Publish wheels to PyPI 135 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/release') }} 136 | uses: pypa/gh-action-pypi-publish@release/v1 137 | publish-javascript: 138 | needs: check 139 | runs-on: ubuntu-latest 140 | environment: publish 141 | permissions: 142 | id-token: write 143 | if: ${{ !contains(github.event.head_commit.message, 'skip js') }} 144 | steps: 145 | - name: Set up Node.js 146 | uses: actions/setup-node@v4 147 | with: 148 | node-version: '20' 149 | registry-url: 'https://registry.npmjs.org' 150 | - name: Update npm 151 | run: npm install -g npm@latest 152 | - name: Download JavaScript artifact 153 | uses: actions/download-artifact@v4 154 | with: 155 | name: dist-npmjs 156 | path: dist/ 157 | - name: Publish package to NPM (dry run) 158 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop') }} 159 | run: npm publish $(find dist -name *.tgz -printf 'file:%p ') ${{ github.event.ref == 'refs/heads/release' && '--tag latest' || '--tag release' }} --dry-run 160 | - name: Publish package to NPM 161 | if: ${{ github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/release') }} 162 | run: npm publish $(find dist -name *.tgz -printf 'file:%p ') ${{ github.event.ref == 'refs/heads/release' && '--tag latest' || '--tag release' }} 163 | release: 164 | needs: check 165 | runs-on: ubuntu-latest 166 | if: ${{ contains(github.event.head_commit.message, 'autorelease') && github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop') }} 167 | steps: 168 | - name: Check out source code 169 | uses: actions/checkout@v4 170 | with: 171 | fetch-depth: 0 172 | token: ${{ secrets.PUSH_TOKEN }} 173 | - name: Update release branch 174 | run: | 175 | release_branch=${{ github.event.ref }} 176 | release_branch=${release_branch/develop/release} 177 | git push origin HEAD:${release_branch} 178 | --------------------------------------------------------------------------------