From 172767e809443c3468681fbf008c3825dc3006ae Mon Sep 17 00:00:00 2001 From: Jeremy Lau <30300826+fdxmw@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:12:43 -0700 Subject: [PATCH] Fix a bug in `CompiledSimulation`'s `arm64` multiplication macro. Enable GitHub actions testing on `macos-latest` to catch these bugs in the future. Also: * Disable `doctests` for `output_to_svg` and `graphviz_detailed_namer` because they depend on `graphviz`, which may not be installed. * Update `pytest` command line to print the names of skipped tests. --- .github/workflows/python-test.yml | 19 +++++++++--- justfile | 4 +-- pyrtl/compilesim.py | 4 +-- pyrtl/visualization.py | 48 +++++++++++++++---------------- 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index c076a4a1..c36a1f0a 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -5,19 +5,30 @@ on: - pull_request jobs: - tests: - runs-on: ubuntu-latest + test: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v7 - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true - - name: Install apt dependencies - run: sudo apt install -y yosys + - name: Install dependencies + shell: bash + run: | + if [ "$RUNNER_OS" = "Linux" ]; then + sudo apt install -y yosys + elif [ "$RUNNER_OS" = "macOS" ]; then + brew install -y yosys + fi - name: Run tests run: uv run just tests - name: Upload coverage to Codecov + if: ${{ matrix.os == 'ubuntu-latest' }} uses: codecov/codecov-action@v7 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/justfile b/justfile index 406833f3..d5814a1c 100644 --- a/justfile +++ b/justfile @@ -7,11 +7,11 @@ tests: # Run `pytest` with the latest version of Python supported by PyRTL, # which is the default for `uv`. The default is set with `uv python # pin` and written to `.python_version`. - uv run pytest -n auto --cov=pyrtl --cov-report=xml + uv run pytest -rsx -n auto --cov=pyrtl --cov-report=xml # Run `pytest` in an isolated virtual environment, with the earliest # version of Python supported by PyRTL. - uv run --python=3.10 --isolated pytest -n auto + uv run --python=3.10 --isolated pytest -rsx -n auto # Run `ruff format` to check that code is formatted properly. # diff --git a/pyrtl/compilesim.py b/pyrtl/compilesim.py index 6aa690d4..ab79250f 100644 --- a/pyrtl/compilesim.py +++ b/pyrtl/compilesim.py @@ -1122,12 +1122,12 @@ def _create_code(self, write): "x86_64": '"mulq %q3":"=a"(pl),"=d"(ph):"%0"(t0),"r"(t1):"cc"', "arm64": ( '"mul %0, %2, %3\\n\\t" \\\n' - '"umulh %1, %2, %3":"=&r"(pl),"=r"(ph):"r"(t0),"r"(t1):"cc"', + '"umulh %1, %2, %3":"=&r"(pl),"=r"(ph):"r"(t0),"r"(t1):"cc"' ), "mips64": ( '"dmultu %2, %3\\n\\t" \\\n' '"tmflo %0\\n\\t" \\\n' - '"mfhi %1":"=r"(pl),"=r"(ph):"r"(t0),"r"(t1)', + '"mfhi %1":"=r"(pl),"=r"(ph):"r"(t0),"r"(t1)' ), } if machine in mul_asm: diff --git a/pyrtl/visualization.py b/pyrtl/visualization.py index 96e1b27a..9903544e 100644 --- a/pyrtl/visualization.py +++ b/pyrtl/visualization.py @@ -346,29 +346,29 @@ def graphviz_detailed_namer( Any additional information in these ``dicts`` will be displayed in parentheses in the Graphviz graph. - .. doctest only:: + .. doctest comment:: - >>> import pyrtl - >>> pyrtl.reset_working_block() + This example is not a `doctest` because it depends on `graphviz`, which might + not be installed. Example:: - >>> a = pyrtl.WireVector(name="a", bitwidth=3) - >>> b = pyrtl.WireVector(name="b", bitwidth=3) - >>> sum = a + b - >>> sum.name = "sum" + a = pyrtl.WireVector(name="a", bitwidth=3) + b = pyrtl.WireVector(name="b", bitwidth=3) + sum = a + b + sum.name = "sum" + + add_logicnets = pyrtl.working_block().logic_subset("+") + len(add_logicnets) - >>> add_logicnets = pyrtl.working_block().logic_subset("+") - >>> len(add_logicnets) - 1 - >>> add_logicnet = add_logicnets.pop() + add_logicnet = add_logicnets.pop() - >>> namer = pyrtl.graphviz_detailed_namer( - ... extra_node_info={add_logicnet: "ADD NODE"}, - ... extra_edge_info={a: "EDGE A", b: "EDGE B"} - ... ) + namer = pyrtl.graphviz_detailed_namer( + extra_node_info={add_logicnet: "ADD NODE"}, + extra_edge_info={a: "EDGE A", b: "EDGE B"} + ) - >>> svg_data = pyrtl.block_to_svg(namer=namer) + svg_data = pyrtl.block_to_svg(namer=namer) ``svg_data`` is a :class:`str` containing the SVG data. This data can be written to a file:: @@ -590,21 +590,21 @@ def block_to_svg(*args, **kwargs) -> str: $ pip install pyrtl[svg] - .. doctest only:: + .. doctest comment:: - >>> import pyrtl - >>> pyrtl.reset_working_block() + This example is not a `doctest` because it depends on ``graphviz``, which might + not be installed. This just calls :func:`block_to_graphviz_string` and renders the Graphviz string as SVG, using the `graphviz `_ ``pip`` package. Example:: - >>> a = pyrtl.WireVector(name="a", bitwidth=3) - >>> b = pyrtl.WireVector(name="b", bitwidth=3) - >>> sum = a + b - >>> sum.name = "sum" + a = pyrtl.WireVector(name="a", bitwidth=3) + b = pyrtl.WireVector(name="b", bitwidth=3) + sum = a + b + sum.name = "sum" - >>> svg_data = pyrtl.block_to_svg() + svg_data = pyrtl.block_to_svg() ``svg_data`` is a :class:`str` containing the SVG data. This data can be written to a file::