test(sim): commit the differential harness behind the DMA write-address fix (Refs #2348) - #2379
Merged
Merged
Conversation
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-08-22 01:02:05 UTC
Summary
Seal Status
|
gHashTag
enabled auto-merge (squash)
August 22, 2026 01:02
…ss fix PR #2345 cited a differential simulation as its primary evidence and did not commit the testbench, so the claim was true but unreproducible from the tree. sim/tb_bitnet_dma_write_address.v elaborates the pre-fix and post-fix renderings of dma_controller in one simulation and drives them from identical stimulus, following the sim/tb_bitnet_request_overflow.v precedent from #2351. The published numbers reproduce: old writes 1..4 and never writes address 0, new writes 0..3. Reporting only -- vvp exits 0 on PASS and on FAIL, and no workflow runs it. Wiring sim/ into CI is out of scope here and unchanged. Refs #2348 Refs #2003
gHashTag
force-pushed
the
sim/2348-dma-write-address-harness
branch
from
August 22, 2026 01:09
1e40ac1 to
b93990a
Compare
Contributor
PR DashboardGenerated at: 2026-08-22 01:09:50 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
gHashTag
pushed a commit
that referenced
this pull request
Aug 22, 2026
…ecipe (Refs #2348) Adds a README section per harness in the style #2379 established, plus the shared emit recipe: every BitNet emitter compiles standalone under `rustc` with a four-line driver, no cargo and no target directory, because the only `use` in any of them is `use super::*` inside `#[cfg(test)]`. Records the base/head shas each harness was rendered from, and the three instrument faults found while reproducing the published claims -- a posedge-sampled observer trailing the design by a cycle, an observer racing the stimulus that drove `start_prefetch`, and `first_chunk`/`last_chunk` having no reset in either rendering. Each was a fault in the instrument; every published number reproduced once the instrument was corrected. Refs #1977, #1985, #2006
gHashTag
added a commit
that referenced
this pull request
Aug 22, 2026
) (#2381) * test(sim): differential harness for the zero-count layer_sequencer hang (Refs #1977) `layer_sequencer` never left RUN when asked for zero work: both terminators are `index == count-1` against an unsigned port, and the bare literal 1 widens each subtraction to 32 bits, so a zero count borrows to 32'hFFFFFFFF while the index zero-extends. Elaborates the PR #2337 pre-fix and post-fix renderings in one simulation. Reproduces the published numbers: 200,000 cycles with no `done` and `neuron_id` reaching exactly 50,000, plus six non-zero controls that are identical on every output every cycle. Reporting, not a gate: `vvp` exits 0 on FAIL as well as PASS. Refs #2348 * test(sim): differential harness for the stale prefetch_done level (Refs #1985) `weight_prefetch_ctrl` documented `prefetch_done` as a one-cycle pulse but cleared it only inside the start guard, leaving it asserted for the whole idle gap. A requester sampling it in the cycle it raises `start_prefetch` reads the previous transaction's completion. Elaborates the PR #2340 pre-fix and post-fix renderings in one simulation. Reproduces the published numbers: t2 sampled_done OLD=1 / NEW=0, done_rises 2/2, we_count 4/4. A second case varies the idle gap to separate level from pulse: old's high-time grows with the gap, new's does not. Reporting, not a gate: `vvp` exits 0 on FAIL as well as PASS. Refs #2348 * test(sim): three-way harness for the latent local_we default (Refs #2006) #2006 defaults `local_we` low ahead of the case. The pre-fix and post-fix renderings are observationally IDENTICAL: every reachable path already drove the strobe, and the states that never mention it are never entered with it high, because READ_DATA's only exit is DONE_ST. A harness that passes by finding no difference proves nothing, so this one is three-way: A = pre-#2006 (PR #2344 base), B = #2006 (PR #2344 head), C = #2006 + #2003 (PR #2345 head). B and C are consecutive revisions -- #2344's head rendering is byte-identical to #2345's base -- so one comparator sees all three. A vs B must be identical; B vs C must differ. Same comparator, same stimulus, same run, same 293-bit vector of every output port. Putting B in the C slot makes the run fail rather than certify its null result. Measured: A vs B 0 mismatching cycles, B vs C 266, over 373 cycles and seven phases. Deleting READ_DATA's `end else local_we <= 1'b0;` from both renderings makes A emit 22 local writes against B's 18 -- latent today, a real backstop the moment an arm stops clearing the strobe. Reporting, not a gate: `vvp` exits 0 on FAIL as well as PASS. Refs #2348 * docs(sim): document the three new harnesses and the standalone emit recipe (Refs #2348) Adds a README section per harness in the style #2379 established, plus the shared emit recipe: every BitNet emitter compiles standalone under `rustc` with a four-line driver, no cargo and no target directory, because the only `use` in any of them is `use super::*` inside `#[cfg(test)]`. Records the base/head shas each harness was rendered from, and the three instrument faults found while reproducing the published claims -- a posedge-sampled observer trailing the design by a cycle, an observer racing the stimulus that drove `start_prefetch`, and `first_chunk`/`last_chunk` having no reset in either rendering. Each was a fault in the instrument; every published number reproduced once the instrument was corrected. Refs #1977, #1985, #2006 --------- Co-authored-by: Claude <claude@anthropic.com>
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.
What
Commits the differential testbench behind PR #2345 as
sim/tb_bitnet_dma_write_address.v.#2348 records that four merged RTL fixes cite differential simulation as their primary
evidence and none commits the instrument. This lands one of the four. The claim was
never in doubt — an independent audit reproduced all four — the defect is that the
evidence was unreproducible from the repository.
Refs #2348
Refs #2003
Path
sim/, not thebootstrap/tests/rtl/the issue suggested.sim/tb_bitnet_request_overflow.v(#2351) is the one harness already committed, and one convention is worth more than a
better-named second one. Same directory, same shape, same README structure.
The published number reproduces
PR #2345's body claims: "OLD writes beats to addr 1..4,
mem[0]never written; NEWwrites 0..3". First run, before any change to the harness:
(=N)is the payload: beat N lands at address N+1 in the old rendering and at address Nin the new one.
Reconstruction needed no build
bootstrap/src/bitnet_dma.rshas nousestatements and nocrate::references, so theemitter compiles standalone under
rustcat any revision. No cargo build, no targetdirectory. The pre-fix and post-fix renderings come from PR #2345's own base
(
cb1f0d4eb980) and head (4db5729b1817); diffing them shows exactly that PR's fourhunks and nothing else. Commands are in
sim/README.md.The harness also passes against current master, whose later waves renamed
beat_indextoword_index— every check is made at the module ports.Three bars
TRUE — the harness compiles under
iverilog -g2005and the numbers above are themeasured output.
ALIVE — it runs, and its anti-vacuity anchors fire. During development the control
case caught itself proving nothing:
BITING — demonstrated with two planted mutants on the post-fix rendering, one per
guard.
Mutant A, reverting the
READ_DATApairing tolocal_addr <= local_addr + 12'd1:Mutant B, deleting only the IDLE re-arm of the index — case 1 still passes, and case 2
alone catches it:
That separation is the point: case 2 is not redundant with case 1, and it is the only
check constraining the IDLE hunk.
This is reporting, not a gate
Stated plainly because the distinction matters.
vvpexits 0 whether the run printsRESULT: PASSorRESULT: FAIL— measured both ways, matchingtb_bitnet_request_overflow.v.And nothing executes it:
cargo test -p t27cis invoked by no workflow (removed by #2292)and
fpga-build.ymlnever callsvvp(#2241). Neither is changed here — #2348 isexplicitly about the artefact existing in the tree, and wiring
sim/into CI overlaps#2241/#2275.
The harness found three defects in itself first
All three are commented at the point of fix, because each is a way a testbench can look
right and measure nothing:
local_addris an unsigned 12-bit port; comparing it against an integer seeded to-1promotes the expression to unsigned, so the high-water mark never advanced and every
range read
1..-1.[255:0]label argument silently truncated a 38-character assertion name from theleft (
FAIL ghest address on second transfer).startpulse raced the DUT's own sampling at the same timestep, so the transfernever began and three cases reported zeros.
The published numbers reproduced before any of these were corrected, so none of them
was fitted to an expected answer.
Scope
One of four. #2337 (#1977), #2340 (#1985) and #2344 (#2006) still have no committed
harness; #2348 stays open.