You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gen-verilog: break lowers to disable fork; and continue to a comment -- 17 no-ops in 8 files, and no fork exists anywhere in the corpus #2988
In Verilog, disable fork terminates processes spawned by a fork in the
current scope. Measured over the 581 .v files gen-verilog produces from the
650 specs under specs/:
The only occurrence of the token fork in the entire generated corpus is
inside disable fork; itself. All 14 are no-ops: the loop runs to completion
and later iterations overwrite whatever the break was meant to preserve. iverilog -g2012 accepts them silently.
continue is the same class: /* continue */; is a comment plus an empty
statement. 1 surviving site (specs_nn_attention.v).
Why it is not a one-line fix, which is the part worth writing down
The obvious repair -- disable __t27_loop_N; -- is available for one branch of
one of the three loop forms. __t27_loop_{n} is emitted at compiler.rs:16377,
inside gen_verilog_while_stmt, and only when while_literal_bound returns Some. gen_verilog_for_stmt (16494), gen_verilog_for_range_stmt (16533) and
the unbounded while branch emit no named block at all, and write_line("disable fork;") has no knowledge of which loop encloses it.
So the repair is: a name stack on the codegen, a named block on every loop, and disable <top of stack>. continue has no ready target even then -- it needs a
per-iteration block, which does not exist.
A hand-patch of the OUTPUT does fix it: substituting disable __t27_loop_N; in
a generated file and re-running the same testbench makes Verilog agree with C,
Rust, Zig and hand arithmetic at all 12 measured points, with one line changed.
That is a control on the artifact, not a repair available in the emitter, and
the two should not be quoted as one.
The artifact is committed
specs/fpga/testbench/mac_tb.v carries the defective lowering in the tree; its
own header says it was produced by t27c gen-verilog.
Found by pointing icarus-simulate at the corpus -- see #2987, which is why
nothing has ever reported this.
Priced: 1 of 14 sites can take the one-line repair, 13 need a block that does not exist
Measured over the 581 .v files gen-verilog produces from the 650 specs under specs/, at 487003fb9, by tracking begin : __t27_loop_N nesting and asking
which disable fork; sites fall inside one:
disable fork sites = 14 inside a named loop block = 1 needing a new block = 13
INSIDE __t27_loop_1: specs/fpga/testbench/mac_tb.v:567
The single site that could take disable __t27_loop_1; today, verbatim:
Of the six files carrying the defect, five contain zero __t27_loop_ blocks
at all:
file
disable fork;
named loop blocks
ar/asp_solver
5
0
compiler/lexer
4
0
math/phi_universal_attractor
2
0
base/types
1
0
sync/schema
1
0
fpga/testbench/mac_tb
1
2
__t27_loop_{n} is emitted at exactly one site (compiler.rs:16377), inside gen_verilog_while_stmt, and only on the branch where while_literal_bound
returns Some — the W700 unrolled form. gen_verilog_for_stmt (16494), gen_verilog_for_range_stmt (16533) and the unbounded while branch emit no
named block.
A second defect at the same site, visible in the artifact
All 14 are emitted at column 0:
specs_ar_asp_solver.v:143 leading_spaces=0
... 14 of 14 ...
NodeKind::StmtBreak => self.write_line("disable fork;") calls write_line
with no write_indent() before it. Same for StmtContinue (1 surviving site, nn/attention.v:436). Cosmetic, but it is the tell that the arm was written
without looking at its own output.
Seal-churn population, if the repair names every loop
126 of 581 generated files carry a user loop. The other 455 contain only the __mul_noop ladder's own for (i = 0; i < 64; i = i + 1), which is preamble
text and not emitted by the loop arms — so naming user loops moves 126 files,
not 581. Worth stating before the change, because a first reading of grep -l 'for (' *.v returns 581 and prices this at four times its cost.
Refs #2989 — the early-return defect needs the same machinery, so the two want
one change and not two.
disable <named block> is a yosys PARSE ERROR — the obvious repair makes synthesis worse
Prior art said it first: SystemVerilog references and HLS discussions state that break and disable are not synthesisable, and that loop exit is normally
expressed as a state machine or a guard flag. Measured here rather than quoted.
The probe, with a one-variable control
moduleDisProbe(input clk, input [7:0] n, outputreg [7:0] out);
integer i;
always @(posedge clk) begin
out =8'd0;
begin : loop0
for (i =0; i <8; i = i +1) beginif (i == n) begin out = i; disable loop0; end
out = out +1;
endendendendmodule
Control — the same file with that one line commented out, nothing else
changed:
$ yosys -p "read_verilog /tmp/dis_ctrl.v; hierarchy -top DisProbe; proc; opt"
End of script. ... -> exit 0
Yosys 0.68 does not parse disable <block> at all. This is a front-end
rejection, not a synthesis warning — and this repository runs fpga-lint (read_verilog + hierarchy), fpga-synthesis and fpga-synthesis-arty in CI.
What that means for the repair
The obvious repair — name every loop, keep a stack, emit disable <top-of-stack>; — would introduce a yosys parse error into every
file it touches. The seal-churn population for "name every loop" is 126 of
581 generated files. Today only 6 carry a disable at all.
So the proposal that fixes simulation semantics makes the synthesis arm strictly
worse, on twenty times the files. A restructuring repair — a guard flag tested in
the loop condition and around the remaining body, the classic translation for a
language without a jump — has no such cost, and is also the only one of the three
that can close continue, which disable cannot reach without a per-iteration
block.
Correction to my own first reading of the corpus
I first wrote that all six carriers fail yosys read_verilogbecause of the disable. That is wrong, and the counterfactual says so — comment out only the disable fork; lines in each and re-read:
file
before
after
first error after
first error line vs first disable
ar/asp_solver
rc=1
rc=0
none
143 vs 143
base/types
rc=1
rc=1
syntax error, unexpected '.'
199 vs 229
compiler/lexer
rc=1
rc=1
Static cast is only supported in SystemVerilog mode
136 vs 682
fpga/testbench/mac_tb
rc=1
rc=1
Static cast is only supported in SystemVerilog mode
398 vs 567
math/phi_universal_attractor
rc=1
rc=1
syntax error, unexpected TOK_REAL
64 vs 111
sync/schema
rc=1
rc=1
syntax error, unexpected '.'
132 vs 153
1 of 6 flips. The other five fail earlier and the parser never reaches the disable — the same shape as the iverilog reading on this issue, met again one
tool over. So the live blast radius today is one file, and the defect is still
real: it is what a future repair must not multiply by 126.
The interim I am NOT shipping, and why
disable fork; is already a no-op — the corpus contains no fork. Replacing it
with an honest // break NOT LOWERED comment costs nothing semantically and
makes ar/asp_solver readable by yosys. It is the pattern this compiler already
uses in the Zig backend (// NOT LOWERED: … (T43)).
I am leaving it for whoever lands the real repair, because shipping it now moves
six files' seals and the real fix moves them again — two re-seals for one change.
Stated here so the option is on the record with its measurement rather than
rediscovered.
Correction: it is 2 of 6, not 1 — I measured in the wrong yosys mode
The claim survives and gets stronger. disable <named block> is a yosys parse
error in every mode, checked on the same probe with the same one-line
control:
read_verilog -> exit 1 syntax error, unexpected TOK_ID
read_verilog -sv -> exit 1 syntax error, unexpected TOK_ID
read_verilog -sv -DSIMULATION -> exit 1 syntax error, unexpected TOK_ID
control (that line commented) -> exit 0 in all three
What was wrong is the corpus counterfactual. I ran it with plain read_verilog. This repository's gate does not.fpga-build.yml:231:
Re-run in the gate's own mode — comment out only the disable fork; lines,
change nothing else:
file
before
after
first error after
ar/asp_solver
rc=1
rc=0
—
compiler/lexer
rc=1
rc=0
—
base/types
rc=1
rc=1
syntax error, unexpected '.'
fpga/testbench/mac_tb
rc=1
rc=1
syntax error, unexpected TOK_TO_SIGNED
math/phi_universal_attractor
rc=1
rc=1
syntax error, unexpected TOK_REAL
sync/schema
rc=1
rc=1
syntax error, unexpected '.'
2 of 6, not 1.compiler/lexer failed earlier in Verilog-2005 mode on Static cast is only supported in SystemVerilog mode — a message that names its
own remedy, and -sv is the remedy the gate already passes.
Confirmed from a second direction
An independent design agent built the guard-flag repair (no disable anywhere)
and ran yosys over the whole corpus in -sv mode: 454 → 455 of 581, with the
set difference naming asp_solver and compiler/lexer as gains and one loss it
went on to diagnose. Two routes — my six-file counterfactual and its 581-file
patch — name the same two files.
Both of my corrections on this issue ran the same way
First I said all six fail because of the disable; the counterfactual said
one. Now the mode correction says two. Both errors were in the direction that
understates, which is the safer direction to be wrong in and still worth
naming: a reader who took the first number would have priced the repair at a
sixth of what it buys.
Two designs built and measured, and the number that decides between them
Two independent agents each built a working patch against origin/master,
resealed FROZEN_HASH, regenerated all 581 .v, and measured. A third
(name-every-loop) never returned — but the second agent built it anyway as a
variant, so its cost is measured rather than missing. Every number below is
attributed; where two routes disagree I say so instead of averaging.
Also measured by B and worth keeping: name-every-loop costs 116 of 581, a 19.3× larger delta than B for the same repair. And it reconciles the
126-file figure I published: 116 files carry a for / for-range / unbounded while, plus 10 whose only loops are already-named W700 bounded whiles and so
stay byte-identical. 116 + 10 = 126, from a different direction.
What decides it
disable <named block> is a yosys parse error — measured on a probe with a
one-line control, in plain mode, -sv, and -sv -DSIMULATION, which is the
line fpga-build.yml:231 actually runs. So option B leaves every one of its six
files unreadable by this project's own synthesis gate, and option C removes the
construct entirely.
Both my six-file counterfactual and C's 581-file patch name the same two
files as the gain: ar/asp_solver and compiler/lexer. Two routes, one
answer.
Recommendation: C, staged in two
First, the break/continue half — 7 files (the 6 with a break, plus nn/attention for the continue). That is where the behavioural evidence is:
C's probes show the guard changing an answer, and the yosys gain lands here.
Second, separately, the #2989 return guard — 30 files, 81% of C's churn,
and by its author's own statement "changed ONLY by the return guard … unverified
by execution". Thirty files of behaviour change with no runnable oracle behind
them is a second decision, not a rider on the first.
Before either lands, specs_ternary_gft_xorbp must be explained. C's own
yosys sweep reports it as a loss — 454 → 455 is net, and a net is not a
measurement of the regression inside it.
What neither design established, stated because both said it themselves
No corpus spec carrying this defect can be run end to end. All 6 files with
a break are inside the 201 that iverilog rejects, before and after. Every
behavioural claim on both sides rests on probes the authors wrote. B put it
plainly: "I demonstrated the mechanism on synthetic code and the cost on real
code, and never both at once."
while (c) : (step) with a jump in the body is unexercised in C — code written,
no corpus spec and no probe reaches it.
B's continue fix needs a block around the loop body, not around the loop
— a second placement it does not have.
Why B is still the right answer to a different question
If the goal is the smallest statement the repository can make about this defect,
B is 99 lines and six files and closes disable fork; completely. It buys no
synthesis. Choose B to stop the no-op; choose C to also stop it being a parse
error, and pay 5.5× the code for it.
The seal question matters here and is easy to get wrong: both patches were built
against 9adbb6910 and each rewrites FROZEN_HASH. Master has since moved three
commits, so the obvious worry is that the sealed hash is stale. It is not — compiler.rs is byte-identical between the two:
because #2993, #2995 and #2996 touched cli/tri and docs/ only. The FROZEN_HASH inside both patches is valid as they stand, and master's own seal
is self-consistent. That stops being true the moment anything else edits compiler.rs, so whoever picks this up should re-run the two-line check above
rather than trust this paragraph.
Sizes, for the record: B is 205 lines of diff, C is 764.
Where they are
Both are kept beside this session at <scratchpad>/design-patches/{B-named-block-when-needed.diff, C-guard-flags.patch}.
They are working trees' output, not a pull request: nobody has reviewed them, the
skeptic phase of the sweep that produced them never ran — one of three design
agents stopped responding and the barrier held — so every number in the
comparison above is a designer's self-report, checked by me only where I had an
independent instrument (the yosys mode, the six-file counterfactual, and the
126 = 116 + 10 reconciliation).
That is the honest status: two measured designs, one adversarial pass short.
Correction to my own recommendation: the yosys loss is a phantom, and C is one better than either of us said
I wrote "C's own yosys sweep reports specs_ternary_gft_xorbp as a loss —
454 → 455 is net, and a net is not a measurement of the regression inside it",
and made explaining it a precondition for landing anything.
There is nothing to explain. Two independent skeptics re-ran the full corpus
sweep and both report 454 → 456, gaining ar/asp_solver and compiler/lexer
and losing nothing. On the alleged loss:
specs/ternary/gft_xorbp.t27 contains no while and no for at all, so C
cannot touch it: sha256(genA/ternary__gft_xorbp.v) = sha256(genB/ternary__gft_xorbp.v) = 07972b342da85b00…, byte-identical, and
yosys accepts it 5/5 against each corpus. Its name is not in the 37-file
changed list.
A file the patch cannot alter cannot flip a verdict on it. Netting a phantom
loss against two real gains is what turned 456 into 455, and I repeated it
without checking. Both skeptics reproduced 456 end to end, twice each.
The evidence both patch authors said they did not have
Both wrote that every behavioural claim rests on their own probes, because all
six break-carrier files fail iverilog for unrelated reasons. A skeptic ran an
independent probe end to end under vvp:
stock
patched (C)
early return in an unbounded while
HANGS (exit 142)
terminates, returns 4
break
returns −2 where 3 is correct
3
continue
returns 15 where 12 is correct
12
That is execution, not argument — on a probe, still, but a probe that runs all
the way through the simulator rather than being read.
Other numbers re-derived, and where the author was off
seal delta 37 of 581, decomposition confirmed: 6 break, 1 continue, 30
return-guard-only (33 carry a return guard, 3 of those also a break).
determinism 0 — the patched binary run twice over 650 specs produces
identical output, so every delta above is signal.
iverilog -g2012: 380 → 380 with the accepted set identical spec-for-spec;
regression set {} and gain set {} both printed empty. Per-file error counts
over the 37 changed files 418 → 418. tools/check_elab_ratchet.py green at
176 = 176 on both sides.
cargo test --release --no-fail-fast: -p t27c 2511 → 2516, workspace
2983 → 2988 — the total rises by exactly the five tests the patch adds.
diff size: git diff --numstat says compiler.rs551/30; the author's
"+552/−31" is the whole patch including the FROZEN_HASH line. Trivial, and
reported because a number quoted against the wrong file is still wrong.
zero NOT LOWERED fallbacks anywhere: the clocked escape arm is never taken by
this corpus, so all 14 break sites and the 1 continue site get a real flag.
Two findings that are not about either patch
gen-c and gen-rust are not byte-deterministic on master. A skeptic
measuring C's blast radius saw 3 differing files in each — and its
stock-against-itself control saw 2 and 3. So the wobble is master's, not the
patch's. gen-verilog is deterministic (0). Filing separately.
physics_chimera_best_gamma.v segfaults yosys — exit 139, deterministically,
3/3 runs, in both corpora — and fpga-lint scores a crash the same as a parse
failure.
What still is not established
The break/continue fix has zero execution evidence on corpus code: 0 of 14
break sites and 0 of the 1 continue site demonstrated behaviourally, because
every carrier fails iverilog first. One skeptic pushed the closest carrier
(math/phi_universal_attractor, 2 diagnostic lines) until its simulation build
turned out to contain reg [31:0] ; and a stub return value, at which point an
honest comparison was unavailable. And of the 14 break sites, 3 were read closely
(2 inert, 1 load-bearing) and 11 were not: "14 sites fixed" is a count of
lowering, not of behaviour changed.
Two of six skeptics have not reported yet; this will be revised if they
disagree.
The adversarial phase this issue never had has now run — six lenses, three on
each patch. Five have reported; one (B's cost numbers) is outstanding and this
will be revised if it disagrees.
The strongest single result
A skeptic wrote five probe specs of its own, computed every answer by hand
first, cross-checked against gen-c / gen-rust / gen, then simulated the
Verilog under iverilog + vvp. Shapes covered: break in a plain unbounded while, in for i in 0..8, in both W700 bounded forms (< and <=); 2- and
3-deep nesting with the break at the inner, middle and outer level; break
inside an if with statements after it; a loop with no jump; while (c) : (step)
with a break and with a continue — the shape both patch authors called
unexercised; break + continue + return in one loop; deep else-if chains; a tail
break; two sibling loops each with a break, to exercise flag-id allocation; a
break in a loop inside an if inside a loop; for k in 0..n with a non-literal
bound; a test block; and fn on_clock, the clocked non-blocking path.
patch C : 67 of 67 assertions correct
master : 28 of 44 scoreable assertions WRONG, and one probe could not be
scored at all because master hangs
Examples: A(10) master 777 / C 8 / oracle 8. F(5) master 210 / C 12 /
oracle 12. K(2) master 312 / C 306 / oracle 306. No input was found where
patch C's Verilog disagrees with the hand oracle.
Three independent confirmations that the yosys loss does not exist
Every skeptic that measured it reports 454 → 456, gaining ar/asp_solver and compiler/lexer and losing nothing. specs/ternary/gft_xorbp contains no loop,
its generated .v is byte-identical under the patch (same sha256), and yosys
accepts it 5/5 and 10/10 in separate runs. The reported loss is a harness
artifact. I repeated it in my own recommendation without checking, and it made
C look worse than it is.
Cost, re-derived twice
37 of 581 files change — 6 break, 1 continue, 30 return-guard-only. Generation is
deterministic (0 differing files on a repeat run). iverilog -g2012 380 → 380
with the accepted set identical file for file, empty regression set and empty
gain set both printed. Per-file error counts over the 37 changed files 418 → 418; tools/check_elab_ratchet.py green at 176 = 176 on both sides. cargo test --release -p t27c2511 → 2516, the rise being exactly the five
tests the patch adds. Diff size is compiler.rs551/30, not the author's
+552/−31, which counted the FROZEN_HASH line.
The hole, and it is wider than either author said
the intersection of {files patch C changes} and {files iverilog accepts} is EMPTY — zero, not just the 6 break-carriers.
So the 30 return-guard-only files cannot be compiled at all, let alone simulated,
before or after. No corpus spec carrying either defect can be run end to end.
Confirmed by a skeptic that tried, not assumed. Every behavioural claim on both
sides — mine included — rests on probes; what changed is that the probes now run
all the way through a simulator, and one of them covers sixty-seven cases.
Recommendation
Land C. It is the only patch that removes the construct yosys cannot parse,
the only one that closes continue, the only one that closes #2989 in the same
shape, and it is 67/67 against a hand oracle on a shape matrix neither author
wrote.
Stage it as before, and for the reason the skeptics sharpened rather than
weakened: the 30 return-guard-only files are 81% of the churn and are inside the
set that cannot be executed. Land the 7 break/continue files first, where the
evidence is; land the return guard as its own change with its own statement that
it is argued rather than demonstrated.
Withdraw the precondition I set. "Explain the gft_xorbp loss before
anything lands" is void — there is nothing to explain.
One finding that is not about either patch
The same skeptic noted in passing that patch C's Verilog is more faithful than
the compiler's own C and Rust backends, which hang on while (c) : (step) with a continue. Reproduced independently with my own probe, drivers and oracle: C
and Rust both fail to terminate (exit 142 under a 5-second alarm), Zig returns
the correct 5. Filed as #3009 — latent, because no corpus spec writes the two
together today.
The full adversarial run closed: 6 of 6 skeptics, and it corrects my verdict in four places
All six returned; none died. The judge's verdict and mine agree on land C,
and disagree with my published comment on four points. Taking mine down first.
1. "No corpus spec carrying either defect can be run end to end" — WRONG
Two skeptics did it, independently, on the spec #2989 names.
One took specs/isa/ternary_search.t27, diagnosed four unrelated emitter
defects blocking it — try eq(A,B) emitted verbatim into Verilog, data.len
lowered to the unbound identifier data_len, data: []i32 lowered to input [31:0] data so every data[x] is a bit-select, and call sites passing data[0] — repaired them identically on both sides, with a substitution-count
assertion that fired twice and caught two of its own errors, and confirmed by
diff that the patch's guard was then the only remaining difference:
stock : vvp exits 142 at 30s AND at 120s, no output.
instrumented: iter=1 lo=0 hi=5 mid=2 ret=0
iter=2..5 and iter=2000 all lo=0 hi=5 mid=2 ret=1
-- identical state at iteration 2000 as at iteration 2.
A measured fixed point, not slowness.
patched : exit 0, [CHECK] got=2 want=2
Split per function, linear_search returns 2 on both (#2989 does not bite it)
and binary_search is the one that hangs. That is #2989 reproduced and
repaired end to end on corpus code, not on a probe.
A second skeptic repaired the same spec differently (8-element array, input [255:0] data, $signed(data[i*32 +: 32]), localparam integer data_len = 8), got the same hang with a negative control
— a miss returns −1 and finishes, rc=0 — and found a second symptom class: linear_search([-1,-1,0,1,1,0,1,0], 1) returns 6, the last match, where the
language says 3. A third found the wrong-answer form on master's emitter
independently (t1(5,2): Verilog 4, C 2). So #2989 is both a
non-termination and a wrong-answer defect, shown three times by people not
looking for the same thing.
And a break carrier ran too: specs/math/phi_universal_attractor.t27, after five
asserted repairs. Stock prints EXIT iter=20; under B, EXIT iter=1; with the
tolerance set so the break is unreachable, both print iter=20 — a negative
control. That is the only behavioural demonstration for #2988 on either side, and
the same skeptic immediately undercut it: the function returns the hard-coded
stub iterate_to_fixed_point = 0 /* ConvergenceResult {...} */, so no caller can
observe the difference.
2. "14 sites in 6 files" — it is 16 in 7
compiler/cli/gen.t27 lives outside specs/, carries 2 sites in basename_without_ext, and is sealed. Every skeptic that scanned only specs/
missed it — including me, in the pricing comment above, three times. It was found
because the seal gate named the file.
Consequence nobody has checked: B handles those two sites; whether C does is
unmeasured, because all three C skeptics also scanned only specs/.
3. Neither patch applies any more, and it is my fault
I wrote that both apply cleanly and their FROZEN_HASH is valid "as they stand",
hedged with "that stops being true the moment anything else edits compiler.rs". It stopped being true four hours later, by my own hand: #3005
merged as b3d6271f0 and rewrote the seal
Checked just now on b280eb236: both patches fail with error: bootstrap/stage0/FROZEN_HASH: patch does not apply. The compiler.rs
hunks still apply; only the seal is stale. And C's rebase lands in the same gen_verilog_for_stmt neighbourhood #3005 just rewrote.
4. Neither patch reseals, and #3005 set the standard by example
Both touch exactly two files — compiler.rs and FROZEN_HASH — and reseal
nothing. Measured for B:
stock : python3 tools/check_seal_coverage.py -> exit 0
"OK: 1318 seals, 1224 hold, 94 known-broken"
B : exit 1, "FAIL: 17 seal(s) newly do not hold",
every one [gen-drift] ... gen_hash_verilog
t27c seal --verify flips 0 -> 1 on all six carriers
seal-coverage.yml runs that script. B changes 6 generated files and drifts 17
seals. C changes 37 and nobody ran the script at all.#3005 shipped the
compiler change, 14 re-sealed .trinity/seals/*.json, a 254-line test file, a docs/now/ entry and mutation-checked tests in one commit. That is the bar.
What the run confirmed, and what it did not
Confirmed by three trees each: yosys 454 → 456 for C, gaining ar/asp_solver and compiler/lexer and losing nothing; gft_xorbp is a phantom
(no loop, byte-identical .v, yosys 10/10). B: 454 → 454 with an identical
passing set — B cements the construct the synthesis gate cannot parse and forgoes
the two wins its own wrapper had already earned. That, and not probe volume, is
what separates the patches.
Not confirmed: my "75 sites in 33 files" for #2989. Three skeptics landed
on 32–33 files — but of generated .v, a different population from the .t27
source I counted, over a corpus where 69 of 650 specs never reach .v at all.
One declined to count and said so; one named its own counter broken after it
printed 152/40 and 99/38 for trees differing in 6 files. The file count is
corroborated; the 75 is not.
Not fixed by C, and worth naming:break inside fn on_clock. C emits // t27#2988: break NOT LOWERED there — an annotation, not a fix. The corpus has
zero such sites, so that arm is unexercised by every measurement taken.
Demonstrated versus argued, stated plainly
B: 1 of 16 break sites shown to change behaviour, 0 of 16 shown to
change an answer anyone can observe. Five sites measured dead
(tolerance : f64 = 0.01 lowers to reg [31:0] and reads 0, so the guard can
never fire; a 524416-bit Lexer lowers to reg [31:0], so four loops never
execute); six more read as trip-count-only idempotent flag writes.
C: 1 of ~82 guarded loops — binary_search, end to end. For break and
continue on corpus code: zero, and two of the 14 sites read as semantically
inert. Everything else is probes: 67/67 against a hand oracle across a shape
matrix neither author wrote, against master's 28-of-44 wrong and one hang.
And my own instrument failed again while checking this
git apply --check "$p" | head -3 && echo APPLIES printed APPLIES for both
patches. head succeeds, so && fires. That is ci-gates 428 — do not put a
pipe between a status and $? — for the third time in two sessions, by the
person who wrote it. The real answer was in the error text I was piping past.
changed the title [-]gen-verilog: break lowers to `disable fork;` and continue to a comment -- 15 no-ops, and no `fork` exists anywhere in the corpus[/-][+]gen-verilog: break lowers to `disable fork;` and continue to a comment -- 17 no-ops in 8 files, and no `fork` exists anywhere in the corpus[/+]on Sep 3, 2026
Correction to my own count, third time on this number. Measured over every .t27 in the tree (745 files, 643 generate Verilog), not just specs/:
sites
files
break -> disable fork;
16
7
continue -> /* continue */;
1
1
total
17
8
The published figures were 14 in 6 (this title), then 16 in 7 (a correction that added compiler/cli/gen.t27 but dropped the single continue), and now 17 in 8. Under specs/ alone it is 15 in 7 -- the two breaks in compiler/cli/gen.t27 are outside the directory every census scoped to.
tri jumps census now prints this, walks the whole tree, and lists the carriers by name:
jumps left as a NO-OP 17 site(s) in 8 file(s)
compiler/cli/gen.t27 2 x break
specs/ar/asp_solver.t27 5 x break
specs/base/types.t27 1 x break
specs/compiler/lexer.t27 4 x break
specs/fpga/testbench/mac_tb.t27 1 x break
specs/math/phi_universal_attractor.t27 2 x break
specs/nn/attention.t27 1 x continue
specs/sync/schema.t27 1 x break
Activity
gHashTag commentedon Aug 30, 2026
Priced: 1 of 14 sites can take the one-line repair, 13 need a block that does not exist
Measured over the 581
.vfilesgen-verilogproduces from the 650 specs underspecs/, at487003fb9, by trackingbegin : __t27_loop_Nnesting and askingwhich
disable fork;sites fall inside one:The single site that could take
disable __t27_loop_1;today, verbatim:Of the six files carrying the defect, five contain zero
__t27_loop_blocksat all:
disable fork;ar/asp_solvercompiler/lexermath/phi_universal_attractorbase/typessync/schemafpga/testbench/mac_tb__t27_loop_{n}is emitted at exactly one site (compiler.rs:16377), insidegen_verilog_while_stmt, and only on the branch wherewhile_literal_boundreturns
Some— the W700 unrolled form.gen_verilog_for_stmt(16494),gen_verilog_for_range_stmt(16533) and the unboundedwhilebranch emit nonamed block.
A second defect at the same site, visible in the artifact
All 14 are emitted at column 0:
NodeKind::StmtBreak => self.write_line("disable fork;")callswrite_linewith no
write_indent()before it. Same forStmtContinue(1 surviving site,nn/attention.v:436). Cosmetic, but it is the tell that the arm was writtenwithout looking at its own output.
Seal-churn population, if the repair names every loop
126 of 581 generated files carry a user loop. The other 455 contain only the
__mul_noopladder's ownfor (i = 0; i < 64; i = i + 1), which is preambletext and not emitted by the loop arms — so naming user loops moves 126 files,
not 581. Worth stating before the change, because a first reading of
grep -l 'for (' *.vreturns 581 and prices this at four times its cost.Refs #2989 — the early-return defect needs the same machinery, so the two want
one change and not two.
gHashTag commentedon Aug 30, 2026
disable <named block>is a yosys PARSE ERROR — the obvious repair makes synthesis worsePrior art said it first: SystemVerilog references and HLS discussions state that
breakanddisableare not synthesisable, and that loop exit is normallyexpressed as a state machine or a guard flag. Measured here rather than quoted.
The probe, with a one-variable control
Control — the same file with that one line commented out, nothing else
changed:
Yosys 0.68 does not parse
disable <block>at all. This is a front-endrejection, not a synthesis warning — and this repository runs
fpga-lint (read_verilog + hierarchy),fpga-synthesisandfpga-synthesis-artyin CI.What that means for the repair
The obvious repair — name every loop, keep a stack, emit
disable <top-of-stack>;— would introduce a yosys parse error into everyfile it touches. The seal-churn population for "name every loop" is 126 of
581 generated files. Today only 6 carry a
disableat all.So the proposal that fixes simulation semantics makes the synthesis arm strictly
worse, on twenty times the files. A restructuring repair — a guard flag tested in
the loop condition and around the remaining body, the classic translation for a
language without a jump — has no such cost, and is also the only one of the three
that can close
continue, whichdisablecannot reach without a per-iterationblock.
Correction to my own first reading of the corpus
I first wrote that all six carriers fail
yosys read_verilogbecause of thedisable. That is wrong, and the counterfactual says so — comment out only thedisable fork;lines in each and re-read:disablear/asp_solverbase/typessyntax error, unexpected '.'compiler/lexerStatic cast is only supported in SystemVerilog modefpga/testbench/mac_tbStatic cast is only supported in SystemVerilog modemath/phi_universal_attractorsyntax error, unexpected TOK_REALsync/schemasyntax error, unexpected '.'1 of 6 flips. The other five fail earlier and the parser never reaches the
disable— the same shape as the iverilog reading on this issue, met again onetool over. So the live blast radius today is one file, and the defect is still
real: it is what a future repair must not multiply by 126.
The interim I am NOT shipping, and why
disable fork;is already a no-op — the corpus contains nofork. Replacing itwith an honest
// break NOT LOWEREDcomment costs nothing semantically andmakes
ar/asp_solverreadable by yosys. It is the pattern this compiler alreadyuses in the Zig backend (
// NOT LOWERED: … (T43)).I am leaving it for whoever lands the real repair, because shipping it now moves
six files' seals and the real fix moves them again — two re-seals for one change.
Stated here so the option is on the record with its measurement rather than
rediscovered.
Refs #2989
feat(tri): vsim funnel -- how far each spec gets when its Verilog is …
gHashTag commentedon Aug 30, 2026
Correction: it is 2 of 6, not 1 — I measured in the wrong yosys mode
The claim survives and gets stronger.
disable <named block>is a yosys parseerror in every mode, checked on the same probe with the same one-line
control:
What was wrong is the corpus counterfactual. I ran it with plain
read_verilog.This repository's gate does not.
fpga-build.yml:231:yosys -p "read_verilog -sv -DSIMULATION $v; hierarchy -top $name" -qRe-run in the gate's own mode — comment out only the
disable fork;lines,change nothing else:
ar/asp_solvercompiler/lexerbase/typessyntax error, unexpected '.'fpga/testbench/mac_tbsyntax error, unexpected TOK_TO_SIGNEDmath/phi_universal_attractorsyntax error, unexpected TOK_REALsync/schemasyntax error, unexpected '.'2 of 6, not 1.
compiler/lexerfailed earlier in Verilog-2005 mode onStatic cast is only supported in SystemVerilog mode— a message that names itsown remedy, and
-svis the remedy the gate already passes.Confirmed from a second direction
An independent design agent built the guard-flag repair (no
disableanywhere)and ran yosys over the whole corpus in
-svmode: 454 → 455 of 581, with theset difference naming
asp_solverandcompiler/lexeras gains and one loss itwent on to diagnose. Two routes — my six-file counterfactual and its 581-file
patch — name the same two files.
Both of my corrections on this issue ran the same way
First I said all six fail because of the
disable; the counterfactual saidone. Now the mode correction says two. Both errors were in the direction that
understates, which is the safer direction to be wrong in and still worth
naming: a reader who took the first number would have priced the repair at a
sixth of what it buys.
Refs #2987
gHashTag commentedon Aug 30, 2026
Two designs built and measured, and the number that decides between them
Two independent agents each built a working patch against
origin/master,resealed
FROZEN_HASH, regenerated all 581.v, and measured. A third(name-every-loop) never returned — but the second agent built it anyway as a
variant, so its cost is measured rather than missing. Every number below is
attributed; where two routes disagree I say so instead of averaging.
breakdisableat allcompiler.rs.vchangediverilog -g2012disableasp_solver,compiler/lexer; losesgft_xorbpcontinuedisable fork;disable __t27_loop_N;)Also measured by B and worth keeping: name-every-loop costs 116 of 581, a
19.3× larger delta than B for the same repair. And it reconciles the
126-file figure I published: 116 files carry a
for/ for-range / unboundedwhile, plus 10 whose only loops are already-named W700 bounded whiles and sostay byte-identical. 116 + 10 = 126, from a different direction.
What decides it
disable <named block>is a yosys parse error — measured on a probe with aone-line control, in plain mode,
-sv, and-sv -DSIMULATION, which is theline
fpga-build.yml:231actually runs. So option B leaves every one of its sixfiles unreadable by this project's own synthesis gate, and option C removes the
construct entirely.
Both my six-file counterfactual and C's 581-file patch name the same two
files as the gain:
ar/asp_solverandcompiler/lexer. Two routes, oneanswer.
Recommendation: C, staged in two
First, the break/continue half — 7 files (the 6 with a
break, plusnn/attentionfor thecontinue). That is where the behavioural evidence is:C's probes show the guard changing an answer, and the yosys gain lands here.
Second, separately, the #2989 return guard — 30 files, 81% of C's churn,
and by its author's own statement "changed ONLY by the return guard … unverified
by execution". Thirty files of behaviour change with no runnable oracle behind
them is a second decision, not a rider on the first.
Before either lands,
specs_ternary_gft_xorbpmust be explained. C's ownyosys sweep reports it as a loss — 454 → 455 is net, and a net is not a
measurement of the regression inside it.
What neither design established, stated because both said it themselves
a
breakare inside the 201 thativerilogrejects, before and after. Everybehavioural claim on both sides rests on probes the authors wrote. B put it
plainly: "I demonstrated the mechanism on synthetic code and the cost on real
code, and never both at once."
while (c) : (step)with a jump in the body is unexercised in C — code written,no corpus spec and no probe reaches it.
continuefix needs a block around the loop body, not around the loop— a second placement it does not have.
Why B is still the right answer to a different question
If the goal is the smallest statement the repository can make about this defect,
B is 99 lines and six files and closes
disable fork;completely. It buys nosynthesis. Choose B to stop the no-op; choose C to also stop it being a parse
error, and pay 5.5× the code for it.
Refs #2989, #2987
gHashTag commentedon Aug 30, 2026
Both patches exist, apply cleanly to today's master, and carry a still-valid seal
Checked rather than asserted, at
9503515aa:The seal question matters here and is easy to get wrong: both patches were built
against
9adbb6910and each rewritesFROZEN_HASH. Master has since moved threecommits, so the obvious worry is that the sealed hash is stale. It is not —
compiler.rsis byte-identical between the two:because #2993, #2995 and #2996 touched
cli/trianddocs/only. TheFROZEN_HASHinside both patches is valid as they stand, and master's own sealis self-consistent. That stops being true the moment anything else edits
compiler.rs, so whoever picks this up should re-run the two-line check aboverather than trust this paragraph.
Sizes, for the record: B is 205 lines of diff, C is 764.
Where they are
Both are kept beside this session at
<scratchpad>/design-patches/{B-named-block-when-needed.diff, C-guard-flags.patch}.They are working trees' output, not a pull request: nobody has reviewed them, the
skeptic phase of the sweep that produced them never ran — one of three design
agents stopped responding and the barrier held — so every number in the
comparison above is a designer's self-report, checked by me only where I had an
independent instrument (the yosys mode, the six-file counterfactual, and the
126 = 116 + 10 reconciliation).
That is the honest status: two measured designs, one adversarial pass short.
gHashTag commentedon Sep 3, 2026
Correction to my own recommendation: the yosys loss is a phantom, and C is one better than either of us said
I wrote "C's own yosys sweep reports
specs_ternary_gft_xorbpas a loss —454 → 455 is net, and a net is not a measurement of the regression inside it",
and made explaining it a precondition for landing anything.
There is nothing to explain. Two independent skeptics re-ran the full corpus
sweep and both report 454 → 456, gaining
ar/asp_solverandcompiler/lexerand losing nothing. On the alleged loss:
A file the patch cannot alter cannot flip a verdict on it. Netting a phantom
loss against two real gains is what turned 456 into 455, and I repeated it
without checking. Both skeptics reproduced 456 end to end, twice each.
The evidence both patch authors said they did not have
Both wrote that every behavioural claim rests on their own probes, because all
six break-carrier files fail
iverilogfor unrelated reasons. A skeptic ran anindependent probe end to end under
vvp:whilebreakcontinueThat is execution, not argument — on a probe, still, but a probe that runs all
the way through the simulator rather than being read.
Other numbers re-derived, and where the author was off
return-guard-only (33 carry a return guard, 3 of those also a break).
identical output, so every delta above is signal.
iverilog -g2012: 380 → 380 with the accepted set identical spec-for-spec;regression set
{}and gain set{}both printed empty. Per-file error countsover the 37 changed files 418 → 418.
tools/check_elab_ratchet.pygreen at176 = 176 on both sides.
cargo test --release --no-fail-fast:-p t27c2511 → 2516, workspace2983 → 2988 — the total rises by exactly the five tests the patch adds.
git diff --numstatsayscompiler.rs551/30; the author's"+552/−31" is the whole patch including the
FROZEN_HASHline. Trivial, andreported because a number quoted against the wrong file is still wrong.
NOT LOWEREDfallbacks anywhere: the clocked escape arm is never taken bythis corpus, so all 14 break sites and the 1 continue site get a real flag.
Two findings that are not about either patch
gen-candgen-rustare not byte-deterministic on master. A skepticmeasuring C's blast radius saw 3 differing files in each — and its
stock-against-itself control saw 2 and 3. So the wobble is master's, not the
patch's.
gen-verilogis deterministic (0). Filing separately.physics_chimera_best_gamma.vsegfaults yosys — exit 139, deterministically,3/3 runs, in both corpora — and
fpga-lintscores a crash the same as a parsefailure.
What still is not established
The break/continue fix has zero execution evidence on corpus code: 0 of 14
break sites and 0 of the 1 continue site demonstrated behaviourally, because
every carrier fails
iverilogfirst. One skeptic pushed the closest carrier(
math/phi_universal_attractor, 2 diagnostic lines) until its simulation buildturned out to contain
reg [31:0] ;and a stub return value, at which point anhonest comparison was unavailable. And of the 14 break sites, 3 were read closely
(2 inert, 1 load-bearing) and 11 were not: "14 sites fixed" is a count of
lowering, not of behaviour changed.
Two of six skeptics have not reported yet; this will be revised if they
disagree.
gHashTag commentedon Sep 3, 2026
Verdict after five of six skeptics: land C
The adversarial phase this issue never had has now run — six lenses, three on
each patch. Five have reported; one (B's cost numbers) is outstanding and this
will be revised if it disagrees.
The strongest single result
A skeptic wrote five probe specs of its own, computed every answer by hand
first, cross-checked against
gen-c/gen-rust/gen, then simulated theVerilog under
iverilog+vvp. Shapes covered:breakin a plain unboundedwhile, infor i in 0..8, in both W700 bounded forms (<and<=); 2- and3-deep nesting with the break at the inner, middle and outer level;
breakinside an
ifwith statements after it; a loop with no jump;while (c) : (step)with a break and with a continue — the shape both patch authors called
unexercised; break + continue + return in one loop; deep else-if chains; a tail
break; two sibling loops each with a break, to exercise flag-id allocation; a
break in a loop inside an
ifinside a loop;for k in 0..nwith a non-literalbound; a
testblock; andfn on_clock, the clocked non-blocking path.Examples:
A(10)master 777 / C 8 / oracle 8.F(5)master 210 / C 12 /oracle 12.
K(2)master 312 / C 306 / oracle 306. No input was found wherepatch C's Verilog disagrees with the hand oracle.
Three independent confirmations that the yosys loss does not exist
Every skeptic that measured it reports 454 → 456, gaining
ar/asp_solverandcompiler/lexerand losing nothing.specs/ternary/gft_xorbpcontains no loop,its generated
.vis byte-identical under the patch (same sha256), and yosysaccepts it 5/5 and 10/10 in separate runs. The reported loss is a harness
artifact. I repeated it in my own recommendation without checking, and it made
C look worse than it is.
Cost, re-derived twice
37 of 581 files change — 6 break, 1 continue, 30 return-guard-only. Generation is
deterministic (0 differing files on a repeat run).
iverilog -g2012380 → 380with the accepted set identical file for file, empty regression set and empty
gain set both printed. Per-file error counts over the 37 changed files 418 → 418;
tools/check_elab_ratchet.pygreen at 176 = 176 on both sides.cargo test --release -p t27c2511 → 2516, the rise being exactly the fivetests the patch adds. Diff size is
compiler.rs551/30, not the author's+552/−31, which counted the
FROZEN_HASHline.The hole, and it is wider than either author said
So the 30 return-guard-only files cannot be compiled at all, let alone simulated,
before or after. No corpus spec carrying either defect can be run end to end.
Confirmed by a skeptic that tried, not assumed. Every behavioural claim on both
sides — mine included — rests on probes; what changed is that the probes now run
all the way through a simulator, and one of them covers sixty-seven cases.
Recommendation
Land C. It is the only patch that removes the construct yosys cannot parse,
the only one that closes
continue, the only one that closes #2989 in the sameshape, and it is 67/67 against a hand oracle on a shape matrix neither author
wrote.
Stage it as before, and for the reason the skeptics sharpened rather than
weakened: the 30 return-guard-only files are 81% of the churn and are inside the
set that cannot be executed. Land the 7 break/continue files first, where the
evidence is; land the return guard as its own change with its own statement that
it is argued rather than demonstrated.
Withdraw the precondition I set. "Explain the
gft_xorbploss beforeanything lands" is void — there is nothing to explain.
One finding that is not about either patch
The same skeptic noted in passing that patch C's Verilog is more faithful than
the compiler's own C and Rust backends, which hang on
while (c) : (step)with acontinue. Reproduced independently with my own probe, drivers and oracle: Cand Rust both fail to terminate (exit 142 under a 5-second alarm), Zig returns
the correct 5. Filed as #3009 — latent, because no corpus spec writes the two
together today.
Refs #2989, #3009
gHashTag commentedon Sep 3, 2026
The full adversarial run closed: 6 of 6 skeptics, and it corrects my verdict in four places
All six returned; none died. The judge's verdict and mine agree on land C,
and disagree with my published comment on four points. Taking mine down first.
1. "No corpus spec carrying either defect can be run end to end" — WRONG
Two skeptics did it, independently, on the spec #2989 names.
One took
specs/isa/ternary_search.t27, diagnosed four unrelated emitterdefects blocking it —
try eq(A,B)emitted verbatim into Verilog,data.lenlowered to the unbound identifier
data_len,data: []i32lowered toinput [31:0] dataso everydata[x]is a bit-select, and call sites passingdata[0]— repaired them identically on both sides, with a substitution-countassertion that fired twice and caught two of its own errors, and confirmed by
diff that the patch's guard was then the only remaining difference:
Split per function,
linear_searchreturns 2 on both (#2989 does not bite it)and
binary_searchis the one that hangs. That is #2989 reproduced andrepaired end to end on corpus code, not on a probe.
A second skeptic repaired the same spec differently (8-element array,
input [255:0] data,$signed(data[i*32 +: 32]),localparam integer data_len = 8), got the same hang with a negative control— a miss returns −1 and finishes, rc=0 — and found a second symptom class:
linear_search([-1,-1,0,1,1,0,1,0], 1)returns 6, the last match, where thelanguage says 3. A third found the wrong-answer form on master's emitter
independently (
t1(5,2): Verilog 4, C 2). So #2989 is both anon-termination and a wrong-answer defect, shown three times by people not
looking for the same thing.
And a break carrier ran too:
specs/math/phi_universal_attractor.t27, after fiveasserted repairs. Stock prints
EXIT iter=20; under B,EXIT iter=1; with thetolerance set so the break is unreachable, both print
iter=20— a negativecontrol. That is the only behavioural demonstration for #2988 on either side, and
the same skeptic immediately undercut it: the function returns the hard-coded
stub
iterate_to_fixed_point = 0 /* ConvergenceResult {...} */, so no caller canobserve the difference.
2. "14 sites in 6 files" — it is 16 in 7
compiler/cli/gen.t27lives outsidespecs/, carries 2 sites inbasename_without_ext, and is sealed. Every skeptic that scanned onlyspecs/missed it — including me, in the pricing comment above, three times. It was found
because the seal gate named the file.
Consequence nobody has checked: B handles those two sites; whether C does is
unmeasured, because all three C skeptics also scanned only
specs/.3. Neither patch applies any more, and it is my fault
I wrote that both apply cleanly and their
FROZEN_HASHis valid "as they stand",hedged with "that stops being true the moment anything else edits
compiler.rs". It stopped being true four hours later, by my own hand: #3005merged as
b3d6271f0and rewrote the sealChecked just now on
b280eb236: both patches fail witherror: bootstrap/stage0/FROZEN_HASH: patch does not apply. Thecompiler.rshunks still apply; only the seal is stale. And C's rebase lands in the same
gen_verilog_for_stmtneighbourhood #3005 just rewrote.4. Neither patch reseals, and #3005 set the standard by example
Both touch exactly two files —
compiler.rsandFROZEN_HASH— and resealnothing. Measured for B:
seal-coverage.ymlruns that script. B changes 6 generated files and drifts 17seals. C changes 37 and nobody ran the script at all. #3005 shipped the
compiler change, 14 re-sealed
.trinity/seals/*.json, a 254-line test file, adocs/now/entry and mutation-checked tests in one commit. That is the bar.What the run confirmed, and what it did not
Confirmed by three trees each: yosys
454 → 456for C, gainingar/asp_solverandcompiler/lexerand losing nothing;gft_xorbpis a phantom(no loop, byte-identical
.v, yosys 10/10). B: 454 → 454 with an identicalpassing set — B cements the construct the synthesis gate cannot parse and forgoes
the two wins its own wrapper had already earned. That, and not probe volume, is
what separates the patches.
Not confirmed: my "75 sites in 33 files" for #2989. Three skeptics landed
on 32–33 files — but of generated
.v, a different population from the.t27source I counted, over a corpus where 69 of 650 specs never reach
.vat all.One declined to count and said so; one named its own counter broken after it
printed 152/40 and 99/38 for trees differing in 6 files. The file count is
corroborated; the 75 is not.
Not fixed by C, and worth naming:
breakinsidefn on_clock. C emits// t27#2988: break NOT LOWEREDthere — an annotation, not a fix. The corpus haszero such sites, so that arm is unexercised by every measurement taken.
Demonstrated versus argued, stated plainly
change an answer anyone can observe. Five sites measured dead
(
tolerance : f64 = 0.01lowers toreg [31:0]and reads 0, so the guard cannever fire; a 524416-bit
Lexerlowers toreg [31:0], so four loops neverexecute); six more read as trip-count-only idempotent flag writes.
binary_search, end to end. For break andcontinue on corpus code: zero, and two of the 14 sites read as semantically
inert. Everything else is probes: 67/67 against a hand oracle across a shape
matrix neither author wrote, against master's 28-of-44 wrong and one hang.
And my own instrument failed again while checking this
git apply --check "$p" | head -3 && echo APPLIESprinted APPLIES for bothpatches.
headsucceeds, so&&fires. That is ci-gates 428 — do not put apipe between a status and
$?— for the third time in two sessions, by theperson who wrote it. The real answer was in the error text I was piping past.
Refs #2989, #3005, #3009
docs(skill): 434-435 -- the pipeline rule is about the last command, …
[-]gen-verilog: break lowers to `disable fork;` and continue to a comment -- 15 no-ops, and no `fork` exists anywhere in the corpus[/-][+]gen-verilog: break lowers to `disable fork;` and continue to a comment -- 17 no-ops in 8 files, and no `fork` exists anywhere in the corpus[/+]gHashTag commentedon Sep 3, 2026
Correction to my own count, third time on this number. Measured over every
.t27in the tree (745 files, 643 generate Verilog), not justspecs/:break->disable fork;continue->/* continue */;The published figures were 14 in 6 (this title), then 16 in 7 (a correction that added
compiler/cli/gen.t27but dropped the singlecontinue), and now 17 in 8. Underspecs/alone it is 15 in 7 -- the twobreaks incompiler/cli/gen.t27are outside the directory every census scoped to.tri jumps censusnow prints this, walks the whole tree, and lists the carriers by name:Fix in #3014.
chore(seals): re-seal the 19 seal files the break/continue lowering m…
docs(compiler): the referee test's comment named a population that ne…
fix(verilog): a return inside a loop left the function and not the lo…
docs(verilog): fourteen was the flag count, not the site count (#3026)