A range literal reaches emitted Verilog: for (i = 0; i < (0 .. 1000); i = i + 1)
Largest single class among the 410 specs iverilog rejects. Found by classifying
every one of those 410 by the construct on the offending line rather than by
the diagnostic text.
The construct, and the three backends beside it
specs/base/ops.t27:1285 — for (0..1000) |_| { … }
/* gen-c */ for (int __t27_i = 0; __t27_i < 1000; __t27_i++) {
/* gen */ for (0 .. 1000) |_| { // native Zig
/* gen-verilog-for-simulation */
for (i = 0; i < (0 .. 1000); i = i + 1) begin
C takes the range's endpoint as the bound. Zig writes the range because Zig has
one. Verilog emits the range expression itself where a bound belongs, and
iverilog answers syntax error.
The C half of this is #2849 — "gen_c_for_stmt opened with 'C doesn't have
for-each natively; emit as a for loop with index' and then emitted a comment,
{, the body, }", which moved real loops 15 → 309. The repair did not
travel to Verilog, which emits the loop skeleton correctly and puts the range
in the bound.
Population, both paths, measured per spec
gen-verilog (synthesizable) 10 specs
gen-verilog-for-simulation 38 specs
So it is not simulation-only: ten synthesizable modules carry (0 .. N) in
emitted RTL today. The simulation path carries more because test and bench bodies
are only emitted there.
It is not only the loop bound
The same literal reaches slice positions, where it is a different repair:
specs/igla/race/backend.t27 left = expr[(0 .. idx)];
specs/memory/semantic_search.t27 top_k = result[(0 .. 0)];
specs/vsa/similarity_search.t27 get_vector = $signed(dummy[(((0 .. 10)) * 32) +: 32]);
specs/provider/stream.t27 … (line[(0 .. SSE_DATA_PREFIX_len)]) …
specs/queen/brain/summaries.t27 summary = aggregate_episodes(episodes[(0 .. count)], …);
Verilog spells a part-select [msb:lsb] or [base +: width]. A range in an
index is a slice; a range in a for bound is an endpoint. Two shapes, two
repairs, and a fix that only teaches the loop leaves five specs where they are.
Not established
- Whether C and Zig lower the slice form correctly — I compared the three
backends on the loop form only.
- Whether repairing this alone makes any of the 38 elaborate. Each carries other
first-errors too; this is the first diagnostic for 38, not the only one.
Refs #2849, #2987
A range literal reaches emitted Verilog:
for (i = 0; i < (0 .. 1000); i = i + 1)Largest single class among the 410 specs
iverilogrejects. Found by classifyingevery one of those 410 by the construct on the offending line rather than by
the diagnostic text.
The construct, and the three backends beside it
specs/base/ops.t27:1285—for (0..1000) |_| { … }C takes the range's endpoint as the bound. Zig writes the range because Zig has
one. Verilog emits the range expression itself where a bound belongs, and
iveriloganswerssyntax error.The C half of this is #2849 — "
gen_c_for_stmtopened with 'C doesn't havefor-each natively; emit as a for loop with index' and then emitted a comment,
{, the body,}", which moved real loops 15 → 309. The repair did nottravel to Verilog, which emits the loop skeleton correctly and puts the range
in the bound.
Population, both paths, measured per spec
So it is not simulation-only: ten synthesizable modules carry
(0 .. N)inemitted RTL today. The simulation path carries more because test and bench bodies
are only emitted there.
It is not only the loop bound
The same literal reaches slice positions, where it is a different repair:
Verilog spells a part-select
[msb:lsb]or[base +: width]. A range in anindex is a slice; a range in a
forbound is an endpoint. Two shapes, tworepairs, and a fix that only teaches the loop leaves five specs where they are.
Not established
backends on the loop form only.
first-errors too; this is the first diagnostic for 38, not the only one.
Refs #2849, #2987