Skip to content

wave-28: t27c gen-verilog const-array aggregate initializer no longer emits unparseable localparam comment-only initializer (Closes #743)#744

Merged
gHashTag merged 1 commit into
masterfrom
wave-28/codegen-verilog-const-array
May 23, 2026
Merged

wave-28: t27c gen-verilog const-array aggregate initializer no longer emits unparseable localparam comment-only initializer (Closes #743)#744
gHashTag merged 1 commit into
masterfrom
wave-28/codegen-verilog-const-array

Conversation

@gHashTag
Copy link
Copy Markdown
Owner

@gHashTag gHashTag commented May 22, 2026

Summary

R-CA-1 fix in t27c VerilogCodegen.

Before this PR, const declarations whose initializer was an array literal or struct literal emitted unparseable Verilog of the form:

localparam [31:0] mac_units = /* array ... */;

Yosys/iverilog reject this with syntax error, unexpected ';'. This was the root cause of the fpga-synthesis CI failure on PR #742.

This PR updates VerilogCodegen::gen_verilog_const (in both the is_array branch and the scalar fall-through branch) to detect ExprArrayLiteral and ExprStructLit children, and emit a placeholder zero value with an explanatory TODO comment:

localparam [31:0] mac_units = 0 /* TODO: array literal initializer not yet lowered to Verilog */;

The placeholder is valid Verilog and unblocks the synthesis frontend on mac.v. A future wave will implement proper lowering of aggregate initializers.

Before / After on line 21 of mac.v

Before:

localparam [31:0] mac_units = /* array [MACUnit{.accumulator=0, ...}] */;

After:

localparam [31:0] mac_units = 0 /* TODO: array literal initializer not yet lowered to Verilog */;

Tests

Two new #[test]s in bootstrap/tests/verilog_const_array.rs:

  1. r_ca_1_emitter_does_not_emit_comment_only_initializer — synthetic spec asserting no localparam ... = /* ... */; pattern is emitted.
  2. r_ca_1_emitter_on_real_mac_spec — regression test that runs the emitter on specs/fpga/mac.t27 and asserts the same.

Local result: 2 passed; 0 failed. Wave 27 tests (verilog_r_si_1) also still pass post-rebase: 2 passed; 0 failed.

CI delta vs Wave-27 baseline (HONEST)

Confirmed by CI on commit 3783ad9: mac.v now parses through Yosys successfully — the synthesis log shows "Generating RTLIL representation for module ZeroDSP_MAC ... Successfully finished Verilog frontend" — the R-CA-1 fix worked end-to-end on the real spec.

However fpga-synthesis is still red because Yosys then fails on uart.v:213 with syntax error, unexpected TOK_INITIAL. Root cause: the emitter places integer _bench_cycles = 0; declarations inside initial begin ... end blocks, which Verilog-2005 forbids (variable declarations must be at module scope). This is a separate emitter bug (call it R-VD-1: variable-declaration-inside-initial-block) distinct from R-CA-1, exposed because the R-CA-1 fix unblocked mac.v and let synthesis proceed to the next file.

R-VD-1 is out of scope for this PR (Wave 28 was scoped to R-CA-1 only) and will be the target of a follow-up wave.

Out of scope (explicit, honest)

  • R-VD-1 (newly exposed by this PR): integer X = 0; inside initial begin block in uart.v:213 and analogous bench blocks elsewhere. Separate emitter fix.
  • fpga-formal: pip install sby no matching distribution (infrastructure).
  • fpga-synthesis-arty: error: unexpected argument '--board' found (CLI drift, infrastructure).
  • Proper lowering of aggregate initializers: the 0 + TODO placeholder preserves symbol existence and makes the gap explicit. Real lowering needs an HIR-level refactor with consistent flattened-name generation (e.g. cells[i].accumulator -> cells_i_accumulator).

Constitution checklist

Closes #743

… emits unparseable localparam comment-only initializer (Closes #743)

R-CA-1 fix: const declarations whose initializer is an array literal
or struct literal previously emitted Verilog of the form

    localparam [31:0] mac_units = /* array ... */;

which is unparseable by Yosys/iverilog (syntax error, unexpected ';').
This was the root cause of the fpga-synthesis CI failure on PR #742.

This wave updates VerilogCodegen::gen_verilog_const in both the
is_array and the scalar fall-through branches to detect
NodeKind::ExprArrayLiteral and NodeKind::ExprStructLit children and
emit a placeholder zero value with an explanatory TODO comment:

    localparam [31:0] mac_units = 0 /* TODO: array literal initializer
                                    not yet lowered to Verilog */;

The placeholder is valid Verilog and unblocks the synthesis frontend.
A future wave will implement proper lowering of aggregate initializers.

Constitution checklist:
 L1 TRACEABILITY: Closes #743
 L2 GENERATION:   edits only in bootstrap/, docs/NOW.md, new bootstrap/tests/
 L3 ASCII:        ASCII source, English doc-comments
 L4 TESTS:        2 new #[test]s in bootstrap/tests/verilog_const_array.rs,
                  both passing locally (2 passed; 0 failed)
 L5 TRINITY:      numeric kernel untouched; phi^2 + 1/phi^2 = 3 preserved
 L6 SPEC/KERNEL:  zero changes under specs/, coq/, trios-coq/, proofs/,
                  conformance/, architecture/, rings/, gen/
 L7 NO BASH:      no new *.sh files

Files:
 - bootstrap/src/compiler.rs              (+50 / -2)
 - bootstrap/tests/verilog_const_array.rs (+173 new)
 - docs/NOW.md                            (+16 wave-28 section)

Closes #743
@gHashTag gHashTag force-pushed the wave-28/codegen-verilog-const-array branch from 2426e32 to 3783ad9 Compare May 22, 2026 17:19
@github-actions
Copy link
Copy Markdown

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions
Copy link
Copy Markdown

PR Dashboard

Generated at: 2026-05-22 17:20:05 UTC

Summary

Status Count
Total Open PRs 22
PRs with Failing Checks 20
PRs with All Checks Green 2
READY 1
FAILING 20
PENDING 0

@gHashTag gHashTag merged commit 67db742 into master May 23, 2026
22 of 25 checks passed
@gHashTag gHashTag deleted the wave-28/codegen-verilog-const-array branch May 23, 2026 04:37
gHashTag pushed a commit that referenced this pull request May 23, 2026
…begin (R-VD-1 fix) (Closes #745)

R-VD-1 fix: Verilog-2005 forbids variable declarations inside procedural
blocks. The previous emitter wrote `integer _bench_cycles = 0;` between
`initial begin` and `end`, which Yosys/iverilog reject with
"syntax error, unexpected TOK_INITIAL". This was observed on uart.v:213
in the CI log of PR #744 (Wave 28 R-CA-1 fix unblocked mac.v and exposed
this next downstream emitter bug).

This wave updates the bench-section loop in VerilogCodegen::gen_verilog
(bootstrap/src/compiler.rs around line 3721) to:

 1. Emit a module-scope `// synthesis translate_off ... translate_on`
    band containing one `integer _bench_<sanitized_name>_cycles = 0;`
    declaration per bench, BEFORE any `initial begin`.
 2. Inside each `initial begin ... end` block, only assign and use the
    pre-declared counter; never re-declare it. Each counter gets a
    unique per-bench sanitized name to avoid collisions when a module
    contains multiple benches.

Before:
    initial begin : uart_tx_ready_latency_bench // synthesis translate_off
        $display("[BENCH] uart_tx_ready_latency : starting");
        integer _bench_cycles = 0;          // <-- R-VD-1 violation
        ...
    end

After:
    // synthesis translate_off
    integer _bench_uart_tx_ready_latency_cycles = 0;
    integer _bench_uart_rx_ready_latency_cycles = 0;
    integer _bench_uart_reset_latency_cycles    = 0;
    // synthesis translate_on
    initial begin : uart_tx_ready_latency_bench // synthesis translate_off
        $display("[BENCH] uart_tx_ready_latency : starting");
        _bench_uart_tx_ready_latency_cycles = 0;
        ...
    end

Constitution checklist:
 L1 TRACEABILITY: Closes #745
 L2 GENERATION:   edits only in bootstrap/, docs/NOW.md, new bootstrap/tests/
 L3 ASCII:        ASCII source, English doc-comments
 L4 TESTS:        2 new #[test]s in bootstrap/tests/verilog_initial_decl.rs,
                  both passing locally (2 passed; 0 failed). Wave 27
                  regression test still green (2 passed; 0 failed).
 L5 TRINITY:      numeric kernel untouched; phi^2 + 1/phi^2 = 3 preserved
 L6 SPEC/KERNEL:  zero changes under specs/, coq/, trios-coq/, proofs/,
                  conformance/, architecture/, rings/, gen/
 L7 NO BASH:      no new *.sh files

Files:
 - bootstrap/src/compiler.rs                 (single hunk, bench section)
 - bootstrap/tests/verilog_initial_decl.rs   (+225 new)
 - docs/NOW.md                               (+wave-29 section, date bumped)

Closes #745
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.

wave-28: t27c gen-verilog const-array aggregate initializer produces unparseable Verilog (R-CA-1)

1 participant