break lowers to disable fork;, and there is no fork anywhere in the generated corpus
bootstrap/src/compiler.rs:16230:
NodeKind::StmtBreak => {
self.write_line("disable fork;");
}
NodeKind::StmtContinue => {
self.write_line("/* continue */;");
}
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/:
$ grep -c 'disable fork;' *.v | grep -v ':0$'
specs_ar_asp_solver.v:5 specs_compiler_lexer.v:4
specs_math_phi_universal_attractor.v:2 specs_base_types.v:1
specs_fpga_testbench_mac_tb.v:1 specs_sync_schema.v:1
-> 6 files, 14 sites
$ grep -h '\bfork\b' *.v | sort -u
disable fork;
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.
breaklowers todisable fork;, and there is noforkanywhere in the generated corpusbootstrap/src/compiler.rs:16230:In Verilog,
disable forkterminates processes spawned by aforkin thecurrent scope. Measured over the 581
.vfilesgen-verilogproduces from the650 specs under
specs/:The only occurrence of the token
forkin the entire generated corpus isinside
disable fork;itself. All 14 are no-ops: the loop runs to completionand later iterations overwrite whatever the break was meant to preserve.
iverilog -g2012accepts them silently.continueis the same class:/* continue */;is a comment plus an emptystatement. 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 ofone of the three loop forms.
__t27_loop_{n}is emitted at compiler.rs:16377,inside
gen_verilog_while_stmt, and only whenwhile_literal_boundreturnsSome.gen_verilog_for_stmt(16494),gen_verilog_for_range_stmt(16533) andthe unbounded
whilebranch emit no named block at all, andwrite_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>.continuehas no ready target even then -- it needs aper-iteration block, which does not exist.
A hand-patch of the OUTPUT does fix it: substituting
disable __t27_loop_N;ina 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.vcarries the defective lowering in the tree; itsown header says it was produced by
t27c gen-verilog.Found by pointing
icarus-simulateat the corpus -- see #2987, which is whynothing has ever reported this.