test(fixtures): multi-bit Hack ALU fixtures (parametric + single-file) - #71
Merged
Conversation
Add tests/fixtures/projects/alu_parametric/: a parametric Hack-style
ALU sub-circuit generic over <W>, plus four per-width root files that
instantiate it at W in {2, 4, 6, 8}. Each wrapper imports the
parametric core and supplies a width-specific ripple-carry adder
(the language can't express that parametrically: no iteration over
bit positions).
The wrappers document three multi-bit-language papercuts surfaced
while building this:
1. Scalar -> width-W broadcast can't pass a {c,c,...} concat
directly into a parametric sub-circuit instance port. The
wrappers route every scalar control through a wire[W] first.
2. Sliced macro outputs feed scalar macros only via intermediate
scalar wires; slice-into-scalar-macro trips the topology
builder otherwise.
3. xor[W] macros and sub-circuit instances in the feedback chain
from an instance's output back to its own input also trip the
topology builder, so the bit-parallel propagate in each
wrapper's adder is hand-expanded from and/not primitives.
Goldens included for the 2-bit (1024 rows) and 4-bit (16384 rows)
wrappers. 6-bit (262k rows) and 8-bit (4M rows) are above the
default --truth-table cap and are exercised via the .wasm runtime.
The 4-bit golden agrees with the existing scalar alu_4bit.truth.
golden on all canonical Hack ALU operations spot-checked.
Add tests/fixtures/circuits/alu_4bit_multibit.circ: a single-file
multi-bit variant of the scalar alu_4bit.circ, demonstrating the
same Hack ALU logic with width-4 buses. Sibling truth-table golden
matches the alu_parametric/alu_4bit golden bit-for-bit on all
16,384 rows, and matches the scalar alu_4bit.truth.golden on every
canonical operation spot-checked.
The fixture exercises the three multi-bit-language papercuts the
parametric project also works around, in a flatter single-file
context (no imports, no sub-circuit instances):
1. Scalar broadcast routes through wire[4] (concat-into-macro
port confuses the validator's width inference).
2. xor[W] macro is hand-expanded from and/not primitives for the
bit-parallel propagate -- the macro produces wrong simulation
values when its output flows through a wire-buffered slice
chain into the per-bit scalar macros below, even though it's
correct in isolation.
3. Slice-into-scalar-macro trips InternalError; per-bit slices
are routed through scalar wire buffers.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two multi-bit Hack ALU test fixtures, each demonstrating a different language usage pattern:
Parametric project (
tests/fixtures/projects/alu_parametric/):alu.circ) generic over<W>, plus four per-width root files (alu_2bit.circ,alu_4bit.circ,alu_6bit.circ,alu_8bit.circ) that instantiate it.--truth-tablecap and are exercised via the.wasmruntime instead.Single-file 4-bit (
tests/fixtures/circuits/alu_4bit_multibit.circ):alu_4bit.circ— same Hack ALU logic, width-4 buses, no imports.Why this is useful even with the workarounds
Both fixtures exercise three multi-bit-language papercuts surfaced while building them; each is worked around inline and documented in the fixture comments:
{c,c,...}concat directly into a parametric sub-circuit instance port. The wrappers route every scalar control through awire[W]first.xor[W]macro produces incorrect simulation values (or breaks topology build entirely) when its output flows through a wire-buffered slice chain into per-bit scalar macros. Both fixtures hand-expand the bit-parallel XOR propagate fromand/notprimitives. The variant that tripsInternalErrorrather than producing wrong values appears specifically in the feedback chain from a sub-circuit instance's output back into its own input.When these are fixed in the validator / topology builder / simulation engine, the workarounds collapse to one-line
xor[W]calls and the goldens stay bit-identical — a clean diff later.Test plan
zig-out/bin/circ-compile tests/fixtures/projects/alu_parametric/alu_2bit.circ --truth-tableproduces a 1024-row table matching the 2-bit golden.zig-out/bin/circ-compile tests/fixtures/projects/alu_parametric/alu_4bit.circ --truth-tableproduces a 16384-row table matching both the parametric 4-bit golden and the existing scalaralu_4bit.truth.goldenon every canonical Hack ALU operation.zig-out/bin/circ-compile tests/fixtures/circuits/alu_4bit_multibit.circ --truth-tableproduces a 16384-row table identical to the parametric 4-bit golden (`diff` exit 0).zig-out/bin/circ-compile tests/fixtures/projects/alu_parametric/alu_6bit.circ --truth-table --truth-table-cap=18produces a 262k-row table (no golden checked in at this size).zig-out/bin/circ-compile tests/fixtures/projects/alu_parametric/alu_8bit.circ -o /tmp/alu_8bit.wasmbuilds a self-contained ~955 KB.wasm.