Skip to content

gen-verilog: an entry parameter named clk/rst_n/en is declared once; a void body's last call stays a statement (Closes #5649, Closes #5650, Closes #5651) - #8844

Open
dmitrii-f-t27 wants to merge 9 commits into
gHashTag:masterfrom
dmitrii-f-t27:sweep/gen-verilog-5649-5651

Conversation

@dmitrii-f-t27

@dmitrii-f-t27 dmitrii-f-t27 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Closes #5649
Closes #5650
Closes #5651

Description

Three t27c gen-verilog defects that made iverilog refuse generated modules.

Spec

The decisions live in .t27, lowered by t27c gen-rust to bootstrap/gen/rust/compiler/ and mounted by #[path] (the verilog_aos_memory.t27 pattern, #8151):

Only t27 (owner rules 2026-10-05 and 2026-10-09)

The issues asked for new bootstrap/tests/*.rs regression tests. A new hand-written .rs file is now denied, so the regression guards are the three specs and the resealed gen_hash_verilog of every sealed spec whose output changed (the suite's seal-verify phase reports any drift). compiler.rs is +25/-11 and FROZEN_HASH 1/1; paid for by deleting scripts/gen_w369.py (a one-shot wave-369 generator nothing runs, as #8617 and #8667 did with gen_w378.py / gen_w379.py). Local own_language.c check_all and check_budget: both 0.

Measured (master tip vs this branch, merged with master d01d772)

Limits

  • A parameter named like a header port in a spec that also declares a module var of that name is not judged here (no corpus spec has one).
  • A return <expr>; written in a void fn (e.g. return undefined;) still becomes <fn> = <expr>;: that is the explicit-return path, not the tail rule, and is out of scope (17 files on master).
  • Red checks that are red on master too are listed in a comment with links.

Dmitrii Fedorov (@dmitrii-f-t27)

…declared once (Closes gHashTag#5649)

A parameter of `fn on_comb` / `fn on_clock` named like a boilerplate
header port was declared a second time, and iverilog refused the module
("'clk' has already been declared in this scope"). Five corpus specs on
master 295b2c5: d_bank13_test, d_direct, led_simple_test, led_test_inv
(`on_comb(clk: bool)`) and dsp_probe (`on_clock(cfgmclk, rst_n, en)`).

- The decision is specs/compiler/verilog_entry_port_collision.t27
  (7 tests), lowered by `t27c gen-rust` to bootstrap/gen/rust/compiler/
  and mounted by #[path]. A 1-bit unsigned parameter IS the boilerplate
  port: the header declares it once and every use keeps the name. A wider
  or signed one refuses the entry point, in the file and on stderr, as
  W699 does for an unsized parameter; it is never narrowed.
- compiler.rs prints it. The W649 `declares` closure moves up so the
  parameter loop can read it. FROZEN_HASH updated.
- Verilog output changed for 5 of 2227 .t27 files, exactly those five; all
  five now elaborate under iverilog -g2012 (each failed before). Resealed
  gen_hash_verilog for the two sealed ones (dsp_probe, led_simple_test)
  and sealed the new spec, with this tree's t27c.
- bootstrap/tests/verilog_entry_port_collision.rs: 7 tests, including the
  five corpus specs, a refused u8 `clk`, an unchanged non-colliding
  header, and the generated copy matching gen-rust.
…ent; both rules within Only t27 (Closes gHashTag#5651, Closes gHashTag#5649)

gHashTag#5651: gen_verilog_fn_body lowered the final bare expression of a body to
`<fn> = <expr>;` (t27#1948) unless the return type was spelled "void".
A fn with no return type is a `task` (W705), so `fn reset() { ...; tick(); }`
ended in `reset = tick(1'b0);`, and gen_verilog_clocked_fn never set the
return type it was judged by, so a void `on_clock` ended in `on_clock <= f(d);`.

- The decision is specs/compiler/verilog_void_tail.t27 (4 tests), lowered
  by `t27c gen-rust` to bootstrap/gen/rust/compiler/ and mounted by #[path].
  Both tail sites (the bare tail and the final if/else) read it, so they
  cannot disagree. on_clock sets its own return type and clears it on exit.
- Verilog output changed for 46 of 2227 .t27 files, 88 lines, each exactly
  `<name> = <expr>;` -> `<expr>;` inside a task. iverilog -g2012 accepts
  23 of them now (0 before): the 22 specs/fpga/testbench/*_tb.t27 and
  specs/tri/t27b/conformance/value_ignored.t27; no file regressed.

gHashTag#5649 rework for the Only-t27 gate (owner rules 2026-10-05 and 2026-10-09):
- bootstrap/tests/verilog_entry_port_collision.rs is removed: a new
  hand-written .rs is denied. The rule stays in
  specs/compiler/verilog_entry_port_collision.t27 and its tests; the output
  is pinned by the gen_hash_verilog seals of the specs it changes.
- compiler.rs reads the rule through one closure; the W699 refusal comment
  names the collision instead of "no derivable width". compiler.rs is +25/-11,
  FROZEN_HASH updated, paid for by deleting scripts/gen_w369.py (a one-shot
  wave-369 generator nothing runs), so hand-written foreign lines shrink.

gHashTag#5650's shape gets a fixture, specs/compiler/verilog_on_comb_zero_arg.t27,
whose seal pins `assign result = on_comb(1'b0);` (sealed in a later commit).
's fixture with this tree's t27c (Closes gHashTag#5650, Closes gHashTag#5649, Closes gHashTag#5651)

Sealed with t27c built from f226c8d (this branch merged with master d01d772).

- 44 sealed specs change Verilog output (5 for gHashTag#5649, 46 files / 41 sealed
  specs for gHashTag#5651, minus the unsealed ones). Each verified MATCH with a
  master-tip t27c before, and only gen_hash_verilog moves now. Forced seals
  keep the same failing tests; the primary seal files move to schema 2 as
  `seal --save` writes it. Every one verifies MATCH with this tree's t27c.
- New: compiler_VerilogVoidTail.json, compiler_VerilogOnCombZeroArg.json;
  compiler_VerilogEntryPortCollision.json resealed. gHashTag#5650's fixture pins
  `input _unused;` and `assign result = on_comb(1'b0);` (fixed by gHashTag#5955);
  d_full_path / d_static_one cannot be sealed: module trinity_top already
  owns openxc7-synth_trinity_top.json (gHashTag#8540).
- docs/reports/t27b_expectations.json: specs/compiler/
  verilog_entry_port_collision.t27 is `pass`, as the t27b native ratchet
  measured it on this PR (run 38092422487: UNLISTED, reference pass,
  t27b pass).
@dmitrii-f-t27 dmitrii-f-t27 changed the title gen-verilog: an entry parameter named clk, rst_n or en is that port, declared once (Closes #5649) gen-verilog: an entry parameter named clk/rst_n/en is declared once; a void body's last call stays a statement (Closes #5649, Closes #5650, Closes #5651) Oct 10, 2026
…oses gHashTag#5650, Closes gHashTag#5651)

The t27b native ratchet on aca8a31 (run 38094798157) reported both
UNLISTED with the reference passing and t27b passing:
specs/compiler/verilog_on_comb_zero_arg.t27 and
specs/compiler/verilog_void_tail.t27. Listed in sorted order.
@dmitrii-f-t27

dmitrii-f-t27 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor Author

Updated 2026-10-11 for head f042d0009 (the PR was in conflict with master; resolved by a merge commit, no rebase, no force-push).

What changed since ba9cba6a0

Local checks with this tree's t27c: test-report on the three specs: 7/7, 4/4, 1/1, 0 vacuous; gen-rust output is byte-identical to the two committed files; cargo test --release for verilog_struct_entry_ports 9, verilog_branch_context 6, on_clock_plain_assign 2, clocked_counter 1, duplicate_declarations 13, behavior_sva_v2 32: all ok.

CI on head f042d0009: 35 green, 7 red. The four required checks pass (validate, check-linked-issue, parse-ratchet, own-language). Each red check gives the same findings on master:

check this PR master
spec-guards run: 1 stale, queen_QueenHolds.json gen_hash_rust 5e5493cab: the same
coverage run: queen_QueenHolds.json gen-drift 5e5493cab: the same
Corpus ratchet run: types ledger 86 vs 89, NEW Entry, Inputs, SkillMeta 5e5493cab: the same
t27b-native-ratchet run: 17 UNLISTED, none of them this PR's 5e5493cab: the same 17
cli-tri run: census quiet 185 -> 188, shell 305 -> 306 a31427373 push: the same numbers; this PR does not touch .github/ or cli/
fpga-lint run: 3/54 modules 9b4338a67 push: 3/54 modules
fpga-conformance run: 206 vs baseline 205, NEW die_probe, eth_reply, eye_isi, line_bounce, ro_race 9b4338a67 push: the same

emit-bitexact, duplicate-bodies and Verilog widths, red on the old head, are green now.

Status: mergeable at f042d0009, required checks green. If master moves into conflict again, I will merge master again and reseal with this tree's t27c.

Dmitrii Fedorov (@dmitrii-f-t27)

This was referenced Oct 10, 2026
This was referenced Oct 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant