diff --git a/.gitignore b/.gitignore index 900637e..975dd7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ __pycache__ /build /dist +/result .pdm-python diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..122b5b0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1723637854, + "narHash": "sha256-med8+5DSWa2UnOqtdICndjDAEjxr5D7zaIiK4pn0Q7c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c3aa7b8938b17aebd2deecf7be0636000d62a2b9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..d851274 --- /dev/null +++ b/flake.nix @@ -0,0 +1,107 @@ +{ + description = "Niar development environment"; + + inputs = { + nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; + flake-utils.url = github:numtide/flake-utils; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs {inherit system;}; + + pyproject-toml = pkgs.lib.importTOML ./pyproject.toml; + + python = let + packageOverrides = final: prev: { + amaranth = prev.amaranth.overridePythonAttrs { + version = "0.6.0.dev45"; + src = pkgs.fetchFromGitHub { + owner = "amaranth-lang"; + repo = "amaranth"; + rev = "bc2e90913311e326d8f396e33d7a1c7f6eef6e4e"; + hash = "sha256-WkZl3XcTfBXoQ/ZigyW/wIGge5PlRPmpuOIcjLEoVTM="; + }; + }; + + amaranth-boards = prev.amaranth-boards.overridePythonAttrs rec { + version = "0.1.dev250"; + src = pkgs.fetchFromGitHub { + owner = "amaranth-lang"; + repo = "amaranth-boards"; + rev = "19b97324ecf9111c5d16377af79f82aad761c476"; + postFetch = "rm -f $out/.git_archival.txt $out/.gitattributes"; + hash = "sha256-0uvn91i/yuIY75lL5Oxvozdw7Q2Uw83JWo7srgEYEpI="; + }; + + build-system = [python.pkgs.pdm-backend]; + dontCheckRuntimeDeps = 1; # amaranth 0.6.0.devX doesn't match anything. + }; + }; + in + pkgs.python3.override { + inherit packageOverrides; + self = python; + }; + + toolchain-pkgs = with pkgs; [ + yosys + icestorm + trellis + nextpnr + openfpgaloader + ]; + in rec { + formatter = pkgs.alejandra; + + packages.default = packages.niar; + + packages.python = python; + packages.niar = python.pkgs.buildPythonPackage { + name = "niar"; + version = pyproject-toml.project.version; + src = ./.; + pyproject = true; + + build-system = [python.pkgs.pdm-backend]; + + propagatedBuildInputs = + [ + python.pkgs.amaranth + python.pkgs.amaranth-boards + ] + ++ toolchain-pkgs; + + doCheck = true; + nativeCheckInputs = [python.pkgs.pytestCheckHook] ++ toolchain-pkgs; + }; + + devShells.default = pkgs.mkShell { + name = "niar"; + + buildInputs = with python.pkgs; [ + python-lsp-server + pyls-isort + pylsp-rope + pytest + ]; + + inputsFrom = [packages.default]; + }; + + devShells.pure-python = pkgs.mkShell { + name = "niar-pure-python"; + + buildInputs = + [ + pkgs.python3 + pkgs.pdm + ] + ++ toolchain-pkgs; + }; + }); +} diff --git a/src/niar/__init__.py b/niar/__init__.py similarity index 100% rename from src/niar/__init__.py rename to niar/__init__.py diff --git a/src/niar/build.py b/niar/build.py similarity index 95% rename from src/niar/build.py rename to niar/build.py index bb54129..3cdfb06 100644 --- a/src/niar/build.py +++ b/niar/build.py @@ -102,6 +102,10 @@ def main(np: Project, args): next_heading = re.compile(r"^Info: Placed ", flags=re.MULTILINE) log_file_between(logging.INFO, nextpnr_report, heading, next_heading, prefix="Info: ") + # TODO: + # Info: Critical path report for cross-domain path 'posedge clk' -> '': + # ... + # Info: 2.3 ns logic, 6.5 ns routing timing_report = None max_freq = re.compile(r"^Info: Max frequency for clock '", flags=re.MULTILINE) slack_histo = re.compile(r"^Info: Slack histogram:", flags=re.MULTILINE) @@ -113,7 +117,7 @@ def main(np: Project, args): timing_report.append(line) if timing_report is None: - logger.warn("Couldn't extract timing information from nextpnr log") + logger.warning("Couldn't extract timing information from nextpnr log") else: for line in timing_report: if slack_histo.match(line): diff --git a/src/niar/cmdrunner.py b/niar/cmdrunner.py similarity index 100% rename from src/niar/cmdrunner.py rename to niar/cmdrunner.py diff --git a/src/niar/cxxrtl.py b/niar/cxxrtl.py similarity index 100% rename from src/niar/cxxrtl.py rename to niar/cxxrtl.py diff --git a/src/niar/cxxrtl_platform.py b/niar/cxxrtl_platform.py similarity index 100% rename from src/niar/cxxrtl_platform.py rename to niar/cxxrtl_platform.py diff --git a/src/niar/logging.py b/niar/logging.py similarity index 100% rename from src/niar/logging.py rename to niar/logging.py diff --git a/src/niar/project.py b/niar/project.py similarity index 100% rename from src/niar/project.py rename to niar/project.py diff --git a/pdm.lock b/pdm.lock index 8441c9d..138b4a9 100644 --- a/pdm.lock +++ b/pdm.lock @@ -3,14 +3,20 @@ [metadata] groups = ["default", "test"] -strategy = ["cross_platform", "inherit_metadata"] -lock_version = "4.4.2" -content_hash = "sha256:256cf41c0adcfe76e6d6f5d94c852d1df928c19788a6ea7c6b451e94c99e6d12" +strategy = ["inherit_metadata"] +lock_version = "4.5.0" +content_hash = "sha256:5432adbed676bebf63d12df3090bd10bd9bf18b8e79c04ca8aa7cb96999b1624" + +[[metadata.targets]] +requires_python = ">=3.8" [[package]] name = "amaranth" -version = "0.5.0" +version = "0.6.0.dev45" requires_python = "~=3.8" +git = "https://github.com/amaranth-lang/amaranth" +ref = "bc2e90913311e326d8f396e33d7a1c7f6eef6e4e" +revision = "bc2e90913311e326d8f396e33d7a1c7f6eef6e4e" summary = "Amaranth hardware definition language" groups = ["default", "test"] dependencies = [ @@ -19,52 +25,47 @@ dependencies = [ "jschon~=0.11.1", "pyvcd<0.5,>=0.2.2", ] -files = [ - {file = "amaranth-0.5.0-py3-none-any.whl", hash = "sha256:3d05d38864d6e88e40db93ed29ac0bee7f2a351d12810d4414f5b65a7cb0e23f"}, - {file = "amaranth-0.5.0.tar.gz", hash = "sha256:9d2a1893d6ac938e0ff3983892eff5b56033e06691cc89674eb8d500dc46cdf6"}, -] [[package]] name = "amaranth-boards" -version = "0.1.dev248" +version = "0.1.dev250" requires_python = "~=3.8" git = "https://github.com/amaranth-lang/amaranth-boards" -ref = "main" -revision = "ad5a939b86020c53e0e193620b96ca19d5960192" +ref = "19b97324ecf9111c5d16377af79f82aad761c476" +revision = "19b97324ecf9111c5d16377af79f82aad761c476" summary = "Board and connector definitions for Amaranth HDL" groups = ["test"] dependencies = [ - "amaranth<0.6,>=0.4", + "amaranth<0.7,>=0.4", ] [[package]] name = "amaranth-yosys" -version = "0.40.0.0.post96" +version = "0.40.0.0.post98" requires_python = "~=3.8" summary = "Specialized WebAssembly build of Yosys used by Amaranth HDL" groups = ["default"] dependencies = [ "importlib-resources>=1.4; python_version < \"3.9\"", - "wasmtime<23,>=1", + "wasmtime<24,>=1", ] files = [ - {file = "amaranth_yosys-0.40.0.0.post96-py3-none-any.whl", hash = "sha256:d4d7b0c40365f00d5090433762d81134209ca69f655ac74bc2e50decd6675255"}, + {file = "amaranth_yosys-0.40.0.0.post98-py3-none-any.whl", hash = "sha256:c8ec7c38e57e09aa88a0f4108df803bbca8753e7774e85abab950cdeefaa449d"}, ] [[package]] name = "amaranth" -version = "0.5.0" +version = "0.6.0.dev45" extras = ["builtin-yosys"] requires_python = "~=3.8" +git = "https://github.com/amaranth-lang/amaranth" +ref = "bc2e90913311e326d8f396e33d7a1c7f6eef6e4e" +revision = "bc2e90913311e326d8f396e33d7a1c7f6eef6e4e" summary = "Amaranth hardware definition language" groups = ["default"] dependencies = [ + "amaranth @ git+https://github.com/amaranth-lang/amaranth@bc2e90913311e326d8f396e33d7a1c7f6eef6e4e", "amaranth-yosys>=0.40", - "amaranth==0.5.0", -] -files = [ - {file = "amaranth-0.5.0-py3-none-any.whl", hash = "sha256:3d05d38864d6e88e40db93ed29ac0bee7f2a351d12810d4414f5b65a7cb0e23f"}, - {file = "amaranth-0.5.0.tar.gz", hash = "sha256:9d2a1893d6ac938e0ff3983892eff5b56033e06691cc89674eb8d500dc46cdf6"}, ] [[package]] @@ -81,30 +82,19 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" requires_python = ">=3.7" summary = "Backport of PEP 654 (exception groups)" groups = ["test"] marker = "python_version < \"3.11\"" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, -] - -[[package]] -name = "execnet" -version = "2.1.1" -requires_python = ">=3.8" -summary = "execnet: rapid multi-Python deployment" -groups = ["test"] -files = [ - {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, - {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [[package]] name = "importlib-resources" -version = "6.4.0" +version = "6.4.3" requires_python = ">=3.8" summary = "Read resources from Python packages" groups = ["default", "test"] @@ -112,8 +102,8 @@ dependencies = [ "zipp>=3.1.0; python_version < \"3.10\"", ] files = [ - {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, - {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, + {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, + {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, ] [[package]] @@ -239,7 +229,7 @@ files = [ [[package]] name = "pytest" -version = "8.2.2" +version = "8.3.2" requires_python = ">=3.8" summary = "pytest: simple powerful testing with Python" groups = ["test"] @@ -248,27 +238,12 @@ dependencies = [ "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", "iniconfig", "packaging", - "pluggy<2.0,>=1.5", + "pluggy<2,>=1.5", "tomli>=1; python_version < \"3.11\"", ] files = [ - {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, - {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, -] - -[[package]] -name = "pytest-xdist" -version = "3.6.1" -requires_python = ">=3.8" -summary = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -groups = ["test"] -dependencies = [ - "execnet>=2.1", - "pytest>=7.0.0", -] -files = [ - {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, - {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, ] [[package]] @@ -307,7 +282,7 @@ files = [ [[package]] name = "wasmtime" -version = "22.0.0" +version = "23.0.0" requires_python = ">=3.8" summary = "A WebAssembly runtime powered by Wasmtime" groups = ["default"] @@ -315,23 +290,23 @@ dependencies = [ "importlib-resources>=5.10", ] files = [ - {file = "wasmtime-22.0.0-py3-none-any.whl", hash = "sha256:618e581f34c650e9d0bd8805812fa012d6c89064e157cc0fef8f853f99cb60ff"}, - {file = "wasmtime-22.0.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:793709e8405805dcf1b74cfb798c00fcb7f57dc39f8fe2df5ed7b0670e966489"}, - {file = "wasmtime-22.0.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:95ba696d2e4c19ef195b7769fc1a265dbaf365960728c121fdea6f239a151559"}, - {file = "wasmtime-22.0.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:f9e1740a6af43c5b34d97cd2fe0774566d2a7f1b05bc5cbb65e3422090a82844"}, - {file = "wasmtime-22.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:963f1f282b43e4f10b729e95e7b88966f2663cea1c73a1f912721b2a904a4373"}, - {file = "wasmtime-22.0.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ad62fd47513e420598f55fd21edfaadc1569c1dce4b063818ac6a7de5d3e847"}, - {file = "wasmtime-22.0.0-py3-none-win_amd64.whl", hash = "sha256:779fc00dcc7d89b9b6815654fecdaa6238880c5b8519a4ed0f3f667bf70b3068"}, + {file = "wasmtime-23.0.0-py3-none-any.whl", hash = "sha256:f496a3fb4e3a7c666aca6aedb2acd56402f300e2a1136fc768ed8d81e6aff7f4"}, + {file = "wasmtime-23.0.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:7bbba2a4a6f2d7273021db3ac7f5a7a6cd806c3086b59490dee990ebf130a707"}, + {file = "wasmtime-23.0.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1267df7b9c83898de0884dc0a9bfa1fa6219dad9242708aee70db501a2d71108"}, + {file = "wasmtime-23.0.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:4144847d89a133a25783e9ee11126dd3e1accea52ee20ed91e2d0315fda3abf2"}, + {file = "wasmtime-23.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:ba664d1298f5e37cafefc97a870e832862f1e60284c82dd3da8aba54457db372"}, + {file = "wasmtime-23.0.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d9e2e16272f0d00ff224f9014eba4f031e01966a97599e15f3c66840f52520c7"}, + {file = "wasmtime-23.0.0-py3-none-win_amd64.whl", hash = "sha256:bedd46766ab44b7910869eaac09ede904eb8fbe80ec7f9b8a13222c6df198549"}, ] [[package]] name = "zipp" -version = "3.19.2" +version = "3.20.0" requires_python = ">=3.8" summary = "Backport of pathlib-compatible object wrapper for zip files" groups = ["default", "test"] marker = "python_version < \"3.10\"" files = [ - {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, - {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, ] diff --git a/pyproject.toml b/pyproject.toml index 152a348..9a5c292 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,19 +1,19 @@ [project] name = "niar" -dynamic = ["version"] +version = "0.1.3" description = "A small framework for building projects with Amaranth" authors = [ { name = "Asherah Connor", email = "ashe@kivikakk.ee" }, ] dependencies = [ - "amaranth[builtin-yosys] >= 0.5", + "amaranth[builtin-yosys] @ git+https://github.com/amaranth-lang/amaranth@bc2e90913311e326d8f396e33d7a1c7f6eef6e4e", ] requires-python = ">=3.8" license = { text = "BSD-2-Clause" } readme = "README.md" [project.urls] -Homepage = "https://github.com/kivikakk/niar" +Homepage = "https://sr.ht/~kivikakk/niar" [build-system] requires = ["pdm-backend"] @@ -22,16 +22,11 @@ build-backend = "pdm.backend" [tool.pdm] distribution = true -[tool.pdm.version] -source = "scm" - [tool.pdm.dev-dependencies] test = [ "pytest>=8.2.2", - "pytest-xdist>=3.6.1", - "amaranth-boards @ git+https://github.com/amaranth-lang/amaranth-boards@main", + "amaranth-boards @ git+https://github.com/amaranth-lang/amaranth-boards@19b97324ecf9111c5d16377af79f82aad761c476", ] [tool.pytest.ini_options] -addopts = ["--import-mode=importlib", "-n", "auto"] testpaths = ["tests"]