From 2329aed4290a49853ff0b7360059de5223066f73 Mon Sep 17 00:00:00 2001 From: Trinity Bee Date: Thu, 24 Sep 2026 10:38:33 +0000 Subject: [PATCH 1/2] salvage(queen-2352): commit what the turn left uncommitted The turn ended with these files edited and never committed. Uncommitted work is invisible to the review - it reads the branch - so the attempt would have been released as empty and the next bee would have started beside this work rather than from it. This commit is not a claim that the work is correct. It is the bee's work, committed on its behalf, and it is judged exactly like any other: the adversarial reviewer reads it, the compiler runs on it, and the issue's own criteria are measured against it. Issue: #2352 Turn: ec564dc8-d8e3-468a-a866-e3fc8df49a0c Ending: finished (the turn closed) Committed: 1 path(s) Left uncommitted: 0 path(s) outside the declared boundary --- bootstrap/src/bitnet_buffers.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/bootstrap/src/bitnet_buffers.rs b/bootstrap/src/bitnet_buffers.rs index 56618e3661..27aed12e40 100644 --- a/bootstrap/src/bitnet_buffers.rs +++ b/bootstrap/src/bitnet_buffers.rs @@ -178,6 +178,7 @@ pub fn build_weight_prefetch_ctrl(module_name: &str) -> String { s.push_str(");\n"); s.push_str("\n"); s.push_str(" reg [15:0] words_remaining;\n"); + s.push_str(" reg [11:0] word_index;\n"); // `bram_addr` is 12 bits, so the BRAM holds 4096 words, while `num_words` // is 16 bits and can name 65536 -- a 16x overrange. s.push_str(" localparam [15:0] MAX_WORDS = 16'd4096; // bram_addr is 12 bits\n"); @@ -192,6 +193,7 @@ pub fn build_weight_prefetch_ctrl(module_name: &str) -> String { s.push_str(" axi_arvalid <= 1'b0; bram_we <= 1'b0; overflow <= 1'b0;\n"); s.push_str(" axi_araddr <= 32'd0; bram_addr <= 12'd0; bram_data <= 54'd0;\n"); s.push_str(" words_remaining <= 16'd0;\n"); + s.push_str(" word_index <= 12'd0;\n"); s.push_str(" end else case (state)\n"); s.push_str(" IDLE: begin\n"); s.push_str(" prefetch_done <= 1'b0;\n"); @@ -202,6 +204,7 @@ pub fn build_weight_prefetch_ctrl(module_name: &str) -> String { s.push_str(" words_remaining <= (num_words > MAX_WORDS) ? MAX_WORDS : num_words;\n"); s.push_str(" overflow <= (num_words > MAX_WORDS);\n"); s.push_str(" bram_addr <= 12'd0;\n"); + s.push_str(" word_index <= 12'd0;\n"); s.push_str(" end\n"); s.push_str(" end\n"); s.push_str(" FETCH: begin\n"); @@ -210,7 +213,8 @@ pub fn build_weight_prefetch_ctrl(module_name: &str) -> String { s.push_str(" if (axi_rvalid) begin\n"); s.push_str(" bram_data <= axi_rdata[53:0];\n"); s.push_str(" bram_we <= 1'b1;\n"); - s.push_str(" bram_addr <= bram_addr + 12'd1;\n"); + s.push_str(" bram_addr <= word_index;\n"); + s.push_str(" word_index <= word_index + 12'd1;\n"); s.push_str(" words_remaining <= words_remaining - 16'd1;\n"); s.push_str(" if (words_remaining == 16'd1) state <= DONE_ST;\n"); s.push_str(" end else bram_we <= 1'b0;\n"); @@ -550,4 +554,28 @@ mod tests { assert!(v.contains(line), "missing reset line `{}`", line); } } + + #[test] + fn fetch_arm_uses_word_index_for_bram_addr() { + let v = build_weight_prefetch_ctrl(DEFAULT_WEIGHT_PREFETCH_CTRL_NAME); + let arm = region(&v, "FETCH: begin", "DONE_ST: begin"); + // Check we use word_index for bram_addr + assert!( + arm.contains("bram_addr <= word_index;"), + "FETCH arm must use word_index for bram_addr to avoid off-by-one. FETCH arm was:\n{}", + arm + ); + // Check we increment word_index + assert!( + arm.contains("word_index <= word_index + 12'd1;"), + "FETCH arm must increment word_index. FETCH arm was:\n{}", + arm + ); + // Check we do NOT have the buggy bram_addr increment + assert!( + !arm.contains("bram_addr <= bram_addr + 12'd1;"), + "FETCH arm must not increment bram_addr directly (off-by-one bug). FETCH arm was:\n{}", + arm + ); + } } From 8604782eb5006b4400a7efd13f897f46479f2147 Mon Sep 17 00:00:00 2001 From: "queen-publisher[bot]" Date: Thu, 24 Sep 2026 10:41:39 +0000 Subject: [PATCH 2/2] docs: the coordination entry this branch needs to land A pull request must add exactly one docs/now entry and a bee has no way to know that: its brief names a boundary file and acceptance criteria, and docs/now/ is neither. The publisher adds it rather than failing the gate. Closes #2352 Co-Authored-By: Claude Opus 5 --- ...ch-ctrl-writes-every-word-one-slot-high-the-200.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/now/2026-09-24-published-weight-prefetch-ctrl-writes-every-word-one-slot-high-the-200.md diff --git a/docs/now/2026-09-24-published-weight-prefetch-ctrl-writes-every-word-one-slot-high-the-200.md b/docs/now/2026-09-24-published-weight-prefetch-ctrl-writes-every-word-one-slot-high-the-200.md new file mode 100644 index 0000000000..cd407940f4 --- /dev/null +++ b/docs/now/2026-09-24-published-weight-prefetch-ctrl-writes-every-word-one-slot-high-the-200.md @@ -0,0 +1,11 @@ +# NOW -- weight_prefetch_ctrl writes every word one slot high — the #2003 shape, fixed in the DMA only (published 2026-09-24) + +## A bee's work on #2352, published from `queen-2352` (Closes #2352) + +- The branch changes 1 file(s): `bootstrap/src/bitnet_buffers.rs`. +- `git diff --stat origin/master...queen-2352` reads: 1 file changed, 29 insertions(+), 1 deletion(-) +- This entry is written by the publisher, not by the bee. A pull request must + add exactly one `docs/now/` entry and a bee has no way to know that: its brief + names a boundary file and acceptance criteria, and `docs/now/` is neither. +- What this entry does NOT establish: that the work is correct. The gates on the + pull request judge that, and they are the same gates every other change meets.