Repository navigation
fpga(ax7203): RLC and 5-node ladder through the linear cell -- one board top for both circuits, PASS on the board, negative controls FAIL on their own circuit (Closes #10565) - #10578
Merged
Conversation
…ard top for both circuits, bitstreams built, board run pending (Closes #10565) specs/fpga/analog_cell_ax7203.t27 (module FpgaAnalogCell) runs the series RLC and the 5-node RC ladder of specs/analog/linear.t27 on the AX7203, one run of 200 steps and one receipt line each, alternating. The machine is a serial shift-and-add multiply-accumulate over a ROM of the circuit's D and N words; the cell's pack, opposite, round_back, add_sm and fold are used as they are, by use. The PLL, UART frame and receipt fields are M0's, by use. 11 tests, 0 vacuous; the tests compare every state of every step with the cell's step. Fmax 106.30 MHz against 100 MHz (nextpnr-xilinx, xc7a200tfbg484-2). The board run and the UART captures are the follow-up, #10565: the build session could not reach USB or the serial port. Part of #10496. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 18, 2026
Closed
Merged
Merged
Contributor
This was referenced Oct 18, 2026
Closed
This was referenced Oct 18, 2026
Merged
Merged
Merged
16 of 21 tasks
Contributor
PR DashboardGenerated at: 2026-10-19 01:08:03 UTC
Summary
Seal Status
|
…s board top keeps its fold (Closes #10565) specs/fpga/board_receipt.t27 (#10475) declared a five-argument `fold`. rc_filter_ax7203.t27 imports it, and rc_filter_ax7203.t27 and specs/analog/linear.t27 both declare a two-argument `fold`. use_resolve.rs leaves a name that two modules of one import closure declare differently unresolved, so specs/fpga/analog_cell_ax7203.t27 (which imports linear and rc_filter_ax7203) stopped compiling after master merged: "use of undeclared identifier 'fold'". board_receipt's own header says it declares no name a board spec also defines; the rename makes that true. - board_receipt, ddr3_head_bandwidth, ddr3_ternary_matvec, tern9m_l0_k_weights: every call is the five-argument beat checksum; renamed to fold_beat, bodies unchanged. - Tests: board_receipt 4/4, rc_filter_ax7203 10/10, tern9m_l0_k_weights 5/5, ddr3_head_bandwidth 12/12, ddr3_ternary_matvec 10/10, analog_cell_ax7203 11/11, 0 vacuous each (t27c test-report). - Resealed the four renamed specs, rc_filter_ax7203 (its closure names board_receipt) and analog_cell_ax7203 (toolchain); seal --verify all MATCH. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
marked this pull request as ready for review
October 19, 2026 01:13
gHashTag
enabled auto-merge (squash)
October 19, 2026 01:13
Contributor
PR DashboardGenerated at: 2026-10-19 01:15:02 UTC
Summary
Seal Status
|
This was referenced Oct 19, 2026
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.
Part of #10496. Closes #10565 (the board step moves there and stays open until the receipts are attached).
The spec, its tests, its seal and three bitstreams are done, and the board run is in: the committed top prints PASS on every line for both circuits, and each negative control prints FAIL on its own circuit only (see "Board run").
What is in the PR
specs/fpga/analog_cell_ax7203.t27(moduleFpgaAnalogCell): the linear cell of analog M1: linear state-space cell -- any linear R/C/L circuit, fixed step, folded to x' = Mx + Nu #10487 (specs/analog/linear.t27) on the AX7203, running the series RLC and the 5-node RC ladder, 200 steps each, one receipt line per run, alternatingT27 RLCandT27 LAD5..trinity/seals/fpga_FpgaAnalogCell.json: sealed by t27c, 11/11 tests, 0 vacuous;seal --verifyall MATCH.specs/fpga/board_receipt.t27and its three users (ddr3_head_bandwidth,ddr3_ternary_matvec,tern9m_l0_k_weights): the five-argument beat checksumfoldis renamedfold_beat, bodies unchanged, and those four specs plusrc_filter_ax7203(closure) are resealed. Why: see "Found on the way"..v,.json,.fasmor.bitis committed, anddocs/reports/t27b_expectations.jsonis not touched.One top, not two
The issue asks for a board top per circuit. This is one top that runs both. The machine is the same for every circuit (only the ROM of D and N words, the state count, the reported state and the expected values differ), so two tops would be two copies of one
on_clock, whichtools/dupe_scan.pyrefuses.CK_FIRSTandCK_LASTchoose the circuits the board cycles through; a single-circuit build is the same file with them equal.Every line is a fresh run of 200 steps (the machine restarts after each line), not the same result printed again.
The machine
pack,opposite,round_back,add_smandfoldare used as they are (byuse); so are M0's PLL, UART frame and receipt fields (use fpga::rc_filter_ax7203). Names that both specs declare with the same text resolve without a conflict.pos_after/neg_after, one bit at a time). No DSP48E1 (live operands read wrong on openXC7, BENCHMARKS.md 4.4) and no wide combinational multiplier.delta_ofandnext_xare split over five clocks (compare, subtract, round, pack, add). The tests prove the split givesnext_x's word on edge cases (half an LSB both ways, equal registers, a negative old state, a carry across zero, 2^40 magnitudes).t27b verilogrefusesExprIndex, even a constant index into a constant array. A test compares every ROM word with the cell'sRLC_D,RLC_NV,LAD5_D,LAD5_NV, and sees a one-LSB change in any of them.Tests (11, 0 vacuous; t27c test-report,
tri test,t27b test --checkall agree)step, gives the same state after every step, and the same fold, for both circuits (200 steps each), and A, B, S equalrun()'s and the pinned values.prod/pos_after/neg_afteron ten pairs includingMAG * MAG, zero and negative operands.baud_div = 1, decodes every field of every line, and checks RLC, LAD5, RLC, LAD5 with L = 0, 1, 2, 3, all PASS.t27c seal --saverefuses it.Measured
Flow, per bitstream (all in
$TMPDIR, nothing committed):t27b verilogthen yosys 0.63 withsynth_xilinx -family xc7 -top FpgaAnalogCell -flatten -abc9 -nodsp -nosrl -run :coarse; techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=6; alumacc; opt; memory -nomap; opt_clean; synth_xilinx (same flags) -run map_memory:(the repo's flow ofbootstrap/src/service.rsplus the two mandatory flags), thennextpnr-xilinx --chipdb xc7a200tfbg484-2.bin --freq 100,fasm2frames.py,xc7frames2bit.Committed top (sealed spec_hash prefix
9980520c7b86):8c0753c08c81ecd679df8e77eecff4c3160291a80b1b85db1ccc7cdfcb65913a(9730772 bytes)The place-and-route is deterministic (two runs of the same netlist gave 106.30 and 66.32 MHz both times) but not stable under small netlist changes. The bitstream header carries the frames file name and a time, so the sha256 of a rebuild differs even for the same netlist (two builds of this one differed in 10 header bytes).
Negative controls (not committed; the same spec with one literal changed; each has the same resources, 20230 frames lines, no fasm2frames error):
NEG | 39851toNEG | 39852173204925e4826d8d190c780ae35f6d266879381562e698d1b8bcd7a39cb49e70e7d7c4b9c81(seed 2)31709to317103a67a96b561929bfa289fb2a87ade703e65ed8cea130f9beb203e4546b09e88061c778876b7b(seed 2)The negative-control bitstreams are the seed-2 runs because seed 1 did not close 100 MHz; the seed is a
nextpnr-xilinx --seedargument, the same knobt27c silicon --pnr-seedexposes.Simulation of the generated Verilog (iverilog, stub primitives, 8 clocks per bit instead of 868), the lines the machine prints:
and the negative controls print, in the same simulation, exactly the values the tests predict:
The A, B and S of the right run were also computed by an independent integer model (a scratch Python script, not committed) and agree with the cell's pinned
RLC_EXP_SandLAD5_EXP_S.The bitstreams are in the build session's
$TMPDIR(/tmp/claude-501/b/:top_9980520c7b86.bit,neg_rlc_173204925e48_seed2.bit,neg_lad5_3a67a96b5619_seed2.bit), not in the tree.Board run (2026-10-19, AX7203 on the bench)
Flashed from the orchestrator's terminal with
openFPGALoader -c digilent_hs2 --busdev-num 000:004 <bit>, then one reader on/dev/cu.usbserial-130at 115200 8N1 for 6 s per bitstream (lsofon the port empty before each capture). Every line below is checked against^T27 (RLC|LAD5) A=<16 hex> B=<16 hex> S=<16 hex> C=<16 hex> L=<16 hex> (PASS|FAIL)$; the only lines that do not match are the first and last of each capture, which the reader cut mid-line.8c0753c08c8126d8d190c78029bfa289fb2aRLC_EXP_*/LAD5_EXP_*and the iverilog run above, on every line.Found on the way
specs/fpga/board_receipt.t27with a five-argumentfold, imported byrc_filter_ax7203. This spec importsanalog::linearandfpga::rc_filter_ax7203, which both declare a two-argumentfold;bootstrap/src/use_resolve.rsdeliberately leaves a name that two modules of one closure declare differently unresolved (an explicituse analog::linear::{fold}does not change that), so after merging master the spec failed withuse of undeclared identifier 'fold'. board_receipt's header already promised "no name a board spec also defines"; renaming its checksumfold_beatmakes that true. After the rename: board_receipt 4/4, rc_filter_ax7203 10/10, tern9m_l0_k_weights 5/5, ddr3_head_bandwidth 12/12, ddr3_ternary_matvec 10/10, this spec 11/11, 0 vacuous;seal --verifyall MATCH;tools/dupe_scan.pyok.fin,hard) from the synchroniser, so the long wire ends in one LUT and one flop beside the logic, did. The restart then runs fromfinalone.ExprIndexin the hardware path (not even a constant index into a constant array); the test bench of a top whose clock is a net does not lower (test bench of a module whose clk is a net), so the generated RTL was simulated with a scratch testbench instead ofiverilog -DT27B_TESTBENCH.fasm2frames.pyfails withPermissionError: /dev/stdoutwhen its stdout is redirected in the sandbox; passing the output file as the second argument works.tri testneeds the Zig cache directories in the sandbox.Not claimed
Why the build session did not flash
The build session's sandbox cannot reach USB (
openFPGALoader --scan-usb:No USB devices found;sttyon the UART:Operation not permitted), so the orchestrator flashed from its terminal tab. The flash and capture steps are in #10565.🤖 Generated with Claude Code