Skip to content

fix(t27b): fold a constant rst_n/en tie-off out of the clocked process (Closes #10046) - #10057

Merged
gHashTag merged 1 commit into
masterfrom
claude/heuristic-volhard-642c67
Oct 17, 2026
Merged

gHashTag merged 1 commit into
masterfrom
claude/heuristic-volhard-642c67

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #10046

What

When a clocked module ties the implicit rst_n or en to true, t27b verilog now leaves them out of the clocked process:

  • rst_n tied on: always @(posedge clk), with no or negedge rst_n and no if (!rst_n) reset branch;
  • en tied on: no else if (en);
  • no wire/assign for a folded tie, since every other read of a constant is already a literal;
  • registers still start at their reset values, from initial.

A tie to false (held in reset / never enabled) and a constant clk stay a wire the process reads.

The rule is tie_folds in specs/tri/t27b/verilog_plan.t27. The writer is folded_tie/tied_on plus the three shapes of clocked() in specs/tri/t27b/verilog_emit.t27. Only .t27 is hand-written.

Why

A cocotb harness writes 0 to every handle at start-up. That deposited 0 on the tied net, its constant driver never fired again, and the design sat in reset. That alone is why arm B failed G1 on CVDP moving_average_0001 in the Build-A-Chip-Bench proxy run.

Files

  • specs/tri/t27b/verilog_plan.t27: rule text, tie_folds, test asserts.
  • specs/tri/t27b/verilog_emit.t27: the fold, tied_counter fixture, 2 new tests.
  • gen/rust/tri/t27b/verilog_{emit,plan}.rs: output of t27c gen-rust. Before regenerating, gen-rust on the pristine specs reproduced the committed files byte for byte.
  • .trinity/seals/t27b_T27b{VerilogEmit,VerilogPlan,AstShape}.json: t27c seal --save. AstShape has verilog_plan in its closure; its own gen/rust is unchanged.

Lab receipts (Railway fs-lab, lane at f787afb + this diff, zig 0.16.0)

Spec tests (t27c test-report)

  • verilog_emit: 7/7, 0 vacuous. The new tests run 15 and 9 runtime asserts.
  • verilog_plan: 14/14.

Mutants, to show the tests are not vacuous

  • folded_tie returns false (the old behavior): a_constant_rst_n_and_en_are_folded_out_of_the_always_block FAILS, 6/7.
  • tie_folds ignores the value (a false tie is folded too): both new tests FAIL, 5/7. That includes the negative control an_rst_n_port_keeps_its_async_reset_and_a_false_en_keeps_its_wire.

moving_average_0001, arm B, same .t27 (sha256 4642aec5...), re-emitted with the rebuilt t27b and run through the same gate driver:

before: RESULT B     moving_average_0001 G1=FAIL [TESTS=1 PASS=0 FAIL=1] G2=PASS G3=PASS G4=PASS drc=0 hold_ws=0.105016 setup_ws=1.24788 area_um2=1109.22
after:  RESULT Bfold moving_average_0001 G1=PASS [TESTS=1 PASS=1 FAIL=0] G2=PASS G3=PASS G4=PASS drc=0 hold_ws=0.101897 setup_ws=1.24497 area_um2=1112.68
        pytest: 5 passed

The spec's own emitted test bench (Icarus, -DT27B_TESTBENCH) passes: 4 tests, 0 failed. The diff of the emitted .v contains the fold and nothing else.

Controls: old vs new t27b on every other spec it is pointed at

spec result
conformance verilog_lib, verilog_use, verilog_widths byte-identical
queen/actors_hw_jtag (rst_n/en are = undefined input ports) byte-identical
conformance verilog_prim (ties true) changed as intended; Yosys equiv_make/equiv_induct proves old == new (40 $equiv cells)
queen/actors_hw_top (ties true) changed as intended; old == new proven (26 $equiv cells)

A mutant of actors_hw_top (div + 2) is rejected by the same equivalence check: 8 cells unproven.

Wider checks

  • t27b crate tests (release): all green.
  • t27c suite --repo-root .: exits 1, but its per-phase summary is identical to the pristine f787afb tree. None of the touched or affected specs appear in its failures.

🤖 Generated with Claude Code

Closes #10046)

A module that ties the implicit rst_n or en to true (`const rst_n : bool =
true;`) was written as `wire rst_n; assign rst_n = 1'b1;` and the always
block still read it (`or negedge rst_n`, `if (!rst_n)`, `else if (en)`). A
test bench that writes every handle at start-up (cocotb dut_init) deposits
0 on that net, the constant driver never fires again, and the design sits
in reset: CVDP moving_average_0001 failed G1 for that reason alone.

verilog_plan.t27 records the rule (tie_folds): a tie of rst_n or en to true
is folded out; a tie to false and a constant clk stay a wire the process
reads. verilog_emit.t27 writes `always @(posedge clk)` without the reset
branch when rst_n is tied on, drops `if (en)` when en is tied on, and
writes no net for a folded tie (every other read of a constant is already
a literal). Registers keep their reset values from `initial`.

Tests: a_constant_rst_n_and_en_are_folded_out_of_the_always_block, and the
negative control an_rst_n_port_keeps_its_async_reset_and_a_false_en_keeps_its_wire.
gen/rust regenerated with t27c gen-rust; VerilogEmit, VerilogPlan and
AstShape (verilog_plan is in its closure) resealed. All on the Railway lab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-17 17:46:57 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 49
PRs with All Checks Green 1
READY 0
FAILING 49
PENDING 0
NO CHECKS YET 0

These columns do not partition: 0 + 49 + 0 + 0 = 49, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=e769ef021713 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag enabled auto-merge (squash) October 17, 2026 17:49
@gHashTag
gHashTag merged commit 896d87b into master Oct 17, 2026
27 of 31 checks passed
dmitrii-f-t27 added a commit to dmitrii-f-t27/t27 that referenced this pull request Oct 17, 2026
Conflicts were in derived files only: the seals of verilog_emit/verilog_plan and
gen/rust/tri/t27b/verilog_emit.rs. The specs merged cleanly (master's gHashTag#10057 rst_n/en
tie-off fold and this branch's pin declarations). The derived files are recomputed
from them with this tree's t27c: gen-rust for both, and both seals re-saved.

Checks with this tree: seals of verilog_emit, verilog_plan, eth_top_ax7203 and
xc7_primitives verify; t27c test-report and t27b test 8/8, 15/15, 2/2, 2/2. t27b
verilog writes eth_top_ax7203 with all 22 pin attributes, and its synthesizable part
equals the top of the bitstream tested on the board (only the test bench differs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t27b verilog: fold a constant rst_n/en tie-off out of the clocked process

1 participant