From b12e8bd969edde1b35503306e38b8233e5656011 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 01:00:27 +0000 Subject: [PATCH 01/56] =?UTF-8?q?v4=20T-4.9:=20model=20extdeps/languages/v?= =?UTF-8?q?erilog.dag=20=E2=80=94=20HW=20concurrency=20as=205=20behaviors?= =?UTF-8?q?=20(IN-B=20probe=20PASS)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IN-B probe RESULT: PASS β€” Verilog hardware concurrency models cleanly under the existing five L1 behaviors with NO 6th `Concurrent` behavior and NO core/pipeline change. The probe surfaces the structurally- correct intra-vs-cross-program partition: intra-program HW concurrency (parallel always-blocks / continuous assigns within one module) is the Conj-of-parallel-siblings + Bind-chain-within-always shape, with per- language effect-typing intrinsic to the wire/reg/vector signal type; cross-program coordination (Endpoint/DeploymentUnit/messaging) is a distinct concern owned by extdeps/coordination.dag (T-4.8). Declares closed-Disj coproducts (each with full 5-pattern Practice-4 ledger β€” Fact-placement / Variant-is-data / Algebraic-form / Dimensional / Parameterized-family-Practice-7 per modeling-discipline.md Β§4): PortDirection, NetType, VariableType, EdgeTrigger, ProceduralAssignKind, PackingShape, ModuleItem. Conj records (no ledger): VectorRange (🟑 scaffold), NetDeclaration, VariableDeclaration, PortDeclaration, ParameterDeclaration, SensitivityItem, ContinuousAssign, AlwaysBlock, InitialBlock, PortConnection, ModuleInstance, VerilogModule, VerilogCost (🟑 scaffold). DEFERRED with named-owner+trigger (do not author, do not improvise): - emit/parse ops ride D1 Outcome (Produced{value:T}|Rejected{...}) when ratified in std/diagnostic.dag (v4 value-or-Diagnostic STOP surfaced by T-4.6 keen-wren-419). - Bit-vector inhabitance (Semiring> / OrderedRing>) rides pending D2 instance-value form (PR #3171's worker pushback precedent). - Expression sub-grammar (RHS of assign, procedural-statement bodies, control-flow conditions) ride the T-4 LanguageModel bundle; verbatim String lexemes carry the textual surface in the interim (spice.dag SpiceValue.lexeme precedent). Scaffold-header Consumes line preserved verbatim with surfaced staleness (primitive.dag deleted PR #3152; coordination.dag is an unfilled scaffold modeling cross-program coordination β€” a different concern from intra- program HW concurrency). The systemic per-file Consumes reconciliation is pending operator ratification (T-4 mgr synthesis msg_1fddb75c). Verification: `v2-compiler compile --source-root src/v4 --target dag` = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 918 ++++++++++++++++++++++++++- 1 file changed, 914 insertions(+), 4 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 9ebf5f7720d..1f093fcef5c 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -29,9 +29,919 @@ // - std/node.dag, std/algebra.dag, std/primitive.dag // - extdeps/coordination.dag (concurrency via effect-typed Bind β€” IN-B) // -// Status: scaffold β€” fill per TASKS.md T-4.9 -// Brief: see BRIEF_TEMPLATE.md; this file's I/O contract is the immutable -// contract for the worker. Splitting this file requires explicit operator -// ratification (substrate extension = stop signal). +// Status: T-4.9 modeled 2026-05-16 (bright-crane-527). IN-B probe RESULT: +// PASS β€” Verilog hardware concurrency models cleanly under the existing +// five L1 behaviors with NO 6th `Concurrent` behavior and NO core/ +// pipeline change (see modeling notes "IN-B PROBE FINDING"). The probe +// surfaces the structurally-correct intra-vs-cross-program partition: +// hardware concurrency (parallel `always`-blocks / continuous assigns +// within ONE module) is the Conj-of-parallel-siblings + Bind-chain +// shape, with per-language effect-typing intrinsic to the wire/reg/ +// vector signal type β€” exactly the THESIS:401 IN-B disposition. +// The scaffold-header `Consumes` line is preserved verbatim and carries +// two known stale citations: (1) `std/primitive.dag` was deleted by +// PR #3152 (STRUCTURE.md Β§"Scalar/numeric concept decomposition"); the +// six concept-anchored scalar files are the replacement, and `Symbol` +// is now substrate-ambient at std/node.dag (K-1). (2) `extdeps/ +// coordination.dag` is an unfilled scaffold (T-4.8) and its modeled +// scope is CROSS-PROGRAM coordination (Endpoint / DeploymentUnit / +// sync-async-stream-pubsub semantics, v4-close-interrogation.md Β§16) β€” +// a different concern from intra-program hardware concurrency, which +// this file demonstrates needs no cross-program coordination carrier +// at all. Both stale citations are surfaced, not edited: the contract +// lines are immutable, and the per-file Consumes correction is +// pending the systemic operator scaffold-Consumes reconciliation +// (T-4 mgr synthesis msg_1fddb75c) β€” uniform with ptx #3170, spice +// #3168, and llvm_ir #3171. The body's `import` reflects what this +// file actually uses. Splitting this file requires explicit operator +// ratification (substrate extension = stop signal). + module v4.extdeps.languages.verilog + + +// std/node.dag is imported: it makes the K-1 opaque `Symbol` (the +// name-reference identity used pervasively in the Verilog grammar β€” +// module names, port names, signal names, instance names) resolvable +// through this file's import closure. std/algebra.dag is NOT imported: +// this file's scaffold-declared `Inhabitance: bit-vectors per +// std/algebra.dag` is DEFERRED to the operator-pending D2 STOP (see the +// Inhabitance section in modeling notes); declaring per-target +// OrderedRing/Semiring instance-values now would be the per-file +// `` improvisation D2 forbids (#3171 worker +// vivid-crab-154 / snappy-badger-570 held precedent). std/diagnostic.dag +// is NOT imported: this declarative LanguageModel declares no +// parse/emit body β€” those ride the operator-pending D1 Outcome +// carrier (`Produced{value:T} | Rejected{diagnostic:Diagnostic}`) when +// ratified in std/diagnostic.dag; improvising a per-file Result shape +// now is exactly the v4 value-or-Diagnostic STOP first surfaced by +// T-4.6 (keen-wren-419). `Int`, `Bool`, `String`, `List` are +// kernel-ambient per STRUCTURE.md Β§"Kernel-ambient types" β€” no import. +import v4.std.node { Symbol } + + +// ───────────────────────────────────────────────────────────────────── +// Modeling notes (read before validating against the anchor) +// +// SPEC, NOT LIBRARY (M3 / L-2). The anchor is IEEE 1364-2005 β€” the +// language specification. The set of synthesizable subsets used by any +// particular tool (Xilinx XST, Synopsys Design Compiler, Yosys), the +// vendor-specific timing libraries, and the simulation-only constructs +// (`$display`, `$monitor`, file I/O system tasks) are NOT modeled: an +// invocation of `$display` is just a system-task call (a Symbol-named +// call site); modeling the system-task universe is infinite and the +// wrong layer. SystemVerilog (IEEE 1800) extensions (interfaces, +// always_comb / always_ff / always_latch sugar, packed structs, classes) +// are scope-negative for this file β€” they are a later language model. +// The 1364-2005 surface is the closed L-2 fidelity authority. +// +// DECLARATIVE MODEL, NOT A RECOGNIZER (T-4 authoring contract). This +// file is the grammar/type/semantics-skeleton as DATA. It declares no +// `parse`/`emit` procedure: those are the GENERIC walker (compiler +// 01_tokenize / 02_parse / 05_emit, B2-OMNI) reading this model. The +// expression sub-grammar (operators, function calls, concatenation, +// system functions) is owned by the bidirectional `LanguageModel` +// substrate that the T-4 bundle introduces β€” when that shape lands, +// the Verilog statement/expression productions slot into the Verilog +// `LanguageModel` instance; the closed classifiers + Conj records +// declared here are the irreducible structural carrier that does not +// prejudge that shape. Lexical-surface bodies of always-blocks, +// continuous-assign right-hand sides, and control-flow conditions are +// carried as verbatim `String` lexemes at this phase (the spice.dag +// `SpiceValue.lexeme` precedent β€” `parse ∘ emit` is identity on the +// textual surface; the sub-grammar interprets the lexeme when the +// expression model lands). +// +// IN-B PROBE FINDING (the deliverable β€” the STOP discipline is the +// product). Verilog HW concurrency models as a plain `LanguageModel` +// over the closed 5 L1 behaviors with NO 6th `Concurrent` / `Parallel` +// behavior and NO core/pipeline change. The probe's stress axis β€” the +// concurrent semantics of `always` / continuous-assign / module +// instantiation β€” resolves into ORDINARY Node structure, surfacing +// the right intra-vs-cross-program partition along the way. The +// mapping, member-by-member: +// +// - MODULE BODY ↦ Conj of parallel siblings. +// A Verilog `module` body is a flat list of items +// (`ModuleItem` β€” continuous-assigns, always-blocks, instances, +// declarations). Concurrent execution across those siblings is +// STRUCTURAL: each item is a child of the module-body Conj, and +// concurrent semantics is the SAME shape as a Conj of submodule +// instantiations (which every C / Rust / Python module already +// models as Conj children). The simulator/synthesizer schedule +// (event-driven evaluation) is the mechanical realization of the +// dependency graph (THESIS:18 "parallelism is the default β€” +// independence is visible in the structure"); it is NOT a +// separate behavior. Tempting alternative: a `Concurrent` behavior +// wrapping each module item. REJECTED β€” it would parallel- +// represent what the Conj's children already say +// (feedback_no_annotations: a property structurally visible is +// never duplicated as a marker). This is precisely the IN-B win. +// +// - CONTINUOUS ASSIGN (`assign net = expr;`) ↦ Transform. +// A continuous assignment is a function from the right-hand-side +// expression's input signals to the left-hand-side net β€” exactly +// the Transform behavior (function application, node.dag:209 +// "Transform=application"). The "continuous" aspect β€” re-evaluate +// whenever an input changes β€” is the SCHEDULE of the surrounding +// dataflow graph, not a property of the Transform itself. +// +// - ALWAYS BLOCK ↦ Loop (one step) + boundary-driven iteration. +// Per node.dag A2 footnote (genuine unboundedness β€” "servers / +// streams / REPLs is a TERMINATING step iterated by the +// coordination-boundary driver β€” never an unbounded `.dag` loop"), +// each `always @(...)` block's ONE TRIGGER is a BOUNDED step +// (one event-fire: read inputs, sequence the statements, write +// outputs). The eternal-iteration ("forever, every clock edge") +// lives at the simulator/synthesizer's coordination boundary; the +// `.dag` model carries the BOUNDED step, not the unbounded +// iteration. The trigger-event-list (`SensitivityItem`s) is the +// bound that gates the next iteration. Tempting alternative: an +// unbounded `Eternal` / `Concurrent` behavior. REJECTED β€” the A2 +// bounded-Loop discipline is the existing surface for this exact +// pattern. +// +// - PROCEDURAL STATEMENT SEQUENCE (within `begin ... end`) ↦ Bind. +// The statements inside an always-block (or initial-block) form +// a sequential composition β€” exactly the Bind behavior +// (node.dag:209 "Bind=let"). Blocking (`=`) vs non-blocking +// (`<=`) assignment is a SCHEDULING discriminator on the Bind's +// write semantics (blocking commits before the next statement; +// non-blocking schedules the write for the end of the time-step), +// not a new behavior. The `ProceduralAssignKind` enum below +// carries that discriminator as data on the assignment statement. +// +// - IF / CASE ↦ Branch. +// Verilog `if ... else` and `case ... endcase` are guarded sums +// over a discriminator β€” exactly the Branch behavior +// (node.dag:209 "Branch=sums"). The case-item ordering and the +// full-case / parallel-case synthesis directives are emission- +// time properties (the synthesizer's concern); the structural +// surface is the Branch. +// +// - SIGNAL DECLARATION (Wire / Reg / Vector) ↦ effect-typed value. +// A Verilog `wire`, `reg`, or `wire [7:0]` is a TYPED signal +// carrier; the type IS the effect-typing locus per the +// v4-close-interrogation Β§16 IN-B disposition ("effects intrinsic +// to the type signature, NOT an annotation layer"). A continuous- +// assign Transform's domain/codomain types name Wire/Reg with +// packing, and the typing is what constrains valid composition +// (a `reg`-typed driver can drive an `output reg` port; a +// procedural assignment is only legal to a `reg`-typed +// destination; etc.). This file's `NetDeclaration` / +// `VariableDeclaration` / `PortDeclaration` records are the +// effect-typed carriers; there is no separate Verilog-effect- +// annotation layer. +// +// - MODULE INSTANCE ↦ structural Conj child. +// `ModuleName instance_name (.port(signal), ...);` is a child +// Node in the parent module-body Conj β€” the same shape as a +// submodule reference in any other LanguageModel. Concurrent +// execution of the instance alongside its sibling items is the +// same Conj-of-parallel-siblings shape as multiple always-blocks +// (above); no new behavior. +// +// INTRA-PROGRAM vs CROSS-PROGRAM EFFECT-TYPING (the partition the +// probe surfaces). The scaffold-header `Consumes` line citing +// `extdeps/coordination.dag` for "concurrency via effect-typed Bind +// β€” IN-B" was a SCAFFOLD-AUTHOR ANTICIPATION that lumped all +// concurrency under one carrier. The probe surfaces the structurally +// correct partition: (a) INTRA-program concurrency (multiple +// `always`-blocks within one Verilog module sharing signal nets) is +// what this file models β€” the effect-typing carriers are the +// signal-type declarations (`NetType` / `VariableType` / `PackingShape`) +// declared HERE, in this language file; (b) CROSS-program coordination +// (one program's output deployed to host A, another to host B, +// communicating via Endpoint / DeploymentUnit / sync-async-stream- +// pubsub) is what `extdeps/coordination.dag` (T-4.8) models β€” a +// distinct concern with a distinct anchor (Wikipedia Distributed +// computing + Messaging pattern). The IN-B principle "effect-typed +// Bind composition, no 6th behavior" holds in BOTH partitions, with +// the effect-typing carriers in their respective per-language / +// per-coordination home files (P2 single-authority). This is the +// per-language effect-typing finding the probe was authored to +// surface β€” and it surfaces here on the SUCCESS side, not the STOP +// side. +// +// INHABITANCE (DEFERRED to D2). The scaffold-declared "Inhabitance: +// bit-vectors (wire/reg [N:0]) per std/algebra.dag" is DEFERRED to +// the operator-pending D2 STOP. Conceptually, an N-bit unsigned +// signal grounds in `Semiring>` (or `OrderedRing>` +// for signed-as-twos-complement reg/integer arithmetic) β€” but +// declaring a `data verilog_wire_n_semiring: Semiring> = …` +// instance-value at this layer would be the per-file +// `` improvisation D2 was authored to hold +// (PR #3171's hold precedent). The instance-value form lands when +// std/integer.dag / std/logic.dag inhabitance walks land plus the +// ratified D2 instance-value shape; the algebra import + the +// instance-value declarations are added in ONE pass, not improvised +// per language. +// +// PROBE LIMITS (honest framing β€” what this file does NOT validate). +// The IN-B finding covers the STRUCTURAL fit of Verilog HW concurrency +// to the 5 L1 behaviors. It does NOT validate: +// - that a synthesizer actually produces gates from `emit`'s output +// (the "clear win" in the header β€” that requires invoking a +// synthesizer process, an `extdeps/process.dag` consumer +// boundary, not modeled here). +// - the expression sub-grammar of `assign net = expr;` right-hand +// sides and procedural statement bodies (verbatim lexemes at +// this phase; the T-4 LanguageModel bundle owns the recursive +// expression productions when it lands). +// - SystemVerilog (IEEE 1800) extensions (`always_comb` / +// `always_ff` / `always_latch` sugar, interfaces, classes, +// packed structs) β€” a later language-version model edits this +// file (under the L-2 pin discipline) when it lands. +// - Simulator-only / testbench constructs (`initial` with +// `$display`, `$finish`, file I/O system tasks, `force` / +// `release`, fork-join, `wait`) β€” `initial` is admitted as a +// `ModuleItem` variant for the once-only-driven case; the +// `$task` universe is the system-task call site, not the +// concurrency primitive. +// - Timing-checks (`$setup`, `$hold`, `specify` blocks) β€” a +// separate timing-annotation layer (SDF β€” Standard Delay +// Format), out of scope for this language model. +// +// PRACTICE-4 LEDGER DISCIPLINE. Every closed-Disj coproduct below +// carries the full 🟒/🟑/πŸ”΄ classification + all FIVE patterns +// attempted (Fact-placement / Variant-is-data / Algebraic-form / +// Dimensional / Parameterized-family-Practice-7) per modeling- +// discipline.md Β§4 (operator-ratified binding 2026-05-15, gate (b); +// PR #3163 made the 4-pattern miss the proof case β€” do not omit +// Practice-7). Conj records carry no ledger (only coproducts +// dissolve); scaffold-residual raw-Int fields (VectorRange, VerilogCost) +// carry a 🟑 bridge note mirroring the std/diagnostic.dag / +// ptx Dim3 precedent. + + +// ───────────────────────────────────────────────────────────────────── +// PortDirection β€” the closed Verilog port-direction classifier +// (IEEE 1364-2005 Β§12.3.2). A module's port is exactly one of three +// directions. +// +// - Input β€” `input` driven by the instantiating context, read +// inside this module +// - Output β€” `output` driven inside this module, read by the +// instantiating context +// - Inout β€” `inout` bidirectional (tri-state nets only) +// +// CLOSED (C1 stop-signal). A fourth direction is an edit to THIS +// declaration under the L-2 pin discipline (IEEE 1364-2005 has fixed +// three directions; SystemVerilog adds `ref` β€” a future language- +// version model would EDIT this enum explicitly). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every port consumer (instantiation +// legality, emission of the `input`/`output`/`inout` keyword, +// reverse-flow check) reads the direction tag uniformly; +// shared classifier, not a per-consumer scattered fact. +// 2. Variant-is-data β€” FAILS: a `{ name: Symbol }` proxy reopens +// the readable-string heuristic surface K-1 forecloses (a +// `match name { "input" => … }` smell). The enum IS the +// faithful form (algebra.dag:332 `Ordering` precedent). +// 3. Algebraic form β€” N/A by construction: the three port +// directions are the Verilog spec's primitive port-flow +// taxonomy; they do not trace to a richer std/ algebraic +// structure (no `BoundedLattice` with Inout = top β€” +// that would be a parallel representation of "Inout admits +// both directions", a property derived FROM the three tags). +// 4. Dimensional β€” FAILS: a port has EXACTLY ONE direction; +// `input output foo` is a syntax error in Verilog itself. +// Mutually-exclusive alternatives, not simultaneous coordinates. +// 5. Parameterized family β€” FAILS: the three are structurally +// distinct flow-roles (consumer / producer / bidirectional) β€” +// NOT one generic `F` / projection over a separately- +// declared source set (Practice 7). They are the IEEE 1364-2005 +// spec's irreducible port-flow partition. +// Terminal: the closed three-way port-flow classifier of the +// IEEE 1364-2005 spec; a fourth direction is the C1 stop-signal. +type PortDirection + = Input + | Output + | Inout + + +// ───────────────────────────────────────────────────────────────────── +// NetType β€” the closed Verilog net-type classifier (IEEE 1364-2005 +// Β§3.7.1, Β§5.6). A net carries a value continuously driven by one or +// more drivers; the net-type fixes the resolution function and the +// default value when undriven. +// +// - Wire β€” `wire` standard net; resolves to X if multiply +// driven with conflicting values +// - Wand β€” `wand` wired-AND resolution +// - Wor β€” `wor` wired-OR resolution +// - Tri β€” `tri` identical to `wire` semantically; +// designer-intent marker for tri-state nets +// - Tri0 β€” `tri0` pull-down (resolves to 0 if undriven) +// - Tri1 β€” `tri1` pull-up (resolves to 1 if undriven) +// - TriReg β€” `trireg` stores last driven value (capacitive) +// - Supply0 β€” `supply0` constant 0 power-rail net +// - Supply1 β€” `supply1` constant 1 power-rail net +// - Uwire β€” `uwire` unresolved wire β€” exactly one driver +// required (IEEE 1364-2005 Β§5.6.6) +// +// CLOSED (C1 stop-signal). A new net-type is an edit to THIS +// declaration under the L-2 pin discipline; the IEEE 1364-2005 Β§3.7.1 +// table is the authority. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every net-declaration emitter and +// every driver-resolution consumer reads the net-type tag +// uniformly; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: a `{ keyword: Symbol }` proxy +// reopens the readable-string heuristic surface K-1 forecloses +// (a `match keyword { "wire" => … }` smell); a +// `{ resolution_kind: Int }` proxy replaces a closed +// 10-valued exhaustive sum with an unbounded Int β€” both +// violate P2 + M4 (algebra.dag:332 `Ordering` precedent). +// 3. Algebraic form β€” N/A by construction: the ten net-types are +// the IEEE 1364-2005 spec's primitive resolution-function set; +// they do not trace to a richer std/ algebraic structure (one +// could attempt a `Lattice` for the wand/wor +// sublattice, but that would be a parallel representation of +// the per-net-type resolution function, not a richer source). +// 4. Dimensional β€” FAILS: a net declaration carries EXACTLY ONE +// net-type; `wire wand x` is a syntax error in Verilog itself. +// Mutually-exclusive alternatives, not coordinates. +// 5. Parameterized family β€” FAILS: the ten are structurally +// distinct resolution / pull / supply / unresolved variants β€” +// NOT one generic `F` / projection over a separately- +// declared source set (Practice 7). They are the spec's +// irreducible net-type partition for IEEE 1364-2005. +// Terminal: the closed ten-way net-type classifier of the +// IEEE 1364-2005 spec. +type NetType + = Wire + | Wand + | Wor + | Tri + | Tri0 + | Tri1 + | TriReg + | Supply0 + | Supply1 + | Uwire + + +// ───────────────────────────────────────────────────────────────────── +// VariableType β€” the closed Verilog variable-type classifier +// (IEEE 1364-2005 Β§3.7.2, Β§5.7). A variable stores a value assigned by +// a procedural statement; the variable-type fixes the storage shape. +// +// - Reg β€” `reg` general-purpose variable (any width; +// the procedural-assignment destination) +// - Integer β€” `integer` 32-bit signed (host integer; the spec +// pins integer to >= 32 bits) +// - Real β€” `real` double-precision floating point (IEEE +// 754) +// - Time β€” `time` 64-bit unsigned (simulation-time +// carrier) +// - RealTime β€” `realtime` alias for `real`, designer-intent +// marker for simulation-time-valued +// reals (kept distinct at the syntactic +// surface per IEEE 1364-2005 Β§3.7.2) +// +// CLOSED (C1 stop-signal). A new variable-type is an edit to THIS +// declaration under the L-2 pin discipline (SystemVerilog adds +// `logic` / `bit` / typed enums β€” a future language-version model +// would EDIT this enum explicitly). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every variable-declaration emitter +// and every procedural-assignment legality check reads the +// variable-type tag uniformly; shared classifier, not +// scattered. +// 2. Variant-is-data β€” FAILS: a `{ keyword: Symbol }` proxy +// reopens the readable-string heuristic surface K-1 +// forecloses. The enum IS the faithful form (algebra.dag:332 +// `Ordering` precedent). +// 3. Algebraic form β€” PARTIAL: each variable-type grounds in a +// std/algebra structure (Regβ†’`Semiring>` or +// `OrderedRing>` per declared width; Integerβ†’ +// `OrderedRing>`; Real / RealTimeβ†’`ApproximateField`; +// Timeβ†’`Semiring>`). That grounding is INHABITANCE β€” +// owned by the inhabiting carrier file (std/integer.dag, +// std/float.dag) per P2, and DEFERRED to the operator-pending +// D2 STOP. The variable-type enum itself stays a closed +// classifier; the "type β†’ algebra" map IS the future +// inhabitance walk, not a richer std/ source to collapse this +// enum INTO. +// 4. Dimensional β€” FAILS: a variable declaration has EXACTLY ONE +// type; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the five are structurally +// distinct storage shapes (bit-vector / signed integer / +// floating-point / unsigned 64-bit time / aliased floating- +// point) β€” NOT one generic `F` / projection over a +// separately-declared source set (Practice 7). The closed set +// is the IEEE 1364-2005 variable-type partition. +// Terminal: the closed five-way variable-type classifier of the +// IEEE 1364-2005 spec. +type VariableType + = Reg + | Integer + | Real + | Time + | RealTime + + +// ───────────────────────────────────────────────────────────────────── +// EdgeTrigger β€” the closed Verilog sensitivity-event classifier +// (IEEE 1364-2005 Β§9.7.2). The trigger condition under which an +// always-block's body re-executes when an event-control signal +// transitions. +// +// - PosEdge β€” `posedge` rising edge: 0β†’1 transition (also +// Xβ†’1, Zβ†’1; the spec defines edge events +// on the implicit ordering 0 < X = Z < 1) +// - NegEdge β€” `negedge` falling edge: 1β†’0 transition +// - AnyChange β€” bare signal name in the event-list (no edge +// keyword): re-executes on ANY signal +// transition (level-sensitive) +// +// CLOSED (C1 stop-signal). A fourth edge type is an edit to THIS +// declaration under the L-2 pin discipline (the IEEE 1364-2005 Β§9.7.2 +// edge-event set is the authority). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every always-block's sensitivity- +// list consumer reads the trigger tag per item (a clock-edge +// always synthesizes to a flip-flop, a level-sensitive always +// to combinational or a latch); shared classifier, not +// scattered. +// 2. Variant-is-data β€” FAILS: a `{ direction: Int }` (+1/-1/0) +// proxy replaces a closed 3-valued exhaustive sum with an +// unbounded Int β€” violates P2 + M4 (algebra.dag:332 `Ordering` +// precedent, which uses the SAME shape). +// 3. Algebraic form β€” N/A by construction: the three triggers +// are the IEEE 1364-2005 spec's primitive event-control +// vocabulary; they do not trace to a richer std/ algebraic +// structure. +// 4. Dimensional β€” FAILS: a sensitivity-list item carries +// EXACTLY ONE trigger; `posedge negedge clk` is a syntax +// error. Mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the three are structurally +// distinct event-control shapes (rising-edge / falling-edge / +// level-sensitive) β€” NOT one generic `F` / projection over +// a separately-declared source set (Practice 7). +// Terminal: the closed three-way sensitivity-trigger classifier of +// the IEEE 1364-2005 spec. +type EdgeTrigger + = PosEdge + | NegEdge + | AnyChange + + +// ───────────────────────────────────────────────────────────────────── +// ProceduralAssignKind β€” the closed Verilog procedural-assignment +// scheduling discriminator (IEEE 1364-2005 Β§9.2). Inside an always- +// or initial-block, an assignment to a `reg`-typed destination is +// either BLOCKING or NON-BLOCKING; the discriminator selects when the +// write commits within the simulation time step. +// +// - Blocking β€” `=` commits BEFORE the next statement in the +// Bind chain (sequential-by-construction; +// the destination's new value is visible to +// the next statement) +// - NonBlocking β€” `<=` SCHEDULES the write for the end of the +// time step (the destination's old value is +// visible to every subsequent statement in +// the same time step; all non-blocking +// writes commit at once) +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two +// assignment-scheduling shapes; SystemVerilog's continuous-assign +// inside procedural blocks is a separate construct, not a third +// scheduling shape. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every procedural-assignment emitter +// AND the synthesis-time race-check ("non-blocking required +// for flip-flop inference") read the kind uniformly; shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: a `{ deferred: Bool }` proxy is a +// faithful 2-valued representation, but the LEXICAL SURFACE +// (`=` vs `<=`) is a closed two-keyword pair the parser / +// emitter must dispatch on; the named-enum is the M4-faithful +// form (closed sets are enums, not Bool proxies β€” the +// `Ordering`-as-Int rejection generalizes). +// 3. Algebraic form β€” N/A by construction: the two are the IEEE +// 1364-2005 spec's primitive scheduling-discriminator pair; +// they do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a procedural assignment carries +// EXACTLY ONE kind; `x = <= y` is a syntax error. +// Mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the two are structurally +// distinct scheduling shapes (immediate / deferred) β€” NOT one +// generic `F` / projection over a separately-declared +// source set (Practice 7). +// Terminal: the closed two-way procedural-assignment scheduling +// classifier of the IEEE 1364-2005 spec. +type ProceduralAssignKind + = Blocking + | NonBlocking + + +// ───────────────────────────────────────────────────────────────────── +// VectorRange β€” a packed bit-vector index range `[msb:lsb]` +// (IEEE 1364-2005 Β§3.10). Conj record (no Practice-4 ledger β€” only +// coproducts dissolve). +// +// - msb, lsb the most- / least-significant bit positions +// +// 🟑 SCAFFOLD (same bridge as std/diagnostic.dag's `Extent.ByteRange` +// and ptx Dim3 raw-Int axes). With only kernel-ambient `Int` +// available at the T-4.9 phase, `{ msb: Int, lsb: Int }` +// STRUCTURALLY ADMITS illegal states (negative indices; widths +// exceeding the IEEE 1364-2005 declared maximum; gaps; non- +// monotonic ranges β€” `[7:0]` is little-endian, `[0:7]` is big- +// endian, BOTH legal per spec, but `[7:7]` requires width=1 and +// `[8:0]` requires width=9). modeling-discipline.md Β§2 (illegal- +// states-unrepresentable) forbids admitting them; no bounded- +// Cardinality refinement substrate exists yet to exclude them. It +// is a TRACKED scaffold, declared with the three bridge properties +// (the precedent diagnostic.dag established 2026-05-15): +// (a) scaffold doc β€” THIS note; the carrier is provisional, not +// the terminal bounded-axis shape. +// (b) bounds on use β€” a producer MUST construct only valid +// Verilog vector ranges; until the substrate enforces it the +// invariant is producer-side, and a VectorRange violating it +// is a producer bug, not a legal value. +// (c) dissolution trigger β€” when std/cardinality.dag's refinement +// substrate lands (T-3, P4 decidability), `msb` / `lsb` become +// refined bounded-Int axes, and this scaffold dissolves. +type VectorRange { + msb: Int + lsb: Int +} + + +// ───────────────────────────────────────────────────────────────────── +// PackingShape β€” the closed Verilog signal packing classifier. A net +// or variable is either SCALAR (a single bit) or PACKED into a +// bit-vector indexed by a `VectorRange`. IEEE 1364-2005 Β§5.2. +// +// - Scalar β€” no range declared; the signal is a single bit +// - Packed β€” `[msb:lsb]` packing into a bit-vector +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits these two packing +// shapes for nets and variables; multi-dimensional unpacked arrays +// are a separate language-surface concern (Β§7.4) deferred to a +// future packing-shape extension under the L-2 pin discipline. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every declaration emitter (net / +// variable / port) and every signal-width consumer reads the +// packing shape uniformly; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: `Scalar` is nullary; `Packed` +// carries a `VectorRange`. Collapsing to `{ width: Int }` +// replaces a closed two-valued exhaustive sum with an +// unbounded Int (width=-1 representable) β€” violates P2 + M4 +// (the illegal-states-unrepresentable shape); also drops the +// msb/lsb endianness which is a legal Verilog distinction. +// 3. Algebraic form β€” N/A by construction: the two are the +// IEEE 1364-2005 spec's primitive packing partition; they do +// not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a signal declaration carries EXACTLY +// ONE packing shape; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: `Scalar` is nullary and +// `Packed` carries a `VectorRange` β€” structurally +// heterogeneous, NOT one generic `F` / projection over a +// separately-declared source set (Practice 7). It IS the +// irreducible two-way packing partition. +// Terminal: the closed two-way packing classifier; multi-dimensional +// unpacked arrays would be an EDIT to this declaration under the +// L-2 pin discipline (a third variant). +type PackingShape + = Scalar + | Packed { range: VectorRange } + + +// ───────────────────────────────────────────────────────────────────── +// NetDeclaration β€” a Verilog net (`wire foo;`, `wire [7:0] bus;`, +// `wand x;`). Conj record (no Practice-4 ledger). +// +// - net_type which net-type (wire / wand / wor / tri / …) +// - name the net identifier (K-1-opaque Symbol) +// - packing scalar or `[msb:lsb]` packed bit-vector +type NetDeclaration { + net_type: NetType + name: Symbol + packing: PackingShape +} + + +// ───────────────────────────────────────────────────────────────────── +// VariableDeclaration β€” a Verilog variable (`reg foo;`, `reg [31:0] +// counter;`, `integer i;`). Conj record (no Practice-4 ledger). +// +// - var_type which variable-type (reg / integer / real / time / +// realtime) +// - name the variable identifier (K-1-opaque Symbol) +// - packing scalar or `[msb:lsb]` packed bit-vector (note: +// `integer` / `real` / `time` / `realtime` accept only +// Scalar; `[N:M] integer i;` is a syntax error per IEEE +// 1364-2005 Β§5.7 β€” the per-variable-type packing- +// admissibility joint check is the T-4 LanguageModel's +// concern, same shape as ptx's RegisterScalarKind-Γ—- +// RegisterWidth admissibility) +type VariableDeclaration { + var_type: VariableType + name: Symbol + packing: PackingShape +} + + +// ───────────────────────────────────────────────────────────────────── +// PortDeclaration β€” a Verilog module port (`input clk`, `output [7:0] +// data`, `inout wire bidir_bus`). Conj record (no Practice-4 ledger). +// +// - direction input / output / inout +// - name the port identifier (K-1-opaque Symbol) +// - packing scalar or `[msb:lsb]` packed bit-vector +// +// IEEE 1364-2005 Β§12.3.3 also admits a per-port net-type or variable- +// type modifier (`output reg [7:0] data` makes the port BOTH a port +// and a procedural-assignment destination); that modifier is a +// MATCHING `VariableDeclaration` or `NetDeclaration` in the module +// body's items list (Practice 7 single-authority β€” the type-fact lives +// in the declaration, not duplicated on the port). The port's `name` +// is the cross-reference; the type modifier is consumed via the +// matching item, never a parallel field here. +type PortDeclaration { + direction: PortDirection + name: Symbol + packing: PackingShape +} + + +// ───────────────────────────────────────────────────────────────────── +// ParameterDeclaration β€” a Verilog compile-time constant +// (`parameter WIDTH = 8;`). Conj record (no Practice-4 ledger). +// +// - name the parameter identifier (K-1-opaque Symbol) +// - default_lexeme the default value as a verbatim lexeme +// (sub-grammar deferred to the T-4 LanguageModel +// expression productions; the spice.dag +// `SpiceValue.lexeme` precedent β€” `parse ∘ emit` +// is identity on the textual surface) +type ParameterDeclaration { + name: Symbol + default_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// SensitivityItem β€” one entry in an always-block's event-control list +// (`posedge clk`, `negedge rst`, bare `data_in`). Conj record (no +// Practice-4 ledger). +// +// - trigger which edge / level-sensitivity +// - signal the signal identifier the trigger watches (K-1- +// opaque Symbol; resolved through the namespace to +// the matching net or variable declaration) +type SensitivityItem { + trigger: EdgeTrigger + signal: Symbol +} + + +// ───────────────────────────────────────────────────────────────────── +// ContinuousAssign β€” a Verilog continuous-assignment statement +// (`assign net = expr;`, IEEE 1364-2005 Β§6.1). Conj record (no +// Practice-4 ledger). +// +// - lhs the destination net identifier (K-1-opaque +// Symbol; resolved to a `NetDeclaration` β€” +// procedural variables cannot be continuous- +// assignment destinations, that legality is the +// T-4 LanguageModel's joint check) +// - rhs_lexeme the right-hand-side expression as a verbatim +// lexeme (sub-grammar deferred β€” same shape as +// `ParameterDeclaration.default_lexeme`) +type ContinuousAssign { + lhs: Symbol + rhs_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// AlwaysBlock β€” a Verilog `always @(...)` block (IEEE 1364-2005 Β§9.9). +// Conj record (no Practice-4 ledger). +// +// - sensitivity the event-control list (empty list = `always` +// with no event control β€” a delay-driven block, +// rare; the common case is one-or-more events) +// - body_lexeme the procedural body (begin…end or single +// statement) as a verbatim lexeme (sub-grammar +// deferred to the T-4 LanguageModel expression / +// statement productions; `parse ∘ emit` is +// identity on the textual surface) +// +// Per the IN-B PROBE FINDING above, this carrier IS the Loop-step + +// Bind-chain unit: the always-block's ONE TRIGGER is a bounded step +// (A2 footnote); the iteration across triggers is the simulator/ +// synthesizer's coordination boundary; the sequential composition of +// statements inside the body is the Bind chain. +type AlwaysBlock { + sensitivity: List + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// InitialBlock β€” a Verilog `initial` block (IEEE 1364-2005 Β§9.9). +// Executes its body ONCE at simulation time 0. Conj record (no +// Practice-4 ledger). +// +// - body_lexeme the procedural body as a verbatim lexeme (sub- +// grammar deferred β€” same shape as `AlwaysBlock. +// body_lexeme`) +// +// `initial` is admitted here for the simulation-time-zero +// initialization case (the synthesizable-subset uses register-reset +// in `always @(posedge clk)` blocks instead); per the PROBE LIMITS +// header note the testbench-only `$display` / `$finish` system tasks +// inside `initial` are out of scope. +type InitialBlock { + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// PortConnection β€” one connection in a module-instance's port-binding +// list (IEEE 1364-2005 Β§12.1.2). Conj record (no Practice-4 ledger). +// +// - port the formal port name on the instantiated module +// (K-1-opaque Symbol; resolved through the namespace +// to the matching `PortDeclaration` on the target +// module) +// - signal the actual signal identifier in the instantiating +// context (K-1-opaque Symbol; resolved to a +// `NetDeclaration` / `VariableDeclaration` / +// `PortDeclaration` of the enclosing module) +// +// This is the NAMED port-connection form (`.port(signal)`) β€” the +// IEEE 1364-2005 Β§12.1.2 alternative positional form (`(signal1, +// signal2, ...)`) is scope-negative for T-4.9 (it is order-dependent +// and prone to silent reorder-bugs the spec recommends against; the +// L-2 pin discipline admits it via a future PortConnectionKind +// coproduct EDIT when consumer demand surfaces). +type PortConnection { + port: Symbol + signal: Symbol +} + + +// ───────────────────────────────────────────────────────────────────── +// ModuleInstance β€” a Verilog module instantiation (`Adder a1 (.a(x), +// .b(y), .sum(z));`). IEEE 1364-2005 Β§12.1. Conj record (no +// Practice-4 ledger). +// +// - module_name the instantiated module's name (K-1-opaque +// Symbol; resolved through the namespace to the +// matching top-level `VerilogModule`) +// - instance_name this instance's local name (K-1-opaque +// Symbol) +// - connections the named port-connection list +type ModuleInstance { + module_name: Symbol + instance_name: Symbol + connections: List +} + + +// ───────────────────────────────────────────────────────────────────── +// ModuleItem β€” the closed Verilog module-body item classifier. The +// items inside a `module ... endmodule` body are a flat list of +// concurrently-executing siblings (IEEE 1364-2005 Β§12.2); ModuleItem +// is the closed variant set of what each sibling can be. +// +// Per the IN-B PROBE FINDING above, this coproduct IS the parallel- +// composition surface: the module-body's `List` is the +// Conj children whose concurrent execution is the IN-B claim's +// structural representation β€” no 6th `Concurrent` behavior; the +// parallelism is the Conj-of-siblings shape, exactly as a Conj of +// submodule instantiations. +// +// - ContinuousAssignItem `assign net = expr;` +// - AlwaysBlockItem `always @(...) begin … end` +// - InitialBlockItem `initial begin … end` +// - NetDeclarationItem `wire`, `wand`, … declarations +// - VariableDeclarationItem `reg`, `integer`, … declarations +// - ParameterDeclarationItem `parameter NAME = expr;` +// - ModuleInstanceItem nested `ModuleName inst (...);` +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.2 admits additional +// item kinds (`defparam`, generate-blocks, specify-blocks, task / +// function declarations) β€” these are scope-negative for T-4.9 +// (`defparam` is deprecated; generate-blocks / task / function / +// specify each open a sub-language out of T-4.9's scope). A new +// item kind is an edit to THIS declaration under the L-2 pin +// discipline. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every module-body consumer (emission, +// port-binding resolution, sensitivity-list signal lookup, +// synthesis dispatch) branches on the item kind; shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: each variant carries a payload of +// a DIFFERENT type (`ContinuousAssign` / `AlwaysBlock` / +// `InitialBlock` / `NetDeclaration` / `VariableDeclaration` / +// `ParameterDeclaration` / `ModuleInstance`). Collapsing to a +// uniform `{ kind: ItemKind, … }` shape requires Option-typed +// payload fields (an item carries the AlwaysBlock or NULL), +// which makes "ContinuousAssign item with an AlwaysBlock +// payload" representable β€” the inverse of P2. +// 3. Algebraic form β€” N/A by construction: the seven module- +// body items are the IEEE 1364-2005 spec's primitive item +// taxonomy; they do not trace to a richer std/ algebraic +// structure. +// 4. Dimensional β€” FAILS: a single item is EXACTLY ONE kind; +// mutually-exclusive alternatives. (The module body as a +// WHOLE is `List` β€” multiple items co-exist as +// siblings, but each item is one kind. The Conj-of-siblings +// IS the dimensional model the IN-B finding consumes; that +// lives on `VerilogModule.items`, not on this enum.) +// 5. Parameterized family β€” FAILS: the seven variants are +// structurally heterogeneous (different payload types; the +// declaration variants carry storage-shape facts while the +// action variants carry computation-shape facts) β€” NOT one +// generic `F` / projection over a separately-declared +// source set (Practice 7). The IEEE 1364-2005 module-body +// item set is the irreducible partition. +// Terminal: the closed seven-way module-body-item classifier of the +// IEEE 1364-2005 spec. +type ModuleItem + = ContinuousAssignItem { assign: ContinuousAssign } + | AlwaysBlockItem { always_block: AlwaysBlock } + | InitialBlockItem { initial_block: InitialBlock } + | NetDeclarationItem { net: NetDeclaration } + | VariableDeclarationItem { variable: VariableDeclaration } + | ParameterDeclarationItem { parameter: ParameterDeclaration } + | ModuleInstanceItem { instance: ModuleInstance } + + +// ───────────────────────────────────────────────────────────────────── +// VerilogModule β€” a top-level Verilog module (`module Name (ports); +// items endmodule`). IEEE 1364-2005 Β§12.1. Conj record (no +// Practice-4 ledger). +// +// - name the module identifier (K-1-opaque Symbol) +// - ports the port-declaration list (the module's external +// interface) +// - items the module-body items list (the Conj of parallel +// siblings β€” the IN-B parallel-composition surface) +// +// Per the IN-B PROBE FINDING: the `items` field IS the parallel- +// Conj surface; the structural concurrency of multiple always-blocks +// / continuous-assigns / instances is precisely "these are siblings +// in the items list". There is no `concurrent: Bool` flag; the +// parallelism is read FROM the list-of-siblings shape ( +// feedback_no_annotations). +type VerilogModule { + name: Symbol + ports: List + items: List +} + + +// ───────────────────────────────────────────────────────────────────── +// VerilogCost β€” the per-target cost-realization carrier shape for the +// Verilog `LanguageModel`. Conj record (no Practice-4 ledger). +// +// This declares the SHAPE the U1 spine reads when computing Verilog- +// target realization cost β€” the scaffold header's "Cost realization: +// per-construct cost on a Verilog target" claim: +// +// - gate_cost per-construct gate-count cost (an XOR, AND, OR +// primitive's gate equivalent; the U1 per-target- +// op cost projection β€” the `map` side of +// `Homomorphism<…, …, VerilogBits>` carries this; +// cost is read FROM the map's structure, never +// stored as a parallel field per algebra.dag's U1 +// no-engine discipline) +// - area_cost per-construct area cost (in technology-dependent +// units β€” gate equivalents in a generic process, +// LUT count on FPGA, transistor count on ASIC; +// the technology-specific cost table sits in the +// inhabitance walk that the T-4 LanguageModel +// shape parameterizes when it lands, not in this +// carrier itself) +// +// Both Int carriers are 🟑 scaffold (same bridge as VectorRange and +// ptx Dim3): cost is a non-negative quantity, but without +// std/cardinality.dag refinement the negative-cost state is +// structurally representable. Producer-side invariant pending the +// cardinality substrate landing. +type VerilogCost { + gate_cost: Int + area_cost: Int +} From b4f0ad63d45d1a8e237944fb6739889968af0ecb Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 01:31:36 +0000 Subject: [PATCH 02/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20address=203=20cod?= =?UTF-8?q?ex=20BLOCKING=20findings=20on=20PR=20#3176=20=E2=80=94=20spec?= =?UTF-8?q?=20fidelity=20+=20structural=20P2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes from the codex review b12e8bd9 (sha-pinned BLOCKING): 1. NetType: add `TriAnd` + `TriOr` to complete the IEEE 1364-2005 Β§3.7.1 net-type table (was 10 variants; spec admits 12 β€” `triand` and `trior` are the designer-intent partners of `wand`/`wor` paired with `tri`, syntactically distinct and parse∘emit-preserving per K-1). Ledger updated to "twelve-way" with the new paired-partner rationale on Practice-7. 2. VariableDeclaration: refactor to Disj-with-named-payloads (`RegVariable { name, packing } | IntegerVariable { name } | RealVariable { name } | TimeVariable { name } | RealTimeVariable { name }`). Only `RegVariable` admits a packing payload; the other four are scalar-only per IEEE 1364-2005 Β§5.7 (`[N:M] integer i;` is a syntax error). The prior `{ var_type: VariableType, packing: PackingShape }` Conj-record-with- independent-coordinates form ratified the illegal state "Integer with Packed range" β€” INVARIANTS P2 illegal-states-unrepresentable anti- pattern. The dissolved Disj-with-heterogeneous-payloads shape mirrors rust.dag's RustScalar and go.dag's GoScalar precedent. Full 5-pattern ledger now lives on `VariableDeclaration`; the `VariableType` enum becomes redundant (its discriminator role is subsumed by the variant names) and is removed. 3. PortDeclaration: drop `packing: PackingShape` field β€” single-authority via the matching `NetDeclaration` / `VariableDeclaration` in the module body (per IEEE 1364-2005 Β§12.3.3 the inline `input wire [7:0] data` form produces TWO items: the port + the matching net declaration). The prior duplicate-authority on `packing` was the INVARIANTS P2 cost-of-change β‰₯ 2 anti-pattern the codex review surfaced. Verification: `v2-compiler compile --source-root src/v4 --target dag` = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 240 ++++++++++++++++----------- 1 file changed, 140 insertions(+), 100 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 1f093fcef5c..4f1b3e73259 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -209,7 +209,8 @@ import v4.std.node { Symbol } // correct partition: (a) INTRA-program concurrency (multiple // `always`-blocks within one Verilog module sharing signal nets) is // what this file models β€” the effect-typing carriers are the -// signal-type declarations (`NetType` / `VariableType` / `PackingShape`) +// signal-type declarations (`NetType` / `VariableDeclaration` variants / +// `PackingShape`) // declared HERE, in this language file; (b) CROSS-program coordination // (one program's output deployed to host A, another to host B, // communicating via Endpoint / DeploymentUnit / sync-async-stream- @@ -330,10 +331,14 @@ type PortDirection // // - Wire β€” `wire` standard net; resolves to X if multiply // driven with conflicting values -// - Wand β€” `wand` wired-AND resolution -// - Wor β€” `wor` wired-OR resolution // - Tri β€” `tri` identical to `wire` semantically; // designer-intent marker for tri-state nets +// - Wand β€” `wand` wired-AND resolution +// - TriAnd β€” `triand` identical to `wand` semantically; +// designer-intent marker pairing with `tri` +// - Wor β€” `wor` wired-OR resolution +// - TriOr β€” `trior` identical to `wor` semantically; +// designer-intent marker pairing with `tri` // - Tri0 β€” `tri0` pull-down (resolves to 0 if undriven) // - Tri1 β€” `tri1` pull-up (resolves to 1 if undriven) // - TriReg β€” `trireg` stores last driven value (capacitive) @@ -355,29 +360,37 @@ type PortDirection // reopens the readable-string heuristic surface K-1 forecloses // (a `match keyword { "wire" => … }` smell); a // `{ resolution_kind: Int }` proxy replaces a closed -// 10-valued exhaustive sum with an unbounded Int β€” both +// 12-valued exhaustive sum with an unbounded Int β€” both // violate P2 + M4 (algebra.dag:332 `Ordering` precedent). -// 3. Algebraic form β€” N/A by construction: the ten net-types are -// the IEEE 1364-2005 spec's primitive resolution-function set; -// they do not trace to a richer std/ algebraic structure (one -// could attempt a `Lattice` for the wand/wor +// 3. Algebraic form β€” N/A by construction: the twelve net-types +// are the IEEE 1364-2005 spec's primitive resolution-function +// set; they do not trace to a richer std/ algebraic structure +// (one could attempt a `Lattice` for the wand/wor // sublattice, but that would be a parallel representation of // the per-net-type resolution function, not a richer source). // 4. Dimensional β€” FAILS: a net declaration carries EXACTLY ONE // net-type; `wire wand x` is a syntax error in Verilog itself. // Mutually-exclusive alternatives, not coordinates. -// 5. Parameterized family β€” FAILS: the ten are structurally +// 5. Parameterized family β€” FAILS: the twelve are structurally // distinct resolution / pull / supply / unresolved variants β€” // NOT one generic `F` / projection over a separately- -// declared source set (Practice 7). They are the spec's -// irreducible net-type partition for IEEE 1364-2005. -// Terminal: the closed ten-way net-type classifier of the +// declared source set (Practice 7). The Wire/Tri, +// Wand/TriAnd, Wor/TriOr designer-intent pairs are +// SEMANTICALLY-equivalent partner variants the spec keeps +// DISTINCT at the syntactic surface (parse ∘ emit must +// preserve the writer's intent); collapsing the pairs into +// `{ resolution: Symbol, tri_intent: Bool }` would be a +// parallel-representation of the spec's enumeration and lose +// the K-1-opaque keyword discrimination. +// Terminal: the closed twelve-way net-type classifier of the // IEEE 1364-2005 spec. type NetType = Wire + | Tri | Wand + | TriAnd | Wor - | Tri + | TriOr | Tri0 | Tri1 | TriReg @@ -386,66 +399,17 @@ type NetType | Uwire -// ───────────────────────────────────────────────────────────────────── -// VariableType β€” the closed Verilog variable-type classifier -// (IEEE 1364-2005 Β§3.7.2, Β§5.7). A variable stores a value assigned by -// a procedural statement; the variable-type fixes the storage shape. -// -// - Reg β€” `reg` general-purpose variable (any width; -// the procedural-assignment destination) -// - Integer β€” `integer` 32-bit signed (host integer; the spec -// pins integer to >= 32 bits) -// - Real β€” `real` double-precision floating point (IEEE -// 754) -// - Time β€” `time` 64-bit unsigned (simulation-time -// carrier) -// - RealTime β€” `realtime` alias for `real`, designer-intent -// marker for simulation-time-valued -// reals (kept distinct at the syntactic -// surface per IEEE 1364-2005 Β§3.7.2) -// -// CLOSED (C1 stop-signal). A new variable-type is an edit to THIS -// declaration under the L-2 pin discipline (SystemVerilog adds -// `logic` / `bit` / typed enums β€” a future language-version model -// would EDIT this enum explicitly). -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every variable-declaration emitter -// and every procedural-assignment legality check reads the -// variable-type tag uniformly; shared classifier, not -// scattered. -// 2. Variant-is-data β€” FAILS: a `{ keyword: Symbol }` proxy -// reopens the readable-string heuristic surface K-1 -// forecloses. The enum IS the faithful form (algebra.dag:332 -// `Ordering` precedent). -// 3. Algebraic form β€” PARTIAL: each variable-type grounds in a -// std/algebra structure (Regβ†’`Semiring>` or -// `OrderedRing>` per declared width; Integerβ†’ -// `OrderedRing>`; Real / RealTimeβ†’`ApproximateField`; -// Timeβ†’`Semiring>`). That grounding is INHABITANCE β€” -// owned by the inhabiting carrier file (std/integer.dag, -// std/float.dag) per P2, and DEFERRED to the operator-pending -// D2 STOP. The variable-type enum itself stays a closed -// classifier; the "type β†’ algebra" map IS the future -// inhabitance walk, not a richer std/ source to collapse this -// enum INTO. -// 4. Dimensional β€” FAILS: a variable declaration has EXACTLY ONE -// type; mutually-exclusive alternatives. -// 5. Parameterized family β€” FAILS: the five are structurally -// distinct storage shapes (bit-vector / signed integer / -// floating-point / unsigned 64-bit time / aliased floating- -// point) β€” NOT one generic `F` / projection over a -// separately-declared source set (Practice 7). The closed set -// is the IEEE 1364-2005 variable-type partition. -// Terminal: the closed five-way variable-type classifier of the -// IEEE 1364-2005 spec. -type VariableType - = Reg - | Integer - | Real - | Time - | RealTime +// (VariableType has been dissolved into VariableDeclaration's +// Disj-with-named-payloads below β€” the spec couples kind Γ— packing +// admissibility (only `reg` accepts a `[msb:lsb]` packing per IEEE +// 1364-2005 Β§5.7), and modeling kind and packing as independent +// coordinates ratified the illegal state "Integer with Packed +// range" β€” the INVARIANTS P2 illegal-states-unrepresentable anti- +// pattern (codex BLOCKING review on PR #3176). The 5-pattern ledger +// for the dissolved partition lives on VariableDeclaration; the +// reasoning is identical except that "Variant-is-data" now FAILS +// for the additional reason that uniform `{ kind, packing }` ratifies +// the illegal state. // ───────────────────────────────────────────────────────────────────── @@ -639,23 +603,90 @@ type NetDeclaration { // ───────────────────────────────────────────────────────────────────── // VariableDeclaration β€” a Verilog variable (`reg foo;`, `reg [31:0] -// counter;`, `integer i;`). Conj record (no Practice-4 ledger). -// -// - var_type which variable-type (reg / integer / real / time / -// realtime) -// - name the variable identifier (K-1-opaque Symbol) -// - packing scalar or `[msb:lsb]` packed bit-vector (note: -// `integer` / `real` / `time` / `realtime` accept only -// Scalar; `[N:M] integer i;` is a syntax error per IEEE -// 1364-2005 Β§5.7 β€” the per-variable-type packing- -// admissibility joint check is the T-4 LanguageModel's -// concern, same shape as ptx's RegisterScalarKind-Γ—- -// RegisterWidth admissibility) -type VariableDeclaration { - var_type: VariableType - name: Symbol - packing: PackingShape -} +// counter;`, `integer i;`, `real x;`, `time t;`, `realtime rt;`). +// IEEE 1364-2005 Β§3.7.2, Β§5.7 partitions variable declarations into +// five kinds, where ONLY `reg` admits a `[msb:lsb]` packing β€” the +// other four (`integer` / `real` / `time` / `realtime`) have spec- +// fixed widths and forbid a vector range (`[N:M] integer i;` is a +// syntax error per Β§5.7). The kind Γ— packing admissibility is +// modeled STRUCTURALLY: only `RegVariable` carries a `packing` +// payload, so "Integer with Packed range" is unrepresentable β€” not +// "rejected by a check" β€” the INVARIANTS P2 illegal-states- +// unrepresentable shape (same design choice as node.dag's EdgeLabel, +// rust.dag's RustScalar Disj-with-named-payloads, and go.dag's +// GoScalar). The prior `{ var_type: VariableType, packing: +// PackingShape }` Conj-record-with-independent-coordinates form was +// the codex BLOCKING-review anti-pattern on PR #3176; this Disj- +// with-payloads form is the dissolution. +// +// - RegVariable β€” `reg [msb:lsb] name;` / `reg name;` +// general-purpose variable; the procedural- +// assignment destination; THE ONLY +// variable-kind that admits a packing +// - IntegerVariable β€” `integer name;` 32-bit signed (the spec +// pins integer to >= 32 bits); no packing +// - RealVariable β€” `real name;` double-precision IEEE-754 +// floating-point; no packing +// - TimeVariable β€” `time name;` 64-bit unsigned simulation- +// time carrier; no packing +// - RealTimeVariable β€” `realtime name;` aliased to `real`, +// designer-intent marker for simulation- +// time-valued reals (the spec keeps it +// distinct at the syntactic surface per +// IEEE 1364-2005 Β§3.7.2 β€” parse ∘ emit +// must preserve the keyword choice); no +// packing +// +// CLOSED (C1 stop-signal). A new variable-kind is an edit to THIS +// declaration under the L-2 pin discipline (SystemVerilog adds +// `logic` / `bit` / typed enums β€” a future language-version model +// would EDIT this Disj explicitly). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every variable-declaration emitter, +// every procedural-assignment legality check (only RegVariable +// is a legal procedural-assignment destination), and the per- +// kind algebra inhabitance walk all read the variant tag +// uniformly; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to `{ kind: +// VariableType, packing: PackingShape }` ratifies the illegal +// state "Integer with Packed range" the spec forbids (Β§5.7); +// collapsing to `{ keyword: Symbol, packing?: PackingShape }` +// additionally reopens the readable-string heuristic surface +// K-1 forecloses. The Disj-with-heterogeneous-payloads IS the +// dissolved form (P2 + Practice 2/6 + M4) β€” same shape as +// rust.dag's RustScalar and go.dag's GoScalar. +// 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ +// algebra structure (RegVariable β†’ `Semiring>` or +// `OrderedRing>` per declared packing; IntegerVariable +// β†’ `OrderedRing>`; RealVariable / RealTimeVariable β†’ +// `ApproximateField`; TimeVariable β†’ `Semiring>`). +// That grounding is INHABITANCE β€” owned by the inhabiting +// carrier file (std/integer.dag, std/float.dag) per P2, and +// DEFERRED to the operator-pending D2 STOP. The variant set +// itself stays a closed classifier. +// 4. Dimensional β€” FAILS: a single variable declaration IS +// EXACTLY ONE variant; mutually-exclusive alternatives. The +// shapes differ across variants (RegVariable carries a +// packing; the rest do not) β€” they cannot be coordinates of a +// single record without the illegal-state smell. +// 5. Parameterized family β€” FAILS: the five are structurally +// heterogeneous (RegVariable carries packing; the rest are +// packing-less; the algebraic groundings are five distinct +// std/algebra structures β€” Semiring / OrderedRing> / +// ApproximateField / Semiring> / aliased +// ApproximateField) β€” NOT one generic `F` / projection +// over a separately-declared source set (Practice 7). +// Terminal: the closed five-variant Verilog variable-declaration +// classifier; illegal kindΓ—packing combinations are unrepresentable +// by construction. +type VariableDeclaration + = RegVariable { name: Symbol, packing: PackingShape } + | IntegerVariable { name: Symbol } + | RealVariable { name: Symbol } + | TimeVariable { name: Symbol } + | RealTimeVariable { name: Symbol } // ───────────────────────────────────────────────────────────────────── @@ -664,20 +695,29 @@ type VariableDeclaration { // // - direction input / output / inout // - name the port identifier (K-1-opaque Symbol) -// - packing scalar or `[msb:lsb]` packed bit-vector // -// IEEE 1364-2005 Β§12.3.3 also admits a per-port net-type or variable- -// type modifier (`output reg [7:0] data` makes the port BOTH a port -// and a procedural-assignment destination); that modifier is a -// MATCHING `VariableDeclaration` or `NetDeclaration` in the module -// body's items list (Practice 7 single-authority β€” the type-fact lives -// in the declaration, not duplicated on the port). The port's `name` -// is the cross-reference; the type modifier is consumed via the -// matching item, never a parallel field here. +// Per IEEE 1364-2005 Β§12.3.3 a port can carry a per-port net-type or +// variable-type modifier (`output reg [7:0] data` makes the port +// BOTH a port and a procedural-assignment destination); that modifier +// is the MATCHING `NetDeclaration` or `VariableDeclaration` in the +// module body's items list. SINGLE-AUTHORITY DISCIPLINE (INVARIANTS +// P2, codex BLOCKING review on PR #3176): the width / packing / +// type-fact lives EXCLUSIVELY in the matching declaration, NOT +// duplicated as a `packing: PackingShape` field here. The port's +// `name` is the cross-reference; downstream consumers (the bundled +// T-4 LanguageModel grammar productions for emission; the well- +// formedness check that every port has exactly one matching +// declaration) resolve the type through the name lookup. The prior +// `packing: PackingShape` field on this record was a parallel +// representation of the width that the matching Net/Variable +// declaration ALSO carries β€” exactly the P2 cost-of-change β‰₯ 2 +// duplicate-authority anti-pattern the codex review surfaced. The +// inline form `input wire [7:0] data` is a parser convenience that +// produces TWO items in the module body (the port declaration here +// + the matching NetDeclaration), preserving single-authority. type PortDeclaration { direction: PortDirection name: Symbol - packing: PackingShape } From cb65ea8cae4fae894e3bb0eda6962621f8254f22 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 02:24:27 +0000 Subject: [PATCH 03/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20add=20Signedness?= =?UTF-8?q?=20=E2=80=94=20preserve=20IEEE=201364-2005=20=C2=A75.6=20signed?= =?UTF-8?q?/unsigned=20boundary=20fact=20(codex=20BLOCKING=20on=20PR=20#31?= =?UTF-8?q?76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING inline review on PR #3176 verilog.dag:597: NetDeclaration collapses signed and unsigned packed nets β€” IEEE 1364-2005 Β§5.6 admits `wire signed [N:0]` / `reg signed [N:0]` as a structural fact every arithmetic and emission consumer must preserve (signedness governs sign-extension on assignment, comparison semantics, signed-vs-unsigned operator dispatch). INVARIANTS P2 boundary-fact violation. Fix: - New closed-Disj Signedness = Signed | Unsigned with full 5-pattern Practice-4 ledger. - NetDeclaration gains signedness: Signedness (every net-type admits the `signed` keyword per spec; even for scalar nets the spec preserves the syntactic distinction β€” parse∘emit identity). - VariableDeclaration.RegVariable gains signedness: Signedness (per spec Β§5.6 `reg` admits `signed`). The spec-fixed-signedness kinds (IntegerVariable always-signed per spec; TimeVariable always-unsigned; RealVariable / RealTimeVariable are IEEE-754 floating-point with sign internal to the representation) carry NO signedness payload β€” illegal states like "RealVariable signedness=Signed" or "TimeVariable signedness=Signed" are unrepresentable by construction (same shape as the kind Γ— packing partition). - VariableDeclaration ledger updated to dissolve the additional kind Γ— signedness illegal-state argument (Practice-2 covers BOTH packing AND signedness Cartesian products simultaneously). Verification: v2-compiler compile --source-root src/v4 --target dag = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 214 +++++++++++++++++++-------- 1 file changed, 153 insertions(+), 61 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 4f1b3e73259..a801cdbb76e 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -591,51 +591,138 @@ type PackingShape // NetDeclaration β€” a Verilog net (`wire foo;`, `wire [7:0] bus;`, // `wand x;`). Conj record (no Practice-4 ledger). // -// - net_type which net-type (wire / wand / wor / tri / …) -// - name the net identifier (K-1-opaque Symbol) -// - packing scalar or `[msb:lsb]` packed bit-vector +// ───────────────────────────────────────────────────────────────────── +// Signedness β€” the closed Verilog net/reg signedness classifier +// (IEEE 1364-2005 Β§5.6 "Signed types"). The `signed` keyword on a net +// or `reg` declaration selects two's-complement signed interpretation +// of the bit-vector; the default (no keyword) is unsigned. The +// signedness fact governs sign-extension on assignment, comparison +// semantics, and arithmetic operator dispatch β€” a fact every emission +// / arithmetic consumer must preserve per INVARIANTS P2 (codex +// BLOCKING review on PR #3176 2026-05-16 surfaced this gap; the +// prior NetDeclaration / RegVariable collapsed signed and unsigned +// packed forms, losing a spec-mandated boundary fact). +// +// - Signed β€” `signed` modifier present; two's-complement +// signed interpretation; sign-extension on +// assignment; signed-arithmetic operator dispatch +// - Unsigned β€” no `signed` modifier; unsigned modular +// interpretation; zero-extension on assignment; +// unsigned-arithmetic operator dispatch (the spec's +// default) +// +// CLOSED (C1 stop-signal). The signedness axis is BINARY per the +// IEEE 1364-2005 spec; a third interpretation is an edit to THIS +// declaration under the L-2 pin discipline. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every arithmetic-emission consumer +// and every assignment-extension consumer reads the signedness +// tag uniformly to dispatch (signed vs unsigned operator +// lowering; sign- vs zero-extension); shared classifier, not +// scattered. +// 2. Variant-is-data β€” FAILS: a `{ signed: Bool }` proxy is a +// faithful 2-valued representation, but the LEXICAL SURFACE +// (`signed` keyword present / absent) is a closed pair the +// parser/emitter dispatch on; the named-enum is the M4-faithful +// form (closed sets are enums, not Bool proxies β€” same +// argument as ProceduralAssignKind's ledger). +// 3. Algebraic form β€” PARTIAL: each variant grounds in a different +// std/algebra structure (Signed β†’ OrderedRing on the underlying +// bit-vector width; Unsigned β†’ Semiring). That grounding is +// the inhabitance walk DEFERRED to D2 per the file's "Owned +// ELSEWHERE" framing; the signedness enum itself stays a closed +// classifier. +// 4. Dimensional β€” FAILS: a net/reg declaration is EXACTLY ONE +// signedness; `wire signed signed x;` is a syntax error. +// Mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the two are structurally +// distinct arithmetic-interpretation primitives β€” NOT one +// generic `F` / projection over a separately-declared +// source set (Practice 7). They are the spec's irreducible +// signedness partition. +// Terminal: the closed two-way Verilog signedness classifier of the +// IEEE 1364-2005 spec. +type Signedness + = Signed + | Unsigned + + +// ───────────────────────────────────────────────────────────────────── +// NetDeclaration β€” a Verilog net (`wire foo;`, `wire [7:0] bus;`, +// `wire signed [15:0] s;`, `wand x;`). Conj record (no Practice-4 +// ledger). +// +// - net_type which net-type (wire / wand / wor / tri / …) +// - name the net identifier (K-1-opaque Symbol) +// - packing scalar or `[msb:lsb]` packed bit-vector +// - signedness `signed` keyword present / absent (IEEE 1364-2005 +// Β§5.6; the spec admits `signed` on any net-type; +// for a scalar (single-bit) net the signedness fact +// is semantically vacuous but the spec preserves it +// syntactically β€” parse ∘ emit must preserve the +// writer's keyword choice. Added 2026-05-16 per +// codex BLOCKING review on PR #3176 to preserve the +// IEEE signedness boundary fact for downstream +// arithmetic/emission consumers, INVARIANTS P2.) type NetDeclaration { net_type: NetType name: Symbol packing: PackingShape + signedness: Signedness } // ───────────────────────────────────────────────────────────────────── // VariableDeclaration β€” a Verilog variable (`reg foo;`, `reg [31:0] -// counter;`, `integer i;`, `real x;`, `time t;`, `realtime rt;`). -// IEEE 1364-2005 Β§3.7.2, Β§5.7 partitions variable declarations into -// five kinds, where ONLY `reg` admits a `[msb:lsb]` packing β€” the -// other four (`integer` / `real` / `time` / `realtime`) have spec- -// fixed widths and forbid a vector range (`[N:M] integer i;` is a -// syntax error per Β§5.7). The kind Γ— packing admissibility is -// modeled STRUCTURALLY: only `RegVariable` carries a `packing` -// payload, so "Integer with Packed range" is unrepresentable β€” not -// "rejected by a check" β€” the INVARIANTS P2 illegal-states- -// unrepresentable shape (same design choice as node.dag's EdgeLabel, -// rust.dag's RustScalar Disj-with-named-payloads, and go.dag's -// GoScalar). The prior `{ var_type: VariableType, packing: -// PackingShape }` Conj-record-with-independent-coordinates form was -// the codex BLOCKING-review anti-pattern on PR #3176; this Disj- -// with-payloads form is the dissolution. -// -// - RegVariable β€” `reg [msb:lsb] name;` / `reg name;` -// general-purpose variable; the procedural- -// assignment destination; THE ONLY -// variable-kind that admits a packing -// - IntegerVariable β€” `integer name;` 32-bit signed (the spec -// pins integer to >= 32 bits); no packing +// counter;`, `reg signed [15:0] s;`, `integer i;`, `real x;`, +// `time t;`, `realtime rt;`). IEEE 1364-2005 Β§3.7.2, Β§5.7 partitions +// variable declarations into five kinds, where ONLY `reg` admits a +// `[msb:lsb]` packing β€” the other four (`integer` / `real` / `time` +// / `realtime`) have spec-fixed widths and forbid a vector range +// (`[N:M] integer i;` is a syntax error per Β§5.7). The kind Γ— packing +// admissibility is modeled STRUCTURALLY: only `RegVariable` carries +// a `packing` payload, so "Integer with Packed range" is +// unrepresentable β€” not "rejected by a check" β€” the INVARIANTS P2 +// illegal-states-unrepresentable shape (same design choice as +// node.dag's EdgeLabel, rust.dag's RustScalar Disj-with-named- +// payloads, and go.dag's GoScalar). The prior `{ var_type: +// VariableType, packing: PackingShape }` Conj-record-with- +// independent-coordinates form was the codex BLOCKING-review anti- +// pattern on PR #3176; this Disj-with-payloads form is the +// dissolution. +// +// The kind Γ— signedness admissibility is also modeled STRUCTURALLY +// per IEEE 1364-2005 Β§5.6: `reg` admits `signed` (`reg signed [N:0]` +// is two's-complement signed bit-vector); `integer` is ALWAYS signed +// by spec (Β§3.7.2: "32-bit signed"); `time` is ALWAYS unsigned (the +// 64-bit simulation-time carrier); `real` and `realtime` are IEEE-754 +// floating-point and carry NO signedness keyword (the floating-point +// sign is internal to the IEEE-754 representation, not a separate +// declaration modifier). Only `RegVariable` carries the +// `signedness: Signedness` payload β€” "RealVariable signedness=Signed" +// is unrepresentable, just like the kind Γ— packing partition (codex +// BLOCKING fix 2026-05-16 on PR #3176; the spec-fixed-signedness +// kinds DO NOT need the carrier because the fact is non-variant per +// spec). +// +// - RegVariable β€” `reg [msb:lsb] name;` / `reg signed [msb: +// lsb] name;` / `reg name;` general-purpose +// variable; the procedural-assignment +// destination; THE ONLY variable-kind that +// admits packing AND signedness modifiers +// - IntegerVariable β€” `integer name;` 32-bit signed (spec-fixed +// signed); no packing, no signedness payload // - RealVariable β€” `real name;` double-precision IEEE-754 -// floating-point; no packing +// floating-point; no packing, no signedness +// payload (sign is internal to the IEEE-754 +// representation, not a declaration modifier) // - TimeVariable β€” `time name;` 64-bit unsigned simulation- -// time carrier; no packing -// - RealTimeVariable β€” `realtime name;` aliased to `real`, -// designer-intent marker for simulation- -// time-valued reals (the spec keeps it -// distinct at the syntactic surface per -// IEEE 1364-2005 Β§3.7.2 β€” parse ∘ emit -// must preserve the keyword choice); no -// packing +// time carrier (spec-fixed unsigned); no +// packing, no signedness payload +// - RealTimeVariable β€” `realtime name;` aliased to `real` per +// Β§3.7.2; no packing, no signedness payload // // CLOSED (C1 stop-signal). A new variable-kind is an edit to THIS // declaration under the L-2 pin discipline (SystemVerilog adds @@ -646,43 +733,48 @@ type NetDeclaration { // 🟒 GREEN (terminal). Ledger β€” five patterns attempted: // 1. Fact placement β€” FAILS: every variable-declaration emitter, // every procedural-assignment legality check (only RegVariable -// is a legal procedural-assignment destination), and the per- -// kind algebra inhabitance walk all read the variant tag -// uniformly; shared classifier, not scattered. -// 2. Variant-is-data β€” FAILS: collapsing to `{ kind: -// VariableType, packing: PackingShape }` ratifies the illegal -// state "Integer with Packed range" the spec forbids (Β§5.7); -// collapsing to `{ keyword: Symbol, packing?: PackingShape }` -// additionally reopens the readable-string heuristic surface -// K-1 forecloses. The Disj-with-heterogeneous-payloads IS the -// dissolved form (P2 + Practice 2/6 + M4) β€” same shape as -// rust.dag's RustScalar and go.dag's GoScalar. +// is a legal procedural-assignment destination), every signed- +// vs-unsigned arithmetic dispatch, and the per-kind algebra +// inhabitance walk all read the variant tag uniformly; shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to `{ kind: VariableType, +// packing: PackingShape, signedness: Signedness }` ratifies +// multiple illegal states the spec forbids β€” "Integer with +// Packed range" (Β§5.7) AND "Real with signedness=Signed" (Β§5.6 +// β€” real is floating-point, no signedness modifier), AND +// "Time with signedness=Signed" (spec-fixed unsigned). The +// Disj-with-heterogeneous-payloads dissolves all of these: +// only RegVariable carries packing AND signedness; the spec- +// fixed-attribute kinds carry only `name`. Same dissolution +// shape as rust.dag's RustScalar and go.dag's GoScalar. // 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ // algebra structure (RegVariable β†’ `Semiring>` or -// `OrderedRing>` per declared packing; IntegerVariable -// β†’ `OrderedRing>`; RealVariable / RealTimeVariable β†’ -// `ApproximateField`; TimeVariable β†’ `Semiring>`). -// That grounding is INHABITANCE β€” owned by the inhabiting -// carrier file (std/integer.dag, std/float.dag) per P2, and -// DEFERRED to the operator-pending D2 STOP. The variant set -// itself stays a closed classifier. +// `OrderedRing>` per declared packing Γ— signedness; +// IntegerVariable β†’ `OrderedRing>`; RealVariable / +// RealTimeVariable β†’ `ApproximateField`; TimeVariable +// β†’ `Semiring>`). That grounding is INHABITANCE β€” +// owned by the inhabiting carrier file (std/integer.dag, +// std/float.dag) per P2, and DEFERRED to the operator-pending +// D2 STOP. The variant set itself stays a closed classifier. // 4. Dimensional β€” FAILS: a single variable declaration IS // EXACTLY ONE variant; mutually-exclusive alternatives. The -// shapes differ across variants (RegVariable carries a -// packing; the rest do not) β€” they cannot be coordinates of a -// single record without the illegal-state smell. +// shapes differ across variants (RegVariable carries packing +// AND signedness; the rest carry neither) β€” they cannot be +// coordinates of a single record without the illegal-state +// smell. // 5. Parameterized family β€” FAILS: the five are structurally -// heterogeneous (RegVariable carries packing; the rest are -// packing-less; the algebraic groundings are five distinct -// std/algebra structures β€” Semiring / OrderedRing> / +// heterogeneous (RegVariable carries packing + signedness; the +// rest carry neither; the algebraic groundings are five +// distinct std/algebra structures β€” Semiring or OrderedRing +// depending on packingΓ—signedness / OrderedRing> / // ApproximateField / Semiring> / aliased // ApproximateField) β€” NOT one generic `F` / projection // over a separately-declared source set (Practice 7). // Terminal: the closed five-variant Verilog variable-declaration -// classifier; illegal kindΓ—packing combinations are unrepresentable -// by construction. +// classifier; illegal kindΓ—packing AND kindΓ—signedness combinations +// are unrepresentable by construction. type VariableDeclaration - = RegVariable { name: Symbol, packing: PackingShape } + = RegVariable { name: Symbol, packing: PackingShape, signedness: Signedness } | IntegerVariable { name: Symbol } | RealVariable { name: Symbol } | TimeVariable { name: Symbol } From cb93eacdea285e78de721c7cef86a35b3e05a7ea Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 02:27:36 +0000 Subject: [PATCH 04/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20add=20AlwaysBlock?= =?UTF-8?q?Sensitivity=20Disj=20=E2=80=94=20represent=20@*=20implicit=20ev?= =?UTF-8?q?ent=20control=20(codex=20BLOCKING=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING inline review on PR #3176 verilog.dag:749: the prior `sensitivity: List` on AlwaysBlock could not represent IEEE 1364-2005 Β§9.7.2 implicit `@*` / `@(*)` event control β€” that form has no explicit signal list (the implicit set is computed from the body at synthesis/simulation time). Modeling it as an empty SensitivityItem list collapsed it with "no event control" (bare `always`). INVARIANTS P1 spec-fidelity violation. Fix: new AlwaysBlockSensitivity Disj with three variants (the IEEE 1364-2005 Β§9.7.2 partition): - NoEventControl: bare `always begin ... end` (no `@`) - ImplicitAtStar: `always @*` / `always @(*)` β€” nullary marker (implicit set computed from body, not stored) - ExplicitEventList { items: List }: explicit list Full 5-pattern Practice-4 ledger. Each variant carries exactly the structural data its form admits β€” heterogeneous payloads make collapsing to a uniform record reintroduce the prior anti-pattern. AlwaysBlock.sensitivity now AlwaysBlockSensitivity (replaces List). Verification: v2-compiler compile --source-root src/v4 --target dag = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 83 ++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index a801cdbb76e..e7702450e9f 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -867,9 +867,10 @@ type ContinuousAssign { // AlwaysBlock β€” a Verilog `always @(...)` block (IEEE 1364-2005 Β§9.9). // Conj record (no Practice-4 ledger). // -// - sensitivity the event-control list (empty list = `always` -// with no event control β€” a delay-driven block, -// rare; the common case is one-or-more events) +// - sensitivity the event-control specification (closed Disj +// over the three IEEE 1364-2005 Β§9.7.2 forms: +// no event control / implicit `@*` / explicit +// event list) // - body_lexeme the procedural body (begin…end or single // statement) as a verbatim lexeme (sub-grammar // deferred to the T-4 LanguageModel expression / @@ -882,11 +883,85 @@ type ContinuousAssign { // synthesizer's coordination boundary; the sequential composition of // statements inside the body is the Bind chain. type AlwaysBlock { - sensitivity: List + sensitivity: AlwaysBlockSensitivity body_lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// AlwaysBlockSensitivity β€” the closed Verilog event-control +// classifier for an `always` block (IEEE 1364-2005 Β§9.7.2). The spec +// admits exactly THREE event-control forms; modeling sensitivity as +// `List` collapsed the implicit `@*` form with both +// "no event control" (empty list) and "explicit event list" (non- +// empty) β€” the codex BLOCKING review on PR #3176 surfaced the gap. +// This Disj-with-named-payloads makes each form structurally distinct +// per INVARIANTS P1 modeling-faithfulness + P2 single-authority. +// +// - NoEventControl β€” bare `always begin ... end` with no +// `@(...)` β€” the body uses internal +// delay control (`#10 ...`) for timing. +// Rare in practice; legal per spec. +// - ImplicitAtStar β€” `always @*` or `always @(*)` β€” +// implicit sensitivity list covering +// ALL signals read in the body (the +// Β§9.7.2 implicit-event-control form; +// recommended for combinational logic +// to avoid manual list errors). The +// implicit set is COMPUTED FROM THE +// BODY at synthesis / simulation time; +// this variant carries no payload β€” +// the body itself is the authority for +// which signals trigger the always. +// - ExplicitEventList β€” `always @(event_expression)` β€” +// explicit list of edge-triggered or +// level-sensitive entries (`posedge +// clk, negedge rst, data`). The +// `items` payload is the list of +// `SensitivityItem` entries. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§9.7.2 admits exactly +// these three event-control forms; a fourth would be a future +// language-version change requiring edit under the L-2 pin +// discipline. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every always-block consumer (the +// synthesis dispatch for flip-flop vs latch vs combinational +// inference, the implicit-set-from-body extraction, the +// explicit-list emission) branches on the form uniformly; +// shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to +// `{ items: List }` (the prior model) +// conflates NoEventControl (empty list) with ExplicitEventList +// (empty list is technically possible) AND has NO +// representation for ImplicitAtStar β€” exactly the codex +// BLOCKING finding. The Disj-with-heterogeneous-payloads is +// the dissolution: each variant carries exactly the structural +// data its form admits. +// 3. Algebraic form β€” N/A by construction: the three forms are +// the IEEE 1364-2005 spec's primitive event-control partition; +// they do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single `always` block has EXACTLY +// ONE event-control form; mutually-exclusive alternatives +// (per spec: a single `always` cannot have both an implicit +// and explicit list). +// 5. Parameterized family β€” FAILS: the three variants carry +// structurally heterogeneous payloads (NoEventControl is +// nullary; ImplicitAtStar is a nullary marker β€” the implicit +// set is computed from the body, not stored; ExplicitEventList +// carries a `List`) β€” NOT one generic `F` +// / projection over a separately-declared source set +// (Practice 7). +// Terminal: the closed three-way Verilog always-block event-control +// classifier of the IEEE 1364-2005 spec. +type AlwaysBlockSensitivity + = NoEventControl + | ImplicitAtStar + | ExplicitEventList { items: List } + + // ───────────────────────────────────────────────────────────────────── // InitialBlock β€” a Verilog `initial` block (IEEE 1364-2005 Β§9.9). // Executes its body ONCE at simulation time 0. Conj record (no From 8613a702a4227b82bb0502785a6abdd47c3033c1 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 02:29:44 +0000 Subject: [PATCH 05/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20ModuleItem=20clos?= =?UTF-8?q?ed-set-coverage=20clarification=20=E2=80=94=20match=20spice=20#?= =?UTF-8?q?3168=20deliberate-non-exhaustive=20framing=20(codex=20BLOCKING?= =?UTF-8?q?=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING inline review on PR #3176 verilog.dag:922: ModuleItem was marked 🟒 GREEN terminal closed while the file's own comment admitted scope-negative IEEE 1364-2005 Β§12.2 items (defparam, generate, specify, task, function). Internal-consistency concern: the ledger claimed terminal-spec-fidelity for a scoped subset. Fix: clarify the framing to match the spice.dag #3168 Component precedent β€” the 5-pattern Practice-4 ledger is about COPRODUCT DISSOLUTION SHAPE (do these variants need to collapse?), NOT membership completeness. Adding the named scope-negative variants is MECHANICAL (one variant per kind with body_lexeme payload for the sub-language portion) and the 5-pattern ledger STAYS UNCHANGED β€” the dissolution argument holds across the full spec set, not just the IN-B-probe-core subset enumerated here. Each pattern's reasoning extended to explicitly cover what adding the named variants would preserve. This is the spice precedent's "deliberate non-exhaustive scoping the probe permits" framing applied to ModuleItem (spice's Component does the same: controlled-source E/F/G/H, JFET, transmission line, switches NOT enumerated in initial cut). No variants added; the framing is sharpened to be internally consistent β€” terminal SHAPE, deliberately non-exhaustive MEMBERSHIP. Verification: v2-compiler compile --source-root src/v4 --target dag = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 77 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index e7702450e9f..07f2036fcec 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1045,20 +1045,43 @@ type ModuleInstance { // - ParameterDeclarationItem `parameter NAME = expr;` // - ModuleInstanceItem nested `ModuleName inst (...);` // -// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.2 admits additional -// item kinds (`defparam`, generate-blocks, specify-blocks, task / -// function declarations) β€” these are scope-negative for T-4.9 -// (`defparam` is deprecated; generate-blocks / task / function / -// specify each open a sub-language out of T-4.9's scope). A new -// item kind is an edit to THIS declaration under the L-2 pin -// discipline. +// CLOSED-SET COVERAGE (clarified per codex BLOCKING review on PR #3176 +// 2026-05-16). IEEE 1364-2005 Β§12.2 also admits `defparam` (deprecated), +// `generate` blocks, `specify` blocks, and `task` / `function` +// declarations as module items. The variants enumerated below cover +// the IN-B PROBE's CORE NEEDS β€” the parallel-composition surface, +// signal declarations, instantiation β€” which is what the T-4.9 probe +// validates. The remaining items are NOT enumerated in this initial +// cut: `defparam` is deprecated per spec, and `generate` / `specify` +// / `task` / `function` each OPEN A SUB-LANGUAGE (the recursive body +// of a generate block, the timing-check vocabulary of `specify`, the +// procedural body of a task/function) whose grammar is owned by the +// bundled T-4 LanguageModel productions when they land. Adding each +// is MECHANICAL (one variant per kind, payload as a Conj record with +// a `body_lexeme: String` for the sub-language portion β€” the same +// `AlwaysBlock.body_lexeme` precedent), and crucially the 5-pattern +// ledger BELOW STAYS UNCHANGED when those variants are added: the +// dissolution argument is about coproduct SHAPE, not membership +// completeness. This is the deliberate non-exhaustive scoping the +// probe permits (same shape as spice.dag #3168 `Component`'s +// "controlled-source variants E/F/G/H, JFET, transmission line, +// switches are NOT enumerated in this initial cut" framing β€” adding +// them is mechanical and does not affect the structural finding). +// A NEW item kind (one the spec does not list) is the C1 stop-signal +// edit; a follow-up adding the named scope-negative items is +// straightforward L-2 maintenance. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 🟒 GREEN (terminal). The ledger is about coproduct DISSOLUTION +// SHAPE (do these variants need to collapse to something simpler?), +// NOT membership completeness β€” adding the named scope-negative +// variants per the closed-set-coverage note above keeps every +// pattern's argument unchanged. Ledger β€” five patterns attempted: // 1. Fact placement β€” FAILS: every module-body consumer (emission, // port-binding resolution, sensitivity-list signal lookup, // synthesis dispatch) branches on the item kind; shared -// classifier, not scattered. +// classifier, not scattered. (Adding generate/specify/task/ +// function would extend the dispatch uniformly; same shape.) // 2. Variant-is-data β€” FAILS: each variant carries a payload of // a DIFFERENT type (`ContinuousAssign` / `AlwaysBlock` / // `InitialBlock` / `NetDeclaration` / `VariableDeclaration` / @@ -1066,26 +1089,34 @@ type ModuleInstance { // uniform `{ kind: ItemKind, … }` shape requires Option-typed // payload fields (an item carries the AlwaysBlock or NULL), // which makes "ContinuousAssign item with an AlwaysBlock -// payload" representable β€” the inverse of P2. -// 3. Algebraic form β€” N/A by construction: the seven module- -// body items are the IEEE 1364-2005 spec's primitive item -// taxonomy; they do not trace to a richer std/ algebraic -// structure. +// payload" representable β€” the inverse of P2. (Adding more +// variants with their own payload types preserves the +// heterogeneity β€” same argument.) +// 3. Algebraic form β€” N/A by construction: the module-body items +// are the IEEE 1364-2005 spec's primitive item taxonomy; they +// do not trace to a richer std/ algebraic structure. // 4. Dimensional β€” FAILS: a single item is EXACTLY ONE kind; // mutually-exclusive alternatives. (The module body as a // WHOLE is `List` β€” multiple items co-exist as // siblings, but each item is one kind. The Conj-of-siblings // IS the dimensional model the IN-B finding consumes; that // lives on `VerilogModule.items`, not on this enum.) -// 5. Parameterized family β€” FAILS: the seven variants are -// structurally heterogeneous (different payload types; the -// declaration variants carry storage-shape facts while the -// action variants carry computation-shape facts) β€” NOT one -// generic `F` / projection over a separately-declared -// source set (Practice 7). The IEEE 1364-2005 module-body -// item set is the irreducible partition. -// Terminal: the closed seven-way module-body-item classifier of the -// IEEE 1364-2005 spec. +// 5. Parameterized family β€” FAILS: the variants are structurally +// heterogeneous (different payload types; the declaration +// variants carry storage-shape facts while the action variants +// carry computation-shape facts) β€” NOT one generic `F` / +// projection over a separately-declared source set (Practice +// 7). The IEEE 1364-2005 module-body item set is the +// irreducible partition; the future scope-negative additions +// preserve heterogeneity (generate carries a body shape, +// specify carries timing-check vocabulary, task/function each +// carry a body) β€” no projection-uniformity. +// Terminal SHAPE: the closed module-body-item classifier of the +// IEEE 1364-2005 spec; the seven variants enumerated below are the +// IN-B-probe-core subset, with the named scope-negative variants +// (defparam, generate, specify, task, function) deliberately +// non-exhaustive in this initial cut. The dissolution argument +// holds across the full spec set. type ModuleItem = ContinuousAssignItem { assign: ContinuousAssign } | AlwaysBlockItem { always_block: AlwaysBlock } From 3d2e57bbd35e8ddeadfe0400b3c60e2d3133a25c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 02:32:54 +0000 Subject: [PATCH 06/56] v4 T-4.9 verilog: drop stray NetDeclaration banner orphaned by Signedness insertion (cursor APPROVE_WITH_COMMENTS on PR #3176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cursor/composer-2 APPROVE_WITH_COMMENTS finding (cosmetic): when commit cb65ea8ca inserted the Signedness block BEFORE the existing NetDeclaration block, the prior `// NetDeclaration β€” …` banner remained orphaned at the Signedness block's position. Real NetDeclaration banner + commentary follows correctly at line ~660. Removing the orphan banner so the Signedness section has its own clean header. Verification: v2-compiler compile --source-root src/v4 --target dag = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 07f2036fcec..4acc19f5f27 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -587,10 +587,6 @@ type PackingShape | Packed { range: VectorRange } -// ───────────────────────────────────────────────────────────────────── -// NetDeclaration β€” a Verilog net (`wire foo;`, `wire [7:0] bus;`, -// `wand x;`). Conj record (no Practice-4 ledger). -// // ───────────────────────────────────────────────────────────────────── // Signedness β€” the closed Verilog net/reg signedness classifier // (IEEE 1364-2005 Β§5.6 "Signed types"). The `signed` keyword on a net From f7ab620b0a70c835eaf30a3a95161beca12c4bae Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 03:45:03 +0000 Subject: [PATCH 07/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20model=20positiona?= =?UTF-8?q?l=20port=20connections=20=E2=80=94=20PortConnections=20Disj=20(?= =?UTF-8?q?codex=20BLOCKING=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING inline review on PR #3176 verilog.dag:999: PortConnection modeled only named (`.port(signal)`) connections while my own comment admitted IEEE 1364-2005 Β§12.1.2 also accepts positional connections (`Adder a1 (sig1, sig2, sig3)`). INVARIANTS P1 modeling-faithfulness violation β€” spec admits both forms; declaring positional as scope- negative excluded valid Verilog syntax. Fix β€” Disj-with-named-payloads at the port-binding-list level (where the spec's per-instance uniformity constraint lives): - Renamed PortConnection β†’ NamedPortConnection (the per-entry named connection record stays the same Conj shape: port + signal). - New PortConnections coproduct = PositionalConnections { signals: List } | NamedConnections { connections: List }. Full 5-pattern Practice-4 ledger. - ModuleInstance.connections is now PortConnections (replaces List). Result: the spec's per-instance uniform-form choice (mixed positional +named within ONE instance is a syntax error per spec) is structurally enforced β€” "mixed positional+named" is unrepresentable by construction. Positional connections are now first-class, no longer scope-negative. Verification: v2-compiler compile --source-root src/v4 --target dag = 63 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 84 +++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 4acc19f5f27..02ea392ffc4 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -978,8 +978,9 @@ type InitialBlock { // ───────────────────────────────────────────────────────────────────── -// PortConnection β€” one connection in a module-instance's port-binding -// list (IEEE 1364-2005 Β§12.1.2). Conj record (no Practice-4 ledger). +// NamedPortConnection β€” one named connection in a module-instance's +// port-binding list (IEEE 1364-2005 Β§12.1.2, named form). Conj record +// (no Practice-4 ledger). // // - port the formal port name on the instantiated module // (K-1-opaque Symbol; resolved through the namespace @@ -989,34 +990,89 @@ type InitialBlock { // context (K-1-opaque Symbol; resolved to a // `NetDeclaration` / `VariableDeclaration` / // `PortDeclaration` of the enclosing module) -// -// This is the NAMED port-connection form (`.port(signal)`) β€” the -// IEEE 1364-2005 Β§12.1.2 alternative positional form (`(signal1, -// signal2, ...)`) is scope-negative for T-4.9 (it is order-dependent -// and prone to silent reorder-bugs the spec recommends against; the -// L-2 pin discipline admits it via a future PortConnectionKind -// coproduct EDIT when consumer demand surfaces). -type PortConnection { +type NamedPortConnection { port: Symbol signal: Symbol } +// ───────────────────────────────────────────────────────────────────── +// PortConnections β€” the closed Verilog port-binding-list form +// classifier (IEEE 1364-2005 Β§12.1.2). The spec admits exactly TWO +// port-connection forms; each module-instance picks ONE form for the +// entire instance (mixing positional and named in a single instance +// is forbidden by the grammar β€” `Adder a1 (x, .b(y))` is a syntax +// error). The Disj-with-named-payloads makes "mixed positional/named" +// structurally unrepresentable (codex BLOCKING fix on PR #3176 +// 2026-05-16: the prior NAMED-ONLY model had positional connections +// scope-negative, which excluded valid spec syntax and violated +// INVARIANTS P1 modeling-faithfulness). +// +// - PositionalConnections β€” `Adder a1 (sig1, sig2, sig3)` β€” +// actuals listed in declaration-order +// position; the i-th signal binds to +// the i-th port of the instantiated +// module. Spec Β§12.1.2 "Ordered port +// connections". +// - NamedConnections β€” `Adder a1 (.a(x), .b(y), .sum(z))` +// β€” actuals explicitly bound to formals +// by name. Spec Β§12.1.2 "Named port +// connections". +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two +// port-connection forms; a third would be an edit to THIS declaration +// under the L-2 pin discipline (SystemVerilog adds `.port` shorthand +// for `.port(port)` and `.*` for "connect all matching names" β€” a +// future language-version model would EDIT this Disj explicitly). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every instance-emission consumer and +// every port-binding resolver reads the connection form +// uniformly to know whether to align by position or by name; +// shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing the variants to a uniform +// `List` where each entry has `kind: Form` +// ratifies the illegal state "mixed positional+named within +// one instance" β€” exactly the spec-forbidden form. The +// Disj-with-heterogeneous-payloads makes the per-instance +// uniform-form choice structural. +// 3. Algebraic form β€” N/A by construction: the two forms are the +// IEEE 1364-2005 spec's primitive port-connection partition; +// they do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single module instance is EXACTLY +// ONE form; mutually-exclusive alternatives. (Mixed-form is a +// syntax error per spec.) +// 5. Parameterized family β€” FAILS: the two variants carry +// structurally heterogeneous payloads (PositionalConnections +// carries `List` β€” the signal names by position only; +// NamedConnections carries `List` β€” each +// with formal+actual) β€” NOT one generic `F` / projection +// over a separately-declared source set (Practice 7). +// Terminal: the closed two-way Verilog port-connection-form +// classifier of the IEEE 1364-2005 spec. +type PortConnections + = PositionalConnections { signals: List } + | NamedConnections { connections: List } + + // ───────────────────────────────────────────────────────────────────── // ModuleInstance β€” a Verilog module instantiation (`Adder a1 (.a(x), -// .b(y), .sum(z));`). IEEE 1364-2005 Β§12.1. Conj record (no -// Practice-4 ledger). +// .b(y), .sum(z));` or `Adder a1 (x, y, sum);`). IEEE 1364-2005 Β§12.1. +// Conj record (no Practice-4 ledger). // // - module_name the instantiated module's name (K-1-opaque // Symbol; resolved through the namespace to the // matching top-level `VerilogModule`) // - instance_name this instance's local name (K-1-opaque // Symbol) -// - connections the named port-connection list +// - connections the port-binding list (PositionalConnections +// OR NamedConnections per spec Β§12.1.2; uniform +// per instance) type ModuleInstance { module_name: Symbol instance_name: Symbol - connections: List + connections: PortConnections } From 9eaf33a26f25b28be0fba707800b1be88f77958f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 00:44:48 -0400 Subject: [PATCH 08/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 88 ++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 02ea392ffc4..f66070cc4da 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -977,6 +977,69 @@ type InitialBlock { } +// ───────────────────────────────────────────────────────────────────── +// PortConnectionActual β€” the closed Verilog port-connection-actual +// classifier (IEEE 1364-2005 Β§12.1.2). The spec admits a port- +// connection's actual to be any of three forms: a full expression +// (including identifier references, literals, bit-selects, arithmetic +// β€” `.en(1'b1)`, `.data(bus[3:0])`, `.sum(a + b)`), or BLANK (an +// explicitly unconnected port β€” `.unused()`). Modeling the actual as +// a bare `Symbol` (the prior form) narrowed it to identifier +// references only, excluding valid IEEE 1364-2005 syntax β€” openai-pro +// REQUEST_CHANGES on PR #3176 surfaced this gap. INVARIANTS P1 +// modeling-faithfulness violation (the spec's port-connection-actual +// partition is wider than just identifiers). +// +// - ExpressionConnection { expression_lexeme: String } +// β€” the connection-actual is a Verilog expression carried as +// a verbatim lexeme (sub-grammar deferred to the T-4 +// LanguageModel grammar productions; the spice.dag +// `SpiceValue.lexeme` precedent β€” `parse ∘ emit` is identity +// on the textual surface; the expression-typed-fact lands +// when the bundled expression productions land). Covers +// identifier references (`.en(clk)`), literals (`.en(1'b1)`), +// bit-selects (`.data(bus[3:0])`), and arithmetic +// (`.sum(a + b)`). +// - BlankConnection +// β€” `.port_name()` β€” an explicitly unconnected port (spec +// Β§12.1.2 admits this form for documenting that a named port +// is intentionally left unconnected); nullary marker. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.1.2 admits these two +// actual-forms; a third would be an edit to THIS declaration under +// the L-2 pin discipline. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every port-connection emitter and +// every dependency-graph walker reads the actual form +// uniformly (a blank connection contributes no dependency; a +// non-blank actual contributes the expression's signal +// references); shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to `{ expression_lexeme: +// String }` where blank = empty-string conflates "intentionally +// blank" with "expression is empty string" (the lexeme `""` is +// not a valid Verilog expression); the Disj-with-named-payloads +// makes blank vs expression structurally distinct. +// 3. Algebraic form β€” N/A by construction: the two actual-forms +// are the IEEE 1364-2005 spec's port-connection-actual partition; +// they do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single port-connection actual is +// EXACTLY ONE form; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: ExpressionConnection carries a +// lexeme payload; BlankConnection is nullary β€” structurally +// heterogeneous, NOT one generic `F` / projection over a +// separately-declared source set (Practice 7). The expression +// sub-grammar is owned by the bundled T-4 LanguageModel; this +// vocabulary slice declares the actual-form partition only. +// Terminal: the closed two-way Verilog port-connection-actual +// classifier; the expression sub-grammar is deferred to T-4 +// LanguageModel. +type PortConnectionActual + = ExpressionConnection { expression_lexeme: String } + | BlankConnection + + // ───────────────────────────────────────────────────────────────────── // NamedPortConnection β€” one named connection in a module-instance's // port-binding list (IEEE 1364-2005 Β§12.1.2, named form). Conj record @@ -986,13 +1049,17 @@ type InitialBlock { // (K-1-opaque Symbol; resolved through the namespace // to the matching `PortDeclaration` on the target // module) -// - signal the actual signal identifier in the instantiating -// context (K-1-opaque Symbol; resolved to a -// `NetDeclaration` / `VariableDeclaration` / -// `PortDeclaration` of the enclosing module) +// - actual the connection's actual value β€” an expression +// (carried as a verbatim lexeme per the closed +// PortConnectionActual classifier above) or a blank +// `.port_name()` marker. The prior `signal: Symbol` +// narrowed this to identifier references only β€” +// corrected per openai-pro REQUEST_CHANGES on +// PR #3176 to admit the full spec-mandated set of +// expression actuals + blank. type NamedPortConnection { port: Symbol - signal: Symbol + actual: PortConnectionActual } @@ -1045,14 +1112,15 @@ type NamedPortConnection { // syntax error per spec.) // 5. Parameterized family β€” FAILS: the two variants carry // structurally heterogeneous payloads (PositionalConnections -// carries `List` β€” the signal names by position only; -// NamedConnections carries `List` β€” each -// with formal+actual) β€” NOT one generic `F` / projection -// over a separately-declared source set (Practice 7). +// carries `List` β€” the actuals by +// position; NamedConnections carries +// `List` β€” each with formal+actual) β€” +// NOT one generic `F` / projection over a separately- +// declared source set (Practice 7). // Terminal: the closed two-way Verilog port-connection-form // classifier of the IEEE 1364-2005 spec. type PortConnections - = PositionalConnections { signals: List } + = PositionalConnections { actuals: List } | NamedConnections { connections: List } From bdac639a9fb638fd8dfdaf58ed1a2793895c3f2f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 04:45:57 +0000 Subject: [PATCH 09/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20address=20openai-?= =?UTF-8?q?pro=20REQUEST=5FCHANGES=20=E2=80=94=20port-connection=20express?= =?UTF-8?q?ions,=20ANSI/non-ANSI=20port=20styles,=20VectorRange=20negative?= =?UTF-8?q?-index=20spec=20fidelity=20(PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro/gpt-5.5-pro REQUEST_CHANGES on PR #3176 at sha c2f06ff1 surfaced three substantive IEEE 1364-2005 spec-fidelity gaps. All three are in-pattern declaration-class refinements: 1. PORT-CONNECTION ACTUAL was modeled as `signal: Symbol`, narrowing to identifier references. Per spec Β§12.1.2 the actual can be any expression (`.en(1'b1)`, `.data(bus[3:0])`, `.sum(a + b)`) or blank (`.unused()`). INVARIANTS P1 modeling-faithfulness violation. Fix: new closed-Disj PortConnectionActual = ExpressionConnection { expression_lexeme: String } | BlankConnection. NamedPortConnection now carries `actual: PortConnectionActual` (replaces `signal: Symbol`). PositionalConnections carries `actuals: List< PortConnectionActual>` (replaces `signals: List`). Full 5-pattern Practice-4 ledger. Expression sub-grammar deferred to T-4 LanguageModel via verbatim lexeme β€” same body_lexeme precedent as AlwaysBlock / ContinuousAssign / spice.dag SpiceValue. 2. PORT DECLARATION SINGLE-AUTHORITY was over-applied to ANSI-style ports. Per spec Β§12.3.3 ANSI-style ports carry their type INLINE (`module M (input wire [7:0] data, output reg b, …);`) and body redeclaration is a syntax error. The prior "type-fact lives EXCLUSIVELY in matching body declaration" rule was correct for non-ANSI (Verilog-1995) style but wrong for ANSI (Verilog-2001 / 1364-2005 Β§12.3.3) style. INVARIANTS P1/P2 violation β€” the model forced all ports to depend on a synthetic matching body item. Fix: new closed-Disj PortDeclarationStyle = NonAnsiStyle | AnsiStyle { net_kind, packing, signedness }. PortDeclaration now carries `style: PortDeclarationStyle`. AnsiStyle carries PortAnsiTypeKind = AnsiNetType { net_type: NetType } | AnsiVariableType { var_kind: AnsiVariableKind } (the ANSI-port type-kind partition, mirroring NetType / VariableDeclaration body forms). AnsiVariableKind = AnsiReg | AnsiInteger | AnsiReal | AnsiTime | AnsiRealTime (matches the body-side variable-kind set). Full 5-pattern Practice-4 ledger on each new Disj. Both styles preserve P2 single-authority β€” just at different loci per spec. 3. VECTORRANGE scaffold (b)-bound incorrectly excluded negative indices. Per spec Β§3.10, msb and lsb constant expressions can be positive, negative, OR zero (`reg [-1:4] b;` is a spec example). The prior bound classified legal Verilog as a producer bug. Fix: corrected the scaffold (b)/(c) bounds to admit the spec's full signed-Int range for msb/lsb (including negative); the bounded-cardinality refinement is the eventual terminal shape, but it must admit the spec range, not exclude it. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics (64 reflects std/verification.dag #3183 landing on main). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 260 +++++++++++++++++++++++---- 1 file changed, 223 insertions(+), 37 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index f66070cc4da..0e179c83f4c 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -521,24 +521,35 @@ type ProceduralAssignKind // 🟑 SCAFFOLD (same bridge as std/diagnostic.dag's `Extent.ByteRange` // and ptx Dim3 raw-Int axes). With only kernel-ambient `Int` // available at the T-4.9 phase, `{ msb: Int, lsb: Int }` -// STRUCTURALLY ADMITS illegal states (negative indices; widths -// exceeding the IEEE 1364-2005 declared maximum; gaps; non- -// monotonic ranges β€” `[7:0]` is little-endian, `[0:7]` is big- -// endian, BOTH legal per spec, but `[7:7]` requires width=1 and -// `[8:0]` requires width=9). modeling-discipline.md Β§2 (illegal- -// states-unrepresentable) forbids admitting them; no bounded- -// Cardinality refinement substrate exists yet to exclude them. It -// is a TRACKED scaffold, declared with the three bridge properties -// (the precedent diagnostic.dag established 2026-05-15): -// (a) scaffold doc β€” THIS note; the carrier is provisional, not -// the terminal bounded-axis shape. -// (b) bounds on use β€” a producer MUST construct only valid -// Verilog vector ranges; until the substrate enforces it the -// invariant is producer-side, and a VectorRange violating it -// is a producer bug, not a legal value. +// STRUCTURALLY ADMITS some states the substrate cannot reject +// (extreme magnitudes far beyond any plausible bus width; degenerate +// gaps the spec doesn't formally forbid in the type system but that +// no synthesizable design uses). PER IEEE 1364-2005 Β§3.10, msb and +// lsb constant expressions ARE ALLOWED to be positive, negative, or +// zero β€” the spec explicitly admits `reg [-1:4] b;` as a legal +// example. Negative indices are NOT illegal; the prior scaffold +// bound forbidding them was a misstatement of the spec (openai-pro +// REQUEST_CHANGES on PR #3176 corrected this). The remaining +// scaffold property is that the refined substrate (when it lands) +// can carry per-axis precision and any synthesizable-subset checks +// the consumer tooling needs, while the spec-level value space β€” +// signed Int for msb/lsb β€” stays admissible. `[7:0]` is little- +// endian, `[0:7]` is big-endian, `[-1:4]` is signed-msb; +// all legal. It is a TRACKED scaffold, declared with the three +// bridge properties (the precedent diagnostic.dag established +// 2026-05-15): +// (a) scaffold doc β€” THIS note; the carrier is provisional. The +// bounded-Cardinality refinement is the terminal shape; for +// now the spec's full Int range is the producer-side bound. +// (b) bounds on use β€” a producer MUST construct only ranges +// admitted by IEEE 1364-2005 Β§3.10 (msb and lsb are any +// signed Int per spec; negative values are legal); until the +// substrate enforces additional per-synthesis-tool bounds, +// those tighter bounds (if any) are producer-side. // (c) dissolution trigger β€” when std/cardinality.dag's refinement // substrate lands (T-3, P4 decidability), `msb` / `lsb` become -// refined bounded-Int axes, and this scaffold dissolves. +// refined signed-Int axes (admitting the spec's full range +// including negatives), and this scaffold dissolves. type VectorRange { msb: Int lsb: Int @@ -777,35 +788,210 @@ type VariableDeclaration | RealTimeVariable { name: Symbol } +// ───────────────────────────────────────────────────────────────────── +// PortDeclarationStyle β€” the closed Verilog port-declaration-style +// classifier (IEEE 1364-2005 Β§12.3.3, Β§12.3.4). The spec admits TWO +// port-declaration styles and they place the type-fact in +// STRUCTURALLY DIFFERENT loci β€” a single-authority constraint that +// only works when the model captures the style choice (openai-pro +// REQUEST_CHANGES on PR #3176 surfaced this gap; the prior +// "type-fact lives EXCLUSIVELY in matching body declaration" framing +// was correct for non-ANSI style but WRONG for ANSI-style ports, +// where the spec says the port declaration is "completely declared" +// and a redeclaration in the body is an ERROR per Β§12.3.3). +// +// - NonAnsiStyle +// β€” `module M (a, b, c); input wire [7:0] a; output reg b; …` +// (legacy / Verilog-1995 style). The header lists port names +// only; the type, direction, width, and signedness facts come +// from MATCHING NetDeclaration / VariableDeclaration items +// inside the module body. The port's authority for type/width/ +// signedness is the matching body declaration. +// - AnsiStyle { net_kind: PortAnsiTypeKind, packing: PackingShape, +// signedness: Signedness } +// β€” `module M (input wire [7:0] a, output reg b, …);` +// (Verilog-2001 / 1364-2005 Β§12.3.3 ANSI style). The header +// carries the port's type, width, and signedness directly; +// the port declaration is "completely declared" per spec. +// Redeclaring in the body is a SYNTAX ERROR per Β§12.3.3 β€” +// the spec's single-authority constraint, structurally +// enforced because an AnsiStyle port has the type-fact ON +// this variant and consumers do not look up a matching body +// declaration. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two +// port-declaration styles; SystemVerilog adds further forms (e.g. +// `interface` ports) β€” a future language-version model EDITS this +// Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every port-emission consumer and +// every type-resolution walker reads the style uniformly to +// know WHERE the type-fact lives (header for ANSI / body +// lookup for non-ANSI); shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to `{ ansi: Bool, type: +// Option<…> }` would let `ansi=true` co-exist with `type=None` +// (ANSI without inline type β€” a spec violation) or `ansi= +// false` with `type=Some(…)` (non-ANSI port carrying its own +// type β€” a spec violation since non-ANSI ports get types from +// the body). The Disj-with-named-payloads makes both illegal +// states structurally unrepresentable. +// 3. Algebraic form β€” N/A by construction: the two styles are +// IEEE 1364-2005 spec's primitive port-declaration partition; +// they do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single port declaration is EXACTLY +// ONE style; mutually-exclusive alternatives. (The spec +// forbids mixing styles within one module β€” Β§12.3.4.) +// 5. Parameterized family β€” FAILS: NonAnsiStyle is nullary +// (type-fact deferred to the body lookup); AnsiStyle carries +// net-kind + packing + signedness payload (type-fact in the +// header) β€” structurally heterogeneous, NOT one generic +// `F` / projection over a separately-declared source set +// (Practice 7). +// Terminal: the closed two-way Verilog port-declaration-style +// classifier of the IEEE 1364-2005 spec. +type PortDeclarationStyle + = NonAnsiStyle + | AnsiStyle { net_kind: PortAnsiTypeKind, packing: PackingShape, signedness: Signedness } + + +// ───────────────────────────────────────────────────────────────────── +// PortAnsiTypeKind β€” the closed Verilog ANSI-port-type-kind +// classifier (IEEE 1364-2005 Β§12.3.3). An ANSI-style port carrying +// its own type declares EITHER a net-type or a variable-type; per +// spec a port with `output reg` is a register-typed port (procedural- +// assignable from within the module), while a port with `output +// wire` is a net-typed port. +// +// - AnsiNetType { net_type: NetType } +// β€” `input wire`, `output wand`, etc. The port's type is a +// net resolution from the closed NetType set. +// - AnsiVariableType { var_kind: AnsiVariableKind } +// β€” `output reg`, `output integer`, `output real`, `output +// time`, `output realtime`. The port's type is a variable +// kind from the closed AnsiVariableKind set below (excludes +// the per-variant payload fields of the body-side +// VariableDeclaration β€” those payloads represent body-side +// declarations, while AnsiVariableType is the port-side +// declaration's type-kind only; the port's packing / +// signedness live on the enclosing AnsiStyle, not here). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits these two +// ANSI-port-type-kind partitions; a future language-version model +// would EDIT this Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: ANSI-port consumers branch on the +// kind uniformly to know whether the port is net-typed (wire +// family) or variable-typed (reg family); shared classifier, +// not scattered. +// 2. Variant-is-data β€” FAILS: a `{ kind: Symbol }` proxy reopens +// K-1's foreclosed readable-string heuristic surface (a +// `match kind { "net" => … }` smell). The enum IS the M4- +// faithful form. +// 3. Algebraic form β€” N/A by construction: the two kinds are +// the net-vs-variable distinction of the IEEE 1364-2005 +// type system; they do not trace to a richer std/ algebraic +// structure. +// 4. Dimensional β€” FAILS: an ANSI port has EXACTLY ONE type-kind; +// mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: each variant carries a +// DIFFERENT payload type (NetType vs AnsiVariableKind) β€” +// structurally heterogeneous, NOT one generic `F` / +// projection over a single source set (Practice 7). +// Terminal: the closed two-way Verilog ANSI-port-type-kind +// classifier of the IEEE 1364-2005 spec. +type PortAnsiTypeKind + = AnsiNetType { net_type: NetType } + | AnsiVariableType { var_kind: AnsiVariableKind } + + +// ───────────────────────────────────────────────────────────────────── +// AnsiVariableKind β€” the closed Verilog ANSI-variable-port-type +// classifier (IEEE 1364-2005 Β§12.3.3). The variable-type set valid +// for ANSI ports matches the VariableDeclaration kind set; this +// nullary enum carries the KIND only (the per-kind payloads β€” name, +// packing, signedness for RegVariable β€” are factored into the +// enclosing AnsiStyle to keep cross-form (NonAnsi vs Ansi) packing/ +// signedness reuse single-authority). +// +// - AnsiReg β€” `output reg name` +// - AnsiInteger β€” `output integer name` +// - AnsiReal β€” `output real name` +// - AnsiTime β€” `output time name` +// - AnsiRealTime β€” `output realtime name` +// +// CLOSED (C1 stop-signal). Matches the VariableDeclaration variant +// kind set per spec Β§12.3.3. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every ANSI-variable-port consumer +// reads the kind uniformly to dispatch emission / type-check +// legality; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: a `{ keyword: Symbol }` proxy +// reopens the readable-string heuristic surface K-1 +// forecloses. The enum IS the M4-faithful form. +// 3. Algebraic form β€” PARTIAL: each variant grounds in the same +// std/algebra structure its body-side VariableDeclaration +// counterpart grounds in (AnsiReg β†’ Semiring/OrderedRing per +// packingΓ—signedness; AnsiInteger β†’ OrderedRing>; +// AnsiReal/AnsiRealTime β†’ ApproximateField; AnsiTime +// β†’ Semiring>); D2-deferred per "Owned ELSEWHERE". +// 4. Dimensional β€” FAILS: an ANSI variable port has EXACTLY ONE +// kind; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the five are structurally +// heterogeneous in their underlying std/algebra grounding +// (same argument as VariableDeclaration's ledger) β€” NOT one +// generic `F` / projection over a separately-declared +// source set (Practice 7). +// Terminal: the closed five-way ANSI-variable-port-kind +// classifier; mirrors VariableDeclaration's kind-partition under +// the IEEE 1364-2005 Β§12.3.3 ANSI-port admissibility rules. +type AnsiVariableKind + = AnsiReg + | AnsiInteger + | AnsiReal + | AnsiTime + | AnsiRealTime + + // ───────────────────────────────────────────────────────────────────── // PortDeclaration β€” a Verilog module port (`input clk`, `output [7:0] -// data`, `inout wire bidir_bus`). Conj record (no Practice-4 ledger). +// data`, `output reg signed [3:0] count`, …). Conj record (no +// Practice-4 ledger). // // - direction input / output / inout // - name the port identifier (K-1-opaque Symbol) -// -// Per IEEE 1364-2005 Β§12.3.3 a port can carry a per-port net-type or -// variable-type modifier (`output reg [7:0] data` makes the port -// BOTH a port and a procedural-assignment destination); that modifier -// is the MATCHING `NetDeclaration` or `VariableDeclaration` in the -// module body's items list. SINGLE-AUTHORITY DISCIPLINE (INVARIANTS -// P2, codex BLOCKING review on PR #3176): the width / packing / -// type-fact lives EXCLUSIVELY in the matching declaration, NOT -// duplicated as a `packing: PackingShape` field here. The port's -// `name` is the cross-reference; downstream consumers (the bundled -// T-4 LanguageModel grammar productions for emission; the well- -// formedness check that every port has exactly one matching -// declaration) resolve the type through the name lookup. The prior -// `packing: PackingShape` field on this record was a parallel -// representation of the width that the matching Net/Variable -// declaration ALSO carries β€” exactly the P2 cost-of-change β‰₯ 2 -// duplicate-authority anti-pattern the codex review surfaced. The -// inline form `input wire [7:0] data` is a parser convenience that -// produces TWO items in the module body (the port declaration here -// + the matching NetDeclaration), preserving single-authority. +// - style which port-declaration style applies (non-ANSI = +// type comes from a matching body NetDeclaration / +// VariableDeclaration; ANSI = type carried inline on +// this declaration, per the AnsiStyle payload). +// +// IEEE 1364-2005 Β§12.3.3 β€” Β§12.3.4 admit two port-declaration styles +// with STRUCTURALLY DIFFERENT type-locus rules (corrected per openai- +// pro REQUEST_CHANGES on PR #3176; the prior "type-fact lives +// EXCLUSIVELY in matching body declaration" framing was over-applied +// β€” it's correct for non-ANSI, but ANSI-style ports declare their +// type INLINE and per Β§12.3.3 a body redeclaration is a syntax +// error). The PortDeclarationStyle Disj makes the locus partition +// structural: +// - NonAnsiStyle β†’ the type/packing/signedness facts come from +// the matching body NetDeclaration / VariableDeclaration; the +// port's `name` is the cross-reference (the prior single- +// authority discipline applied to this style). +// - AnsiStyle { net_kind, packing, signedness } β†’ the type/ +// packing/signedness facts are CARRIED INLINE on this port +// declaration; per spec Β§12.3.3 a body redeclaration is an +// error (the spec's structural single-authority enforcement). +// Either style preserves INVARIANTS P2 single-authority β€” just at +// different loci per spec. type PortDeclaration { direction: PortDirection name: Symbol + style: PortDeclarationStyle } From 491f78429d89124226df781c777acbe3fb8894d5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 05:06:36 +0000 Subject: [PATCH 10/56] v4 T-4.9 verilog: module-level port-list style Disj + ModuleInstance parameter-overrides (codex BLOCKING on PR #3176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING at sha 96f57080 surfaced two substantive spec-fidelity gaps. Both in-pattern declaration-class refinements: 1. PORT-LIST STYLE was modeled as a PER-PORT `style: PortDeclaration Style` field, which admitted the IEEE 1364-2005 Β§12.3.4 spec- forbidden mixed-style state within one module. The spec admits two port-list styles (non-ANSI / ANSI) MUTUALLY EXCLUSIVE PER MODULE β€” the style choice belongs on the module's port-list as a whole. Fix: - Removed PortDeclarationStyle Disj (dissolved into the new module-level partition). - PortDeclaration now carries only direction + name (the non-ANSI form β€” type-fact in matching body declaration). - New AnsiPortDeclaration Conj record carries direction + name + net_kind + packing + signedness inline (the ANSI form per spec Β§12.3.3). - New closed-Disj ModulePortsList = NonAnsiPorts { ports: List } | AnsiPorts { ports: List } with full 5-pattern Practice-4 ledger. - VerilogModule.ports now ModulePortsList (replaces List). Mixed-style within one module is unrepresentable by construction. 2. MODULE INSTANCE OMITTED parameter-override carrier (`Adder #(.WIDTH(8)) a1 (...)` per spec Β§12.1.3). The prior ModuleInstance had module_name + instance_name + connections only; the Β§12.1 parameterized-instantiation surface was unrepresentable. Fix: - New ParameterOverrides Disj = NoParameterOverrides | OrderedParameterOverrides { actuals: List } | NamedParameterOverrides { overrides: List } with full 5-pattern Practice-4 ledger. Expression-actuals carried as verbatim lexemes per the body_lexeme precedent. Mixed ordered+named within one #(...) clause is unrepresentable per spec. - ModuleInstance now carries parameter_overrides: ParameterOverrides before connections. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 328 ++++++++++++++++++--------- 1 file changed, 221 insertions(+), 107 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 0e179c83f4c..2a5bc825e25 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -788,72 +788,15 @@ type VariableDeclaration | RealTimeVariable { name: Symbol } -// ───────────────────────────────────────────────────────────────────── -// PortDeclarationStyle β€” the closed Verilog port-declaration-style -// classifier (IEEE 1364-2005 Β§12.3.3, Β§12.3.4). The spec admits TWO -// port-declaration styles and they place the type-fact in -// STRUCTURALLY DIFFERENT loci β€” a single-authority constraint that -// only works when the model captures the style choice (openai-pro -// REQUEST_CHANGES on PR #3176 surfaced this gap; the prior -// "type-fact lives EXCLUSIVELY in matching body declaration" framing -// was correct for non-ANSI style but WRONG for ANSI-style ports, -// where the spec says the port declaration is "completely declared" -// and a redeclaration in the body is an ERROR per Β§12.3.3). -// -// - NonAnsiStyle -// β€” `module M (a, b, c); input wire [7:0] a; output reg b; …` -// (legacy / Verilog-1995 style). The header lists port names -// only; the type, direction, width, and signedness facts come -// from MATCHING NetDeclaration / VariableDeclaration items -// inside the module body. The port's authority for type/width/ -// signedness is the matching body declaration. -// - AnsiStyle { net_kind: PortAnsiTypeKind, packing: PackingShape, -// signedness: Signedness } -// β€” `module M (input wire [7:0] a, output reg b, …);` -// (Verilog-2001 / 1364-2005 Β§12.3.3 ANSI style). The header -// carries the port's type, width, and signedness directly; -// the port declaration is "completely declared" per spec. -// Redeclaring in the body is a SYNTAX ERROR per Β§12.3.3 β€” -// the spec's single-authority constraint, structurally -// enforced because an AnsiStyle port has the type-fact ON -// this variant and consumers do not look up a matching body -// declaration. -// -// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two -// port-declaration styles; SystemVerilog adds further forms (e.g. -// `interface` ports) β€” a future language-version model EDITS this -// Disj explicitly. -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every port-emission consumer and -// every type-resolution walker reads the style uniformly to -// know WHERE the type-fact lives (header for ANSI / body -// lookup for non-ANSI); shared classifier, not scattered. -// 2. Variant-is-data β€” FAILS: collapsing to `{ ansi: Bool, type: -// Option<…> }` would let `ansi=true` co-exist with `type=None` -// (ANSI without inline type β€” a spec violation) or `ansi= -// false` with `type=Some(…)` (non-ANSI port carrying its own -// type β€” a spec violation since non-ANSI ports get types from -// the body). The Disj-with-named-payloads makes both illegal -// states structurally unrepresentable. -// 3. Algebraic form β€” N/A by construction: the two styles are -// IEEE 1364-2005 spec's primitive port-declaration partition; -// they do not trace to a richer std/ algebraic structure. -// 4. Dimensional β€” FAILS: a single port declaration is EXACTLY -// ONE style; mutually-exclusive alternatives. (The spec -// forbids mixing styles within one module β€” Β§12.3.4.) -// 5. Parameterized family β€” FAILS: NonAnsiStyle is nullary -// (type-fact deferred to the body lookup); AnsiStyle carries -// net-kind + packing + signedness payload (type-fact in the -// header) β€” structurally heterogeneous, NOT one generic -// `F` / projection over a separately-declared source set -// (Practice 7). -// Terminal: the closed two-way Verilog port-declaration-style -// classifier of the IEEE 1364-2005 spec. -type PortDeclarationStyle - = NonAnsiStyle - | AnsiStyle { net_kind: PortAnsiTypeKind, packing: PackingShape, signedness: Signedness } +// (PortDeclarationStyle has been dissolved into ModulePortsList's +// Disj-with-named-payloads at the MODULE level β€” IEEE 1364-2005 +// Β§12.3.4 forbids mixing ANSI and non-ANSI styles within ONE module, +// so the style-choice belongs on the module's port-list as a whole, +// not as a per-port field. The prior per-port `style: PortDeclaration +// Style` admitted the spec-forbidden mixed-style state (codex BLOCKING +// review on PR #3176 surfaced this β€” the per-port encoding was a +// product-axis miscarve relative to the spec's module-header +// partition). See ModulePortsList below.) // ───────────────────────────────────────────────────────────────────── @@ -959,42 +902,120 @@ type AnsiVariableKind // ───────────────────────────────────────────────────────────────────── -// PortDeclaration β€” a Verilog module port (`input clk`, `output [7:0] -// data`, `output reg signed [3:0] count`, …). Conj record (no -// Practice-4 ledger). +// PortDeclaration β€” a non-ANSI-style Verilog module port (`module M +// (a, b, c); input wire [7:0] a; output reg b; …`). The header lists +// port direction + name; the type/packing/signedness facts come from +// a MATCHING `NetDeclaration` / `VariableDeclaration` in the module +// body's items list. Conj record (no Practice-4 ledger). // // - direction input / output / inout -// - name the port identifier (K-1-opaque Symbol) -// - style which port-declaration style applies (non-ANSI = -// type comes from a matching body NetDeclaration / -// VariableDeclaration; ANSI = type carried inline on -// this declaration, per the AnsiStyle payload). -// -// IEEE 1364-2005 Β§12.3.3 β€” Β§12.3.4 admit two port-declaration styles -// with STRUCTURALLY DIFFERENT type-locus rules (corrected per openai- -// pro REQUEST_CHANGES on PR #3176; the prior "type-fact lives -// EXCLUSIVELY in matching body declaration" framing was over-applied -// β€” it's correct for non-ANSI, but ANSI-style ports declare their -// type INLINE and per Β§12.3.3 a body redeclaration is a syntax -// error). The PortDeclarationStyle Disj makes the locus partition -// structural: -// - NonAnsiStyle β†’ the type/packing/signedness facts come from -// the matching body NetDeclaration / VariableDeclaration; the -// port's `name` is the cross-reference (the prior single- -// authority discipline applied to this style). -// - AnsiStyle { net_kind, packing, signedness } β†’ the type/ -// packing/signedness facts are CARRIED INLINE on this port -// declaration; per spec Β§12.3.3 a body redeclaration is an -// error (the spec's structural single-authority enforcement). -// Either style preserves INVARIANTS P2 single-authority β€” just at -// different loci per spec. +// - name the port identifier (K-1-opaque Symbol; resolves +// through the namespace to the matching body +// Net/Variable declaration that carries the type-fact) +// +// Per IEEE 1364-2005 Β§12.3.4 a module's port-list is uniformly EITHER +// non-ANSI (this record's form) OR ANSI (AnsiPortDeclaration below); +// mixing styles within one module is forbidden. The +// ModulePortsList Disj makes that uniformity structural at the +// module level. type PortDeclaration { direction: PortDirection name: Symbol - style: PortDeclarationStyle } +// ───────────────────────────────────────────────────────────────────── +// AnsiPortDeclaration β€” an ANSI-style Verilog module port (`module M +// (input wire [7:0] a, output reg b, output reg signed [3:0] count, +// …);`). The header carries direction, name, AND the full type/ +// packing/signedness facts INLINE. Per IEEE 1364-2005 Β§12.3.3 the +// port declaration is "completely declared" by this single carrier; +// a body redeclaration is a SYNTAX ERROR β€” single-authority enforced +// structurally because the type-fact lives ON this record, not in a +// matching body item. Conj record (no Practice-4 ledger). +// +// - direction input / output / inout +// - name the port identifier (K-1-opaque Symbol) +// - net_kind net-type vs variable-kind (PortAnsiTypeKind β€” +// AnsiNetType { net_type } | AnsiVariableType +// { var_kind }) +// - packing scalar or `[msb:lsb]` packed bit-vector +// - signedness `signed` keyword present / absent (IEEE 1364-2005 +// Β§5.6) +type AnsiPortDeclaration { + direction: PortDirection + name: Symbol + net_kind: PortAnsiTypeKind + packing: PackingShape + signedness: Signedness +} + + +// ───────────────────────────────────────────────────────────────────── +// ModulePortsList β€” the closed Verilog module-ports-list-style +// classifier (IEEE 1364-2005 Β§12.3.4). The spec admits two port-list +// styles and they are MUTUALLY EXCLUSIVE PER MODULE: a single module +// declares its entire port list in EITHER non-ANSI style (port names +// in header + matching body declarations) OR ANSI style (full type- +// fact inline in header). Mixing styles within one module is a syntax +// error per Β§12.3.4. The Disj-with-named-payloads makes that +// uniformity structural at the module-list level β€” the prior per-port +// `style: PortDeclarationStyle` field admitted the spec-forbidden +// mixed state (codex BLOCKING review on PR #3176 corrected this; the +// per-port encoding was a product-axis miscarve relative to the spec's +// module-header partition). +// +// - NonAnsiPorts { ports: List } +// β€” the entire module's port list is non-ANSI style; each port +// declares direction + name only and the type-fact comes from +// the matching body Net/Variable declaration. The spec's +// Verilog-1995 module-header form. +// - AnsiPorts { ports: List } +// β€” the entire module's port list is ANSI style; each port +// carries direction + name + inline net_kind + packing + +// signedness. The spec's Verilog-2001 / 1364-2005 Β§12.3.3 +// module-header form. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two +// module-port-list styles; SystemVerilog adds `.name`-shorthand and +// interface ports β€” a future language-version model would EDIT this +// Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every module-port-list emitter and +// every type-resolution walker reads the style uniformly to +// know WHERE the type-fact lives across the entire port list +// (header for ANSI / body lookup for non-ANSI); shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ ports: +// List, ansi: Bool }` ratifies the +// spec-forbidden mixed-style state (an `ansi=false` flag with +// ANSI-typed elements, or vice versa) β€” INVARIANTS P2 +// illegal-states-unrepresentable anti-pattern (this PR's +// BLOCKING fix exists to dissolve). The Disj-with-typed- +// payload-lists makes mixed-style unrepresentable by +// construction. +// 3. Algebraic form β€” N/A by construction: the two styles are +// the IEEE 1364-2005 module-header primitive partition; they +// do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single module's port-list is EXACTLY +// ONE style; mutually-exclusive alternatives per Β§12.3.4. +// 5. Parameterized family β€” FAILS: the two variants carry +// structurally heterogeneous payload-element types +// (NonAnsiPorts.ports: List with direction + +// name only; AnsiPorts.ports: List with +// direction + name + net_kind + packing + signedness) β€” NOT +// one generic `F` / projection over a single source set +// (Practice 7). The list-element-shape difference IS the +// partition's defining structural fact. +// Terminal: the closed two-way Verilog module-ports-list-style +// classifier of the IEEE 1364-2005 spec. +type ModulePortsList + = NonAnsiPorts { ports: List } + | AnsiPorts { ports: List } + + // ───────────────────────────────────────────────────────────────────── // ParameterDeclaration β€” a Verilog compile-time constant // (`parameter WIDTH = 8;`). Conj record (no Practice-4 ledger). @@ -1310,22 +1331,110 @@ type PortConnections | NamedConnections { connections: List } +// ───────────────────────────────────────────────────────────────────── +// NamedParameterOverride β€” one named parameter override on a module +// instantiation (`.WIDTH(8)`). IEEE 1364-2005 Β§12.1.3. Conj record +// (no Practice-4 ledger). +// +// - parameter the formal parameter name on the instantiated +// module (K-1-opaque Symbol; resolves to a matching +// ParameterDeclaration on the target module) +// - actual the override value as a verbatim lexeme (expression +// sub-grammar deferred to the T-4 LanguageModel β€” +// same precedent as PortConnectionActual / +// ParameterDeclaration.default_lexeme) +type NamedParameterOverride { + parameter: Symbol + actual: String +} + + +// ───────────────────────────────────────────────────────────────────── +// ParameterOverrides β€” the closed Verilog module-instance parameter- +// override classifier (IEEE 1364-2005 Β§12.1.3). A module +// instantiation can override the instantiated module's parameter +// declarations via the `#(...)` syntax (`Adder #(.WIDTH(8)) a1 +// (.a(x), .b(y))` named form, or `Adder #(8) a1 (x, y)` ordered +// form), or omit overrides entirely. The spec admits three mutually- +// exclusive forms; modeling parameter-overrides as omitted (the prior +// ModuleInstance shape) excluded valid Verilog syntax that +// parameterized instantiations depend on (codex BLOCKING review on +// PR #3176). INVARIANTS P1 modeling-faithfulness violation. +// +// - NoParameterOverrides +// β€” `Adder a1 (.a(x), .b(y))` β€” no `#(...)` clause; the +// instantiated module uses its declared default-parameter +// values. +// - OrderedParameterOverrides { actuals: List } +// β€” `Adder #(8, 16) a1 (...)` β€” overrides listed in +// declaration-order position; the i-th actual overrides the +// i-th parameter of the instantiated module. Each actual is a +// verbatim expression lexeme. +// - NamedParameterOverrides { overrides: List } +// β€” `Adder #(.WIDTH(8), .DEPTH(16)) a1 (...)` β€” overrides +// explicitly bound to formals by name. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.1.3 admits exactly +// these three parameter-override forms; mixing ordered and named +// within one `#(...)` clause is a syntax error per spec β€” the Disj- +// with-named-payloads makes that uniform-form choice structural +// (same shape as PortConnections). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every instance-emission consumer and +// every parameter-resolution walker reads the override form +// uniformly; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing the three forms to a +// uniform `{ named?: List<...>, ordered?: List<...> }` ratifies +// "both named and ordered in one clause" β€” exactly the spec- +// forbidden mixed form. The Disj makes per-instance uniformity +// structural. +// 3. Algebraic form β€” N/A by construction: the three forms are +// the IEEE 1364-2005 spec's parameter-override partition; they +// do not trace to a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single module instance has EXACTLY +// ONE parameter-override form; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: NoParameterOverrides is +// nullary; OrderedParameterOverrides carries +// `List` (verbatim expression lexemes by position); +// NamedParameterOverrides carries `List` +// (each with formal + actual) β€” structurally heterogeneous, +// NOT one generic `F` / projection over a single source set +// (Practice 7). +// Terminal: the closed three-way Verilog module-instance parameter- +// override classifier of the IEEE 1364-2005 spec. +type ParameterOverrides + = NoParameterOverrides + | OrderedParameterOverrides { actuals: List } + | NamedParameterOverrides { overrides: List } + + // ───────────────────────────────────────────────────────────────────── // ModuleInstance β€” a Verilog module instantiation (`Adder a1 (.a(x), -// .b(y), .sum(z));` or `Adder a1 (x, y, sum);`). IEEE 1364-2005 Β§12.1. -// Conj record (no Practice-4 ledger). +// .b(y), .sum(z));` or `Adder a1 (x, y, sum);` or `Adder #(.WIDTH(8)) +// a1 (...)`). IEEE 1364-2005 Β§12.1. Conj record (no Practice-4 +// ledger). // -// - module_name the instantiated module's name (K-1-opaque -// Symbol; resolved through the namespace to the -// matching top-level `VerilogModule`) -// - instance_name this instance's local name (K-1-opaque -// Symbol) -// - connections the port-binding list (PositionalConnections -// OR NamedConnections per spec Β§12.1.2; uniform -// per instance) +// - module_name the instantiated module's name (K-1- +// opaque Symbol; resolved through the +// namespace to the matching top-level +// `VerilogModule`) +// - instance_name this instance's local name (K-1-opaque +// Symbol) +// - parameter_overrides the `#(...)` parameter-override clause β€” +// none, ordered, or named per spec Β§12.1.3 +// (corrected per codex BLOCKING on +// PR #3176: the prior ModuleInstance had +// NO parameter-override carrier, omitting +// a Β§12.1 spec construct). +// - connections the port-binding list (PositionalConnections +// OR NamedConnections per spec Β§12.1.2; +// uniform per instance) type ModuleInstance { module_name: Symbol instance_name: Symbol + parameter_overrides: ParameterOverrides connections: PortConnections } @@ -1439,8 +1548,13 @@ type ModuleItem // Practice-4 ledger). // // - name the module identifier (K-1-opaque Symbol) -// - ports the port-declaration list (the module's external -// interface) +// - ports the port-declaration list as a ModulePortsList Disj +// (NonAnsiPorts OR AnsiPorts per spec Β§12.3.4; +// uniform per module β€” mixing styles in one module is +// a syntax error). Corrected from `List` +// per codex BLOCKING on PR #3176: the prior per-port +// style encoding admitted the spec-forbidden mixed +// state. // - items the module-body items list (the Conj of parallel // siblings β€” the IN-B parallel-composition surface) // @@ -1452,7 +1566,7 @@ type ModuleItem // feedback_no_annotations). type VerilogModule { name: Symbol - ports: List + ports: ModulePortsList items: List } From c705f0b7082837ed5f6819318ccf29340410b61e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 05:09:26 +0000 Subject: [PATCH 11/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20PortAnsiTypeKind?= =?UTF-8?q?=20per-variant=20packing/signedness=20payloads=20=E2=80=94=20il?= =?UTF-8?q?legal=20ANSI=20states=20unrepresentable=20(codex=20BLOCKING=20o?= =?UTF-8?q?n=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING inline review on PR #3176: my prior AnsiPortDeclaration uniformly applied `packing` + `signedness` to every variant of PortAnsiTypeKind (including AnsiVariableKind = AnsiInteger / AnsiReal / AnsiTime / AnsiRealTime), but IEEE 1364-2005 Β§3.7.2 / Β§5.6 forbid packing AND signedness modifiers on integer/real/time/realtime variable kinds (integer is spec-fixed 32-bit signed; real / realtime are floating-point; time is spec-fixed 64-bit unsigned). The uniform-payload encoding admitted spec-forbidden states like `output integer signed [N:0]`. INVARIANTS P2 illegal-states-unrepresentable violation β€” same shape my body-side VariableDeclaration Disj already dissolves. Fix: - Restructured PortAnsiTypeKind from a two-variant Disj (AnsiNetType / AnsiVariableType { var_kind: AnsiVariableKind }) to a SIX-variant Disj-with-heterogeneous-payloads: AnsiNetType { net_type, packing, signedness } AnsiRegType { packing, signedness } AnsiIntegerType // no packing, no sign AnsiRealType // no packing, no sign AnsiTimeType // no packing, no sign AnsiRealTimeType // no packing, no sign - Dissolved AnsiVariableKind (the nullary 5-way enum subsumed by per-variant payloads on PortAnsiTypeKind). - AnsiPortDeclaration dropped its uniform packing + signedness fields (now per-variant on type_kind). Mirror of body-side VariableDeclaration's kind Γ— packing Γ— signedness dissolution. - Full 5-pattern Practice-4 ledger on the new PortAnsiTypeKind. Result: illegal states like `output integer signed`, `output real [7:0]`, `output time signed`, `output realtime [N:0]` are unrepresentable by construction. Mirrors body-side VariableDeclaration P2 dissolution. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 212 +++++++++++++-------------- 1 file changed, 100 insertions(+), 112 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 2a5bc825e25..2f3db30de88 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -800,105 +800,89 @@ type VariableDeclaration // ───────────────────────────────────────────────────────────────────── -// PortAnsiTypeKind β€” the closed Verilog ANSI-port-type-kind -// classifier (IEEE 1364-2005 Β§12.3.3). An ANSI-style port carrying -// its own type declares EITHER a net-type or a variable-type; per -// spec a port with `output reg` is a register-typed port (procedural- -// assignable from within the module), while a port with `output -// wire` is a net-typed port. -// -// - AnsiNetType { net_type: NetType } -// β€” `input wire`, `output wand`, etc. The port's type is a -// net resolution from the closed NetType set. -// - AnsiVariableType { var_kind: AnsiVariableKind } -// β€” `output reg`, `output integer`, `output real`, `output -// time`, `output realtime`. The port's type is a variable -// kind from the closed AnsiVariableKind set below (excludes -// the per-variant payload fields of the body-side -// VariableDeclaration β€” those payloads represent body-side -// declarations, while AnsiVariableType is the port-side -// declaration's type-kind only; the port's packing / -// signedness live on the enclosing AnsiStyle, not here). -// -// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits these two -// ANSI-port-type-kind partitions; a future language-version model -// would EDIT this Disj explicitly. +// PortAnsiTypeKind β€” the closed Verilog ANSI-port type/kind +// classifier (IEEE 1364-2005 Β§12.3.3, Β§5.6, Β§5.7). An ANSI-style port +// declares EITHER a net-type or a variable-kind; spec-admissibility +// of `packing` and `signedness` modifiers DIFFERS per variant β€” only +// net-types and `reg` admit them, the spec-fixed-width variable kinds +// (integer/real/time/realtime) forbid them. The kind Γ— packing Γ— sign +// admissibility is modeled STRUCTURALLY via Disj-with-heterogeneous- +// payloads: only the variants whose spec form admits packing/sign +// carry those payloads (codex BLOCKING fix on PR #3176 β€” the prior +// uniform `packing + signedness` on every ANSI-port admitted spec- +// forbidden states like `output integer signed [N:0]`, mirroring +// what the body-side VariableDeclaration Disj already dissolves). +// +// - AnsiNetType { net_type: NetType, packing: PackingShape, +// signedness: Signedness } +// β€” `input wire`, `output wand`, `inout tri0`, etc. Net ports +// admit any net-type from the closed NetType set, any +// PackingShape, and any signedness (per IEEE 1364-2005 Β§5.6). +// - AnsiRegType { packing: PackingShape, signedness: Signedness } +// β€” `output reg [N:0]`, `output reg signed`, etc. Reg-typed +// ANSI ports admit both packing and signedness (Β§5.6). +// - AnsiIntegerType +// β€” `output integer`. Spec-fixed 32-bit signed (Β§3.7.2); NO +// packing, NO signedness modifier. +// - AnsiRealType +// β€” `output real`. IEEE-754 double; NO packing, NO signedness +// (sign is internal to IEEE-754). +// - AnsiTimeType +// β€” `output time`. Spec-fixed 64-bit unsigned (Β§3.7.2); NO +// packing, NO signedness modifier. +// - AnsiRealTimeType +// β€” `output realtime`. Aliased to `real` per Β§3.7.2; NO +// packing, NO signedness modifier (parse∘emit preserves the +// keyword choice). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits this six- +// way ANSI-port type/kind partition; a future language-version model +// (SystemVerilog `logic`/`bit`/etc.) would EDIT this Disj explicitly. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” // 🟒 GREEN (terminal). Ledger β€” five patterns attempted: // 1. Fact placement β€” FAILS: ANSI-port consumers branch on the -// kind uniformly to know whether the port is net-typed (wire -// family) or variable-typed (reg family); shared classifier, -// not scattered. -// 2. Variant-is-data β€” FAILS: a `{ kind: Symbol }` proxy reopens -// K-1's foreclosed readable-string heuristic surface (a -// `match kind { "net" => … }` smell). The enum IS the M4- -// faithful form. -// 3. Algebraic form β€” N/A by construction: the two kinds are -// the net-vs-variable distinction of the IEEE 1364-2005 -// type system; they do not trace to a richer std/ algebraic -// structure. -// 4. Dimensional β€” FAILS: an ANSI port has EXACTLY ONE type-kind; -// mutually-exclusive alternatives. -// 5. Parameterized family β€” FAILS: each variant carries a -// DIFFERENT payload type (NetType vs AnsiVariableKind) β€” -// structurally heterogeneous, NOT one generic `F` / -// projection over a single source set (Practice 7). -// Terminal: the closed two-way Verilog ANSI-port-type-kind -// classifier of the IEEE 1364-2005 spec. +// kind uniformly to dispatch emission / type-check legality / +// eventual algebra inhabitance; shared classifier, not +// scattered. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ kind: +// Symbol, packing: PackingShape, signedness: Signedness }` +// record reopens BOTH (a) the readable-string K-1 heuristic +// surface AND (b) the spec-forbidden illegal states like +// "AnsiIntegerType with signedness=Signed" that the per-variant +// payload-presence rule dissolves. Disj-with-heterogeneous- +// payloads is the dissolved form (P2 + Practice 2/6 + M4) β€” +// same shape as body-side VariableDeclaration's kind Γ— packing +// Γ— signedness dissolution. +// 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ +// algebra structure (AnsiNetType / AnsiRegType β†’ Semiring or +// OrderedRing per packing Γ— signedness; AnsiIntegerType β†’ +// OrderedRing>; AnsiRealType / AnsiRealTimeType β†’ +// ApproximateField; AnsiTimeType β†’ Semiring>); +// D2-deferred per "Owned ELSEWHERE". +// 4. Dimensional β€” FAILS: an ANSI port has EXACTLY ONE type/kind; +// mutually-exclusive alternatives. The shapes differ across +// variants (net + reg carry packing+signedness; integer/real/ +// time/realtime carry neither) β€” they cannot be coordinates of +// a single record without the illegal-state smell. +// 5. Parameterized family β€” FAILS: the six are structurally +// heterogeneous in BOTH their payload shapes AND their +// algebraic groundings (Semiring/OrderedRing depending on +// packingΓ—signedness / OrderedRing> / ApproximateField +// / Semiring> / aliased ApproximateField β€” five +// distinct std/algebra groundings plus an additional NetType- +// payload-bearing variant). NOT one generic `F` / projection +// over a separately-declared source set (Practice 7). +// Terminal: the closed six-variant Verilog ANSI-port type/kind +// classifier; illegal kind Γ— packing / kind Γ— signedness combinations +// are unrepresentable by construction. type PortAnsiTypeKind - = AnsiNetType { net_type: NetType } - | AnsiVariableType { var_kind: AnsiVariableKind } - - -// ───────────────────────────────────────────────────────────────────── -// AnsiVariableKind β€” the closed Verilog ANSI-variable-port-type -// classifier (IEEE 1364-2005 Β§12.3.3). The variable-type set valid -// for ANSI ports matches the VariableDeclaration kind set; this -// nullary enum carries the KIND only (the per-kind payloads β€” name, -// packing, signedness for RegVariable β€” are factored into the -// enclosing AnsiStyle to keep cross-form (NonAnsi vs Ansi) packing/ -// signedness reuse single-authority). -// -// - AnsiReg β€” `output reg name` -// - AnsiInteger β€” `output integer name` -// - AnsiReal β€” `output real name` -// - AnsiTime β€” `output time name` -// - AnsiRealTime β€” `output realtime name` -// -// CLOSED (C1 stop-signal). Matches the VariableDeclaration variant -// kind set per spec Β§12.3.3. -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every ANSI-variable-port consumer -// reads the kind uniformly to dispatch emission / type-check -// legality; shared classifier, not scattered. -// 2. Variant-is-data β€” FAILS: a `{ keyword: Symbol }` proxy -// reopens the readable-string heuristic surface K-1 -// forecloses. The enum IS the M4-faithful form. -// 3. Algebraic form β€” PARTIAL: each variant grounds in the same -// std/algebra structure its body-side VariableDeclaration -// counterpart grounds in (AnsiReg β†’ Semiring/OrderedRing per -// packingΓ—signedness; AnsiInteger β†’ OrderedRing>; -// AnsiReal/AnsiRealTime β†’ ApproximateField; AnsiTime -// β†’ Semiring>); D2-deferred per "Owned ELSEWHERE". -// 4. Dimensional β€” FAILS: an ANSI variable port has EXACTLY ONE -// kind; mutually-exclusive alternatives. -// 5. Parameterized family β€” FAILS: the five are structurally -// heterogeneous in their underlying std/algebra grounding -// (same argument as VariableDeclaration's ledger) β€” NOT one -// generic `F` / projection over a separately-declared -// source set (Practice 7). -// Terminal: the closed five-way ANSI-variable-port-kind -// classifier; mirrors VariableDeclaration's kind-partition under -// the IEEE 1364-2005 Β§12.3.3 ANSI-port admissibility rules. -type AnsiVariableKind - = AnsiReg - | AnsiInteger - | AnsiReal - | AnsiTime - | AnsiRealTime + = AnsiNetType { net_type: NetType, packing: PackingShape, signedness: Signedness } + | AnsiRegType { packing: PackingShape, signedness: Signedness } + | AnsiIntegerType + | AnsiRealType + | AnsiTimeType + | AnsiRealTimeType // ───────────────────────────────────────────────────────────────────── @@ -927,27 +911,31 @@ type PortDeclaration { // ───────────────────────────────────────────────────────────────────── // AnsiPortDeclaration β€” an ANSI-style Verilog module port (`module M // (input wire [7:0] a, output reg b, output reg signed [3:0] count, -// …);`). The header carries direction, name, AND the full type/ -// packing/signedness facts INLINE. Per IEEE 1364-2005 Β§12.3.3 the -// port declaration is "completely declared" by this single carrier; -// a body redeclaration is a SYNTAX ERROR β€” single-authority enforced -// structurally because the type-fact lives ON this record, not in a -// matching body item. Conj record (no Practice-4 ledger). -// -// - direction input / output / inout -// - name the port identifier (K-1-opaque Symbol) -// - net_kind net-type vs variable-kind (PortAnsiTypeKind β€” -// AnsiNetType { net_type } | AnsiVariableType -// { var_kind }) -// - packing scalar or `[msb:lsb]` packed bit-vector -// - signedness `signed` keyword present / absent (IEEE 1364-2005 -// Β§5.6) +// …);`). The header carries direction, name, AND the per-kind type +// payload INLINE. Per IEEE 1364-2005 Β§12.3.3 the port declaration is +// "completely declared" by this single carrier; a body redeclaration +// is a SYNTAX ERROR β€” single-authority enforced structurally because +// the type-fact lives ON this record, not in a matching body item. +// Conj record (no Practice-4 ledger). +// +// - direction input / output / inout +// - name the port identifier (K-1-opaque Symbol) +// - type_kind the full per-variant ANSI-port type payload +// (PortAnsiTypeKind: AnsiNetType / AnsiRegType carry +// their own packing + signedness; AnsiIntegerType / +// AnsiRealType / AnsiTimeType / AnsiRealTimeType +// carry neither per spec). The prior uniform +// packing + signedness fields on this record were a +// codex BLOCKING (PR #3176): they admitted spec- +// forbidden states like `output integer signed [N:0]` +// β€” INVARIANTS P2 illegal-states-unrepresentable +// violation. Packing / signedness are now per-variant +// payloads on the type-kind, dissolving those illegal +// states by construction. type AnsiPortDeclaration { direction: PortDirection name: Symbol - net_kind: PortAnsiTypeKind - packing: PackingShape - signedness: Signedness + type_kind: PortAnsiTypeKind } From 9cbec1731d994c9612be55af2b48d7263f858b63 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 05:30:53 +0000 Subject: [PATCH 12/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20ModuleItem=20exha?= =?UTF-8?q?ustive=20=E2=80=94=20add=20defparam/generate/specify/task/funct?= =?UTF-8?q?ion=20variants=20(codex=20REQUEST=5FCHANGES=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex/codex-default REQUEST_CHANGES on PR #3176: ModuleItem's prior "deliberately non-exhaustive" framing (spice.dag #3168 precedent reference) was insufficient for spec-fidelity β€” the spec partition includes defparam (Β§4.10.2.1), generate (Β§12.4), specify (Β§14), task (Β§10.2), and function (Β§10.3) declarations as legal module items, so a closed-Disj claiming IEEE 1364-2005 Β§12.2 fidelity must include them. Fix: - Added 5 supporting Conj records: - DefparamDeclaration { target_path: String, value_lexeme: String } - GenerateRegion { body_lexeme: String } - SpecifyBlock { body_lexeme: String } - TaskDeclaration { name: Symbol, body_lexeme: String } - FunctionDeclaration { name: Symbol, body_lexeme: String } Each defers its sub-language body to the bundled T-4 LanguageModel productions via the established body_lexeme precedent (same shape as AlwaysBlock.body_lexeme / ContinuousAssign.rhs_lexeme). - Added 5 ModuleItem variants: - DefparamDeclarationItem - GenerateRegionItem - SpecifyBlockItem - TaskDeclarationItem - FunctionDeclarationItem - Updated ModuleItem ledger from "deliberately non-exhaustive" to twelve-way exhaustive over the Β§12.2 partition; each pattern's argument extended to cover the new variants (Variant-is-data payload-list extended; Parameterized-family argument notes the new variants preserve heterogeneity). - Removed the spice.dag non-exhaustive-precedent reference from ModuleItem (the framing is now exhaustive; the spice precedent remains the right framing for spice's own Component partition). Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 185 +++++++++++++++++++-------- 1 file changed, 134 insertions(+), 51 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 2f3db30de88..e29b1b63f49 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1427,6 +1427,99 @@ type ModuleInstance { } +// ───────────────────────────────────────────────────────────────────── +// DefparamDeclaration β€” a Verilog `defparam` statement +// (`defparam top.sub.WIDTH = 8;`). IEEE 1364-2005 Β§12.2 + +// Β§4.10.2.1. Deprecated per spec but admitted. Conj record (no +// Practice-4 ledger). +// +// - target_path the hierarchical target-parameter path as a +// verbatim lexeme (sub-grammar deferred to the +// T-4 LanguageModel β€” hierarchical identifier +// resolution is its concern) +// - value_lexeme the override value as a verbatim expression +// lexeme (same body_lexeme precedent as +// ParameterDeclaration.default_lexeme) +type DefparamDeclaration { + target_path: String + value_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// GenerateRegion β€” a Verilog `generate ... endgenerate` block +// (IEEE 1364-2005 Β§12.4, Β§12.1.3.3). Generate regions admit +// `generate-for`, `generate-if`, and `generate-case` constructs that +// are ELABORATED at compile time to produce additional module items. +// Conj record (no Practice-4 ledger). +// +// - body_lexeme the entire `generate ... endgenerate` body as +// a verbatim lexeme (sub-grammar deferred to the +// T-4 LanguageModel β€” the elaboration rules for +// generate-for / generate-if / generate-case + +// the elaboration-time iteration are owned by +// the bundled LanguageModel productions when +// they land) +type GenerateRegion { + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// SpecifyBlock β€” a Verilog `specify ... endspecify` block +// (IEEE 1364-2005 Β§14, Β§12.2). Specify blocks declare module path +// delays + timing checks (`$setup`, `$hold`, `$width`, etc.). Conj +// record (no Practice-4 ledger). +// +// - body_lexeme the entire `specify ... endspecify` body as a +// verbatim lexeme (sub-grammar deferred β€” the +// SDF-class timing-check vocabulary is owned by +// the bundled T-4 LanguageModel productions when +// they land; per the header PROBE LIMITS, +// timing-checks are a separate layer) +type SpecifyBlock { + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// TaskDeclaration β€” a Verilog `task ... endtask` declaration +// (IEEE 1364-2005 Β§10.2, Β§12.2). A task is a procedural sub-routine +// callable from procedural code; it can carry input/output/inout +// arguments and contain delay/event controls (unlike `function`). +// Conj record (no Practice-4 ledger). +// +// - name the task identifier (K-1-opaque Symbol) +// - body_lexeme the procedural body (port list + statements +// between `task name;` and `endtask`) as a +// verbatim lexeme (sub-grammar deferred to the +// T-4 LanguageModel) +type TaskDeclaration { + name: Symbol + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// FunctionDeclaration β€” a Verilog `function ... endfunction` +// declaration (IEEE 1364-2005 Β§10.3, Β§12.2). A function is a pure +// (synthesizable) sub-routine that returns a value; the spec +// forbids delay/event controls inside the body (distinguishing +// functions from tasks). Conj record (no Practice-4 ledger). +// +// - name the function identifier (K-1-opaque Symbol) +// - body_lexeme the function body (return-type + arguments + +// statements between `function name;` and +// `endfunction`) as a verbatim lexeme (sub- +// grammar deferred to the T-4 LanguageModel β€” +// the return-type declaration + the pure-body +// constraint enforcement live there) +type FunctionDeclaration { + name: Symbol + body_lexeme: String +} + + // ───────────────────────────────────────────────────────────────────── // ModuleItem β€” the closed Verilog module-body item classifier. The // items inside a `module ... endmodule` body are a flat list of @@ -1447,54 +1540,45 @@ type ModuleInstance { // - VariableDeclarationItem `reg`, `integer`, … declarations // - ParameterDeclarationItem `parameter NAME = expr;` // - ModuleInstanceItem nested `ModuleName inst (...);` -// -// CLOSED-SET COVERAGE (clarified per codex BLOCKING review on PR #3176 -// 2026-05-16). IEEE 1364-2005 Β§12.2 also admits `defparam` (deprecated), -// `generate` blocks, `specify` blocks, and `task` / `function` -// declarations as module items. The variants enumerated below cover -// the IN-B PROBE's CORE NEEDS β€” the parallel-composition surface, -// signal declarations, instantiation β€” which is what the T-4.9 probe -// validates. The remaining items are NOT enumerated in this initial -// cut: `defparam` is deprecated per spec, and `generate` / `specify` -// / `task` / `function` each OPEN A SUB-LANGUAGE (the recursive body -// of a generate block, the timing-check vocabulary of `specify`, the -// procedural body of a task/function) whose grammar is owned by the -// bundled T-4 LanguageModel productions when they land. Adding each -// is MECHANICAL (one variant per kind, payload as a Conj record with -// a `body_lexeme: String` for the sub-language portion β€” the same -// `AlwaysBlock.body_lexeme` precedent), and crucially the 5-pattern -// ledger BELOW STAYS UNCHANGED when those variants are added: the -// dissolution argument is about coproduct SHAPE, not membership -// completeness. This is the deliberate non-exhaustive scoping the -// probe permits (same shape as spice.dag #3168 `Component`'s -// "controlled-source variants E/F/G/H, JFET, transmission line, -// switches are NOT enumerated in this initial cut" framing β€” adding -// them is mechanical and does not affect the structural finding). -// A NEW item kind (one the spec does not list) is the C1 stop-signal -// edit; a follow-up adding the named scope-negative items is -// straightforward L-2 maintenance. +// - DefparamDeclarationItem `defparam top.sub.PARAM = value;` (Β§4.10.2.1) +// - GenerateRegionItem `generate ... endgenerate` (Β§12.4) +// - SpecifyBlockItem `specify ... endspecify` (Β§14) +// - TaskDeclarationItem `task name; … endtask` (Β§10.2) +// - FunctionDeclarationItem `function name; … endfunction` (Β§10.3) +// +// CLOSED-SET COVERAGE β€” the variants enumerated below cover the full +// IEEE 1364-2005 Β§12.2 module-item set. The initial cut deliberately +// scoped to the IN-B-probe-core subset (the spice.dag #3168 +// non-exhaustive precedent) was insufficiently faithful per codex +// REQUEST_CHANGES on PR #3176 β€” the spec partition includes +// `defparam`, `generate`, `specify`, `task`, and `function` +// declarations, and a closed-Disj claiming spec-fidelity must include +// them. Each is represented as its own variant; the sub-language body +// of generate / specify / task / function is carried as a verbatim +// `body_lexeme: String` (the established AlwaysBlock body_lexeme +// precedent β€” the recursive sub-grammar of each sub-language is owned +// by the bundled T-4 LanguageModel productions when they land, but +// the variant + payload-skeleton lives here so the closed-Disj +// honestly covers Β§12.2). A NEW item kind (one the spec does not +// list) is the C1 stop-signal edit. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). The ledger is about coproduct DISSOLUTION -// SHAPE (do these variants need to collapse to something simpler?), -// NOT membership completeness β€” adding the named scope-negative -// variants per the closed-set-coverage note above keeps every -// pattern's argument unchanged. Ledger β€” five patterns attempted: +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: // 1. Fact placement β€” FAILS: every module-body consumer (emission, // port-binding resolution, sensitivity-list signal lookup, -// synthesis dispatch) branches on the item kind; shared -// classifier, not scattered. (Adding generate/specify/task/ -// function would extend the dispatch uniformly; same shape.) +// synthesis dispatch, generate-elaboration, specify-timing- +// check, task/function inlining) branches on the item kind; +// shared classifier, not scattered. // 2. Variant-is-data β€” FAILS: each variant carries a payload of // a DIFFERENT type (`ContinuousAssign` / `AlwaysBlock` / // `InitialBlock` / `NetDeclaration` / `VariableDeclaration` / -// `ParameterDeclaration` / `ModuleInstance`). Collapsing to a +// `ParameterDeclaration` / `ModuleInstance` / `Defparam +// Declaration` / `GenerateRegion` / `SpecifyBlock` / +// `TaskDeclaration` / `FunctionDeclaration`). Collapsing to a // uniform `{ kind: ItemKind, … }` shape requires Option-typed // payload fields (an item carries the AlwaysBlock or NULL), // which makes "ContinuousAssign item with an AlwaysBlock -// payload" representable β€” the inverse of P2. (Adding more -// variants with their own payload types preserves the -// heterogeneity β€” same argument.) +// payload" representable β€” the inverse of P2. // 3. Algebraic form β€” N/A by construction: the module-body items // are the IEEE 1364-2005 spec's primitive item taxonomy; they // do not trace to a richer std/ algebraic structure. @@ -1507,19 +1591,13 @@ type ModuleInstance { // 5. Parameterized family β€” FAILS: the variants are structurally // heterogeneous (different payload types; the declaration // variants carry storage-shape facts while the action variants -// carry computation-shape facts) β€” NOT one generic `F` / -// projection over a separately-declared source set (Practice -// 7). The IEEE 1364-2005 module-body item set is the -// irreducible partition; the future scope-negative additions -// preserve heterogeneity (generate carries a body shape, -// specify carries timing-check vocabulary, task/function each -// carry a body) β€” no projection-uniformity. -// Terminal SHAPE: the closed module-body-item classifier of the -// IEEE 1364-2005 spec; the seven variants enumerated below are the -// IN-B-probe-core subset, with the named scope-negative variants -// (defparam, generate, specify, task, function) deliberately -// non-exhaustive in this initial cut. The dissolution argument -// holds across the full spec set. +// carry computation-shape facts; generate / specify / task / +// function each carry their own sub-language body) β€” NOT one +// generic `F` / projection over a separately-declared +// source set (Practice 7). The IEEE 1364-2005 module-body +// item set is the irreducible partition. +// Terminal: the closed twelve-way module-body-item classifier of +// the IEEE 1364-2005 Β§12.2 spec. type ModuleItem = ContinuousAssignItem { assign: ContinuousAssign } | AlwaysBlockItem { always_block: AlwaysBlock } @@ -1528,6 +1606,11 @@ type ModuleItem | VariableDeclarationItem { variable: VariableDeclaration } | ParameterDeclarationItem { parameter: ParameterDeclaration } | ModuleInstanceItem { instance: ModuleInstance } + | DefparamDeclarationItem { defparam: DefparamDeclaration } + | GenerateRegionItem { generate_region: GenerateRegion } + | SpecifyBlockItem { specify_block: SpecifyBlock } + | TaskDeclarationItem { task: TaskDeclaration } + | FunctionDeclarationItem { function_decl: FunctionDeclaration } // ───────────────────────────────────────────────────────────────────── From aa5e156d23da2dc57b11ddb61125643eaef2d8f2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 02:28:06 -0400 Subject: [PATCH 13/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 181 ++++++++++++++++++++------- 1 file changed, 139 insertions(+), 42 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index e29b1b63f49..4513174a0e4 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -908,35 +908,113 @@ type PortDeclaration { } +// ───────────────────────────────────────────────────────────────────── +// AnsiNetPortType β€” the closed type/payload variants admitted for an +// ANSI port that ONLY accepts net types (input + inout ports per IEEE +// 1364-2005 Β§12.3.3). Input and inout ports cannot be reg-typed +// (procedural assignment requires reg, which only output can carry), +// and cannot be the spec-fixed-width variable kinds (integer / real / +// time / realtime are output-only per spec). This carrier is the +// closed type-payload set for input / inout β€” strictly the net family. +// +// - AnsiInputInoutNet { net_type: NetType, packing: PackingShape, +// signedness: Signedness } +// β€” any NetType variant (wire/wand/wor/tri/etc.) with optional +// packing + signedness per spec Β§5.6. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits exactly net +// types for input/inout ANSI ports; SystemVerilog `logic` would EDIT +// this Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Single-variant Disj (currently exactly one +// type-shape β€” net with payload β€” admitted; future spec extensions +// would add variants). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every input/inout-ANSI consumer reads +// the type uniformly to dispatch emission / drive net-resolution; +// shared classifier. +// 2. Variant-is-data β€” FAILS: the single variant carries a +// structured payload (net_type + packing + signedness); a +// uniform record would collapse the future-extension axis a +// Disj preserves. +// 3. Algebraic form β€” N/A by construction: net types are the spec's +// primitive resolution-function set per Β§3.7.1; D2-deferred per +// "Owned ELSEWHERE". +// 4. Dimensional β€” FAILS: an input/inout ANSI port has EXACTLY ONE +// net-type payload; the variant is the dispatcher. +// 5. Parameterized family β€” FAILS: the single variant's payload is +// a structured record (NetType Γ— PackingShape Γ— Signedness), +// not one generic `F` projection (Practice 7). +// Terminal: the closed net-only type-payload classifier for input / +// inout ANSI ports; a second variant would be an L-2 pin edit. +type AnsiNetPortType + = AnsiInputInoutNet { net_type: NetType, packing: PackingShape, signedness: Signedness } + + // ───────────────────────────────────────────────────────────────────── // AnsiPortDeclaration β€” an ANSI-style Verilog module port (`module M // (input wire [7:0] a, output reg b, output reg signed [3:0] count, -// …);`). The header carries direction, name, AND the per-kind type -// payload INLINE. Per IEEE 1364-2005 Β§12.3.3 the port declaration is -// "completely declared" by this single carrier; a body redeclaration -// is a SYNTAX ERROR β€” single-authority enforced structurally because -// the type-fact lives ON this record, not in a matching body item. -// Conj record (no Practice-4 ledger). +// inout tri bus, …);`). The header carries direction, name, AND a +// direction-specific type payload. Per IEEE 1364-2005 Β§12.3.3 the +// port declaration is "completely declared" by this single carrier; +// a body redeclaration is a SYNTAX ERROR. +// +// Direction Γ— type-kind admissibility is modeled STRUCTURALLY via +// Disj-with-named-payloads per direction (codex BLOCKING fix on +// PR #3176 2026-05-16: the prior uniform `{ direction, name, type_ +// kind }` Conj record admitted spec-forbidden combinations like +// `input reg [N:0]` and `inout integer` β€” INVARIANTS P2 illegal- +// states-unrepresentable violation. Per spec Β§12.3.3 input/inout +// ports MUST be net-typed; only output ports admit reg/integer/real/ +// time/realtime variable kinds. The per-direction split makes those +// illegal combinations structurally unrepresentable, mirroring the +// VariableDeclaration kindΓ—packingΓ—signedness dissolution). +// +// - AnsiInputPort { name: Symbol, net: AnsiNetPortType } +// β€” input ports are net-typed only (the spec forbids +// `input reg`). +// - AnsiOutputPort { name: Symbol, type_kind: PortAnsiTypeKind } +// β€” output ports admit the full PortAnsiTypeKind set (net or +// any variable kind; output is the only direction that +// admits reg/integer/real/time/realtime). +// - AnsiInoutPort { name: Symbol, net: AnsiNetPortType } +// β€” inout ports are net-typed only (bidirectional requires +// nets; `inout reg` is a spec violation). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits exactly +// these three direction-bearing ANSI-port forms; SystemVerilog +// `ref` ports would EDIT this Disj explicitly. // -// - direction input / output / inout -// - name the port identifier (K-1-opaque Symbol) -// - type_kind the full per-variant ANSI-port type payload -// (PortAnsiTypeKind: AnsiNetType / AnsiRegType carry -// their own packing + signedness; AnsiIntegerType / -// AnsiRealType / AnsiTimeType / AnsiRealTimeType -// carry neither per spec). The prior uniform -// packing + signedness fields on this record were a -// codex BLOCKING (PR #3176): they admitted spec- -// forbidden states like `output integer signed [N:0]` -// β€” INVARIANTS P2 illegal-states-unrepresentable -// violation. Packing / signedness are now per-variant -// payloads on the type-kind, dissolving those illegal -// states by construction. -type AnsiPortDeclaration { - direction: PortDirection - name: Symbol - type_kind: PortAnsiTypeKind -} +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every ANSI-port consumer branches on +// direction Γ— type-kind to dispatch emission / type-check +// legality / drive net-vs-reg-assignment-legality; shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform +// `{ direction: PortDirection, name: Symbol, type_kind: +// PortAnsiTypeKind }` ratifies spec-forbidden combinations +// (Input + AnsiRegType, Inout + AnsiIntegerType, etc.) β€” the +// product-axis admits illegal states this per-direction Disj +// dissolves. INVARIANTS P2 illegal-states-unrepresentable. +// 3. Algebraic form β€” N/A by construction: the three direction- +// bearing ANSI forms are the spec's primitive direction Γ— type +// admissibility table β€” not a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single ANSI port is EXACTLY ONE +// direction variant; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: AnsiInputPort and AnsiInoutPort +// carry `net: AnsiNetPortType` (net-only); AnsiOutputPort +// carries `type_kind: PortAnsiTypeKind` (full type-kind set +// including reg/integer/real/time/realtime). The payload +// types differ structurally β€” NOT one generic `F` / +// projection over a single source set (Practice 7). +// Terminal: the closed three-way Verilog ANSI-port direction-kind +// classifier; illegal direction Γ— type-kind combinations are +// unrepresentable by construction. +type AnsiPortDeclaration + = AnsiInputPort { name: Symbol, net: AnsiNetPortType } + | AnsiOutputPort { name: Symbol, type_kind: PortAnsiTypeKind } + | AnsiInoutPort { name: Symbol, net: AnsiNetPortType } // ───────────────────────────────────────────────────────────────────── @@ -1022,34 +1100,53 @@ type ParameterDeclaration { // ───────────────────────────────────────────────────────────────────── // SensitivityItem β€” one entry in an always-block's event-control list -// (`posedge clk`, `negedge rst`, bare `data_in`). Conj record (no -// Practice-4 ledger). -// -// - trigger which edge / level-sensitivity -// - signal the signal identifier the trigger watches (K-1- -// opaque Symbol; resolved through the namespace to -// the matching net or variable declaration) +// (`posedge clk`, `negedge rst`, `posedge (a & b)`, bare expression). +// IEEE 1364-2005 Β§9.7.2. Conj record (no Practice-4 ledger). +// +// - trigger which edge / level-sensitivity +// - event_expression_lexeme the expression the trigger watches +// as a verbatim lexeme. Per spec +// Β§9.7.2 the event_expression can be +// ANY expression (identifier, bit- +// select, arithmetic combination), not +// just a bare identifier β€” corrected +// 2026-05-16 per codex BLOCKING on +// PR #3176 (the prior `signal: Symbol` +// narrowed event expressions to +// identifier references, excluding +// valid syntax). Sub-grammar deferred +// to the T-4 LanguageModel via the +// established body_lexeme precedent. type SensitivityItem { trigger: EdgeTrigger - signal: Symbol + event_expression_lexeme: String } // ───────────────────────────────────────────────────────────────────── // ContinuousAssign β€” a Verilog continuous-assignment statement -// (`assign net = expr;`, IEEE 1364-2005 Β§6.1). Conj record (no -// Practice-4 ledger). -// -// - lhs the destination net identifier (K-1-opaque -// Symbol; resolved to a `NetDeclaration` β€” -// procedural variables cannot be continuous- -// assignment destinations, that legality is the -// T-4 LanguageModel's joint check) +// (`assign net = expr;`, `assign {a, b} = c;`, `assign x[3:0] = …`). +// IEEE 1364-2005 Β§6.1. Conj record (no Practice-4 ledger). +// +// - lhs_lexeme the destination net_lvalue as a verbatim +// lexeme. Per spec Β§6.1 the lvalue of a +// continuous assign is a net_lvalue: an +// identifier reference, a net bit-select, a +// net part-select, or a concatenation/replication +// of net_lvalues β€” NOT just a bare identifier +// (corrected 2026-05-16 per codex BLOCKING on +// PR #3176; the prior `lhs: Symbol` narrowed +// lvalues to identifier references, excluding +// valid Β§6.1 net_lvalue forms). Sub-grammar +// deferred to the T-4 LanguageModel. Procedural +// variables cannot be continuous-assignment +// destinations β€” that joint check is the T-4 +// LanguageModel's concern. // - rhs_lexeme the right-hand-side expression as a verbatim // lexeme (sub-grammar deferred β€” same shape as // `ParameterDeclaration.default_lexeme`) type ContinuousAssign { - lhs: Symbol + lhs_lexeme: String rhs_lexeme: String } From 949f421fb4c5f8fa1219d278b7ad8964a977a1fc Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 06:29:28 +0000 Subject: [PATCH 14/56] =?UTF-8?q?v4=20T-4.9=20verilog:=203=20codex=20BLOCK?= =?UTF-8?q?INGs=20=E2=80=94=20ANSI=20direction=C3=97type-kind=20partition,?= =?UTF-8?q?=20lexeme=20consistency,=20ModuleItem=20exhaustive=20(PR=20#317?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex/codex-default REQUEST_CHANGES at sha 9cbec173 surfaced three spec-fidelity gaps. All in-pattern: 1. ANSI DIRECTION Γ— TYPE-KIND was a product axis (direction + type_kind independent), admitting spec-forbidden combinations like `input reg [N:0]` and `inout integer` (per IEEE 1364-2005 Β§12.3.3 input/inout ports MUST be net-typed; only output ports admit variable kinds reg/integer/real/time/realtime). Fix: restructured AnsiPortDeclaration into a per-direction Disj: AnsiInputPort { name, net: AnsiNetPortType } // net-only AnsiOutputPort { name, type_kind: PortAnsiTypeKind } // full set AnsiInoutPort { name, net: AnsiNetPortType } // net-only New AnsiNetPortType Disj carries the net-only payload (single AnsiInputInoutNet variant currently). Full 5-pattern Practice-4 ledger on each new Disj. Mirror of body-side VariableDeclaration's per-kind admissibility dissolution. 2. LEXEME CONSISTENCY β€” SensitivityItem.signal was Symbol (narrowed to identifier references; spec Β§9.7.2 admits any expression); ContinuousAssign.lhs was Symbol (narrowed to identifier; spec Β§6.1 admits net_lvalue forms β€” bit-select, part-select, concat). Fix: - SensitivityItem.signal: Symbol β†’ event_expression_lexeme: String - ContinuousAssign.lhs: Symbol β†’ lhs_lexeme: String Both sub-grammars deferred to T-4 LanguageModel via established body_lexeme precedent. 3. MODULEITEM STILL INCOMPLETE β€” the prior 12-variant cut missed event_declaration (Β§9.7.3), genvar_declaration (Β§12.4.2), local_parameter_declaration (Β§3.10), gate_instantiation (Β§7), udp_instantiation (Β§8), and specparam_declaration (Β§14.3.1) per the full Β§12.2 + Β§14.3.1 grammar. Fix: added 6 new Conj records (EventDeclaration, GenvarDeclaration, LocalParameterDeclaration, GateInstantiation, UdpInstantiation, SpecparamDeclaration) each with body_lexeme deferral for their sub-language portion. ModuleItem expanded from 12 to 18 variants; ledger updated to note the Β§12.2 + Β§14.3.1 exhaustive coverage. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 198 +++++++++++++++++++++------ 1 file changed, 157 insertions(+), 41 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 4513174a0e4..f397b3065d0 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1617,6 +1617,114 @@ type FunctionDeclaration { } +// ───────────────────────────────────────────────────────────────────── +// EventDeclaration β€” a Verilog named-event declaration (`event ev;`). +// IEEE 1364-2005 Β§9.7.3 / Β§10.3. Named events are explicitly- +// triggered control-flow primitives (`-> ev;` triggers, `@ev` waits). +// Conj record (no Practice-4 ledger). +// +// - name the event identifier (K-1-opaque Symbol) +type EventDeclaration { + name: Symbol +} + + +// ───────────────────────────────────────────────────────────────────── +// GenvarDeclaration β€” a Verilog `genvar` declaration (`genvar i;`). +// IEEE 1364-2005 Β§12.4.2. Generate variables drive elaboration-time +// loop iteration in `generate-for` constructs. Conj record (no +// Practice-4 ledger). +// +// - name the genvar identifier (K-1-opaque Symbol) +type GenvarDeclaration { + name: Symbol +} + + +// ───────────────────────────────────────────────────────────────────── +// LocalParameterDeclaration β€” a Verilog `localparam` declaration +// (`localparam W = 8;`). IEEE 1364-2005 Β§3.10, Β§12.2. Local parameters +// differ from ordinary parameters in that they CANNOT be overridden +// by `defparam` or by parameter overrides on a module instantiation +// (the spec's distinct binding rule). Conj record (no Practice-4 +// ledger). +// +// - name the localparam identifier (K-1-opaque Symbol) +// - default_lexeme the value as a verbatim expression lexeme +// (mirrors ParameterDeclaration; sub-grammar +// deferred) +type LocalParameterDeclaration { + name: Symbol + default_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// GateInstantiation β€” a Verilog built-in primitive instantiation +// (`and g1(out, a, b);` / `not n1(o, i);` / `bufif1 b1(out, in, en);`, +// etc.). IEEE 1364-2005 Β§7 admits 24 built-in primitive gate types +// (and / or / nand / nor / xor / xnor / not / buf / bufif0 / bufif1 / +// notif0 / notif1 / pulldown / pullup / nmos / pmos / cmos / rnmos / +// rpmos / rcmos / tran / tranif0 / tranif1 / rtran / rtranif0 / +// rtranif1). Conj record (no Practice-4 ledger). +// +// - gate_keyword the primitive's keyword as a verbatim lexeme +// (the closed 24-keyword set is owned by the +// bundled T-4 LanguageModel productions; the +// vocabulary slice carries the keyword as +// lexeme + the per-keyword terminal-arity table +// is a LanguageModel-level joint check, same +// pattern as gate primitives' per-keyword +// admissibility) +// - body_lexeme instance name + terminal list as a verbatim +// lexeme (sub-grammar deferred β€” the +// per-primitive terminal arity / drive strength +// / delay control is in the bundled +// LanguageModel) +type GateInstantiation { + gate_keyword: String + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// UdpInstantiation β€” a Verilog user-defined-primitive instantiation +// (a UDP defined via `primitive ... endprimitive` at the file level +// per IEEE 1364-2005 Β§8 is instantiated like a gate at the module- +// body level). Conj record (no Practice-4 ledger). +// +// - udp_name the UDP identifier (K-1-opaque Symbol; +// resolves through the namespace to the +// matching top-level UDP definition β€” UDP +// definitions themselves are a file-level +// concern, separate from module body items) +// - instance_name this instance's local name (K-1-opaque Symbol) +// - body_lexeme port list + drive strength + delay as a +// verbatim lexeme (sub-grammar deferred to the +// bundled T-4 LanguageModel) +type UdpInstantiation { + udp_name: Symbol + instance_name: Symbol + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// SpecparamDeclaration β€” a Verilog `specparam` declaration. IEEE +// 1364-2005 Β§14.3.1 + Β§12.2. Specify parameters are distinct from +// ordinary parameters: they are intended for timing-check values +// (rise/fall/hi-Z transitions, pulse-control limits) and CANNOT be +// used as bit-vector widths or array indices per spec. Conj record +// (no Practice-4 ledger). +// +// - name the specparam identifier (K-1-opaque Symbol) +// - default_lexeme the value as a verbatim expression lexeme +type SpecparamDeclaration { + name: Symbol + default_lexeme: String +} + + // ───────────────────────────────────────────────────────────────────── // ModuleItem β€” the closed Verilog module-body item classifier. The // items inside a `module ... endmodule` body are a flat list of @@ -1630,52 +1738,54 @@ type FunctionDeclaration { // parallelism is the Conj-of-siblings shape, exactly as a Conj of // submodule instantiations. // -// - ContinuousAssignItem `assign net = expr;` -// - AlwaysBlockItem `always @(...) begin … end` -// - InitialBlockItem `initial begin … end` -// - NetDeclarationItem `wire`, `wand`, … declarations -// - VariableDeclarationItem `reg`, `integer`, … declarations -// - ParameterDeclarationItem `parameter NAME = expr;` -// - ModuleInstanceItem nested `ModuleName inst (...);` -// - DefparamDeclarationItem `defparam top.sub.PARAM = value;` (Β§4.10.2.1) -// - GenerateRegionItem `generate ... endgenerate` (Β§12.4) -// - SpecifyBlockItem `specify ... endspecify` (Β§14) -// - TaskDeclarationItem `task name; … endtask` (Β§10.2) -// - FunctionDeclarationItem `function name; … endfunction` (Β§10.3) +// - ContinuousAssignItem `assign net = expr;` +// - AlwaysBlockItem `always @(...) begin … end` +// - InitialBlockItem `initial begin … end` +// - NetDeclarationItem `wire`, `wand`, … declarations +// - VariableDeclarationItem `reg`, `integer`, … declarations +// - ParameterDeclarationItem `parameter NAME = expr;` +// - LocalParameterDeclarationItem `localparam NAME = expr;` (Β§3.10) +// - ModuleInstanceItem nested `ModuleName inst (...);` +// - DefparamDeclarationItem `defparam top.sub.PARAM = value;` (Β§4.10.2.1) +// - GenerateRegionItem `generate ... endgenerate` (Β§12.4) +// - SpecifyBlockItem `specify ... endspecify` (Β§14) +// - TaskDeclarationItem `task name; … endtask` (Β§10.2) +// - FunctionDeclarationItem `function name; … endfunction` (Β§10.3) +// - EventDeclarationItem `event ev;` (Β§9.7.3) +// - GenvarDeclarationItem `genvar i;` (Β§12.4.2) +// - GateInstantiationItem `and g1(out, a, b);` (Β§7) +// - UdpInstantiationItem UDP instantiation (Β§8) +// - SpecparamDeclarationItem `specparam ...;` (Β§14.3.1) // // CLOSED-SET COVERAGE β€” the variants enumerated below cover the full -// IEEE 1364-2005 Β§12.2 module-item set. The initial cut deliberately -// scoped to the IN-B-probe-core subset (the spice.dag #3168 -// non-exhaustive precedent) was insufficiently faithful per codex -// REQUEST_CHANGES on PR #3176 β€” the spec partition includes -// `defparam`, `generate`, `specify`, `task`, and `function` -// declarations, and a closed-Disj claiming spec-fidelity must include -// them. Each is represented as its own variant; the sub-language body -// of generate / specify / task / function is carried as a verbatim -// `body_lexeme: String` (the established AlwaysBlock body_lexeme -// precedent β€” the recursive sub-grammar of each sub-language is owned +// IEEE 1364-2005 Β§12.2 module_or_generate_item + specparam_declaration +// grammar partition per Annex A.1.4. The prior 12-variant cut missed +// `event_declaration`, `genvar_declaration`, `local_parameter_ +// declaration`, `gate_instantiation`, `udp_instantiation`, and +// `specparam_declaration` (codex BLOCKING on PR #3176, codex/codex- +// default 2026-05-16 β€” the strict spec-fidelity bar surfaced these +// gaps). Each new variant is a Conj record + body_lexeme deferral +// per the established AlwaysBlock body_lexeme precedent β€” the sub- +// language structures (gate-primitive terminal lists, UDP definition +// tables, generate-for elaboration, specify timing checks) are owned // by the bundled T-4 LanguageModel productions when they land, but // the variant + payload-skeleton lives here so the closed-Disj -// honestly covers Β§12.2). A NEW item kind (one the spec does not -// list) is the C1 stop-signal edit. +// honestly covers Β§12.2 + Β§14.3.1. A NEW item kind (one the spec +// does not list) is the C1 stop-signal edit. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” // 🟒 GREEN (terminal). Ledger β€” five patterns attempted: // 1. Fact placement β€” FAILS: every module-body consumer (emission, // port-binding resolution, sensitivity-list signal lookup, // synthesis dispatch, generate-elaboration, specify-timing- -// check, task/function inlining) branches on the item kind; +// check, task/function inlining, gate-primitive emission, UDP +// resolution, genvar elaboration) branches on the item kind; // shared classifier, not scattered. // 2. Variant-is-data β€” FAILS: each variant carries a payload of -// a DIFFERENT type (`ContinuousAssign` / `AlwaysBlock` / -// `InitialBlock` / `NetDeclaration` / `VariableDeclaration` / -// `ParameterDeclaration` / `ModuleInstance` / `Defparam -// Declaration` / `GenerateRegion` / `SpecifyBlock` / -// `TaskDeclaration` / `FunctionDeclaration`). Collapsing to a -// uniform `{ kind: ItemKind, … }` shape requires Option-typed -// payload fields (an item carries the AlwaysBlock or NULL), -// which makes "ContinuousAssign item with an AlwaysBlock -// payload" representable β€” the inverse of P2. +// a DIFFERENT type (the 18 distinct payload records). Collapsing +// to a uniform `{ kind: ItemKind, … }` shape requires Option- +// typed payload fields, which makes mismatched-kind+payload +// combinations representable β€” the inverse of P2. // 3. Algebraic form β€” N/A by construction: the module-body items // are the IEEE 1364-2005 spec's primitive item taxonomy; they // do not trace to a richer std/ algebraic structure. @@ -1688,13 +1798,13 @@ type FunctionDeclaration { // 5. Parameterized family β€” FAILS: the variants are structurally // heterogeneous (different payload types; the declaration // variants carry storage-shape facts while the action variants -// carry computation-shape facts; generate / specify / task / -// function each carry their own sub-language body) β€” NOT one -// generic `F` / projection over a separately-declared -// source set (Practice 7). The IEEE 1364-2005 module-body -// item set is the irreducible partition. -// Terminal: the closed twelve-way module-body-item classifier of -// the IEEE 1364-2005 Β§12.2 spec. +// carry computation-shape facts; gate / udp / specify / task / +// function / generate each carry their own sub-language body) +// β€” NOT one generic `F` / projection over a separately- +// declared source set (Practice 7). The IEEE 1364-2005 module- +// body item set is the irreducible partition. +// Terminal: the closed eighteen-way module-body-item classifier of +// the IEEE 1364-2005 Β§12.2 + Β§14.3.1 spec. type ModuleItem = ContinuousAssignItem { assign: ContinuousAssign } | AlwaysBlockItem { always_block: AlwaysBlock } @@ -1702,12 +1812,18 @@ type ModuleItem | NetDeclarationItem { net: NetDeclaration } | VariableDeclarationItem { variable: VariableDeclaration } | ParameterDeclarationItem { parameter: ParameterDeclaration } + | LocalParameterDeclarationItem { local_parameter: LocalParameterDeclaration } | ModuleInstanceItem { instance: ModuleInstance } | DefparamDeclarationItem { defparam: DefparamDeclaration } | GenerateRegionItem { generate_region: GenerateRegion } | SpecifyBlockItem { specify_block: SpecifyBlock } | TaskDeclarationItem { task: TaskDeclaration } | FunctionDeclarationItem { function_decl: FunctionDeclaration } + | EventDeclarationItem { event_decl: EventDeclaration } + | GenvarDeclarationItem { genvar_decl: GenvarDeclaration } + | GateInstantiationItem { gate: GateInstantiation } + | UdpInstantiationItem { udp_instance: UdpInstantiation } + | SpecparamDeclarationItem { specparam: SpecparamDeclaration } // ───────────────────────────────────────────────────────────────────── From fbbe8d2c006c362eae47a0fafb96a563dbad3078 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 03:31:06 -0400 Subject: [PATCH 15/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 87 ++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index f397b3065d0..2f9c86737f1 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -886,22 +886,67 @@ type PortAnsiTypeKind // ───────────────────────────────────────────────────────────────────── -// PortDeclaration β€” a non-ANSI-style Verilog module port (`module M -// (a, b, c); input wire [7:0] a; output reg b; …`). The header lists -// port direction + name; the type/packing/signedness facts come from -// a MATCHING `NetDeclaration` / `VariableDeclaration` in the module -// body's items list. Conj record (no Practice-4 ledger). +// NonAnsiPort β€” a non-ANSI-style Verilog module-HEADER port entry +// (`module M (a, b, c);` β€” the header lists port-EXPRESSIONS only; +// direction lives in BODY port_declaration items per IEEE 1364-2005 +// Β§12.3.2). Conj record (no Practice-4 ledger). +// +// - port_expression_lexeme the port_expression as a verbatim +// lexeme (per spec grammar the +// port_expression can be a bare +// identifier `a`, a bit/part-select +// `a[3:0]`, a concatenation `{a, b[3:0]}`, +// or a renamed-port form +// `.external_name(internal_expression)`). +// Sub-grammar deferred to the T-4 +// LanguageModel via the established +// body_lexeme precedent β€” at the +// vocabulary-slice layer the slice +// carries the port-expression text +// losslessly; downstream +// port-binding resolution is the +// LanguageModel grammar's concern. +// +// Per IEEE 1364-2005 Β§12.3.2 the non-ANSI header carries port- +// expressions ONLY β€” port direction (input/output/inout) and any +// inline type/packing/signedness facts live in BODY +// `port_declaration` items (see PortDeclaration below + the +// PortDeclarationItem ModuleItem variant). The prior +// `PortDeclaration { direction, name }` on the header port-list +// collapsed this spec-boundary; corrected per codex BLOCKING on +// PR #3176 2026-05-16. +type NonAnsiPort { + port_expression_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// PortDeclaration β€” a non-ANSI-style Verilog BODY port_declaration +// (`input a;`, `output b;`, `inout c;`). IEEE 1364-2005 Β§12.3.4 + +// Β§12.2 admit these as module-body items. Each declares port +// direction + name; the type/packing/signedness facts come from a +// MATCHING `NetDeclaration` / `VariableDeclaration` in the same +// module body (the non-ANSI separated form), OR β€” per spec β€” a body +// port_declaration may combine direction + type inline (`input wire +// [7:0] a;`). The combined form is structurally equivalent to ANSI +// and is admitted by the same `AnsiPortDeclaration` carrier surfaced +// as `BodyPortDeclarationItem` in ModuleItem; this PortDeclaration +// record covers the direction-only form. // // - direction input / output / inout // - name the port identifier (K-1-opaque Symbol; resolves // through the namespace to the matching body -// Net/Variable declaration that carries the type-fact) -// -// Per IEEE 1364-2005 Β§12.3.4 a module's port-list is uniformly EITHER -// non-ANSI (this record's form) OR ANSI (AnsiPortDeclaration below); -// mixing styles within one module is forbidden. The -// ModulePortsList Disj makes that uniformity structural at the -// module level. +// Net/Variable declaration that carries the type- +// fact, when separated) +// +// Per IEEE 1364-2005 Β§12.3.4 / Β§12.2 PortDeclaration is a MODULE +// BODY item (PortDeclarationItem in ModuleItem), NOT a module- +// header element. The non-ANSI header carries port-EXPRESSIONS via +// NonAnsiPort above; this body declaration carries the direction +// fact that the non-ANSI form requires. Corrected per codex +// BLOCKING on PR #3176 2026-05-16 β€” the prior shape mis-located +// PortDeclaration on the header port-list, conflating the spec's +// header-vs-body partition. type PortDeclaration { direction: PortDirection name: Symbol @@ -1031,11 +1076,13 @@ type AnsiPortDeclaration // per-port encoding was a product-axis miscarve relative to the spec's // module-header partition). // -// - NonAnsiPorts { ports: List } -// β€” the entire module's port list is non-ANSI style; each port -// declares direction + name only and the type-fact comes from -// the matching body Net/Variable declaration. The spec's -// Verilog-1995 module-header form. +// - NonAnsiPorts { ports: List } +// β€” the entire module's port list is non-ANSI style; each +// header entry is a port-EXPRESSION (port name or bit-select +// or renamed-port form) per spec Β§12.3.2. Port direction + +// type-facts live in BODY port_declaration items +// (PortDeclarationItem / BodyPortDeclarationItem in +// ModuleItem). The spec's Verilog-1995 module-header form. // - AnsiPorts { ports: List } // β€” the entire module's port list is ANSI style; each port // carries direction + name + inline net_kind + packing + @@ -1069,7 +1116,7 @@ type AnsiPortDeclaration // ONE style; mutually-exclusive alternatives per Β§12.3.4. // 5. Parameterized family β€” FAILS: the two variants carry // structurally heterogeneous payload-element types -// (NonAnsiPorts.ports: List with direction + +// (NonAnsiPorts.ports: List with port-expression // name only; AnsiPorts.ports: List with // direction + name + net_kind + packing + signedness) β€” NOT // one generic `F` / projection over a single source set @@ -1078,7 +1125,7 @@ type AnsiPortDeclaration // Terminal: the closed two-way Verilog module-ports-list-style // classifier of the IEEE 1364-2005 spec. type ModulePortsList - = NonAnsiPorts { ports: List } + = NonAnsiPorts { ports: List } | AnsiPorts { ports: List } @@ -1824,6 +1871,8 @@ type ModuleItem | GateInstantiationItem { gate: GateInstantiation } | UdpInstantiationItem { udp_instance: UdpInstantiation } | SpecparamDeclarationItem { specparam: SpecparamDeclaration } + | PortDeclarationItem { port_decl: PortDeclaration } + | BodyPortDeclarationItem { body_port: AnsiPortDeclaration } // ───────────────────────────────────────────────────────────────────── From 42c265ec4ac024a4e5d5c7bfffdedd4033e2f1ed Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 07:31:47 +0000 Subject: [PATCH 16/56] v4 T-4.9 verilog: separate non-ANSI header port-list from body port_declaration (codex BLOCKING on PR #3176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176 at sha 949f421fb (1755): non-ANSI module header was carrying PortDeclaration { direction, name } as a header element, but per IEEE 1364-2005 Β§12.3.2 non-ANSI headers carry only port-expressions (port-names or bit-selects); direction is a BODY port_declaration item per Β§12.3.4 + Β§12.2 module_item grammar. The prior shape collapsed the spec's header-vs-body partition AND made ModuleItem's Β§12.2 closed-set coverage incomplete (body port_declarations are Β§12.2 items the prior 18-way cut omitted). Fix: - New NonAnsiPort Conj record carrying `port_expression_lexeme: String` β€” covers port-name + bit-select + renamed-port forms via the established body_lexeme precedent. - ModulePortsList.NonAnsiPorts.ports now List (was List). Non-ANSI headers carry expressions only; direction lives in body items. - PortDeclaration { direction, name } stays as a body item carrier (unchanged shape; relocated semantically). - ModuleItem gains 2 new variants: - PortDeclarationItem { port_decl: PortDeclaration } β€” body direction-only port_declaration (`input a;`). - BodyPortDeclarationItem { body_port: AnsiPortDeclaration } β€” body port_declaration with inline type (`input wire [7:0] a;`), reusing AnsiPortDeclaration's per-direction Disj structure since the body combined form is shape-equivalent to ANSI per Β§12.3.4. - ModuleItem ledger updated 18β†’20 variants; closed-set-coverage note explains the header/body separation + the AnsiPortDeclaration carrier reuse for body's combined form. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 2f9c86737f1..8ca6ec97333 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1850,8 +1850,15 @@ type SpecparamDeclaration { // β€” NOT one generic `F` / projection over a separately- // declared source set (Practice 7). The IEEE 1364-2005 module- // body item set is the irreducible partition. -// Terminal: the closed eighteen-way module-body-item classifier of -// the IEEE 1364-2005 Β§12.2 + Β§14.3.1 spec. +// Terminal: the closed twenty-way module-body-item classifier of +// the IEEE 1364-2005 Β§12.2 + Β§14.3.1 spec (corrected per codex +// BLOCKING on PR #3176 2026-05-16 β€” added PortDeclarationItem +// (direction-only body port_declaration) and BodyPortDeclarationItem +// (body port_declaration with inline type, reusing the +// AnsiPortDeclaration carrier; the body-form combined declaration +// is structurally equivalent to ANSI per Β§12.3.4). The body port_ +// declaration is itself a Β§12.2 module_item the spec lists; the +// prior 18-way cut missed both body forms. type ModuleItem = ContinuousAssignItem { assign: ContinuousAssign } | AlwaysBlockItem { always_block: AlwaysBlock } From 013de64682cf5d34e8463146d6583a05b6b89c80 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 08:30:00 +0000 Subject: [PATCH 17/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20ModuleParameterPo?= =?UTF-8?q?rtList=20=E2=80=94=20model=20module-header=20#(parameter=20W=20?= =?UTF-8?q?=3D=208)=20clause=20per=20=C2=A712.1=20(codex=20BLOCKING=20on?= =?UTF-8?q?=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: VerilogModule had no carrier for the IEEE 1364-2005 Β§12.1 module_parameter_port_list β€” the optional `module M #(parameter W = 8, parameter D = 16) (...)` clause was unrepresentable, collapsing header parameters with body ParameterDeclarationItem. Header parameters are spec-distinct from body parameters: header parameters are externally overridable via instantiation `#(...)` syntax (ParameterOverrides on ModuleInstance); body parameters are not. Fix: - New closed Disj ModuleParameterPortList = NoModuleParameterPortList | ModuleParameters { parameters: List } with full 5-pattern Practice-4 ledger. Explicit "no clause" vs "with parameters" distinction (Disj-with-named-payloads). - VerilogModule.parameter_port_list: ModuleParameterPortList field added between name and ports. The Β§12.1 header structure is now faithfully ordered: name β†’ optional #(...) parameters β†’ ports β†’ body items. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 99 ++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 13 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 8ca6ec97333..d546deac897 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1883,20 +1883,92 @@ type ModuleItem // ───────────────────────────────────────────────────────────────────── -// VerilogModule β€” a top-level Verilog module (`module Name (ports); -// items endmodule`). IEEE 1364-2005 Β§12.1. Conj record (no -// Practice-4 ledger). +// ModuleParameterPortList β€” the closed Verilog module-header +// parameter-port-list classifier (IEEE 1364-2005 Β§12.1). A module +// declaration may carry an OPTIONAL `#(parameter W = 8, parameter +// D = 16)` clause between the module name and the port list. Per +// spec grammar the clause is module_parameter_port_list and admits +// parameter_declarations only (not localparam β€” localparams must +// live in the body). The optional-presence is structural and +// modeled via a closed Disj rather than a nullable field. +// +// - NoModuleParameterPortList +// β€” `module M (a, b);` β€” no `#(...)` clause; the module +// takes no header-overridable parameters. (Body +// ParameterDeclarationItem may still appear, but those +// parameters are body-scoped and not part of the header- +// overridable surface; a ModuleInstance's +// ParameterOverrides bind to the HEADER parameter port list +// per Β§12.1.3.) +// - ModuleParameters { parameters: List } +// β€” `module M #(parameter W = 8, parameter D = 16) (a, b);` +// β€” the header carries the parameter port list. These +// parameters are externally overridable via instantiation +// `#(...)` syntax (the ParameterOverrides Disj's actuals +// bind positionally or by name to THESE header parameters, +// not to body ParameterDeclarations). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.1 admits exactly the +// present-or-absent partition; SystemVerilog adds type parameters +// and parameterized class declarations β€” a future language-version +// model would EDIT this Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every module-instantiation / +// parameter-resolution consumer reads the header parameter +// port list to know which parameters are externally +// overridable; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ +// parameters: List }` where empty-list +// = "no clause" conflates "explicitly `#()` empty" (a syntax +// no Verilog admits) with "no `#(...)` clause at all" β€” the +// Disj makes the present-vs-absent partition structural. +// 3. Algebraic form β€” N/A by construction: the two variants are +// the spec's primitive clause-presence partition; not a +// richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single module declaration has +// EXACTLY ONE parameter-port-list-presence state; mutually- +// exclusive alternatives. +// 5. Parameterized family β€” FAILS: NoModuleParameterPortList is +// nullary; ModuleParameters carries +// `List` β€” structurally heterogeneous, +// NOT one generic `F` / projection over a single source +// set (Practice 7). +// Terminal: the closed two-way Verilog module-header parameter- +// port-list classifier of the IEEE 1364-2005 spec Β§12.1. +type ModuleParameterPortList + = NoModuleParameterPortList + | ModuleParameters { parameters: List } + + +// ───────────────────────────────────────────────────────────────────── +// VerilogModule β€” a top-level Verilog module (`module Name +// #(parameters) (ports); items endmodule`). IEEE 1364-2005 Β§12.1. +// Conj record (no Practice-4 ledger). // -// - name the module identifier (K-1-opaque Symbol) -// - ports the port-declaration list as a ModulePortsList Disj -// (NonAnsiPorts OR AnsiPorts per spec Β§12.3.4; -// uniform per module β€” mixing styles in one module is -// a syntax error). Corrected from `List` -// per codex BLOCKING on PR #3176: the prior per-port -// style encoding admitted the spec-forbidden mixed -// state. -// - items the module-body items list (the Conj of parallel -// siblings β€” the IN-B parallel-composition surface) +// - name the module identifier (K-1-opaque Symbol) +// - parameter_port_list +// the OPTIONAL header `#(...)` parameter +// port list (ModuleParameterPortList Disj β€” +// NoModuleParameterPortList | ModuleParameters +// per spec Β§12.1). These header parameters +// are externally overridable via +// instantiation `#(...)` syntax +// (ParameterOverrides on ModuleInstance). +// Added per codex BLOCKING on PR #3176 β€” the +// prior shape had no carrier for `module M +// #(parameter W = 8) (...)` headers, +// collapsing the Β§12.1 partition with body +// ParameterDeclarationItem (which is body- +// scoped only). +// - ports the port-declaration list as a +// ModulePortsList Disj (NonAnsiPorts OR +// AnsiPorts per spec Β§12.3.4; uniform per +// module β€” mixing styles is a syntax error). +// - items the module-body items list (the Conj of +// parallel siblings β€” the IN-B parallel- +// composition surface) // // Per the IN-B PROBE FINDING: the `items` field IS the parallel- // Conj surface; the structural concurrency of multiple always-blocks @@ -1906,6 +1978,7 @@ type ModuleItem // feedback_no_annotations). type VerilogModule { name: Symbol + parameter_port_list: ModuleParameterPortList ports: ModulePortsList items: List } From 94b74b0011304205ea240e7a9fad7f2e04132ab5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 04:32:37 -0400 Subject: [PATCH 18/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 47 ++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index d546deac897..8f59d8c1169 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1859,7 +1859,14 @@ type SpecparamDeclaration { // is structurally equivalent to ANSI per Β§12.3.4). The body port_ // declaration is itself a Β§12.2 module_item the spec lists; the // prior 18-way cut missed both body forms. -type ModuleItem +// AnsiModuleItem β€” the closed Verilog module-body item classifier +// for ANSI-style modules (IEEE 1364-2005 Β§12.2 β€” the 18 items spec- +// admitted in any module body, EXCLUDING body port_declarations). +// ANSI ports are "completely declared" per Β§12.3.3, so body port_ +// declarations (`PortDeclarationItem` / `BodyPortDeclarationItem`) +// are a SYNTAX ERROR in ANSI-style modules β€” they are admitted only +// in the NonAnsiModuleItem set below. +type AnsiModuleItem = ContinuousAssignItem { assign: ContinuousAssign } | AlwaysBlockItem { always_block: AlwaysBlock } | InitialBlockItem { initial_block: InitialBlock } @@ -1878,8 +1885,23 @@ type ModuleItem | GateInstantiationItem { gate: GateInstantiation } | UdpInstantiationItem { udp_instance: UdpInstantiation } | SpecparamDeclarationItem { specparam: SpecparamDeclaration } - | PortDeclarationItem { port_decl: PortDeclaration } - | BodyPortDeclarationItem { body_port: AnsiPortDeclaration } + + +// ───────────────────────────────────────────────────────────────────── +// NonAnsiModuleItem β€” the closed Verilog module-body item classifier +// for non-ANSI-style modules. Non-ANSI bodies admit ALL AnsiModuleItem +// variants PLUS body port_declarations (PortDeclarationItem + +// BodyPortDeclarationItem) per IEEE 1364-2005 Β§12.3.4 β€” port direction +// + (optional) type live in body items in the non-ANSI form. The +// Disj-with-named-payloads makes "ANSI port-list module with body +// PortDeclarationItem" structurally unrepresentable (codex BLOCKING +// fix on PR #3176 2026-05-16: items list was previously +// `List` regardless of port style, admitting the Β§12.3.3 +// "ANSI ports are completely declared" violation). +type NonAnsiModuleItem + = NonAnsiAnsiCompatItem { item: AnsiModuleItem } + | NonAnsiPortDeclarationItem { port_decl: PortDeclaration } + | NonAnsiBodyPortDeclarationItem { body_port: AnsiPortDeclaration } // ───────────────────────────────────────────────────────────────────── @@ -1976,12 +1998,19 @@ type ModuleParameterPortList // in the items list". There is no `concurrent: Bool` flag; the // parallelism is read FROM the list-of-siblings shape ( // feedback_no_annotations). -type VerilogModule { - name: Symbol - parameter_port_list: ModuleParameterPortList - ports: ModulePortsList - items: List -} +type VerilogModule + = NonAnsiVerilogModule { + name: Symbol, + parameter_port_list: ModuleParameterPortList, + header_ports: List, + items: List + } + | AnsiVerilogModule { + name: Symbol, + parameter_port_list: ModuleParameterPortList, + header_ports: List, + items: List + } // ───────────────────────────────────────────────────────────────────── From ec34a6b5ad641903b8ae9689ae8a2cbba07b5f72 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 08:33:25 +0000 Subject: [PATCH 19/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20VerilogModule=20p?= =?UTF-8?q?er-style=20Disj=20=E2=80=94=20body=20items=20=C3=97=20port-styl?= =?UTF-8?q?e=20admissibility=20(codex=20BLOCKING=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: items: List was unrestricted by port style β€” an ANSI-port module could carry body PortDeclarationItem / BodyPortDeclarationItem, but per IEEE 1364-2005 Β§12.3.3 ANSI ports are "completely declared" and body redeclarations are a syntax error. INVARIANTS P2 illegal-states-unrepresentable violation. Fix: - Split ModuleItem into AnsiModuleItem (18 variants β€” all of the prior set EXCEPT PortDeclarationItem and BodyPortDeclarationItem) and NonAnsiModuleItem (3 variants β€” NonAnsiAnsiCompatItem wrapping an AnsiModuleItem + NonAnsiPortDeclarationItem + NonAnsiBodyPortDeclarationItem). - Dissolved the standalone ModulePortsList Disj; lifted port-style choice to VerilogModule itself. - VerilogModule is now a Disj: - NonAnsiVerilogModule { name, parameter_port_list, header_ports: List, items: List } - AnsiVerilogModule { name, parameter_port_list, header_ports: List, items: List } Result: "ANSI port-list module with body port_declaration items" is unrepresentable by construction. The Β§12.3.4 module-style partition is structural at the module-as-a-whole level; both header port-list type AND body items admissibility are per-variant on VerilogModule's Disj. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 76 ++++------------------------ 1 file changed, 11 insertions(+), 65 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 8f59d8c1169..56036ac9d0e 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1062,71 +1062,17 @@ type AnsiPortDeclaration | AnsiInoutPort { name: Symbol, net: AnsiNetPortType } -// ───────────────────────────────────────────────────────────────────── -// ModulePortsList β€” the closed Verilog module-ports-list-style -// classifier (IEEE 1364-2005 Β§12.3.4). The spec admits two port-list -// styles and they are MUTUALLY EXCLUSIVE PER MODULE: a single module -// declares its entire port list in EITHER non-ANSI style (port names -// in header + matching body declarations) OR ANSI style (full type- -// fact inline in header). Mixing styles within one module is a syntax -// error per Β§12.3.4. The Disj-with-named-payloads makes that -// uniformity structural at the module-list level β€” the prior per-port -// `style: PortDeclarationStyle` field admitted the spec-forbidden -// mixed state (codex BLOCKING review on PR #3176 corrected this; the -// per-port encoding was a product-axis miscarve relative to the spec's -// module-header partition). -// -// - NonAnsiPorts { ports: List } -// β€” the entire module's port list is non-ANSI style; each -// header entry is a port-EXPRESSION (port name or bit-select -// or renamed-port form) per spec Β§12.3.2. Port direction + -// type-facts live in BODY port_declaration items -// (PortDeclarationItem / BodyPortDeclarationItem in -// ModuleItem). The spec's Verilog-1995 module-header form. -// - AnsiPorts { ports: List } -// β€” the entire module's port list is ANSI style; each port -// carries direction + name + inline net_kind + packing + -// signedness. The spec's Verilog-2001 / 1364-2005 Β§12.3.3 -// module-header form. -// -// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two -// module-port-list styles; SystemVerilog adds `.name`-shorthand and -// interface ports β€” a future language-version model would EDIT this -// Disj explicitly. -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every module-port-list emitter and -// every type-resolution walker reads the style uniformly to -// know WHERE the type-fact lives across the entire port list -// (header for ANSI / body lookup for non-ANSI); shared -// classifier, not scattered. -// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ ports: -// List, ansi: Bool }` ratifies the -// spec-forbidden mixed-style state (an `ansi=false` flag with -// ANSI-typed elements, or vice versa) β€” INVARIANTS P2 -// illegal-states-unrepresentable anti-pattern (this PR's -// BLOCKING fix exists to dissolve). The Disj-with-typed- -// payload-lists makes mixed-style unrepresentable by -// construction. -// 3. Algebraic form β€” N/A by construction: the two styles are -// the IEEE 1364-2005 module-header primitive partition; they -// do not trace to a richer std/ algebraic structure. -// 4. Dimensional β€” FAILS: a single module's port-list is EXACTLY -// ONE style; mutually-exclusive alternatives per Β§12.3.4. -// 5. Parameterized family β€” FAILS: the two variants carry -// structurally heterogeneous payload-element types -// (NonAnsiPorts.ports: List with port-expression -// name only; AnsiPorts.ports: List with -// direction + name + net_kind + packing + signedness) β€” NOT -// one generic `F` / projection over a single source set -// (Practice 7). The list-element-shape difference IS the -// partition's defining structural fact. -// Terminal: the closed two-way Verilog module-ports-list-style -// classifier of the IEEE 1364-2005 spec. -type ModulePortsList - = NonAnsiPorts { ports: List } - | AnsiPorts { ports: List } +// (The standalone ModulePortsList Disj has been dissolved into +// VerilogModule's own per-style Disj β€” VerilogModule is now +// NonAnsiVerilogModule | AnsiVerilogModule, each variant carrying its +// own header-port list type AND its own admissible body-items list +// type. This lifts the port-style choice from the port-list carrier +// to the module-as-a-whole carrier, making "ANSI port-list module +// with body PortDeclarationItem" structurally unrepresentable β€” +// INVARIANTS P2 illegal-states-unrepresentable fix per codex BLOCKING +// on PR #3176 2026-05-16. The Β§12.3.4 module-style partition is now +// the dimensional axis of VerilogModule itself; the rationale +// formerly housed here is folded into VerilogModule's ledger below.) // ───────────────────────────────────────────────────────────────────── From 89ed5916b1ef8b36c791f857edf4a1c9907014fa Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 08:35:05 +0000 Subject: [PATCH 20/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20PrimitiveGateKind?= =?UTF-8?q?=20closed=20Disj=20=E2=80=94=20replace=20free=20gate=5Fkeyword?= =?UTF-8?q?=20String=20(codex=20BLOCKING=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: GateInstantiation.gate_keyword was a free String even though IEEE 1364-2005 Β§7 admits a closed 26-keyword primitive-gate set. MODELING M4 closed-sets-are-enums-not-strings + INVARIANTS P2 illegal-states-unrepresentable violation. Fix: new closed PrimitiveGateKind Disj over the 26 spec gate types across six families per Β§7: - N-input: GateAnd / GateNand / GateOr / GateNor / GateXor / GateXnor - N-output: GateBuf / GateNot - Three-state: GateBufif0 / GateBufif1 / GateNotif0 / GateNotif1 - MOS: GateNmos / GatePmos / GateCmos / GateRnmos / GateRpmos / GateRcmos - Bidirectional: GateTran / GateRtran / GateTranif0 / GateTranif1 / GateRtranif0 / GateRtranif1 - Pull: GatePulldown / GatePullup Full 5-pattern Practice-4 ledger. GateInstantiation.gate_keyword: String β†’ gate_kind: PrimitiveGateKind. Body lexeme deferral unchanged (terminal-arity/drive-strength/delay admissibility lives in T-4 LanguageModel). Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 114 ++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 20 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 56036ac9d0e..06207905d1e 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1652,30 +1652,104 @@ type LocalParameterDeclaration { } +// ───────────────────────────────────────────────────────────────────── +// PrimitiveGateKind β€” the closed Verilog built-in primitive-gate +// kind classifier (IEEE 1364-2005 Β§7.2). The spec admits exactly 26 +// primitive gate types partitioned into six families per Β§7. Modeling +// the keyword as a free `String` admits spec-illegal keywords β€” +// corrected per codex BLOCKING on PR #3176 (M4 closed-sets-are-enums +// + INVARIANTS P2 illegal-states-unrepresentable). The keyword IS the +// closed kind discriminator and lives on this enum. +// +// N-input gates (Β§7.2): +// - GateAnd, GateNand, GateOr, GateNor, GateXor, GateXnor +// N-output gates (Β§7.2): +// - GateBuf, GateNot +// Three-state gates (Β§7.2): +// - GateBufif0, GateBufif1, GateNotif0, GateNotif1 +// MOS switches (Β§7.5): +// - GateNmos, GatePmos, GateCmos, GateRnmos, GateRpmos, GateRcmos +// Bidirectional pass switches (Β§7.6): +// - GateTran, GateRtran, GateTranif0, GateTranif1, GateRtranif0, +// GateRtranif1 +// Pull gates (Β§7.7): +// - GatePulldown, GatePullup +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§7 admits this 26-way +// primitive-gate partition; SystemVerilog adds no new primitives. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every gate-emission consumer + every +// per-gate terminal-arity check + every per-gate drive-strength +// legality check reads the kind tag uniformly; shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: a `{ keyword: String }` proxy admits +// spec-illegal keywords (M4 closed-sets-are-enums-not-strings; +// the K-1 readable-string heuristic surface this Disj forecloses). +// A `{ id: Int }` proxy admits unbounded Int β€” same anti-pattern. +// The enum IS the M4-faithful form. +// 3. Algebraic form β€” N/A by construction: the 26 gates are the +// spec's primitive electrical-primitive taxonomy; the per-family +// sub-partitions (n-input / n-output / three-state / MOS / pass / +// pull) are observable derivations, not richer std/ algebra. +// 4. Dimensional β€” FAILS: a single gate instantiation has EXACTLY +// ONE kind; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the 26 are structurally +// heterogeneous per family (varying terminal-arity admissibility +// per gate, varying drive-strength admissibility, varying +// bidirectionality) β€” NOT one generic `F` / projection over +// a separately-declared source set (Practice 7). The spec's +// partition is irreducible. +// Terminal: the closed twenty-six-way Verilog primitive-gate-kind +// classifier of the IEEE 1364-2005 Β§7 spec. +type PrimitiveGateKind + = GateAnd + | GateNand + | GateOr + | GateNor + | GateXor + | GateXnor + | GateBuf + | GateNot + | GateBufif0 + | GateBufif1 + | GateNotif0 + | GateNotif1 + | GateNmos + | GatePmos + | GateCmos + | GateRnmos + | GateRpmos + | GateRcmos + | GateTran + | GateRtran + | GateTranif0 + | GateTranif1 + | GateRtranif0 + | GateRtranif1 + | GatePulldown + | GatePullup + + // ───────────────────────────────────────────────────────────────────── // GateInstantiation β€” a Verilog built-in primitive instantiation // (`and g1(out, a, b);` / `not n1(o, i);` / `bufif1 b1(out, in, en);`, -// etc.). IEEE 1364-2005 Β§7 admits 24 built-in primitive gate types -// (and / or / nand / nor / xor / xnor / not / buf / bufif0 / bufif1 / -// notif0 / notif1 / pulldown / pullup / nmos / pmos / cmos / rnmos / -// rpmos / rcmos / tran / tranif0 / tranif1 / rtran / rtranif0 / -// rtranif1). Conj record (no Practice-4 ledger). -// -// - gate_keyword the primitive's keyword as a verbatim lexeme -// (the closed 24-keyword set is owned by the -// bundled T-4 LanguageModel productions; the -// vocabulary slice carries the keyword as -// lexeme + the per-keyword terminal-arity table -// is a LanguageModel-level joint check, same -// pattern as gate primitives' per-keyword -// admissibility) -// - body_lexeme instance name + terminal list as a verbatim -// lexeme (sub-grammar deferred β€” the -// per-primitive terminal arity / drive strength -// / delay control is in the bundled -// LanguageModel) +// etc.). IEEE 1364-2005 Β§7. Conj record (no Practice-4 ledger). +// +// - gate_kind which built-in primitive gate (PrimitiveGateKind +// closed Disj; replaces the prior free-String +// gate_keyword that admitted spec-illegal +// keywords β€” M4 / INVARIANTS P2 fix per codex +// BLOCKING on PR #3176) +// - body_lexeme instance name + terminal list + drive-strength +// + delay control as a verbatim lexeme (sub- +// grammar deferred β€” the per-primitive terminal +// arity / drive strength / delay control +// admissibility lives in the bundled T-4 +// LanguageModel productions) type GateInstantiation { - gate_keyword: String + gate_kind: PrimitiveGateKind body_lexeme: String } From 734e50df95324e9abfe2ccba0055f354002838c5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 05:31:06 -0400 Subject: [PATCH 21/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 157 ++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 26 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 06207905d1e..96ad13d32b8 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -885,6 +885,68 @@ type PortAnsiTypeKind | AnsiRealTimeType +// ───────────────────────────────────────────────────────────────────── +// OutputPortAnsiTypeKind β€” the closed Verilog ANSI-OUTPUT-port +// type/kind classifier. IEEE 1364-2005 Β§12.3.3 admits ALL six +// PortAnsiTypeKind variants for outputs MINUS real / realtime (the +// spec explicitly states "An output port can be of any net or +// variable type EXCEPT a real type" β€” floating-point types are not +// admitted as output ports because they have no well-defined +// inter-module wire representation). The OUTPUT-specific subset is +// modeled here; the spec-illegal AnsiRealType / AnsiRealTimeType +// outputs are unrepresentable by construction (codex BLOCKING fix on +// PR #3176 2026-05-16 β€” the prior AnsiOutputPort reused +// PortAnsiTypeKind directly, admitting `output real` / `output +// realtime` which the spec forbids). +// +// - OutputAnsiNetType { net_type: NetType, packing: PackingShape, +// signedness: Signedness } +// β€” `output wire [7:0] data`; net family. +// - OutputAnsiRegType { packing: PackingShape, signedness: Signedness } +// β€” `output reg [7:0] count`; reg-typed (procedural-assignable +// output, the most common parameterized output form). +// - OutputAnsiIntegerType +// β€” `output integer counter`; 32-bit signed. +// - OutputAnsiTimeType +// β€” `output time t`; 64-bit unsigned simulation-time. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits exactly +// this four-way output-type partition; SystemVerilog adds further +// types β€” future language-version model EDITS this Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every output-port consumer reads the +// kind to dispatch emission / type-check legality; shared +// classifier, not scattered. +// 2. Variant-is-data β€” FAILS: reusing PortAnsiTypeKind directly +// (the prior shape) admits AnsiRealType / AnsiRealTimeType +// outputs β€” exactly the Β§12.3.3 illegal state this Disj +// dissolves. P2 illegal-states-unrepresentable. +// 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ +// algebra structure (OutputAnsiNetType / OutputAnsiRegType β†’ +// Semiring or OrderedRing per packing Γ— signedness; +// OutputAnsiIntegerType β†’ OrderedRing>; +// OutputAnsiTimeType β†’ Semiring>). D2-deferred per +// "Owned ELSEWHERE". +// 4. Dimensional β€” FAILS: an ANSI output port has EXACTLY ONE +// type/kind; mutually-exclusive alternatives. +// 5. Parameterized family β€” PARTIAL: this Disj is a SUBSET +// projection of PortAnsiTypeKind (the 6-variant general +// partition minus real/realtime). The projection is the spec's +// output-port-admissibility filter β€” not a generic `F` over +// a richer source set (Practice 7), because the real/realtime +// exclusion IS the partition's defining filter. +// Terminal: the closed four-way Verilog ANSI-output-port type/kind +// classifier; real/realtime outputs unrepresentable by construction +// per IEEE 1364-2005 Β§12.3.3. +type OutputPortAnsiTypeKind + = OutputAnsiNetType { net_type: NetType, packing: PackingShape, signedness: Signedness } + | OutputAnsiRegType { packing: PackingShape, signedness: Signedness } + | OutputAnsiIntegerType + | OutputAnsiTimeType + + // ───────────────────────────────────────────────────────────────────── // NonAnsiPort β€” a non-ANSI-style Verilog module-HEADER port entry // (`module M (a, b, c);` β€” the header lists port-EXPRESSIONS only; @@ -1058,7 +1120,7 @@ type AnsiNetPortType // unrepresentable by construction. type AnsiPortDeclaration = AnsiInputPort { name: Symbol, net: AnsiNetPortType } - | AnsiOutputPort { name: Symbol, type_kind: PortAnsiTypeKind } + | AnsiOutputPort { name: Symbol, type_kind: OutputPortAnsiTypeKind } | AnsiInoutPort { name: Symbol, net: AnsiNetPortType } @@ -1987,37 +2049,80 @@ type ModuleParameterPortList // ───────────────────────────────────────────────────────────────────── // VerilogModule β€” a top-level Verilog module (`module Name // #(parameters) (ports); items endmodule`). IEEE 1364-2005 Β§12.1. -// Conj record (no Practice-4 ledger). +// Per-style Disj β€” each variant carries its own header-port-list type +// AND its own admissible body-items list type. The Β§12.3.4 module- +// style partition is the dimensional axis of VerilogModule itself; +// "ANSI port-list module with body PortDeclarationItem" is +// unrepresentable by construction. // -// - name the module identifier (K-1-opaque Symbol) -// - parameter_port_list -// the OPTIONAL header `#(...)` parameter -// port list (ModuleParameterPortList Disj β€” -// NoModuleParameterPortList | ModuleParameters -// per spec Β§12.1). These header parameters -// are externally overridable via -// instantiation `#(...)` syntax -// (ParameterOverrides on ModuleInstance). -// Added per codex BLOCKING on PR #3176 β€” the -// prior shape had no carrier for `module M -// #(parameter W = 8) (...)` headers, -// collapsing the Β§12.1 partition with body -// ParameterDeclarationItem (which is body- -// scoped only). -// - ports the port-declaration list as a -// ModulePortsList Disj (NonAnsiPorts OR -// AnsiPorts per spec Β§12.3.4; uniform per -// module β€” mixing styles is a syntax error). -// - items the module-body items list (the Conj of -// parallel siblings β€” the IN-B parallel- -// composition surface) +// - NonAnsiVerilogModule +// β€” non-ANSI style: header carries port-EXPRESSIONS only +// (List); body carries the full NonAnsiModuleItem +// set including body PortDeclarationItem + +// BodyPortDeclarationItem per Β§12.3.4. +// - AnsiVerilogModule +// β€” ANSI style: header carries fully-declared ports +// (List); body carries AnsiModuleItem +// only (the 18 items spec-admitted in any module body +// EXCLUDING port_declarations β€” per Β§12.3.3 ANSI ports are +// "completely declared" and body redeclarations are a syntax +// error). +// +// Both variants carry name + parameter_port_list. The header +// parameter_port_list (`#(parameter W = 8)`) extends with body +// parameter declarations to form the module's UNIFIED OVERRIDEABLE +// parameter surface β€” instantiation `#(...)` overrides bind to the +// projection of header parameters concatenated with body +// ParameterDeclarationItems (in declaration order); body +// LocalParameterDeclarationItem is EXCLUDED from the overrideable +// surface per Β§3.10 (codex BLOCKING on PR #3176 β€” the prior framing +// suggested only header parameters were overrideable, but per spec +// both header and body `parameter` declarations are overrideable; +// only `localparam` is not). // // Per the IN-B PROBE FINDING: the `items` field IS the parallel- // Conj surface; the structural concurrency of multiple always-blocks // / continuous-assigns / instances is precisely "these are siblings // in the items list". There is no `concurrent: Bool` flag; the -// parallelism is read FROM the list-of-siblings shape ( -// feedback_no_annotations). +// parallelism is read FROM the list-of-siblings shape +// (feedback_no_annotations). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.4 admits exactly the +// two module-style forms; SystemVerilog adds further declaration +// forms β€” future language-version model EDITS this Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every module-level consumer +// (emission, port-binding resolution, body item-set +// admissibility check, synthesis dispatch) branches on the +// style uniformly; shared classifier at the module-as-a-whole +// level, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform Conj +// record `{ name, parameter_port_list, ports: ModulePortsList, +// items: List }` ratifies the Β§12.3.3 +// illegal state "ANSI ports + body port_declaration" β€” the +// prior shape this VerilogModule Disj was introduced to +// dissolve. The per-style payloads make admissibility +// structural. +// 3. Algebraic form β€” N/A by construction: the two module styles +// are the IEEE 1364-2005 spec's primitive module-style +// partition; they do not trace to a richer std/ algebraic +// structure. +// 4. Dimensional β€” FAILS: a single module declaration is EXACTLY +// ONE style; mutually-exclusive alternatives per Β§12.3.4. +// 5. Parameterized family β€” FAILS: the two variants carry +// structurally heterogeneous payloads (NonAnsi.header_ports: +// List + items: List vs Ansi. +// header_ports: List + items: +// List) β€” the header port-list type AND the +// body item-set type both differ per style. NOT one generic +// `F` / projection over a single source set (Practice 7). +// The compound payload-type difference IS the partition's +// defining structural fact. +// Terminal: the closed two-way Verilog module-declaration-style +// classifier of the IEEE 1364-2005 Β§12.3.4 spec; ledger added per +// codex BLOCKING on PR #3176 2026-05-16. type VerilogModule = NonAnsiVerilogModule { name: Symbol, From 2b1e43b09b75104bf549269a90286832e82a52d8 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 09:33:48 +0000 Subject: [PATCH 22/56] v4 T-4.9 verilog: declarator carriers + output-port subset + module-style ledger + parameter-surface clarification (codex 4 BLOCKINGs on PR #3176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING summary at sha 89ed5916 surfaced 4 spec-fidelity gaps. All in-pattern declaration-class refactors: 1. DECLARATION-BOUNDARY FACTS COLLAPSED. NetDeclaration / Variable Declaration carried name-only, missing strength/delay/dimensions/ initializer/multi-declarator facts per IEEE 1364-2005 Β§A.2.1.3 / Β§A.2.4 / Β§3.10. Fix: - NetDeclaration now carries net_type + packing + signedness + drive_strength_lexeme + delay_lexeme + declarators: List. NetDeclarator { name, initializer_lexeme } covers list_of_net_decl_assignments per spec. - VariableDeclaration variants restructured: each carries declarators: List instead of single name. VariableDeclarator { name, unpacked_dimensions_lexeme, initializer_lexeme } covers list_of_variable_decl_assignments + unpacked-array dimensions per spec Β§7.4. 2. MODULE PARAMETER AUTHORITY split by header location. The Β§12.1 overrideable-parameter surface is the UNION of header parameter_ port_list + body ParameterDeclarationItem (excluding Local ParameterDeclarationItem per Β§3.10). Fix: clarified VerilogModule commentary to document the unified parameter-overrideable surface β€” instantiation #(...) overrides bind to the projection union of header+body parameter declarations in source order, excluding localparam. Structural carrier remains the per-variant items list; the unified surface is the projection the binding consumer walks. 3. OUTPUT PORT TAXONOMY admitted spec-forbidden real/realtime outputs (per Β§12.3.3 "An output port can be of any net or variable type EXCEPT a real type"). Fix: new OutputPortAnsiTypeKind closed Disj (4 variants: OutputAnsiNetType / OutputAnsiRegType / OutputAnsiIntegerType / OutputAnsiTimeType) β€” real/realtime outputs unrepresentable by construction. AnsiOutputPort.type_kind: PortAnsiTypeKind β†’ OutputPortAnsiTypeKind. 4. VERILOGMODULE DISJ MISSED 5-pattern Practice-4 ledger (a new substrate Disj introduced in commit ec34a6b5a without the modeling-discipline.md Β§4 required ledger). Fix: added full 5-pattern ledger to VerilogModule β€” each pattern covers the per-style structural shape, illegal-states- unrepresentable argument (ANSI-with-body-port-decl dissolution), the Β§12.3.4 module-style partition framing. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 149 ++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 24 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 96ad13d32b8..a7c8a6d82ac 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -657,27 +657,90 @@ type Signedness // ───────────────────────────────────────────────────────────────────── -// NetDeclaration β€” a Verilog net (`wire foo;`, `wire [7:0] bus;`, -// `wire signed [15:0] s;`, `wand x;`). Conj record (no Practice-4 +// NetDeclaration β€” a Verilog net declaration (`wire foo;`, +// `wire [7:0] bus;`, `wire signed [15:0] s;`, `wand x;`, +// `wire (strong0, weak1) #5 a = expr_a, b, c = expr_c;`). +// IEEE 1364-2005 Β§3.10 / Β§A.2.1.3. Conj record (no Practice-4 // ledger). // -// - net_type which net-type (wire / wand / wor / tri / …) -// - name the net identifier (K-1-opaque Symbol) -// - packing scalar or `[msb:lsb]` packed bit-vector -// - signedness `signed` keyword present / absent (IEEE 1364-2005 -// Β§5.6; the spec admits `signed` on any net-type; -// for a scalar (single-bit) net the signedness fact -// is semantically vacuous but the spec preserves it -// syntactically β€” parse ∘ emit must preserve the -// writer's keyword choice. Added 2026-05-16 per -// codex BLOCKING review on PR #3176 to preserve the -// IEEE signedness boundary fact for downstream -// arithmetic/emission consumers, INVARIANTS P2.) +// A net_declaration declares ONE OR MORE nets sharing a common +// (net_type, packing, signedness, drive_strength, delay) β€” each +// individual net is a NetDeclarator carrying its own name + optional +// initializer expression. Per spec Β§A.2.1.3 grammar: +// +// net_declaration ::= net_type [drive_strength | charge_strength] +// [vectored | scalared] [signed] [range] +// [delay3] list_of_net_decl_assignments ; +// +// The vectored/scalared modifier is a synthesis hint (rare); not +// modeled in this initial cut β€” the lexeme captures it via +// drive_strength_lexeme (the parser collapses it into the strength +// lexeme position by Β§A.2.2). The charge_strength applies only to +// `trireg` per spec Β§7.10; admitted alongside drive_strength via the +// shared lexeme. +// +// - net_type which net-type (wire / wand / wor / +// tri / … per the closed NetType set) +// - packing scalar or `[msb:lsb]` packed +// bit-vector (the shared range applies +// to all declarators in the list) +// - signedness `signed` keyword present / absent +// (IEEE 1364-2005 Β§5.6) +// - drive_strength_lexeme the optional drive_strength / +// charge_strength clause as a verbatim +// lexeme (`(strong0, weak1)`, +// `(small)`, etc.); "" = absent. +// Sub-grammar deferred β€” the strength +// keyword set is the spec's closed set +// owned by the bundled T-4 +// LanguageModel. +// - delay_lexeme the optional delay3 clause as a +// verbatim lexeme (`#5`, `#(2:3:4)`, +// etc.); "" = absent. Sub-grammar +// deferred to T-4 LanguageModel per +// the body_lexeme precedent. +// - declarators the list_of_net_decl_assignments β€” +// each NetDeclarator carries a name + +// optional initializer expression. +// Per spec a net_declaration must have +// at least one declarator; the empty +// list is structurally representable +// but is a producer-side bug +// (well-formedness joint check in the +// T-4 LanguageModel). +// +// Multi-declarator + strength + delay + initializer added per codex +// BLOCKING review on PR #3176 2026-05-16 β€” the prior {net_type, name, +// packing, signedness} shape collapsed the spec's declaration- +// boundary facts (strength, delay, dimensions, initializer, +// declarator-list) into name-only. type NetDeclaration { net_type: NetType - name: Symbol packing: PackingShape signedness: Signedness + drive_strength_lexeme: String + delay_lexeme: String + declarators: List +} + + +// ───────────────────────────────────────────────────────────────────── +// NetDeclarator β€” one (name, optional-initializer) pair in a +// net_declaration's list_of_net_decl_assignments (IEEE 1364-2005 +// Β§A.2.4 / Β§3.10). A single net_declaration like `wire [7:0] a = ex1, +// b, c = ex2;` carries THREE NetDeclarators. Conj record (no +// Practice-4 ledger). +// +// - name the net identifier (K-1-opaque Symbol) +// - initializer_lexeme the net_decl_assignment initializer +// expression as a verbatim lexeme; "" +// denotes the absent-initializer form +// (`wire a;` vs `wire a = expr;`). Sub- +// grammar deferred to T-4 LanguageModel via +// the established body_lexeme precedent. +type NetDeclarator { + name: Symbol + initializer_lexeme: String } @@ -781,11 +844,45 @@ type NetDeclaration { // classifier; illegal kindΓ—packing AND kindΓ—signedness combinations // are unrepresentable by construction. type VariableDeclaration - = RegVariable { name: Symbol, packing: PackingShape, signedness: Signedness } - | IntegerVariable { name: Symbol } - | RealVariable { name: Symbol } - | TimeVariable { name: Symbol } - | RealTimeVariable { name: Symbol } + = RegVariable { packing: PackingShape, signedness: Signedness, declarators: List } + | IntegerVariable { declarators: List } + | RealVariable { declarators: List } + | TimeVariable { declarators: List } + | RealTimeVariable { declarators: List } + + +// ───────────────────────────────────────────────────────────────────── +// VariableDeclarator β€” one (name, optional-unpacked-dimensions, +// optional-initializer) triple in a variable declaration's +// list_of_variable_decl_assignments (IEEE 1364-2005 Β§A.2.4 / Β§3.10). +// A single declaration like `reg [7:0] a = 8'h00, mem[0:1023], c = +// 4'hF;` carries THREE VariableDeclarators (the second of which has +// an unpacked-array dimensions clause). Conj record (no Practice-4 +// ledger). +// +// - name the variable identifier (K-1- +// opaque Symbol) +// - unpacked_dimensions_lexeme the optional unpacked-array +// dimensions as a verbatim lexeme +// (`[0:1023]`, `[0:15][0:7]`); "" +// denotes a scalar (no unpacked +// array). Per spec Β§7.4 a variable +// can carry both PACKED dimensions +// (on the type β€” RegVariable's +// shared packing field) and UNPACKED +// dimensions (per-declarator β€” +// this field). Sub-grammar deferred +// to T-4 LanguageModel. +// - initializer_lexeme the variable_decl_assignment +// initializer expression as a +// verbatim lexeme; "" denotes the +// absent-initializer form. Sub- +// grammar deferred. +type VariableDeclarator { + name: Symbol + unpacked_dimensions_lexeme: String + initializer_lexeme: String +} // (PortDeclarationStyle has been dissolved into ModulePortsList's @@ -1080,10 +1177,14 @@ type AnsiNetPortType // - AnsiInputPort { name: Symbol, net: AnsiNetPortType } // β€” input ports are net-typed only (the spec forbids // `input reg`). -// - AnsiOutputPort { name: Symbol, type_kind: PortAnsiTypeKind } -// β€” output ports admit the full PortAnsiTypeKind set (net or -// any variable kind; output is the only direction that -// admits reg/integer/real/time/realtime). +// - AnsiOutputPort { name: Symbol, type_kind: OutputPortAnsiTypeKind } +// β€” output ports admit the OutputPortAnsiTypeKind subset (net, +// reg, integer, time per Β§12.3.3 β€” REAL / REALTIME outputs +// are excluded per spec). The closed 4-way subset is structural +// per the OutputPortAnsiTypeKind ledger below; corrected per +// codex BLOCKING on PR #3176 2026-05-16 β€” the prior reuse of +// the full 6-way PortAnsiTypeKind admitted spec-forbidden +// `output real` / `output realtime`. // - AnsiInoutPort { name: Symbol, net: AnsiNetPortType } // β€” inout ports are net-typed only (bidirectional requires // nets; `inout reg` is a spec violation). From 051aa56175642b9c890f2491aa1b43f52322995c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 09:36:21 +0000 Subject: [PATCH 23/56] v4 T-4.9 verilog: ParameterDeclaration / LocalParameterDeclaration / SpecparamDeclaration multi-assignment + type-kind facts (codex BLOCKING on PR #3176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: ParameterDeclaration stored only { name, default_lexeme } β€” missing type/range/signedness facts that per IEEE 1364-2005 Β§A.2.1.1 govern Β§12.1.3 override conversion. INVARIANTS P2 boundary-fact preservation. Fix: - New ParameterTypeKind closed Disj = UntypedParameter { packing, signedness } | IntegerParameter | RealParameter | TimeParameter | RealTimeParameter β€” covers the spec Β§A.2.1.1 parameter-type partition; UntypedParameter is the only variant carrying range+signedness per spec (explicit-typed forms forbid those modifiers). Full 5-pattern Practice-4 ledger. - New ParameterAssignment Conj record { name, default_lexeme } β€” covers list_of_param_assignments per spec Β§A.2.4. - ParameterDeclaration restructured: { type_kind: ParameterTypeKind, assignments: List }. Multi-assignment per spec (`parameter W = 8, D = 16;` is one declaration with 2 assignments). - LocalParameterDeclaration restructured similarly (same shape per spec). - SpecparamDeclaration restructured: { packing: PackingShape, assignments: List } β€” specparams admit optional range but no type-kind per Β§14.3.1 / Β§A.2.1.1. The Β§12.1.3 override conversion machinery now has the spec-mandated type-kind facts available; illegal forms like `parameter integer X = 8, signed [3:0] Y = 4'sb1100` (mixing typed + range modifiers) are unrepresentable by construction. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 144 ++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 24 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index a7c8a6d82ac..26f22329947 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1239,21 +1239,108 @@ type AnsiPortDeclaration // ───────────────────────────────────────────────────────────────────── -// ParameterDeclaration β€” a Verilog compile-time constant -// (`parameter WIDTH = 8;`). Conj record (no Practice-4 ledger). +// ParameterTypeKind β€” the closed Verilog parameter-type classifier +// (IEEE 1364-2005 Β§A.2.1.1). A parameter declaration's type is +// either UNTYPED (inferring from the default-value's type per Β§3.10) +// OR an explicit parameter_type (integer / real / realtime / time). +// The explicit-type form FORBIDS [signed]/[range] modifiers per +// spec β€” those apply only to the untyped form. +// +// - UntypedParameter { packing: PackingShape, signedness: Signedness } +// β€” `parameter WIDTH = 8;`, `parameter signed [3:0] X = 4'sb1100;` +// The packing + signedness modifiers apply ONLY to this form. +// - IntegerParameter β€” `parameter integer N = 4;` +// - RealParameter β€” `parameter real PI = 3.14;` +// - TimeParameter β€” `parameter time T = 10;` +// - RealTimeParameter β€” `parameter realtime RT = 1.5;` +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.2.1.1 admits exactly +// this five-way parameter-type partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every parameter consumer (override- +// conversion per Β§12.1.3, type-check legality, emission) +// reads the type kind uniformly; shared classifier. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ kind: +// Symbol, packing?: PackingShape, signedness?: Signedness }` +// ratifies spec-forbidden states like "IntegerParameter with +// signed [3:0]" (per spec the explicit-type forms forbid +// range/signedness modifiers). Disj-with-heterogeneous- +// payloads makes the per-kind admissibility structural. +// 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ +// algebra structure (UntypedParameter β†’ polymorphic per the +// default-value's inferred type; IntegerParameter β†’ +// OrderedRing>; RealParameter / RealTimeParameter β†’ +// ApproximateField; TimeParameter β†’ Semiring>). +// D2-deferred per "Owned ELSEWHERE". +// 4. Dimensional β€” FAILS: a single parameter has EXACTLY ONE +// type kind; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: heterogeneous payload-presence +// (UntypedParameter carries packing+signedness; the typed +// kinds carry neither) β€” NOT one generic `F` / projection +// over a single source set (Practice 7). Mirror of body-side +// VariableDeclaration's kind Γ— packing Γ— signedness +// dissolution. +// Terminal: the closed five-way Verilog parameter-type classifier. +type ParameterTypeKind + = UntypedParameter { packing: PackingShape, signedness: Signedness } + | IntegerParameter + | RealParameter + | TimeParameter + | RealTimeParameter + + +// ───────────────────────────────────────────────────────────────────── +// ParameterAssignment β€” one (name, default-value) pair in a +// parameter_declaration's list_of_param_assignments (IEEE 1364-2005 +// Β§A.2.4 / Β§3.10). A single declaration like `parameter WIDTH = 8, +// DEPTH = 16;` carries TWO ParameterAssignments. Conj record (no +// Practice-4 ledger). // // - name the parameter identifier (K-1-opaque Symbol) -// - default_lexeme the default value as a verbatim lexeme -// (sub-grammar deferred to the T-4 LanguageModel -// expression productions; the spice.dag -// `SpiceValue.lexeme` precedent β€” `parse ∘ emit` -// is identity on the textual surface) -type ParameterDeclaration { +// - default_lexeme the default value as a verbatim expression +// lexeme; per spec every parameter declaration +// requires a default value (unlike net/variable +// decls), so this field is non-empty in a +// well-formed declaration. Sub-grammar deferred +// to T-4 LanguageModel. +type ParameterAssignment { name: Symbol default_lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// ParameterDeclaration β€” a Verilog compile-time constant declaration +// (`parameter WIDTH = 8;`, `parameter signed [3:0] X = 4'sb1100;`, +// `parameter integer N = 4;`, `parameter WIDTH = 8, DEPTH = 16;`). +// IEEE 1364-2005 Β§3.10 / Β§A.2.1.1. Conj record (no Practice-4 +// ledger). +// +// - type_kind which parameter-type form (ParameterTypeKind +// Disj β€” UntypedParameter carries packing + +// signedness; the typed forms IntegerParameter +// / RealParameter / TimeParameter / +// RealTimeParameter carry neither per spec +// Β§A.2.1.1). +// - assignments the list_of_param_assignments β€” each +// ParameterAssignment carries name + +// default_lexeme. Per spec a parameter +// declaration must have at least one assignment. +// +// Multi-assignment + type_kind added per codex BLOCKING on PR #3176 +// 2026-05-16 β€” the prior {name, default_lexeme} shape collapsed the +// spec's type/range/signedness facts that govern Β§12.1.3 override +// conversion (when an instantiation #(...) overrides a parameter, +// the spec defines conversion semantics based on the declared type; +// without these facts the conversion is unspecified). +type ParameterDeclaration { + type_kind: ParameterTypeKind + assignments: List +} + + // ───────────────────────────────────────────────────────────────────── // SensitivityItem β€” one entry in an always-block's event-control list // (`posedge clk`, `negedge rst`, `posedge (a & b)`, bare expression). @@ -1805,13 +1892,15 @@ type GenvarDeclaration { // (the spec's distinct binding rule). Conj record (no Practice-4 // ledger). // -// - name the localparam identifier (K-1-opaque Symbol) -// - default_lexeme the value as a verbatim expression lexeme -// (mirrors ParameterDeclaration; sub-grammar -// deferred) +// - type_kind which parameter-type form (ParameterTypeKind +// Disj β€” same per-kind admissibility as +// ParameterDeclaration). Mirrors ParameterDeclaration's +// type-fact preservation per IEEE 1364-2005 Β§A.2.1.1. +// - assignments the list_of_param_assignments per spec β€” each +// ParameterAssignment carries name + default_lexeme. type LocalParameterDeclaration { - name: Symbol - default_lexeme: String + type_kind: ParameterTypeKind + assignments: List } @@ -1941,17 +2030,24 @@ type UdpInstantiation { // ───────────────────────────────────────────────────────────────────── // SpecparamDeclaration β€” a Verilog `specparam` declaration. IEEE -// 1364-2005 Β§14.3.1 + Β§12.2. Specify parameters are distinct from -// ordinary parameters: they are intended for timing-check values -// (rise/fall/hi-Z transitions, pulse-control limits) and CANNOT be -// used as bit-vector widths or array indices per spec. Conj record -// (no Practice-4 ledger). -// -// - name the specparam identifier (K-1-opaque Symbol) -// - default_lexeme the value as a verbatim expression lexeme +// 1364-2005 Β§14.3.1 + Β§12.2 + Β§A.2.1.1. Specify parameters are +// distinct from ordinary parameters: they are intended for timing- +// check values (rise/fall/hi-Z transitions, pulse-control limits) +// and CANNOT be used as bit-vector widths or array indices per spec. +// Per spec grammar specparam admits an optional range and a list of +// specparam_assignments. Conj record (no Practice-4 ledger). +// +// - packing optional range (`specparam [9:0]`); applies to +// all assignments in this declaration. +// - assignments the list_of_specparam_assignments β€” each +// ParameterAssignment carries name + default_lexeme. +// Reusing ParameterAssignment per the shared +// (name, value-expression-lexeme) shape; +// specparam-specific pulse-control variants are +// admitted via the assignment's lexeme. type SpecparamDeclaration { - name: Symbol - default_lexeme: String + packing: PackingShape + assignments: List } From af708f9b0baf2838fc5362a8c275511c5c272500 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 05:55:07 -0400 Subject: [PATCH 24/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 42 +++++++++++++++++++++------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 26f22329947..c4098d88746 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -720,7 +720,7 @@ type NetDeclaration { signedness: Signedness drive_strength_lexeme: String delay_lexeme: String - declarators: List + declarators: NonEmptyList } @@ -844,11 +844,11 @@ type NetDeclarator { // classifier; illegal kindΓ—packing AND kindΓ—signedness combinations // are unrepresentable by construction. type VariableDeclaration - = RegVariable { packing: PackingShape, signedness: Signedness, declarators: List } - | IntegerVariable { declarators: List } - | RealVariable { declarators: List } - | TimeVariable { declarators: List } - | RealTimeVariable { declarators: List } + = RegVariable { packing: PackingShape, signedness: Signedness, declarators: NonEmptyList } + | IntegerVariable { declarators: NonEmptyList } + | RealVariable { declarators: NonEmptyList } + | TimeVariable { declarators: NonEmptyList } + | RealTimeVariable { declarators: NonEmptyList } // ───────────────────────────────────────────────────────────────────── @@ -1291,6 +1291,28 @@ type ParameterTypeKind | RealTimeParameter +// ───────────────────────────────────────────────────────────────────── +// NonEmptyList β€” a list known to be non-empty by construction: a +// required head element + a (possibly empty) tail. Used wherever the +// IEEE 1364-2005 grammar requires "at least one" entry β€” a structural +// dissolution of the spec-illegal empty-list state that a bare +// `List` would admit. INVARIANTS P2 illegal-states-unrepresentable +// + modeling-discipline.md Practices 2 / 6. +// +// - head the required first entry +// - tail the remaining entries (may be empty) +// +// Conj record (no Practice-4 ledger β€” only coproducts dissolve). +// Added per codex REQUEST_CHANGES on PR #3176 2026-05-16 β€” multiple +// declaration carriers' `List<…>` fields admitted empty-list states +// the spec grammar forbids; NonEmptyList makes the "at least one" +// requirement structural. +type NonEmptyList { + head: T + tail: List +} + + // ───────────────────────────────────────────────────────────────────── // ParameterAssignment β€” one (name, default-value) pair in a // parameter_declaration's list_of_param_assignments (IEEE 1364-2005 @@ -1337,7 +1359,7 @@ type ParameterAssignment { // without these facts the conversion is unspecified). type ParameterDeclaration { type_kind: ParameterTypeKind - assignments: List + assignments: NonEmptyList } @@ -1900,7 +1922,7 @@ type GenvarDeclaration { // ParameterAssignment carries name + default_lexeme. type LocalParameterDeclaration { type_kind: ParameterTypeKind - assignments: List + assignments: NonEmptyList } @@ -2047,7 +2069,7 @@ type UdpInstantiation { // admitted via the assignment's lexeme. type SpecparamDeclaration { packing: PackingShape - assignments: List + assignments: NonEmptyList } @@ -2240,7 +2262,7 @@ type NonAnsiModuleItem // port-list classifier of the IEEE 1364-2005 spec Β§12.1. type ModuleParameterPortList = NoModuleParameterPortList - | ModuleParameters { parameters: List } + | ModuleParameters { parameters: NonEmptyList } // ───────────────────────────────────────────────────────────────────── From f87fdf1896ec2a3482e82360fff58c384bc6d6b6 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 10:02:44 +0000 Subject: [PATCH 25/56] =?UTF-8?q?v4=20T-4.9=20verilog:=203=20openai-pro=20?= =?UTF-8?q?REQUEST=5FCHANGES=20=E2=80=94=20generate=20constructs,=20parame?= =?UTF-8?q?ter-override=20conditional,=20optional-clause=20sentinels=20(PR?= =?UTF-8?q?=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro REQUEST_CHANGES at sha 051aa561 surfaced 3 substantive findings. All in-pattern declaration-class spec-fidelity: 1. GENERATE CONSTRUCTS β€” per IEEE 1364-2005 Annex A.1.4 loop_generate_construct and conditional_generate_construct are admitted DIRECTLY at module_or_generate_item level, not nested inside `generate ... endgenerate`. The prior GenerateRegionItem covered only the `generate ... endgenerate` form, omitting bare `for (genvar ...) ...` and `if/case (cond) ...` generate-block forms. Fix: new LoopGenerateConstruct + ConditionalGenerateConstruct Conj records (each with body_lexeme deferral). Added LoopGenerateConstructItem + ConditionalGenerateConstructItem variants to AnsiModuleItem (which propagate to NonAnsiModuleItem via NonAnsiAnsiCompatItem wrapping). 2. PARAMETER-OVERRIDE CONDITIONAL RULE β€” VerilogModule commentary was internally inconsistent: one block said overrides bind to header parameters only; another said header+body. Per spec Β§12.1 the rule is CONDITIONAL: when header `#(...)` is present, body `parameter` declarations are LOCAL (not overrideable); when no header `#(...)`, body `parameter` declarations ARE the overrideable surface. (`localparam` is never overrideable per Β§3.10.) Fix: rewrote both VerilogModule and ModuleParameterPortList commentary blocks with the Β§12.1 conditional rule explicitly stated. Each NoModuleParameterPortList / ModuleParameters variant docs which surface IS overrideable for that variant. 3. OPTIONAL-CLAUSE EMPTY-STRING SENTINELS β€” 5 fields used `"" = absent` String sentinel for optional clauses (drive_strength_ lexeme, delay_lexeme, initializer_lexeme on NetDeclaration / NetDeclarator; unpacked_dimensions_lexeme, initializer_lexeme on VariableDeclarator). The file's own PortConnectionActual rejected this exact pattern in favor of a closed BlankConnection variant. Inconsistent + INVARIANTS P3 / C-9 / P5 untracked-sentinel debt. Fix: 5 new closed Disjs (DriveStrengthClause, DelayClause, NetInitializerClause, UnpackedDimensionsClause, VariableInitializerClause), each a 2-way present-or-absent partition with the Lexeme variant carrying the verbatim lexeme. Full 5-pattern Practice-4 ledgers (the first one is verbose; the following ones use the same argument shape with abbreviated form per the established pattern). NetDeclaration / NetDeclarator / VariableDeclarator field types updated to the new Disjs. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 287 ++++++++++++++++++++++++--- 1 file changed, 258 insertions(+), 29 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index c4098d88746..7f442d5b407 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -656,6 +656,173 @@ type Signedness | Unsigned +// ───────────────────────────────────────────────────────────────────── +// DriveStrengthClause β€” the closed Verilog drive-strength / +// charge-strength clause classifier on a net_declaration (IEEE +// 1364-2005 Β§A.2.1.3 / Β§7.10). The clause is OPTIONAL per spec β€” +// present-or-absent partition modeled as a closed Disj rather than +// an empty-string sentinel on a `String` field (openai-pro +// REQUEST_CHANGES on PR #3176; same pattern as PortConnectionActual's +// BlankConnection β€” closed sum, not sentinel). +// +// - NoDriveStrength +// β€” no `(strong0, weak1)` / `(small)` clause on the +// declaration. +// - DriveStrengthLexeme { lexeme: String } +// β€” the clause as a verbatim lexeme (sub-grammar deferred to +// T-4 LanguageModel β€” the spec's closed strength-keyword set +// lives there). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits the present/absent +// partition; per-strength-keyword closure is owned by the bundled +// LanguageModel. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every net-declaration emitter + +// every drive-resolution consumer reads the clause uniformly; +// shared classifier. +// 2. Variant-is-data β€” FAILS: collapsing to `{ lexeme: String }` +// with "" = absent reintroduces the empty-string sentinel +// anti-pattern this Disj exists to dissolve (PortConnection +// Actual's BlankConnection precedent rejected the same shape). +// 3. Algebraic form β€” N/A by construction: the present/absent +// partition is the spec's clause-presence axis; not a richer +// std/ algebraic structure. +// 4. Dimensional β€” FAILS: a net_declaration has EXACTLY ONE +// drive-strength clause state; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: NoDriveStrength is nullary; +// DriveStrengthLexeme carries a `lexeme: String` payload β€” +// structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog drive-strength clause- +// presence classifier. +type DriveStrengthClause + = NoDriveStrength + | DriveStrengthLexeme { lexeme: String } + + +// ───────────────────────────────────────────────────────────────────── +// DelayClause β€” the closed Verilog delay3 clause classifier on a +// net_declaration (IEEE 1364-2005 Β§A.2.1.3 / Β§7.14). The clause is +// OPTIONAL per spec β€” present-or-absent partition as a closed Disj +// (same pattern as DriveStrengthClause). +// +// - NoDelay +// β€” no `#5` / `#(2:3:4)` clause on the declaration. +// - DelayLexeme { lexeme: String } +// β€” the delay clause as a verbatim lexeme; sub-grammar deferred +// to T-4 LanguageModel. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every net-declaration emitter and +// every timing-aware consumer reads the clause uniformly. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejection +// same argument as DriveStrengthClause. +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: exactly one delay-clause state per +// declaration. +// 5. Parameterized family β€” FAILS: heterogeneous payloads +// (Practice 7). +// Terminal: the closed two-way Verilog delay-clause-presence +// classifier. +type DelayClause + = NoDelay + | DelayLexeme { lexeme: String } + + +// ───────────────────────────────────────────────────────────────────── +// NetInitializerClause β€” the closed Verilog net_decl_assignment +// initializer-presence classifier (IEEE 1364-2005 Β§A.2.4). Optional +// per spec β€” present-or-absent partition as a closed Disj. +// +// - NoNetInitializer +// β€” `wire a;` form: no initializer expression. +// - NetInitializerLexeme { lexeme: String } +// β€” `wire a = expr;` form: the initializer expression as a +// verbatim lexeme. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every net-declaration emitter and +// every elaboration-time net-initialization consumer reads +// the clause uniformly. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected +// (same argument). +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one initializer state per declarator. +// 5. Parameterized family β€” FAILS: heterogeneous payloads. +// Terminal: the closed two-way Verilog net-initializer-presence +// classifier. +type NetInitializerClause + = NoNetInitializer + | NetInitializerLexeme { lexeme: String } + + +// ───────────────────────────────────────────────────────────────────── +// UnpackedDimensionsClause β€” the closed Verilog +// unpacked-array-dimensions-presence classifier on a variable +// declarator (IEEE 1364-2005 Β§7.4 / Β§A.2.4). Optional per spec β€” +// present-or-absent partition. +// +// - NoUnpackedDimensions +// β€” `reg a;` form: scalar (no unpacked array). +// - UnpackedDimensionsLexeme { lexeme: String } +// β€” `reg mem[0:1023];` form: unpacked-array dimensions as a +// verbatim lexeme. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every variable-declaration consumer +// reads the clause uniformly to size the unpacked array vs +// scalar. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected. +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one unpacked-dimensions state per +// declarator. +// 5. Parameterized family β€” FAILS: heterogeneous payloads. +// Terminal: the closed two-way Verilog unpacked-dimensions-presence +// classifier. +type UnpackedDimensionsClause + = NoUnpackedDimensions + | UnpackedDimensionsLexeme { lexeme: String } + + +// ───────────────────────────────────────────────────────────────────── +// VariableInitializerClause β€” the closed Verilog variable-declarator +// initializer-presence classifier (IEEE 1364-2005 Β§A.2.4). Optional +// per spec β€” present-or-absent partition. +// +// - NoVariableInitializer +// β€” `reg a;` form: no initializer. +// - VariableInitializerLexeme { lexeme: String } +// β€” `reg a = 8'h00;` form: initializer as a verbatim lexeme. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape +// as NetInitializerClause; abbreviated for brevity (each pattern's +// argument is identical modulo "net" vs "variable"). +// 1. Fact placement β€” FAILS: shared classifier across emitters / +// simulation-init / elaboration consumers. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected. +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one initializer state per declarator. +// 5. Parameterized family β€” FAILS: heterogeneous payloads. +// Terminal: the closed two-way Verilog variable-initializer- +// presence classifier. +type VariableInitializerClause + = NoVariableInitializer + | VariableInitializerLexeme { lexeme: String } + + // ───────────────────────────────────────────────────────────────────── // NetDeclaration β€” a Verilog net declaration (`wire foo;`, // `wire [7:0] bus;`, `wire signed [15:0] s;`, `wand x;`, @@ -718,8 +885,8 @@ type NetDeclaration { net_type: NetType packing: PackingShape signedness: Signedness - drive_strength_lexeme: String - delay_lexeme: String + drive_strength: DriveStrengthClause + delay: DelayClause declarators: NonEmptyList } @@ -740,7 +907,7 @@ type NetDeclaration { // the established body_lexeme precedent. type NetDeclarator { name: Symbol - initializer_lexeme: String + initializer: NetInitializerClause } @@ -880,8 +1047,8 @@ type VariableDeclaration // grammar deferred. type VariableDeclarator { name: Symbol - unpacked_dimensions_lexeme: String - initializer_lexeme: String + unpacked_dimensions: UnpackedDimensionsClause + initializer: VariableInitializerClause } @@ -1827,6 +1994,52 @@ type GenerateRegion { } +// ───────────────────────────────────────────────────────────────────── +// LoopGenerateConstruct β€” a Verilog `for ( genvar = init ; cond ; +// next ) generate_block` construct (IEEE 1364-2005 Β§12.4 + +// Β§A.1.4 / Β§A.4.2 loop_generate_construct). Per spec grammar +// loop_generate_construct is a module_or_generate_item DIRECTLY +// (not nested inside `generate ... endgenerate`); a bare +// `for (genvar i = 0; i < 8; i = i + 1) … endgenerate` is a legal +// module-body item per Annex A.1.4. Conj record (no Practice-4 +// ledger). +// +// - body_lexeme the entire generate-for construct (genvar +// init/cond/iteration + generate_block body) +// as a verbatim lexeme; sub-grammar deferred to +// T-4 LanguageModel (the elaboration-time +// iteration semantics live there). +// +// Added per openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 β€” +// the prior GenerateRegion variant only covered the `generate ... +// endgenerate` form, omitting the bare loop_generate_construct +// admitted directly at module-item level per spec Annex A.1.4. +type LoopGenerateConstruct { + body_lexeme: String +} + + +// ───────────────────────────────────────────────────────────────────── +// ConditionalGenerateConstruct β€” a Verilog `if (cond) generate_block +// [else generate_block]` or `case (cond) ... endcase` conditional +// generate construct (IEEE 1364-2005 Β§A.1.4 / Β§A.4.2 +// conditional_generate_construct = if_generate_construct | +// case_generate_construct). Like LoopGenerateConstruct, this is +// admitted directly at module-item level per spec Annex A.1.4 +// (not nested inside `generate ... endgenerate`). Conj record (no +// Practice-4 ledger). +// +// - body_lexeme the entire conditional-generate construct +// (if/case head + generate_block body) as a +// verbatim lexeme; sub-grammar deferred to +// T-4 LanguageModel. +// +// Added per openai-pro REQUEST_CHANGES on PR #3176 2026-05-16. +type ConditionalGenerateConstruct { + body_lexeme: String +} + + // ───────────────────────────────────────────────────────────────────── // SpecifyBlock β€” a Verilog `specify ... endspecify` block // (IEEE 1364-2005 Β§14, Β§12.2). Specify blocks declare module path @@ -2178,6 +2391,8 @@ type AnsiModuleItem | ModuleInstanceItem { instance: ModuleInstance } | DefparamDeclarationItem { defparam: DefparamDeclaration } | GenerateRegionItem { generate_region: GenerateRegion } + | LoopGenerateConstructItem { loop_generate: LoopGenerateConstruct } + | ConditionalGenerateConstructItem { conditional_generate: ConditionalGenerateConstruct } | SpecifyBlockItem { specify_block: SpecifyBlock } | TaskDeclarationItem { task: TaskDeclaration } | FunctionDeclarationItem { function_decl: FunctionDeclaration } @@ -2216,20 +2431,21 @@ type NonAnsiModuleItem // modeled via a closed Disj rather than a nullable field. // // - NoModuleParameterPortList -// β€” `module M (a, b);` β€” no `#(...)` clause; the module -// takes no header-overridable parameters. (Body -// ParameterDeclarationItem may still appear, but those -// parameters are body-scoped and not part of the header- -// overridable surface; a ModuleInstance's -// ParameterOverrides bind to the HEADER parameter port list -// per Β§12.1.3.) -// - ModuleParameters { parameters: List } +// β€” `module M (a, b);` β€” no `#(...)` clause; the module's +// OVERRIDEABLE-PARAMETER SURFACE is the ordered list of body +// `ParameterDeclarationItem` declarations per spec Β§12.1 +// conditional rule (when no header parameter port list is +// given, body `parameter` declarations are the overrideable +// parameters). Instantiation `ParameterOverrides` actuals +// bind to THAT body-derived list. +// - ModuleParameters { parameters: NonEmptyList } // β€” `module M #(parameter W = 8, parameter D = 16) (a, b);` -// β€” the header carries the parameter port list. These -// parameters are externally overridable via instantiation -// `#(...)` syntax (the ParameterOverrides Disj's actuals -// bind positionally or by name to THESE header parameters, -// not to body ParameterDeclarations). +// β€” the header carries an explicit `#(...)` parameter port +// list. THESE header parameters are the overrideable surface; +// any body `ParameterDeclarationItem` becomes LOCAL (not +// overrideable) per the spec Β§12.1 conditional rule. Instantiation +// `ParameterOverrides` actuals bind positionally or by name +// to the header parameters only. // // CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.1 admits exactly the // present-or-absent partition; SystemVerilog adds type parameters @@ -2287,17 +2503,30 @@ type ModuleParameterPortList // "completely declared" and body redeclarations are a syntax // error). // -// Both variants carry name + parameter_port_list. The header -// parameter_port_list (`#(parameter W = 8)`) extends with body -// parameter declarations to form the module's UNIFIED OVERRIDEABLE -// parameter surface β€” instantiation `#(...)` overrides bind to the -// projection of header parameters concatenated with body -// ParameterDeclarationItems (in declaration order); body -// LocalParameterDeclarationItem is EXCLUDED from the overrideable -// surface per Β§3.10 (codex BLOCKING on PR #3176 β€” the prior framing -// suggested only header parameters were overrideable, but per spec -// both header and body `parameter` declarations are overrideable; -// only `localparam` is not). +// Both variants carry name + parameter_port_list. The module's +// OVERRIDEABLE-PARAMETER SURFACE is determined by IEEE 1364-2005 +// Β§12.1's CONDITIONAL rule (clarified per openai-pro REQUEST_CHANGES +// on PR #3176 2026-05-16 β€” the prior framing was internally +// inconsistent on this rule): +// +// - WHEN `parameter_port_list` is `ModuleParameters { ... }` (i.e. +// the module has an explicit `#(...)` header clause), THOSE +// header parameters ARE the overrideable parameter surface; any +// body `ParameterDeclarationItem` is LOCAL (not overrideable β€” +// even though it uses the `parameter` keyword). +// - WHEN `parameter_port_list` is `NoModuleParameterPortList` (no +// header `#(...)`), the OVERRIDEABLE parameter surface is the +// ORDERED LIST of body `ParameterDeclarationItem` declarations +// in source-appearance order. +// - `LocalParameterDeclarationItem` is NEVER part of the +// overrideable surface regardless of header presence (per Β§3.10 +// `localparam` is local-only by spec). +// +// Instantiation `#(parameter overrides)` clauses bind by position or +// by name to whichever set IS the overrideable surface per the +// conditional rule above. Downstream override-resolution consumers +// read the per-variant `parameter_port_list` to determine which set +// to walk. // // Per the IN-B PROBE FINDING: the `items` field IS the parallel- // Conj surface; the structural concurrency of multiple always-blocks From 1c2c31e0b2b619a26129fb2871f1ddd932cacc75 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 10:05:47 +0000 Subject: [PATCH 26/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20revert=20NonEmpty?= =?UTF-8?q?List=20form=20per=20T-4=20mgr=20disposition=20=E2=80=94=20de?= =?UTF-8?q?fer=20to=20std/collection.dag=20Wave-A2=20refinement=20(RQ-3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T-4 mgr (vivid-carp-207) msg_30a7ec7c disposition: HOLD on NonEmptyList form. Three anchors: 1. CANONICAL FORM resolved by docs/coercion-design.md RQ-3: "refinements of base containers, NOT separate inhabitant families. NonEmptyList = List where non_empty. Separate inhabitants would grow the authority surface." The hand-rolled `type NonEmptyList { head: T, tail: List }` IS a separate inhabitant family β€” breaks the ratified Vec coercion. 2. The canonical `List where non_empty` refinement is NOT yet expressible in merged v4 (no where-refinement substrate landed). std/collection.dag merged-on-main DEFERS its finite-cardinality/ refinement layer to "Wave-A2 β€” TRACKED SCAFFOLD (🟑)". 3. verilog.dag's frozen scaffold header neither Owns nor Consumes std/collection.dag. Minting a parallel non-empty carrier in a leaf language probe would be a 5-language parallel-declaration precedent β€” the v3 cross-layer spine-drift this T-4 directive exists to prevent. Sanctioned deferral middle-path: - Removed `type NonEmptyList` declaration. - Reverted all 6 spec-non-empty sites to `List`: - NetDeclaration.declarators - VariableDeclaration.{Reg,Integer,Real,Time,RealTime}Variable.declarators - ParameterDeclaration.assignments - LocalParameterDeclaration.assignments - SpecparamDeclaration.assignments - ModuleParameters.parameters - Replaced the prior NonEmptyList declaration block with a shared 🟑 TRACKED-SCAFFOLD note documenting: - The codex empty-list-illegal-state motivation (spec-correct). - RQ-3's "refinements over base containers, not separate inhabitants" authority (foreclosing the worker-mint). - std/collection.dag Wave-A2 deferral (the canonical refinement substrate's tracked location). - The frozen-header scope argument (no Consume on collection.dag). - DISSOLUTION TRIGGER: when std/collection.dag Wave-A2 lands the non-empty refinement, the six sites adopt `List where non_empty` uniformly in one sweep. The empty-list state is a producer-side invariant pending the refinement substrate. The codex obligation is real but it is a DEFERRED refinement obligation, not a verilog-local carrier mint. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 87 ++++++++++++++++++---------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 7f442d5b407..98e05b57a2a 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -887,7 +887,7 @@ type NetDeclaration { signedness: Signedness drive_strength: DriveStrengthClause delay: DelayClause - declarators: NonEmptyList + declarators: List } @@ -1011,11 +1011,11 @@ type NetDeclarator { // classifier; illegal kindΓ—packing AND kindΓ—signedness combinations // are unrepresentable by construction. type VariableDeclaration - = RegVariable { packing: PackingShape, signedness: Signedness, declarators: NonEmptyList } - | IntegerVariable { declarators: NonEmptyList } - | RealVariable { declarators: NonEmptyList } - | TimeVariable { declarators: NonEmptyList } - | RealTimeVariable { declarators: NonEmptyList } + = RegVariable { packing: PackingShape, signedness: Signedness, declarators: List } + | IntegerVariable { declarators: List } + | RealVariable { declarators: List } + | TimeVariable { declarators: List } + | RealTimeVariable { declarators: List } // ───────────────────────────────────────────────────────────────────── @@ -1459,25 +1459,52 @@ type ParameterTypeKind // ───────────────────────────────────────────────────────────────────── -// NonEmptyList β€” a list known to be non-empty by construction: a -// required head element + a (possibly empty) tail. Used wherever the -// IEEE 1364-2005 grammar requires "at least one" entry β€” a structural -// dissolution of the spec-illegal empty-list state that a bare -// `List` would admit. INVARIANTS P2 illegal-states-unrepresentable -// + modeling-discipline.md Practices 2 / 6. -// -// - head the required first entry -// - tail the remaining entries (may be empty) -// -// Conj record (no Practice-4 ledger β€” only coproducts dissolve). -// Added per codex REQUEST_CHANGES on PR #3176 2026-05-16 β€” multiple -// declaration carriers' `List<…>` fields admitted empty-list states -// the spec grammar forbids; NonEmptyList makes the "at least one" -// requirement structural. -type NonEmptyList { - head: T - tail: List -} +// 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed +// disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). +// +// Six sites in this file carry `List` payloads where IEEE 1364-2005 +// requires AT LEAST ONE entry β€” the spec-illegal empty state is +// structurally representable, the same INVARIANTS P2 illegal-states- +// unrepresentable concern codex correctly flagged. The MOTIVATION is +// real and spec-grounded. The CANONICAL FIX is NOT a worker-minted +// `NonEmptyList` generic carrier: +// +// - `docs/coercion-design.md` RQ-3 (ratified): "refinements of +// base containers, NOT separate inhabitant families. +// `NonEmptyList = List where non_empty`. Separate +// inhabitants would grow the authority surface." A hand-rolled +// `NonEmptyList { head: T, tail: List }` IS a separate +// inhabitant family and breaks the ratified Vec coercion. +// - `std/collection.dag` (merged on main) DEFERS its entire +// finite-cardinality / refinement layer to "Wave-A2 β€” TRACKED +// SCAFFOLD (🟑)". The `List where non_empty` refinement IS +// that deferred layer. +// - This file's frozen scaffold header neither Owns nor Consumes +// `std/collection.dag`. Minting a parallel non-empty carrier in +// a leaf language probe would be a 5-language parallel- +// declaration precedent β€” the v3 cross-layer spine-drift this +// T-4 directive exists to prevent. +// +// SANCTIONED DEFERRAL (the deferral middle-path, mirroring +// collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 +// inhabitance-deferral pattern): +// - Each of the six spec-non-empty sites keeps `List` for now. +// - Each site carries a back-pointer comment to THIS shared note. +// - The empty-list illegal state is a PRODUCER-SIDE invariant +// pending the refinement substrate landing. +// - DISSOLUTION TRIGGER: when `std/collection.dag` Wave-A2 lands the +// non-empty refinement, the six sites adopt +// `List where non_empty` uniformly in one sweep β€” single- +// authority preserved. +// +// The six spec-non-empty sites (back-pointers to this note): +// 1. NetDeclaration.declarators (Β§A.2.1.3) +// 2. VariableDeclaration.{Reg,Integer,Real,Time,RealTime}Variable.declarators +// (Β§A.2.4 / Β§7.4) +// 3. ParameterDeclaration.assignments (Β§A.2.1.1) +// 4. LocalParameterDeclaration.assignments (Β§A.2.1.1) +// 5. SpecparamDeclaration.assignments (Β§A.2.1.1) +// 6. ModuleParameters.parameters (Β§12.1) // ───────────────────────────────────────────────────────────────────── @@ -1526,7 +1553,7 @@ type ParameterAssignment { // without these facts the conversion is unspecified). type ParameterDeclaration { type_kind: ParameterTypeKind - assignments: NonEmptyList + assignments: List } @@ -2135,7 +2162,7 @@ type GenvarDeclaration { // ParameterAssignment carries name + default_lexeme. type LocalParameterDeclaration { type_kind: ParameterTypeKind - assignments: NonEmptyList + assignments: List } @@ -2282,7 +2309,7 @@ type UdpInstantiation { // admitted via the assignment's lexeme. type SpecparamDeclaration { packing: PackingShape - assignments: NonEmptyList + assignments: List } @@ -2438,7 +2465,7 @@ type NonAnsiModuleItem // given, body `parameter` declarations are the overrideable // parameters). Instantiation `ParameterOverrides` actuals // bind to THAT body-derived list. -// - ModuleParameters { parameters: NonEmptyList } +// - ModuleParameters { parameters: List } // β€” `module M #(parameter W = 8, parameter D = 16) (a, b);` // β€” the header carries an explicit `#(...)` parameter port // list. THESE header parameters are the overrideable surface; @@ -2478,7 +2505,7 @@ type NonAnsiModuleItem // port-list classifier of the IEEE 1364-2005 spec Β§12.1. type ModuleParameterPortList = NoModuleParameterPortList - | ModuleParameters { parameters: NonEmptyList } + | ModuleParameters { parameters: List } // ───────────────────────────────────────────────────────────────────── From 1c404c2918baebc38f4e1ba6c69da1eec27a226a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 10:11:28 +0000 Subject: [PATCH 27/56] v4 T-4.9 verilog: extend non-empty-list deferral to 3 additional sites + add per-site back-pointers (codex REQUEST_CHANGES; manager-relayed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex REQUEST_CHANGES at sha f87fdf189 flagged 3 additional spec-non- empty list fields (the prior NonEmptyList shape had been reverted per T-4 mgr disposition msg_30a7ec7c β€” RQ-3 / collection.dag Wave-A2 deferral): - ExplicitEventList.items (Β§9.7.2): explicit @(...) form requires β‰₯1 - OrderedParameterOverrides.actuals (Β§12.1.3): present #(...) clause with zero actuals is redundant with NoParameterOverrides AND spec-illegal - NamedParameterOverrides.overrides (Β§12.1.3): same shape Per manager-relayed disposition msg_30a7ec7c + msg_38dd2617: the codex motivation is spec-correct, but the FORM is the deferred refinement (`List where non_empty` per RQ-3, owned by std/collection.dag Wave-A2), NOT a worker-minted carrier in this file. Same disposition applies to the 3 new sites. Fix: - Updated shared 🟑 TRACKED-SCAFFOLD note's enumeration 6β†’9 sites (added sites 7-9 covering ExplicitEventList.items + both ParameterOverrides variants). - Added terse per-site `// 🟑 spec-non-empty (Β§) β€” deferred to std/collection.dag Wave-A2 refinement; see shared TRACKED- SCAFFOLD note above` back-pointers at all 9 sites (the 6 prior + 3 new), per manager's preferred form msg_38dd2617 "ONE shared note + terse per-site back-pointer". No type-shape changes; all 9 fields remain List pending the collection.dag Wave-A2 refinement. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 98e05b57a2a..9e91d515706 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -887,6 +887,9 @@ type NetDeclaration { signedness: Signedness drive_strength: DriveStrengthClause delay: DelayClause + // 🟑 spec-non-empty (Β§A.2.1.3) β€” deferred to std/collection.dag + // Wave-A2 `List where non_empty` refinement; see shared + // TRACKED-SCAFFOLD note above. declarators: List } @@ -1011,6 +1014,9 @@ type NetDeclarator { // classifier; illegal kindΓ—packing AND kindΓ—signedness combinations // are unrepresentable by construction. type VariableDeclaration + // declarators: 🟑 spec-non-empty (Β§A.2.4 / Β§7.4) β€” deferred to + // std/collection.dag Wave-A2 `List where non_empty` refinement; + // see shared TRACKED-SCAFFOLD note above. = RegVariable { packing: PackingShape, signedness: Signedness, declarators: List } | IntegerVariable { declarators: List } | RealVariable { declarators: List } @@ -1505,6 +1511,14 @@ type ParameterTypeKind // 4. LocalParameterDeclaration.assignments (Β§A.2.1.1) // 5. SpecparamDeclaration.assignments (Β§A.2.1.1) // 6. ModuleParameters.parameters (Β§12.1) +// 7. AlwaysBlockSensitivity.ExplicitEventList.items (Β§9.7.2) +// 8. ParameterOverrides.OrderedParameterOverrides.actuals (Β§12.1.3) +// 9. ParameterOverrides.NamedParameterOverrides.overrides (Β§12.1.3) +// +// Sites 7-9 added 2026-05-16 per codex REQUEST_CHANGES on PR #3176 +// at sha f87fdf189; same deferred-refinement disposition per the +// RQ-3 / Wave-A2 authority above (codex's motivation is spec-correct; +// the FORM is the deferred refinement, not a verilog-local mint). // ───────────────────────────────────────────────────────────────────── @@ -1553,6 +1567,8 @@ type ParameterAssignment { // without these facts the conversion is unspecified). type ParameterDeclaration { type_kind: ParameterTypeKind + // 🟑 spec-non-empty (Β§A.2.1.1) β€” deferred to std/collection.dag + // Wave-A2 refinement; see shared TRACKED-SCAFFOLD note above. assignments: List } @@ -1706,6 +1722,9 @@ type AlwaysBlock { type AlwaysBlockSensitivity = NoEventControl | ImplicitAtStar + // ExplicitEventList.items: 🟑 spec-non-empty (Β§9.7.2) β€” deferred to + // std/collection.dag Wave-A2 refinement; see shared TRACKED-SCAFFOLD + // note above. (NoEventControl already covers the no-`@(...)` form.) | ExplicitEventList { items: List } @@ -1950,6 +1969,12 @@ type NamedParameterOverride { // override classifier of the IEEE 1364-2005 spec. type ParameterOverrides = NoParameterOverrides + // OrderedParameterOverrides.actuals + NamedParameterOverrides. + // overrides: 🟑 spec-non-empty (Β§12.1.3) β€” deferred to + // std/collection.dag Wave-A2 refinement; see shared TRACKED-SCAFFOLD + // note above. (NoParameterOverrides already covers the omitted- + // clause form, so an empty present-clause is structurally redundant + // AND spec-illegal.) | OrderedParameterOverrides { actuals: List } | NamedParameterOverrides { overrides: List } @@ -2162,6 +2187,8 @@ type GenvarDeclaration { // ParameterAssignment carries name + default_lexeme. type LocalParameterDeclaration { type_kind: ParameterTypeKind + // 🟑 spec-non-empty (Β§A.2.1.1) β€” deferred to std/collection.dag + // Wave-A2 refinement; see shared TRACKED-SCAFFOLD note above. assignments: List } @@ -2309,6 +2336,8 @@ type UdpInstantiation { // admitted via the assignment's lexeme. type SpecparamDeclaration { packing: PackingShape + // 🟑 spec-non-empty (Β§A.2.1.1) β€” deferred to std/collection.dag + // Wave-A2 refinement; see shared TRACKED-SCAFFOLD note above. assignments: List } @@ -2505,6 +2534,9 @@ type NonAnsiModuleItem // port-list classifier of the IEEE 1364-2005 spec Β§12.1. type ModuleParameterPortList = NoModuleParameterPortList + // ModuleParameters.parameters: 🟑 spec-non-empty (Β§12.1) β€” deferred + // to std/collection.dag Wave-A2 refinement; see shared TRACKED- + // SCAFFOLD note above. | ModuleParameters { parameters: List } From bcc6b5f89caeef349bee37743899949e537e7cb3 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 10:15:16 +0000 Subject: [PATCH 28/56] v4 T-4.9 verilog: split shared OrderedParameterOverrides marker into 9th per-site back-pointer (T-4 mgr msg_341befa3 residual) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T-4 mgr verify-caught residual on 1c404c291: 8 of 9 enumerated non-empty-list sites carried the inline `🟑 spec-non-empty` back- pointer; OrderedParameterOverrides was covered by a SHARED marker above the variant pair (Ordered + Named) but did not have its own identical-form inline marker β€” broke the single-grep-token dissolution-sweep property by exactly one site. Fix: split the prior shared marker into TWO per-variant markers, each with the byte-identical `🟑 spec-non-empty (Β§12.1.3) β€” deferred to std/collection.dag Wave-A2 \`List where non_empty\` refinement; see shared TRACKED-SCAFFOLD note above` token. Now all 9 sites carry the uniform grep-token; `grep -c "🟑 spec-non-empty (Β§"` returns 9. Comment-only, additive. The shared TRACKED-SCAFFOLD note's enumeration unchanged. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 9e91d515706..523080ce1ee 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1969,13 +1969,15 @@ type NamedParameterOverride { // override classifier of the IEEE 1364-2005 spec. type ParameterOverrides = NoParameterOverrides - // OrderedParameterOverrides.actuals + NamedParameterOverrides. - // overrides: 🟑 spec-non-empty (Β§12.1.3) β€” deferred to - // std/collection.dag Wave-A2 refinement; see shared TRACKED-SCAFFOLD - // note above. (NoParameterOverrides already covers the omitted- - // clause form, so an empty present-clause is structurally redundant - // AND spec-illegal.) + // OrderedParameterOverrides.actuals: 🟑 spec-non-empty (Β§12.1.3) β€” + // deferred to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note above. + // (NoParameterOverrides covers the omitted-clause form, so an + // empty present-clause is structurally redundant AND spec-illegal.) | OrderedParameterOverrides { actuals: List } + // NamedParameterOverrides.overrides: 🟑 spec-non-empty (Β§12.1.3) β€” + // deferred to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note above. | NamedParameterOverrides { overrides: List } From df1a0ab0e7c58986856ac23d6998872318a2310a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 06:29:38 -0400 Subject: [PATCH 29/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 68 +++++++++++++++++++--------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 523080ce1ee..e6d4ad6a9a5 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1514,11 +1514,15 @@ type ParameterTypeKind // 7. AlwaysBlockSensitivity.ExplicitEventList.items (Β§9.7.2) // 8. ParameterOverrides.OrderedParameterOverrides.actuals (Β§12.1.3) // 9. ParameterOverrides.NamedParameterOverrides.overrides (Β§12.1.3) +// 10. ContinuousAssign.assignments (Β§6.1) // // Sites 7-9 added 2026-05-16 per codex REQUEST_CHANGES on PR #3176 -// at sha f87fdf189; same deferred-refinement disposition per the -// RQ-3 / Wave-A2 authority above (codex's motivation is spec-correct; -// the FORM is the deferred refinement, not a verilog-local mint). +// at sha f87fdf189; site 10 added 2026-05-16 per codex BLOCKING on +// PR #3176 at sha bcc6b5f89 (ContinuousAssign restructured to carry +// drive_strength + delay + list_of_net_assignments per Β§6.1, with +// the non-empty assignments list deferred under the same RQ-3 +// disposition). Codex's motivation is spec-correct in each case; +// the FORM is the deferred refinement, not a verilog-local mint. // ───────────────────────────────────────────────────────────────────── @@ -1599,33 +1603,53 @@ type SensitivityItem { // ───────────────────────────────────────────────────────────────────── -// ContinuousAssign β€” a Verilog continuous-assignment statement -// (`assign net = expr;`, `assign {a, b} = c;`, `assign x[3:0] = …`). -// IEEE 1364-2005 Β§6.1. Conj record (no Practice-4 ledger). +// NetAssignment β€” one (net_lvalue, expression) pair in a +// continuous_assign's list_of_net_assignments (IEEE 1364-2005 Β§6.1 + +// Β§A.6.1). A single `assign net1 = expr1, net2 = expr2;` carries TWO +// NetAssignments. Conj record (no Practice-4 ledger). // // - lhs_lexeme the destination net_lvalue as a verbatim -// lexeme. Per spec Β§6.1 the lvalue of a -// continuous assign is a net_lvalue: an -// identifier reference, a net bit-select, a -// net part-select, or a concatenation/replication -// of net_lvalues β€” NOT just a bare identifier -// (corrected 2026-05-16 per codex BLOCKING on -// PR #3176; the prior `lhs: Symbol` narrowed -// lvalues to identifier references, excluding -// valid Β§6.1 net_lvalue forms). Sub-grammar -// deferred to the T-4 LanguageModel. Procedural -// variables cannot be continuous-assignment -// destinations β€” that joint check is the T-4 -// LanguageModel's concern. +// lexeme (identifier ref, bit/part-select, or +// concatenation/replication of net_lvalues per +// Β§6.1). Sub-grammar deferred to T-4 +// LanguageModel. // - rhs_lexeme the right-hand-side expression as a verbatim -// lexeme (sub-grammar deferred β€” same shape as -// `ParameterDeclaration.default_lexeme`) -type ContinuousAssign { +// lexeme. +type NetAssignment { lhs_lexeme: String rhs_lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// ContinuousAssign β€” a Verilog continuous-assignment statement +// (`assign net = expr;`, `assign (strong0, weak1) #5 a = e1, b = e2;`). +// IEEE 1364-2005 Β§6.1 + Β§A.6.1. Conj record (no Practice-4 ledger). +// +// Per spec Β§6.1 a continuous_assign carries an optional drive_strength, +// an optional delay3, and a non-empty list_of_net_assignments β€” +// declaration-boundary facts the prior single-(lhs,rhs)-pair shape +// collapsed (codex BLOCKING on PR #3176 2026-05-16). +// +// - drive_strength optional drive_strength clause (`(strong0, +// weak1)`); reuses the DriveStrengthClause Disj +// shared with NetDeclaration. +// - delay optional delay3 clause (`#5`, `#(2:3:4)`); +// reuses the DelayClause Disj shared with +// NetDeclaration. +// - assignments the list_of_net_assignments per spec Β§A.6.1 +// β€” each NetAssignment carries a net_lvalue +// lexeme + expression lexeme. +type ContinuousAssign { + drive_strength: DriveStrengthClause + delay: DelayClause + // ContinuousAssign.assignments: 🟑 spec-non-empty (Β§6.1) β€” + // deferred to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note above. + assignments: List +} + + // ───────────────────────────────────────────────────────────────────── // AlwaysBlock β€” a Verilog `always @(...)` block (IEEE 1364-2005 Β§9.9). // Conj record (no Practice-4 ledger). From 3b92101a88f50e8bd308c48b75c1fa8992fcc62e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 10:31:31 +0000 Subject: [PATCH 30/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20NonAnsiModuleItem?= =?UTF-8?q?=20=E2=80=94=20add=20required=205-pattern=20Practice-4=20ledger?= =?UTF-8?q?=20(codex=20BLOCKING=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: NonAnsiModuleItem Disj (introduced in ec34a6b5a as part of the VerilogModule per-style restructure) carried no 5-pattern Practice-4 ledger, violating modeling- discipline.md Β§4 binding (every new substrate Disj needs the 🟒/🟑/πŸ”΄ classification + 5-pattern ledger). Fix: added full 5-pattern Practice-4 ledger to NonAnsiModuleItem with 🟒 GREEN classification. Each pattern's argument covers the 3-way non-ANSI item-set partition (NonAnsiAnsiCompatItem wrapper + the two body port_declaration forms per Β§12.3.4); the membership-vs-style admissibility constraint lives at the VerilogModule-Disj level (already documented in VerilogModule's own ledger). Comment-only, additive. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index e6d4ad6a9a5..3da5434906b 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -2496,6 +2496,65 @@ type AnsiModuleItem // fix on PR #3176 2026-05-16: items list was previously // `List` regardless of port style, admitting the Β§12.3.3 // "ANSI ports are completely declared" violation). +// +// - NonAnsiAnsiCompatItem β€” wraps any AnsiModuleItem +// variant (the 18-way common +// item set admitted in any +// module body). +// - NonAnsiPortDeclarationItem β€” body port_declaration in +// direction-only form (`input +// a;`); spec Β§12.3.4 non-ANSI +// style only. +// - NonAnsiBodyPortDeclarationItem +// β€” body port_declaration in +// direction-plus-type combined +// form (`input wire [7:0] a;`); +// reuses the AnsiPortDeclaration +// carrier per the body-form-is- +// shape-equivalent-to-ANSI +// framing of Β§12.3.4. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.4 admits this +// three-way non-ANSI module-item partition (the common-items +// wrapper + the two body port_declaration forms); SystemVerilog +// adds further forms β€” future language-version model EDITS this +// Disj explicitly. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every non-ANSI module-body consumer +// branches on the variant to dispatch β€” common items go to +// the AnsiModuleItem walker (via the wrapped item), body +// port_declarations go to the Β§12.3.4 port-binding-resolution +// walker. Shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ kind: +// ItemKind, … }` shape reintroduces the Β§12.3.3 illegal state +// this Disj-split exists to dissolve at the VerilogModule +// level (NonAnsiModuleItem variants belong ONLY to non-ANSI +// modules per VerilogModule's Disj; admitting them on ANSI +// modules would re-open the Β§12.3.3 "ANSI ports are completely +// declared" violation). The structural-membership constraint +// lives at the VerilogModule-Disj level; this Disj enumerates +// the per-style admissible items. +// 3. Algebraic form β€” N/A by construction: the three variants +// are the Β§12.3.4 non-ANSI item-set partition (common-items +// wrapper + two body-port forms); they do not trace to a +// richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single non-ANSI module-body item is +// EXACTLY ONE variant; mutually-exclusive alternatives. (A +// module body's `items` is `List` β€” +// multiple items co-exist as siblings, but each item is one +// variant.) +// 5. Parameterized family β€” FAILS: the three variants carry +// structurally heterogeneous payloads (NonAnsiAnsiCompatItem +// wraps an AnsiModuleItem; NonAnsiPortDeclarationItem carries +// a PortDeclaration direction-only record; +// NonAnsiBodyPortDeclarationItem carries an +// AnsiPortDeclaration per-direction Disj) β€” NOT one generic +// `F` / projection over a single source set (Practice 7). +// Terminal: the closed three-way Verilog non-ANSI module-body-item +// classifier of the IEEE 1364-2005 Β§12.3.4 spec; ledger added per +// codex BLOCKING on PR #3176 2026-05-16. type NonAnsiModuleItem = NonAnsiAnsiCompatItem { item: AnsiModuleItem } | NonAnsiPortDeclarationItem { port_decl: PortDeclaration } From 0114c02d16933a346407495d35cc290ceb4fa621 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 07:29:38 -0400 Subject: [PATCH 31/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 53 ++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 3da5434906b..126c0f5ca97 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -733,6 +733,58 @@ type DelayClause | DelayLexeme { lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// VectoredessClause β€” the closed Verilog vectored/scalared +// declaration-boundary classifier on a net_declaration (IEEE +// 1364-2005 Β§A.2.1.3 / Β§3.7.1). The clause is OPTIONAL per spec and +// is DISTINCT from drive_strength: it carries a synthesizer hint +// about whether the net is to be treated as a single addressable +// unit (`vectored`) or as bit-addressable (`scalared`). +// +// - NoVectoredness +// β€” neither `vectored` nor `scalared` keyword on the +// declaration (the spec default). +// - VectoredNet +// β€” `vectored` modifier; synthesizer treats the net as a +// single addressable unit (bit/part-select access constrained). +// - ScalaredNet +// β€” `scalared` modifier; synthesizer treats the net as +// bit-addressable. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly the +// three-way present/absent + which-keyword partition (vectored +// and scalared are mutually exclusive per spec β€” both modifiers +// in one declaration is a syntax error). +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every net-declaration emitter + +// every synthesizer-hint consumer reads the clause uniformly; +// shared classifier. +// 2. Variant-is-data β€” FAILS: a `{ kind: Symbol }` proxy reopens +// the readable-string heuristic surface K-1 forecloses; a +// `{ vectored: Bool, scalared: Bool }` proxy ratifies the +// spec-forbidden "both keywords" state. The 3-variant Disj +// IS the dissolved form. +// 3. Algebraic form β€” N/A by construction: synthesizer-hint +// partition, not a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single net_declaration has EXACTLY +// ONE vectoredness state; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: the three variants are +// structurally distinct (none-vs-vectored-vs-scalared +// semantically heterogeneous) β€” NOT one generic `F` +// projection (Practice 7). +// Terminal: the closed three-way Verilog vectored/scalared clause +// classifier. Added per codex BLOCKING on PR #3176 2026-05-16 β€” +// the vectored/scalared clause is a Β§A.2.1.3 declaration-boundary +// fact distinct from drive_strength; the prior commentary "collapsed +// into the strength lexeme position" overloaded the two clauses. +type VectoredessClause + = NoVectoredness + | VectoredNet + | ScalaredNet + + // ───────────────────────────────────────────────────────────────────── // NetInitializerClause β€” the closed Verilog net_decl_assignment // initializer-presence classifier (IEEE 1364-2005 Β§A.2.4). Optional @@ -886,6 +938,7 @@ type NetDeclaration { packing: PackingShape signedness: Signedness drive_strength: DriveStrengthClause + vectoredness: VectoredessClause delay: DelayClause // 🟑 spec-non-empty (Β§A.2.1.3) β€” deferred to std/collection.dag // Wave-A2 `List where non_empty` refinement; see shared From 2bf0024ba6987bb603ba633725090faab1216a23 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 11:30:28 +0000 Subject: [PATCH 32/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20VectoredessClause?= =?UTF-8?q?=20=E2=80=94=20separate=20=C2=A7A.2.1.3=20net-vectoring=20claus?= =?UTF-8?q?e=20from=20drive=5Fstrength=20(codex=20BLOCKING=20on=20PR=20#31?= =?UTF-8?q?76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: NetDeclaration commentary previously said the vectored/scalared modifier was "collapsed into the strength lexeme position" β€” but per IEEE 1364-2005 Β§A.2.1.3 grammar vectored/scalared is a SEPARATE optional clause between drive_strength and signed, not part of drive_strength. The collapse overloaded two distinct Β§A.2.1.3 declaration-boundary facts. INVARIANTS P1/P2 boundary-fact preservation. Fix: - New closed VectoredessClause Disj = NoVectoredness | VectoredNet | ScalaredNet with full 5-pattern Practice-4 ledger. The 3-way partition makes the spec-forbidden "both vectored and scalared" state unrepresentable (a `{ vectored: Bool, scalared: Bool }` proxy admits the illegal combination). - NetDeclaration gains `vectoredness: VectoredessClause` field between drive_strength and delay (matching the Β§A.2.1.3 grammar clause-ordering for clarity). - NetDeclaration commentary corrected: vectored/scalared is now noted as a SEPARATE Β§A.2.1.3 declaration-boundary fact carried via the dedicated VectoredessClause; the prior collapse-into- drive_strength framing was wrong. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 126c0f5ca97..6885977a3dc 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -891,12 +891,16 @@ type VariableInitializerClause // [vectored | scalared] [signed] [range] // [delay3] list_of_net_decl_assignments ; // -// The vectored/scalared modifier is a synthesis hint (rare); not -// modeled in this initial cut β€” the lexeme captures it via -// drive_strength_lexeme (the parser collapses it into the strength -// lexeme position by Β§A.2.2). The charge_strength applies only to -// `trireg` per spec Β§7.10; admitted alongside drive_strength via the -// shared lexeme. +// The vectored/scalared modifier is a SEPARATE Β§A.2.1.3 declaration- +// boundary fact distinct from drive_strength β€” modeled structurally +// via the dedicated `VectoredessClause` field (NoVectoredness | +// VectoredNet | ScalaredNet). The prior framing that collapsed +// vectored/scalared into the drive_strength lexeme position was a +// codex BLOCKING-fix correction on PR #3176 2026-05-16. The +// charge_strength applies only to `trireg` per spec Β§7.10; admitted +// alongside drive_strength via the shared DriveStrengthClause lexeme +// (charge_strength is itself a closed keyword set owned by the +// bundled T-4 LanguageModel). // // - net_type which net-type (wire / wand / wor / // tri / … per the closed NetType set) From 16c992f3485af0c6b2febca57426120212718ae2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 11:32:33 +0000 Subject: [PATCH 33/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20ModuleInstantiati?= =?UTF-8?q?on=20=E2=80=94=20multi-instance=20form=20with=20shared=20module?= =?UTF-8?q?=5Fname=20+=20parameter=5Foverrides=20per=20=C2=A7A.4.1.1=20(co?= =?UTF-8?q?dex=20BLOCKING=20on=20PR=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex BLOCKING on PR #3176: prior ModuleInstance modeled ONE instance per carrier (one module_name + one parameter_overrides + one instance_name + one connections), losing the Β§12.1 / Β§A.4.1.1 multi-instance form `Adder #(.W(8)) a1 (.a(x1)), a2 (.a(x2));` β€” where one module_instantiation statement carries ONE shared (module_name, parameter_overrides) and a non-empty list of (instance_name, connections) entries. The shared statement-boundary and parameter-override authority were lost. INVARIANTS P1/P2. Fix: - Refactored ModuleInstance to per-instance entry: { instance_name, connections } β€” drops module_name + parameter_overrides (those are shared at the instantiation level). - New ModuleInstantiation Conj record { module_name, parameter_overrides, instances: List } per spec Β§A.4.1.1 β€” the shared-clause + per-instance-list shape. - ModuleItem variant renamed: ModuleInstanceItem β†’ ModuleInstantiationItem { instantiation: ModuleInstantiation }. - Site 11 added to shared 🟑 TRACKED-SCAFFOLD note enumeration (ModuleInstantiation.instances per Β§A.4.1.1) with the inline per-site back-pointer marker matching the uniform grep-token form. grep -c '🟑 spec-non-empty (Β§' = 11. Multi-instance forms now structurally representable; shared statement-level facts preserved. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 77 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 6885977a3dc..ccb25669ca2 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1572,14 +1572,19 @@ type ParameterTypeKind // 8. ParameterOverrides.OrderedParameterOverrides.actuals (Β§12.1.3) // 9. ParameterOverrides.NamedParameterOverrides.overrides (Β§12.1.3) // 10. ContinuousAssign.assignments (Β§6.1) +// 11. ModuleInstantiation.instances (Β§A.4.1.1) // // Sites 7-9 added 2026-05-16 per codex REQUEST_CHANGES on PR #3176 // at sha f87fdf189; site 10 added 2026-05-16 per codex BLOCKING on // PR #3176 at sha bcc6b5f89 (ContinuousAssign restructured to carry // drive_strength + delay + list_of_net_assignments per Β§6.1, with // the non-empty assignments list deferred under the same RQ-3 -// disposition). Codex's motivation is spec-correct in each case; -// the FORM is the deferred refinement, not a verilog-local mint. +// disposition); site 11 added 2026-05-16 per codex BLOCKING on +// PR #3176 at sha 2bf0024ba (ModuleInstantiation restructured to +// carry shared module_name + parameter_overrides + non-empty +// instances per Β§A.4.1.1 multi-instance form). Codex's motivation +// is spec-correct in each case; the FORM is the deferred refinement, +// not a verilog-local mint. // ───────────────────────────────────────────────────────────────────── @@ -2063,31 +2068,56 @@ type ParameterOverrides // ───────────────────────────────────────────────────────────────────── -// ModuleInstance β€” a Verilog module instantiation (`Adder a1 (.a(x), -// .b(y), .sum(z));` or `Adder a1 (x, y, sum);` or `Adder #(.WIDTH(8)) -// a1 (...)`). IEEE 1364-2005 Β§12.1. Conj record (no Practice-4 -// ledger). +// ModuleInstance β€” one instance within a module_instantiation +// statement (`a1 (.a(x), .b(y), .sum(z))`). IEEE 1364-2005 Β§12.1 + +// Β§A.4.1.1. A single module_instantiation can declare MULTIPLE +// instances sharing a common (module_name, parameter_overrides); +// each instance carries its own (instance_name, port_connections). +// Conj record (no Practice-4 ledger). +// +// - instance_name this instance's local name (K-1-opaque Symbol) +// - connections the port-binding list per spec Β§12.1.2 +// (PositionalConnections OR NamedConnections; +// uniform per instance). +type ModuleInstance { + instance_name: Symbol + connections: PortConnections +} + + +// ───────────────────────────────────────────────────────────────────── +// ModuleInstantiation β€” a Verilog module_instantiation statement +// (`Adder #(.WIDTH(8)) a1 (.a(x1), .b(y1)), a2 (.a(x2), .b(y2));`). +// IEEE 1364-2005 Β§12.1 + Β§A.4.1.1. Per spec grammar +// module_instantiation is ONE shared (module_identifier + +// parameter_value_assignment) clause followed by a NON-EMPTY LIST of +// module_instance entries β€” multi-instance declarations share the +// statement's module-name and parameter-override authority across +// all listed instances. The prior shape modeled ONE instance per +// ModuleInstance carrier and lost the Β§12.1 statement-boundary +// (shared module + shared overrides) for multi-instance forms +// (codex BLOCKING on PR #3176 2026-05-16). INVARIANTS P1/P2. // // - module_name the instantiated module's name (K-1- // opaque Symbol; resolved through the // namespace to the matching top-level -// `VerilogModule`) -// - instance_name this instance's local name (K-1-opaque -// Symbol) -// - parameter_overrides the `#(...)` parameter-override clause β€” -// none, ordered, or named per spec Β§12.1.3 -// (corrected per codex BLOCKING on -// PR #3176: the prior ModuleInstance had -// NO parameter-override carrier, omitting -// a Β§12.1 spec construct). -// - connections the port-binding list (PositionalConnections -// OR NamedConnections per spec Β§12.1.2; -// uniform per instance) -type ModuleInstance { +// `VerilogModule`). Shared across all +// instances in this statement. +// - parameter_overrides the `#(...)` parameter-override clause +// per spec Β§12.1.3. Shared across all +// instances; the same overrides bind to +// every instance in the multi-instance +// form. +// - instances the per-instance entries β€” each carries +// its own (instance_name, connections). +// Conj record (no Practice-4 ledger). +type ModuleInstantiation { module_name: Symbol - instance_name: Symbol parameter_overrides: ParameterOverrides - connections: PortConnections + // ModuleInstantiation.instances: 🟑 spec-non-empty (Β§A.4.1.1) β€” + // deferred to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note above. + instances: List } @@ -2445,7 +2475,8 @@ type SpecparamDeclaration { // - VariableDeclarationItem `reg`, `integer`, … declarations // - ParameterDeclarationItem `parameter NAME = expr;` // - LocalParameterDeclarationItem `localparam NAME = expr;` (Β§3.10) -// - ModuleInstanceItem nested `ModuleName inst (...);` +// - ModuleInstantiationItem nested `ModuleName inst (...);` (or +// multi-instance form `Name a1(...), a2(...)`) // - DefparamDeclarationItem `defparam top.sub.PARAM = value;` (Β§4.10.2.1) // - GenerateRegionItem `generate ... endgenerate` (Β§12.4) // - SpecifyBlockItem `specify ... endspecify` (Β§14) @@ -2527,7 +2558,7 @@ type AnsiModuleItem | VariableDeclarationItem { variable: VariableDeclaration } | ParameterDeclarationItem { parameter: ParameterDeclaration } | LocalParameterDeclarationItem { local_parameter: LocalParameterDeclaration } - | ModuleInstanceItem { instance: ModuleInstance } + | ModuleInstantiationItem { instantiation: ModuleInstantiation } | DefparamDeclarationItem { defparam: DefparamDeclaration } | GenerateRegionItem { generate_region: GenerateRegion } | LoopGenerateConstructItem { loop_generate: LoopGenerateConstruct } From 23d8db021c52320448eba3bc89f73d7c0c8e4793 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 08:25:11 -0400 Subject: [PATCH 34/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 47 ++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index ccb25669ca2..3c762f790cc 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -2416,9 +2416,9 @@ type GateInstantiation { // // - udp_name the UDP identifier (K-1-opaque Symbol; // resolves through the namespace to the -// matching top-level UDP definition β€” UDP -// definitions themselves are a file-level -// concern, separate from module body items) +// matching file-level UdpDefinition β€” see +// below; the UDP and Module sibling design- +// elements share the same name-space). // - instance_name this instance's local name (K-1-opaque Symbol) // - body_lexeme port list + drive strength + delay as a // verbatim lexeme (sub-grammar deferred to the @@ -2430,6 +2430,47 @@ type UdpInstantiation { } +// ───────────────────────────────────────────────────────────────────── +// UdpDefinition β€” a Verilog user-defined-primitive definition +// (`primitive XorPrim (out, a, b); output out; input a, b; table … endtable +// endprimitive`). IEEE 1364-2005 Β§8 + Β§A.5. UDP definitions are +// FILE-LEVEL design elements (sibling of `module`/`macromodule`/ +// `config`), NOT module-body items β€” codex BLOCKING on PR #3176 +// 2026-05-16 surfaced the gap that the prior model referenced UDP +// definitions from UdpInstantiation but did not declare a carrier +// for them. +// +// Conj record (no Practice-4 ledger). +// +// - name the UDP identifier (K-1-opaque Symbol; +// cross-referenced by UdpInstantiation.udp_name) +// - body_lexeme the entire `primitive ... endprimitive` body +// (port list + port declarations + state table +// for sequential UDPs or output assignments for +// combinational UDPs) as a verbatim lexeme; sub- +// grammar deferred to the T-4 LanguageModel β€” +// the UDP state-table sub-grammar (Β§8.2) is its +// own recursive sub-language, owned by the +// bundled productions when they land. +// +// FILE-LEVEL DESIGN-ELEMENT NOTE. UdpDefinition is declared at the +// same scope as VerilogModule (top-level type, sibling of the +// module-style Disj). The IEEE 1364-2005 source_text grammar (Β§A.1.1) +// admits a list of file-level design elements +// `module_declaration | udp_declaration | config_declaration`; the +// file-level Disj wrapping these into a single design-element +// classifier is owned by the bundled T-4 LanguageModel grammar +// productions when they land. At this vocabulary-slice phase +// UdpDefinition exists as a sibling-typed carrier consumed by +// UdpInstantiation; `config_declaration` is scope-negative per the +// header PROBE LIMITS framing (configuration is a separate +// elaboration-time concern outside the IN-B probe). +type UdpDefinition { + name: Symbol + body_lexeme: String +} + + // ───────────────────────────────────────────────────────────────────── // SpecparamDeclaration β€” a Verilog `specparam` declaration. IEEE // 1364-2005 Β§14.3.1 + Β§12.2 + Β§A.2.1.1. Specify parameters are From 0c797c08634f99f3f3e14f6d2b3a2c6a808377cd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 12:27:14 +0000 Subject: [PATCH 35/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20VerilogDesignElem?= =?UTF-8?q?ent=20=E2=80=94=20file-level=20design-element=20carrier=20per?= =?UTF-8?q?=20spec=20=C2=A7A.1.1=20(codex=20top-level=20BLOCKING=20on=20PR?= =?UTF-8?q?=20#3176)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex top-level BLOCKING summary at sha 16c992f3: module-body coverage was closed before the top-level Verilog description boundary was modeled. UdpDefinition added in 23d8db021 lived as a sibling type of VerilogModule but had no wrapping Disj β€” the spec Β§A.1.1 source_text design-element partition was implicit. Fix: new closed VerilogDesignElement Disj = ModuleDesignElement { module_decl: VerilogModule } | UdpDesignElement { udp_def: UdpDefinition } with full 5-pattern Practice-4 ledger. The spec-admitted third variant `config_declaration` is scope-negative for T-4.9 per the header PROBE LIMITS (configuration is an elaboration-time concern outside the IN-B probe); the Disj covers the two in-scope file-level design elements. The bundled T-4 LanguageModel grammar productions consume this Disj when walking the file-level design-element list; the carrier makes the Β§A.1.1 partition structural at the top level. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 61 ++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 3c762f790cc..eb54fa7e5e6 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -2859,6 +2859,67 @@ type VerilogModule } +// ───────────────────────────────────────────────────────────────────── +// VerilogDesignElement β€” the closed Verilog file-level +// design-element classifier (IEEE 1364-2005 Β§A.1.1 source_text / +// description). A Verilog source file is a sequence of design +// elements; the spec partition admits module declarations, UDP +// declarations, and config declarations. ConfigDeclaration is +// scope-negative for T-4.9 per the header PROBE LIMITS (config is +// an elaboration-time concern outside the IN-B probe); the two +// in-scope variants are modeled here. +// +// - ModuleDesignElement { module_decl: VerilogModule } +// β€” a `module ... endmodule` (or `macromodule`) declaration +// per Β§12.1. Carries the full VerilogModule per-style Disj. +// - UdpDesignElement { udp_def: UdpDefinition } +// β€” a `primitive ... endprimitive` UDP declaration per Β§8. +// Carries the UdpDefinition Conj. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.1.1 admits a third +// `config_declaration` form which is scope-negative for this slice +// per the header PROBE LIMITS framing (configuration is a separate +// elaboration-time concern, not part of the IN-B probe). A future +// language-version model EDITS this Disj to add ConfigDesignElement +// when the configuration sub-language lands. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal for the IN-B-probe scope; scope-negative +// ConfigDesignElement marked in the closed-set-coverage note). +// Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every file-level walker (the +// bundled T-4 LanguageModel grammar emitter, the +// UdpInstantiation udp_name resolver, the +// ModuleInstantiation module_name resolver, the lens-side +// design-element-list traverser) reads the design-element +// variant uniformly; shared classifier, not scattered. +// 2. Variant-is-data β€” FAILS: collapsing the two variants to a +// uniform `{ kind: ElementKind, payload: … }` shape requires +// Option-typed payload fields admitting mismatched-kind +// combinations (the inverse of P2 illegal-states- +// unrepresentable). Disj-with-heterogeneous-payloads is the +// dissolved form. +// 3. Algebraic form β€” N/A by construction: the partition is the +// IEEE 1364-2005 Β§A.1.1 spec's design-element taxonomy; not +// a richer std/ algebraic structure. +// 4. Dimensional β€” FAILS: a single design element is EXACTLY ONE +// variant; mutually-exclusive alternatives (`module M { … +// primitive U …}` is a syntax error per spec β€” primitive +// definitions cannot nest inside modules). +// 5. Parameterized family β€” FAILS: ModuleDesignElement carries +// VerilogModule (itself a per-style Disj); UdpDesignElement +// carries UdpDefinition (Conj with body_lexeme). Structurally +// heterogeneous payloads β€” NOT one generic `F` projection +// (Practice 7). +// Terminal: the closed two-way Verilog file-level design-element +// classifier for the T-4.9 in-scope partition (module + UDP); +// config is scope-negative per PROBE LIMITS. Added per codex +// BLOCKING on PR #3176 2026-05-16. +type VerilogDesignElement + = ModuleDesignElement { module_decl: VerilogModule } + | UdpDesignElement { udp_def: UdpDefinition } + + // ───────────────────────────────────────────────────────────────────── // VerilogCost β€” the per-target cost-realization carrier shape for the // Verilog `LanguageModel`. Conj record (no Practice-4 ledger). From 6f587e6ccb829ae93f2712f37bac85c6df45c5d3 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 12:32:05 +0000 Subject: [PATCH 36/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20revert=20VerilogD?= =?UTF-8?q?esignElement=20local-mint=20per=20T-4=20mgr=20disposition=20?= =?UTF-8?q?=E2=80=94=20defer=20source=5Ftext=20aggregator=20to=20canonical?= =?UTF-8?q?=20T-4=20LanguageModel=20(TASKS.md:504)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T-4 mgr (vivid-carp-207) msg_f2a511b6 disposition: HOLD on VerilogDesignElement local mint. The 0c797c086 carrier contradicted my own (and manager-blessed) FILE-LEVEL DESIGN-ELEMENT NOTE from 23d8db021, which named the bundled T-4 LanguageModel grammar- productions as the owner of the source_text design-element classifier. Three anchors: 1. TASKS.md:504 (verbatim, dispositive): "A local Byte/Word copy or private language-model schema is invalid." The source_text design-element classifier IS the canonical LanguageModel contract spine (top-level compilation-unit composition), not verilog-private grammar. Minting it locally is the v3 cross- layer spine-drift the canonical-first directive exists to kill. 2. P2 single-authority + canonical-LanguageModel-first directive: the design-element aggregator is owned by the canonical T-4 LanguageModel grammar-productions work β€” already the named owner in UdpDefinition's FILE-LEVEL DESIGN-ELEMENT NOTE. 3. Codex's gap finding is spec-right (the Β§A.1.1 partition should exist somewhere), but the FORM is the deferred canonical- LanguageModel obligation, not a verilog-local mint. Same pattern as the NonEmptyList β†’ std/collection.dag Wave-A2 deferral. Sanctioned deferral middle-path: - Removed `type VerilogDesignElement` and its ModuleDesignElement / UdpDesignElement variants. The local mint is gone. - Replaced the declaration block with a deferral-note comment block that explicitly cites TASKS.md:504 + P2 + the named-owner (bundled T-4 LanguageModel grammar productions) + the dissolution trigger. - Tightened the FILE-LEVEL DESIGN-ELEMENT NOTE in UdpDefinition's commentary to explicitly state "verilog.dag does NOT mint the design-element Disj locally" per TASKS.md:504, P2, and the canonical-LanguageModel-first directive. Added the dissolution- trigger clause. The Β§A.1.1 design-element gap is a producer-side / canonical- LanguageModel-owner obligation; the in-scope vocabulary carriers (VerilogModule + UdpDefinition) remain declared at file scope as the named owner's input. Verification: v2-compiler compile --source-root src/v4 --target dag = 64 modules / 0 diagnostics. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 132 +++++++++++++-------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index eb54fa7e5e6..5d236d0a115 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -2457,14 +2457,35 @@ type UdpInstantiation { // same scope as VerilogModule (top-level type, sibling of the // module-style Disj). The IEEE 1364-2005 source_text grammar (Β§A.1.1) // admits a list of file-level design elements -// `module_declaration | udp_declaration | config_declaration`; the -// file-level Disj wrapping these into a single design-element -// classifier is owned by the bundled T-4 LanguageModel grammar -// productions when they land. At this vocabulary-slice phase -// UdpDefinition exists as a sibling-typed carrier consumed by -// UdpInstantiation; `config_declaration` is scope-negative per the -// header PROBE LIMITS framing (configuration is a separate -// elaboration-time concern outside the IN-B probe). +// `module_declaration | udp_declaration | config_declaration`. +// +// verilog.dag does NOT mint the design-element Disj LOCALLY. Per +// TASKS.md:504 (verbatim, dispositive): "A local Byte/Word copy or +// private language-model schema is invalid." The source_text +// design-element classifier IS the canonical T-4 LanguageModel +// contract spine (top-level compilation-unit composition) β€” owned +// by the bundled LanguageModel grammar-productions work per the +// canonical-LanguageModel-first directive (TASKS.md 457/473/504), +// + P2 single-authority. Per-language minting would be the v3 +// cross-layer spine-drift the canonical-first directive exists to +// kill (5-language parallel-declaration precedent: every language +// file otherwise hits "source_text needs a design-element +// classifier" and would mint locally; codex top-level review will +// push each language file to do so, exactly what TASKS.md:504 +// forbids). +// +// Dissolution trigger: when the canonical T-4 LanguageModel +// grammar-productions work lands, that owner aggregates +// VerilogModule + UdpDefinition (+ config_declaration when its +// sub-language lands) into the source_text design-element Disj. +// `config_declaration` is scope-negative here per the header +// PROBE LIMITS framing (configuration is a separate elaboration- +// time concern outside the IN-B probe). +// +// At this vocabulary-slice phase UdpDefinition exists as a +// sibling-typed carrier consumed by UdpInstantiation (the +// name-reference resolution target). This NOTE is the single +// source-of-truth deferral marker for the missing aggregator. type UdpDefinition { name: Symbol body_lexeme: String @@ -2860,64 +2881,43 @@ type VerilogModule // ───────────────────────────────────────────────────────────────────── -// VerilogDesignElement β€” the closed Verilog file-level -// design-element classifier (IEEE 1364-2005 Β§A.1.1 source_text / -// description). A Verilog source file is a sequence of design -// elements; the spec partition admits module declarations, UDP -// declarations, and config declarations. ConfigDeclaration is -// scope-negative for T-4.9 per the header PROBE LIMITS (config is -// an elaboration-time concern outside the IN-B probe); the two -// in-scope variants are modeled here. -// -// - ModuleDesignElement { module_decl: VerilogModule } -// β€” a `module ... endmodule` (or `macromodule`) declaration -// per Β§12.1. Carries the full VerilogModule per-style Disj. -// - UdpDesignElement { udp_def: UdpDefinition } -// β€” a `primitive ... endprimitive` UDP declaration per Β§8. -// Carries the UdpDefinition Conj. -// -// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.1.1 admits a third -// `config_declaration` form which is scope-negative for this slice -// per the header PROBE LIMITS framing (configuration is a separate -// elaboration-time concern, not part of the IN-B probe). A future -// language-version model EDITS this Disj to add ConfigDesignElement -// when the configuration sub-language lands. -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal for the IN-B-probe scope; scope-negative -// ConfigDesignElement marked in the closed-set-coverage note). -// Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every file-level walker (the -// bundled T-4 LanguageModel grammar emitter, the -// UdpInstantiation udp_name resolver, the -// ModuleInstantiation module_name resolver, the lens-side -// design-element-list traverser) reads the design-element -// variant uniformly; shared classifier, not scattered. -// 2. Variant-is-data β€” FAILS: collapsing the two variants to a -// uniform `{ kind: ElementKind, payload: … }` shape requires -// Option-typed payload fields admitting mismatched-kind -// combinations (the inverse of P2 illegal-states- -// unrepresentable). Disj-with-heterogeneous-payloads is the -// dissolved form. -// 3. Algebraic form β€” N/A by construction: the partition is the -// IEEE 1364-2005 Β§A.1.1 spec's design-element taxonomy; not -// a richer std/ algebraic structure. -// 4. Dimensional β€” FAILS: a single design element is EXACTLY ONE -// variant; mutually-exclusive alternatives (`module M { … -// primitive U …}` is a syntax error per spec β€” primitive -// definitions cannot nest inside modules). -// 5. Parameterized family β€” FAILS: ModuleDesignElement carries -// VerilogModule (itself a per-style Disj); UdpDesignElement -// carries UdpDefinition (Conj with body_lexeme). Structurally -// heterogeneous payloads β€” NOT one generic `F` projection -// (Practice 7). -// Terminal: the closed two-way Verilog file-level design-element -// classifier for the T-4.9 in-scope partition (module + UDP); -// config is scope-negative per PROBE LIMITS. Added per codex -// BLOCKING on PR #3176 2026-05-16. -type VerilogDesignElement - = ModuleDesignElement { module_decl: VerilogModule } - | UdpDesignElement { udp_def: UdpDefinition } +// (The file-level Β§A.1.1 source_text design-element Disj +// aggregating VerilogModule + UdpDefinition is DELIBERATELY NOT +// declared in this file β€” relayed disposition from T-4 mgr +// vivid-carp-207 msg_f2a511b6, 2026-05-16; same shape as the +// NonEmptyList β†’ std/collection.dag Wave-A2 deferral. +// +// Three anchors: +// 1. TASKS.md:504 (verbatim, dispositive): "A local Byte/Word +// copy or private language-model schema is invalid." The +// source_text design-element classifier IS the canonical +// LanguageModel contract spine (top-level compilation-unit +// composition), not verilog-private grammar; minting it +// locally is the v3 cross-layer spine-drift this directive +// exists to prevent (every language file otherwise hits +// "source_text needs a design-element classifier" β†’ 5-language +// parallel-declaration precedent). +// 2. P2 single-authority + canonical-LanguageModel-first +// directive (TASKS.md 457/473/504): the design-element +// aggregator is owned by the canonical T-4 LanguageModel +// grammar-productions work β€” already the named owner in +// UdpDefinition's FILE-LEVEL DESIGN-ELEMENT NOTE. +// 3. Codex's gap finding is spec-right (the Β§A.1.1 partition +// should exist somewhere), but the FORM is the deferred +// canonical-LanguageModel obligation, not a verilog-local +// mint. Same pattern the NonEmptyList HOLD established. +// +// In-scope vocabulary carriers at file scope: VerilogModule (the +// per-style Disj declared above) + UdpDefinition (the Conj +// declared earlier alongside UdpInstantiation). The bundled +// T-4 LanguageModel grammar productions, when they land, aggregate +// these two file-level carriers into the canonical source_text +// design-element classifier β€” `config_declaration` is admitted by +// that canonical Disj when its sub-language lands (scope-negative +// here per the header PROBE LIMITS framing). The FILE-LEVEL +// DESIGN-ELEMENT NOTE in UdpDefinition's commentary is the single +// source-of-truth deferral marker; verilog.dag does NOT mint the +// design-element Disj locally.) // ───────────────────────────────────────────────────────────────────── From de04c86e327b20b936de9c60bf498cf53306d480 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 09:26:40 -0400 Subject: [PATCH 37/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 229 ++++++++++++++++++--------- 1 file changed, 151 insertions(+), 78 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 5d236d0a115..f0a7abab23b 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -324,10 +324,17 @@ type PortDirection // ───────────────────────────────────────────────────────────────────── -// NetType β€” the closed Verilog net-type classifier (IEEE 1364-2005 -// Β§3.7.1, Β§5.6). A net carries a value continuously driven by one or -// more drivers; the net-type fixes the resolution function and the -// default value when undriven. +// NonTriregNetKind β€” the closed Verilog net-type-keyword classifier +// over the eleven non-`trireg` net types (IEEE 1364-2005 Β§3.7.1, Β§5.6). +// `trireg` is partitioned OFF this Disj because it is the only spec +// net-type that (a) carries storage (capacitive last-driven-value +// semantics, Β§3.10 / Β§7.10) and (b) admits `charge_strength` in +// net_declaration position while FORBIDDING `drive_strength` on the +// identifier-only form (Β§A.2.1.3 grammar's third/fourth alternatives). +// Treating that partition as STRUCTURAL β€” variant-of-`NetType` not +// admit-then-check on a free field β€” is the dissolution of the +// net_declaration illegal-states-representable concern openai-pro +// REQUEST_CHANGES flagged on PR #3176 2026-05-16. // // - Wire β€” `wire` standard net; resolves to X if multiply // driven with conflicting values @@ -341,50 +348,35 @@ type PortDirection // designer-intent marker pairing with `tri` // - Tri0 β€” `tri0` pull-down (resolves to 0 if undriven) // - Tri1 β€” `tri1` pull-up (resolves to 1 if undriven) -// - TriReg β€” `trireg` stores last driven value (capacitive) // - Supply0 β€” `supply0` constant 0 power-rail net // - Supply1 β€” `supply1` constant 1 power-rail net // - Uwire β€” `uwire` unresolved wire β€” exactly one driver // required (IEEE 1364-2005 Β§5.6.6) // -// CLOSED (C1 stop-signal). A new net-type is an edit to THIS -// declaration under the L-2 pin discipline; the IEEE 1364-2005 Β§3.7.1 -// table is the authority. +// CLOSED (C1 stop-signal). The eleven non-trireg keywords of the +// IEEE 1364-2005 Β§3.7.1 table; `trireg` is the twelfth, and lives +// as a distinct top-level NetType variant rather than here. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” // 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every net-declaration emitter and +// 1. Fact placement β€” FAILS: every net-declaration emitter + // every driver-resolution consumer reads the net-type tag -// uniformly; shared classifier, not scattered. +// uniformly; shared classifier. // 2. Variant-is-data β€” FAILS: a `{ keyword: Symbol }` proxy -// reopens the readable-string heuristic surface K-1 forecloses -// (a `match keyword { "wire" => … }` smell); a +// reopens the K-1-forbidden readable-string heuristic; a // `{ resolution_kind: Int }` proxy replaces a closed -// 12-valued exhaustive sum with an unbounded Int β€” both -// violate P2 + M4 (algebra.dag:332 `Ordering` precedent). -// 3. Algebraic form β€” N/A by construction: the twelve net-types -// are the IEEE 1364-2005 spec's primitive resolution-function -// set; they do not trace to a richer std/ algebraic structure -// (one could attempt a `Lattice` for the wand/wor -// sublattice, but that would be a parallel representation of -// the per-net-type resolution function, not a richer source). -// 4. Dimensional β€” FAILS: a net declaration carries EXACTLY ONE -// net-type; `wire wand x` is a syntax error in Verilog itself. -// Mutually-exclusive alternatives, not coordinates. -// 5. Parameterized family β€” FAILS: the twelve are structurally -// distinct resolution / pull / supply / unresolved variants β€” -// NOT one generic `F` / projection over a separately- -// declared source set (Practice 7). The Wire/Tri, -// Wand/TriAnd, Wor/TriOr designer-intent pairs are -// SEMANTICALLY-equivalent partner variants the spec keeps -// DISTINCT at the syntactic surface (parse ∘ emit must -// preserve the writer's intent); collapsing the pairs into -// `{ resolution: Symbol, tri_intent: Bool }` would be a -// parallel-representation of the spec's enumeration and lose -// the K-1-opaque keyword discrimination. -// Terminal: the closed twelve-way net-type classifier of the -// IEEE 1364-2005 spec. -type NetType +// exhaustive sum with an unbounded Int (algebra.dag:332 +// `Ordering` precedent). +// 3. Algebraic form β€” N/A by construction: spec primitives. +// 4. Dimensional β€” FAILS: exactly one keyword per net declaration. +// 5. Parameterized family β€” FAILS: eleven structurally distinct +// resolution / pull / supply / unresolved variants (Practice 7). +// The Wire/Tri, Wand/TriAnd, Wor/TriOr designer-intent pairs +// MUST stay distinct at the syntactic surface (parse ∘ emit +// preserves writer intent). +// Terminal: the closed eleven-way non-trireg net-type-keyword +// classifier of the IEEE 1364-2005 spec. +type NonTriregNetKind = Wire | Tri | Wand @@ -393,12 +385,61 @@ type NetType | TriOr | Tri0 | Tri1 - | TriReg | Supply0 | Supply1 | Uwire +// ───────────────────────────────────────────────────────────────────── +// NetType β€” the Verilog net-type classifier as the {storage-vs-non- +// storage} structural partition over the IEEE 1364-2005 Β§3.7.1 table. +// The partition is structural per spec Β§A.2.1.3 net_declaration +// grammar: `trireg` admits `charge_strength` and a different declarator +// alternative set than the other eleven net types. Modeling the +// partition at NetType (rather than a flat twelve-way Disj) makes the +// {trireg?} fact STRUCTURAL β€” consumers that need to discriminate +// `trireg` from the others (NetDeclaration variants, future port- +// position Β§12.3.3 carriers) get the partition from the type itself, +// no admit-then-check (codex / openai-pro REQUEST_CHANGES discipline +// on PR #3176 2026-05-16). +// +// - NonTriregNet { kind: NonTriregNetKind } +// β€” one of the eleven non-`trireg` net-type keywords (see +// NonTriregNetKind above). +// - TriregNet +// β€” `trireg`; the storage net type. Nullary variant because +// there is only one trireg keyword (no sub-discrimination). +// +// CLOSED (C1 stop-signal). Two-way storage-vs-non-storage partition; +// a new net-type with `trireg`-like behavior is an edit to TriregNet +// (sub-Disj-with-payload, identical to NonTriregNet's shape if it +// ever needs sub-discrimination); a new non-storage net-type extends +// NonTriregNetKind. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: shared classifier across all net +// declarations + ANSI port-net carriers + driver-resolution +// consumers; the {trireg?} fact must be uniformly available. +// 2. Variant-is-data β€” FAILS: a `{ is_trireg: Bool, keyword: ... }` +// proxy reintroduces the admit-then-check shape the structural +// partition exists to dissolve. The 2-way Disj IS the dissolution. +// 3. Algebraic form β€” N/A by construction: the {storage-vs-non- +// storage} partition is the spec's irreducible Β§3.10 / Β§A.2.1.3 +// structural axis, not a richer std/ algebraic source. +// 4. Dimensional β€” FAILS: one net-type per declaration; mutually +// exclusive alternatives. +// 5. Parameterized family β€” FAILS: the two variants are structurally +// heterogeneous (NonTriregNet carries a `kind` payload, TriregNet +// is nullary). The trireg keyword is the SOLE storage net-type +// per spec β€” no generic `F` projection over a richer source. +// Terminal: the closed two-way Verilog net-type {storage-vs-non- +// storage} partition. +type NetType + = NonTriregNet { kind: NonTriregNetKind } + | TriregNet + + // (VariableType has been dissolved into VariableDeclaration's // Disj-with-named-payloads below β€” the spec couples kind Γ— packing // admissibility (only `reg` accepts a `[msb:lsb]` packing per IEEE @@ -657,17 +698,20 @@ type Signedness // ───────────────────────────────────────────────────────────────────── -// DriveStrengthClause β€” the closed Verilog drive-strength / -// charge-strength clause classifier on a net_declaration (IEEE -// 1364-2005 Β§A.2.1.3 / Β§7.10). The clause is OPTIONAL per spec β€” -// present-or-absent partition modeled as a closed Disj rather than -// an empty-string sentinel on a `String` field (openai-pro -// REQUEST_CHANGES on PR #3176; same pattern as PortConnectionActual's -// BlankConnection β€” closed sum, not sentinel). +// DriveStrengthClause β€” the closed Verilog drive-strength clause +// classifier on a net_declaration (IEEE 1364-2005 Β§A.2.1.3 / Β§7.10). +// The clause is OPTIONAL per spec β€” present-or-absent partition +// modeled as a closed Disj rather than an empty-string sentinel on +// a `String` field (openai-pro REQUEST_CHANGES on PR #3176; same +// pattern as PortConnectionActual's BlankConnection β€” closed sum, +// not sentinel). `drive_strength` admits the Β§7.10 `(strength0, +// strength1)` keyword set; `charge_strength` (for `trireg`) is a +// DISTINCT spec set (Β§A.5.1 `small | medium | large`) and lives in +// its own sibling Disj `ChargeStrengthClause` below β€” the two are +// not interchangeable on the spec surface. // // - NoDriveStrength -// β€” no `(strong0, weak1)` / `(small)` clause on the -// declaration. +// β€” no `(strong0, weak1)` clause on the declaration. // - DriveStrengthLexeme { lexeme: String } // β€” the clause as a verbatim lexeme (sub-grammar deferred to // T-4 LanguageModel β€” the spec's closed strength-keyword set @@ -701,6 +745,51 @@ type DriveStrengthClause | DriveStrengthLexeme { lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// ChargeStrengthClause β€” the closed Verilog charge-strength clause +// classifier on a `trireg` net_declaration (IEEE 1364-2005 Β§A.2.1.3 / +// Β§A.5.1 / Β§7.10). The clause is OPTIONAL per spec and applies ONLY +// to the identifier-only `trireg` net_declaration form (Β§A.2.1.3 +// third alternative); on the `trireg` assignment form `drive_strength` +// applies instead. Sibling Disj of DriveStrengthClause β€” kept distinct +// because the spec keyword sets are disjoint: drive_strength = (Β§7.10 +// strength0, strength1 pairs), charge_strength = Β§A.5.1 small | +// medium | large. +// +// - NoChargeStrength +// β€” no `(small)` / `(medium)` / `(large)` clause on the +// trireg declaration. +// - ChargeStrengthLexeme { lexeme: String } +// β€” the clause as a verbatim lexeme; sub-grammar (the +// small/medium/large keyword closure) deferred to the bundled +// T-4 LanguageModel. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape +// as DriveStrengthClause; abbreviated for brevity (each pattern's +// argument is identical modulo "drive" vs "charge"). +// 1. Fact placement β€” FAILS: shared classifier across trireg-form +// emitters / simulation-init consumers. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected +// (same BlankConnection precedent argument). +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one charge-strength state per trireg +// declaration. +// 5. Parameterized family β€” FAILS: NoChargeStrength is nullary; +// ChargeStrengthLexeme carries a `lexeme: String` payload β€” +// structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog charge-strength clause- +// presence classifier. Added 2026-05-16 per openai-pro REQUEST_ +// CHANGES on PR #3176 β€” net_declaration Β§A.2.1.3 grammar requires +// charge_strength to be available on the identifier-only `trireg` +// form distinct from `drive_strength`. +type ChargeStrengthClause + = NoChargeStrength + | ChargeStrengthLexeme { lexeme: String } + + // ───────────────────────────────────────────────────────────────────── // DelayClause β€” the closed Verilog delay3 clause classifier on a // net_declaration (IEEE 1364-2005 Β§A.2.1.3 / Β§7.14). The clause is @@ -734,7 +823,7 @@ type DelayClause // ───────────────────────────────────────────────────────────────────── -// VectoredessClause β€” the closed Verilog vectored/scalared +// VectorednessClause β€” the closed Verilog vectored/scalared // declaration-boundary classifier on a net_declaration (IEEE // 1364-2005 Β§A.2.1.3 / Β§3.7.1). The clause is OPTIONAL per spec and // is DISTINCT from drive_strength: it carries a synthesizer hint @@ -779,40 +868,24 @@ type DelayClause // the vectored/scalared clause is a Β§A.2.1.3 declaration-boundary // fact distinct from drive_strength; the prior commentary "collapsed // into the strength lexeme position" overloaded the two clauses. -type VectoredessClause +type VectorednessClause = NoVectoredness | VectoredNet | ScalaredNet // ───────────────────────────────────────────────────────────────────── -// NetInitializerClause β€” the closed Verilog net_decl_assignment -// initializer-presence classifier (IEEE 1364-2005 Β§A.2.4). Optional -// per spec β€” present-or-absent partition as a closed Disj. -// -// - NoNetInitializer -// β€” `wire a;` form: no initializer expression. -// - NetInitializerLexeme { lexeme: String } -// β€” `wire a = expr;` form: the initializer expression as a -// verbatim lexeme. -// -// CLOSED (C1 stop-signal). Two-way present/absent partition. -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: every net-declaration emitter and -// every elaboration-time net-initialization consumer reads -// the clause uniformly. -// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected -// (same argument). -// 3. Algebraic form β€” N/A by construction. -// 4. Dimensional β€” FAILS: one initializer state per declarator. -// 5. Parameterized family β€” FAILS: heterogeneous payloads. -// Terminal: the closed two-way Verilog net-initializer-presence -// classifier. -type NetInitializerClause - = NoNetInitializer - | NetInitializerLexeme { lexeme: String } +// (NetInitializerClause was DISSOLVED on PR #3176 2026-05-16 per +// openai-pro REQUEST_CHANGES. The optional-initializer state is +// dissolved structurally by NetDeclaration's per-form Disj split: +// the Β§A.2.1.3 assignment form's declarators ALWAYS carry an +// initializer (NetAssignmentDeclarator.rhs_lexeme), the identifier- +// only form's declarators NEVER do (NetIdentifierDeclarator carries +// only `name: Symbol`). The "no initializer on an assignment-form +// declarator" and "initializer on an identifier-only declarator" +// states are structurally unrepresentable, so a present/absent +// initializer-presence Disj on a single declarator type became dead +// weight. The deletion is the dissolution.) // ───────────────────────────────────────────────────────────────────── @@ -893,7 +966,7 @@ type VariableInitializerClause // // The vectored/scalared modifier is a SEPARATE Β§A.2.1.3 declaration- // boundary fact distinct from drive_strength β€” modeled structurally -// via the dedicated `VectoredessClause` field (NoVectoredness | +// via the dedicated `VectorednessClause` field (NoVectoredness | // VectoredNet | ScalaredNet). The prior framing that collapsed // vectored/scalared into the drive_strength lexeme position was a // codex BLOCKING-fix correction on PR #3176 2026-05-16. The @@ -942,7 +1015,7 @@ type NetDeclaration { packing: PackingShape signedness: Signedness drive_strength: DriveStrengthClause - vectoredness: VectoredessClause + vectoredness: VectorednessClause delay: DelayClause // 🟑 spec-non-empty (Β§A.2.1.3) β€” deferred to std/collection.dag // Wave-A2 `List where non_empty` refinement; see shared From 1eb241a2474af11de0b4381174bd2963e2f33bfd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 13:29:44 +0000 Subject: [PATCH 38/56] v4 T-4.9 verilog: fix openai-pro REQUEST_CHANGES on PR #3176 sha 6f587e6c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three findings, all spec-right, addressed in one bundle (manager disposition from vivid-carp-207 msg_8c2cf95f): 1. BLOCKING β€” NetDeclaration Conj β†’ 4-way Disj per IEEE 1364-2005 Β§A.2.1.3. The prior free-product shape admitted drive_strength on the identifier-only form, charge_strength on a non-trireg form, mixed init/non-init declarator lists, identifier-only-with- initializer, and assignment-form-without-initializer (P2 illegal- states-representable). Replaced with the four spec alternatives: NonTriregIdentifierForm / NonTriregAssignForm / TriregIdentifierForm / TriregAssignForm. The {trireg?} Γ— {form: identifier-only vs assignment} partition is STRUCTURAL per variant β€” trireg-variants carry no net_type field (variant identity IS the net_type fact); non-trireg variants carry the new NonTriregNetKind (11-way closed Disj of the Β§3.7.1 non-trireg keywords). Strength presence rides the existing Clause Disjs (DriveStrengthClause / new ChargeStrengthClause), not a top-level NetDeclaration axis. Per-form declarators split: NetAssignmentDeclarator (name + required rhs_lexeme) vs NetIdentifierDeclarator (name only). The unified NetDeclarator + NetInitializerClause types dissolved into this structural split. NetType refactored to {NonTriregNet { kind: NonTriregNetKind } | TriregNet} 2-way Disj β€” single source of truth for the Β§3.7.1 keywords, no parallel/duplicated representation of the partition. ANSI port-net carriers (AnsiNetType / OutputAnsiNetType / AnsiInputInoutNet) continue to use `net_type: NetType` unchanged in shape; port-position Β§12.3.3 trireg-exclusion is a separate finding not in scope here. 2. NON-BLOCKING β€” VectoredessClause β†’ VectorednessClause rename (field is already named `vectoredness`). Four occurrences updated. 3. NON-BLOCKING β€” shared NonEmptyList scaffold-note header text updated from "Six sites" to match the enumeration. NetDeclaration's former single non-empty site dissolves into the four per-variant list_of_net_decl_assignments / list_of_net_identifiers sites; the enumeration is now 14 entries (was 11). grep -c '🟑 spec-non-empty (Β§' invariant: 14 (verified). The NonEmptyList deferral disposition is unchanged β€” the four new per-variant sites ride the existing RQ-3 / std/collection.dag Wave-A2 `List where non_empty` refinement deferral, NOT a verilog-local NonEmptyList carrier mint. Same operator-pending dissolution trigger. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 339 ++++++++++++++++++--------- 1 file changed, 222 insertions(+), 117 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index f0a7abab23b..409d4c84300 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -933,8 +933,11 @@ type UnpackedDimensionsClause // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” // 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape -// as NetInitializerClause; abbreviated for brevity (each pattern's -// argument is identical modulo "net" vs "variable"). +// as UnpackedDimensionsClause; abbreviated for brevity (each pattern's +// argument is identical modulo "unpacked-dimensions" vs "variable- +// initializer"). The pre-#3176-openai-pro shape pointed at +// NetInitializerClause, which has since been dissolved structurally +// by NetDeclaration's per-form Disj split. // 1. Fact placement β€” FAILS: shared classifier across emitters / // simulation-init / elaboration consumers. // 2. Variant-is-data β€” FAILS: empty-string sentinel rejected. @@ -951,96 +954,182 @@ type VariableInitializerClause // ───────────────────────────────────────────────────────────────────── // NetDeclaration β€” a Verilog net declaration (`wire foo;`, // `wire [7:0] bus;`, `wire signed [15:0] s;`, `wand x;`, -// `wire (strong0, weak1) #5 a = expr_a, b, c = expr_c;`). -// IEEE 1364-2005 Β§3.10 / Β§A.2.1.3. Conj record (no Practice-4 -// ledger). +// `wire (strong0, weak1) #5 a = expr_a, b = expr_b;`, `trireg +// (small) [3:0] cap_bus;`, `trireg (weak0, weak1) #2 stor = expr_s;`). +// IEEE 1364-2005 Β§3.10 / Β§A.2.1.3. +// +// Per spec Β§A.2.1.3 net_declaration is a FOUR-WAY closed alternative +// set, NOT a free product of {net_type, strength, form, declarators}: +// +// net_declaration ::= +// net_type [drive_strength] [vectored|scalared] [signed] [range] +// [delay3] list_of_net_decl_assignments ; +// | net_type [vectored|scalared] [signed] [range] [delay3] +// list_of_net_identifiers ; +// | trireg [charge_strength] [vectored|scalared] [signed] [range] +// [delay3] list_of_net_identifiers ; +// | trireg [drive_strength] [vectored|scalared] [signed] [range] +// [delay3] list_of_net_decl_assignments ; +// +// where `net_type` (per Β§3.7.1) is one of the eleven non-`trireg` +// keywords; `trireg` is the fourth-row net-type with distinct +// strength-and-form admissibility. +// +// Modeling the four spec alternatives as STRUCTURAL variants makes +// these illegal states unrepresentable (openai-pro REQUEST_CHANGES +// on PR #3176 2026-05-16; same INVARIANTS P2 / Practice-2 discipline +// as VariableDeclaration's kindΓ—packing structural split below): +// +// - drive_strength on the identifier-only form (forbidden by spec) +// - charge_strength on a non-trireg net_type (forbidden by spec) +// - mixed init/non-init declarator lists (forbidden by spec) +// - identifier-only declarators with initializers (forbidden by spec) +// - assignment-form declarators without initializers (forbidden) +// +// The discriminating axes are STRUCTURAL per variant: {trireg?} Γ— +// {form: identifier-only vs assignment}. The non-trireg-net-type +// keyword set (`wire / tri / wand / triand / wor / trior / tri0 / +// tri1 / supply0 / supply1 / uwire`) rides as a `NonTriregNetKind` +// field on the two non-trireg variants; the trireg variants do NOT +// carry a `net_type` field β€” the variant identity IS the net_type +// fact. `drive_strength` and `charge_strength` PRESENCE remain inside +// their respective Clause Disjs (DriveStrengthClause / +// ChargeStrengthClause), not as a top-level variant axis β€” strength +// is optional per spec brackets, and the existing Clause Disjs +// already structurally encode present-vs-absent. +// +// - NonTriregIdentifierForm β€” `wire [7:0] a, b, c;` (no drive_ +// strength permitted on this spec +// alternative; declarators are +// name-only). +// - NonTriregAssignForm β€” `wire (strong0, weak1) [7:0] a = +// e1, b = e2;` (optional drive_ +// strength; declarators carry +// required initializers). +// - TriregIdentifierForm β€” `trireg (small) [3:0] cap_bus;` +// (optional charge_strength; +// declarators are name-only). +// - TriregAssignForm β€” `trireg (weak0, weak1) #2 stor = +// e_s;` (optional drive_strength; +// declarators carry required +// initializers). // -// A net_declaration declares ONE OR MORE nets sharing a common -// (net_type, packing, signedness, drive_strength, delay) β€” each -// individual net is a NetDeclarator carrying its own name + optional -// initializer expression. Per spec Β§A.2.1.3 grammar: -// -// net_declaration ::= net_type [drive_strength | charge_strength] -// [vectored | scalared] [signed] [range] -// [delay3] list_of_net_decl_assignments ; -// -// The vectored/scalared modifier is a SEPARATE Β§A.2.1.3 declaration- -// boundary fact distinct from drive_strength β€” modeled structurally -// via the dedicated `VectorednessClause` field (NoVectoredness | -// VectoredNet | ScalaredNet). The prior framing that collapsed -// vectored/scalared into the drive_strength lexeme position was a -// codex BLOCKING-fix correction on PR #3176 2026-05-16. The -// charge_strength applies only to `trireg` per spec Β§7.10; admitted -// alongside drive_strength via the shared DriveStrengthClause lexeme -// (charge_strength is itself a closed keyword set owned by the -// bundled T-4 LanguageModel). -// -// - net_type which net-type (wire / wand / wor / -// tri / … per the closed NetType set) -// - packing scalar or `[msb:lsb]` packed -// bit-vector (the shared range applies -// to all declarators in the list) -// - signedness `signed` keyword present / absent -// (IEEE 1364-2005 Β§5.6) -// - drive_strength_lexeme the optional drive_strength / -// charge_strength clause as a verbatim -// lexeme (`(strong0, weak1)`, -// `(small)`, etc.); "" = absent. -// Sub-grammar deferred β€” the strength -// keyword set is the spec's closed set -// owned by the bundled T-4 -// LanguageModel. -// - delay_lexeme the optional delay3 clause as a -// verbatim lexeme (`#5`, `#(2:3:4)`, -// etc.); "" = absent. Sub-grammar -// deferred to T-4 LanguageModel per -// the body_lexeme precedent. -// - declarators the list_of_net_decl_assignments β€” -// each NetDeclarator carries a name + -// optional initializer expression. -// Per spec a net_declaration must have -// at least one declarator; the empty -// list is structurally representable -// but is a producer-side bug -// (well-formedness joint check in the -// T-4 LanguageModel). -// -// Multi-declarator + strength + delay + initializer added per codex -// BLOCKING review on PR #3176 2026-05-16 β€” the prior {net_type, name, -// packing, signedness} shape collapsed the spec's declaration- -// boundary facts (strength, delay, dimensions, initializer, -// declarator-list) into name-only. -type NetDeclaration { - net_type: NetType - packing: PackingShape - signedness: Signedness - drive_strength: DriveStrengthClause - vectoredness: VectorednessClause - delay: DelayClause - // 🟑 spec-non-empty (Β§A.2.1.3) β€” deferred to std/collection.dag - // Wave-A2 `List where non_empty` refinement; see shared - // TRACKED-SCAFFOLD note above. - declarators: List +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every net-declaration emitter + +// every elaboration / well-formedness consumer reads the +// net_declaration uniformly; not a scattered fact. +// 2. Variant-is-data β€” FAILS: collapsing into `{ is_trireg: Bool, +// has_assignments: Bool, drive_strength, charge_strength, … }` +// reintroduces the admit-then-check shape this Disj exists to +// dissolve (non-trireg + charge_strength becomes representable; +// identifier-form + drive_strength becomes representable). +// Structural Disj forecloses. +// 3. Algebraic form β€” N/A by construction: the {trireg?} Γ— {form} +// partition is the spec's Β§A.2.1.3 irreducible structural axis, +// not a richer std/ algebraic source. +// 4. Dimensional β€” FAILS: a net_declaration is EXACTLY ONE of +// the four spec forms; mutually exclusive alternatives. +// 5. Parameterized family β€” FAILS: the four variants are +// structurally heterogeneous (kind-vs-no-kind, drive-vs-charge- +// vs-neither strength, assignment-vs-identifier declarators) β€” +// no generic `F` projection over a richer source set +// (Practice 7). +// Terminal: the closed four-way IEEE 1364-2005 Β§A.2.1.3 +// net_declaration alternative set. +// +// Prior shape (single Conj-record with free {net_type, drive_strength, +// declarators: List}) was the codex BLOCKING-fix shape +// on PR #3176 2026-05-16; openai-pro REQUEST_CHANGES at sha 6f587e6c +// correctly flagged that it admitted the five spec-illegal states +// above as a free product. This four-variant structural split is +// the dissolution. +type NetDeclaration + = NonTriregIdentifierForm { + kind: NonTriregNetKind + vectoredness: VectorednessClause + signedness: Signedness + packing: PackingShape + delay: DelayClause + // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_identifiers) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + identifiers: List + } + | NonTriregAssignForm { + kind: NonTriregNetKind + drive_strength: DriveStrengthClause + vectoredness: VectorednessClause + signedness: Signedness + packing: PackingShape + delay: DelayClause + // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_decl_assignments) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + assignments: List + } + | TriregIdentifierForm { + charge_strength: ChargeStrengthClause + vectoredness: VectorednessClause + signedness: Signedness + packing: PackingShape + delay: DelayClause + // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_identifiers) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + identifiers: List + } + | TriregAssignForm { + drive_strength: DriveStrengthClause + vectoredness: VectorednessClause + signedness: Signedness + packing: PackingShape + delay: DelayClause + // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_decl_assignments) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + assignments: List + } + + +// ───────────────────────────────────────────────────────────────────── +// NetAssignmentDeclarator β€” one (net_identifier, initializer- +// expression) pair in a net_declaration's list_of_net_decl_assignments +// (IEEE 1364-2005 Β§A.2.4: `net_decl_assignment ::= net_identifier = +// expression`). A single `wire [7:0] a = e_a, b = e_b;` carries TWO +// NetAssignmentDeclarators. The initializer is REQUIRED on every +// element of the assignment-form (no `[]` brackets in the spec +// production) β€” it is structurally non-optional here, dissolving the +// prior optional-initializer Disj on a unified NetDeclarator type +// (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16). Conj record +// (no Practice-4 ledger). +// +// - name the declared net identifier (K-1-opaque +// Symbol). +// - rhs_lexeme the initializer expression as a verbatim +// lexeme. Sub-grammar deferred to the bundled +// T-4 LanguageModel via the established +// body_lexeme precedent. +type NetAssignmentDeclarator { + name: Symbol + rhs_lexeme: String } // ───────────────────────────────────────────────────────────────────── -// NetDeclarator β€” one (name, optional-initializer) pair in a -// net_declaration's list_of_net_decl_assignments (IEEE 1364-2005 -// Β§A.2.4 / Β§3.10). A single net_declaration like `wire [7:0] a = ex1, -// b, c = ex2;` carries THREE NetDeclarators. Conj record (no -// Practice-4 ledger). +// NetIdentifierDeclarator β€” one element of a net_declaration's +// list_of_net_identifiers (IEEE 1364-2005 Β§A.2.3 / Β§A.2.1.3 +// identifier-only form). Carries ONLY the net identifier: the +// identifier-only spec form forbids initializers structurally +// (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 β€” making +// "identifier-only-with-initializer" unrepresentable rather than a +// runtime check). A single `wire [7:0] a, b, c;` carries THREE +// NetIdentifierDeclarators. Conj record (no Practice-4 ledger). // -// - name the net identifier (K-1-opaque Symbol) -// - initializer_lexeme the net_decl_assignment initializer -// expression as a verbatim lexeme; "" -// denotes the absent-initializer form -// (`wire a;` vs `wire a = expr;`). Sub- -// grammar deferred to T-4 LanguageModel via -// the established body_lexeme precedent. -type NetDeclarator { +// - name the declared net identifier (K-1-opaque +// Symbol). +type NetIdentifierDeclarator { name: Symbol - initializer: NetInitializerClause } @@ -1598,12 +1687,13 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Six sites in this file carry `List` payloads where IEEE 1364-2005 -// requires AT LEAST ONE entry β€” the spec-illegal empty state is -// structurally representable, the same INVARIANTS P2 illegal-states- -// unrepresentable concern codex correctly flagged. The MOTIVATION is -// real and spec-grounded. The CANONICAL FIX is NOT a worker-minted -// `NonEmptyList` generic carrier: +// Fourteen sites in this file carry `List` payloads where IEEE +// 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty +// state is structurally representable, the same INVARIANTS P2 +// illegal-states-unrepresentable concern codex / openai-pro +// correctly flagged. The MOTIVATION is real and spec-grounded. The +// CANONICAL FIX is NOT a worker-minted `NonEmptyList` generic +// carrier: // // - `docs/coercion-design.md` RQ-3 (ratified): "refinements of // base containers, NOT separate inhabitant families. @@ -1624,40 +1714,55 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the six spec-non-empty sites keeps `List` for now. +// - Each of the fourteen spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. // - DISSOLUTION TRIGGER: when `std/collection.dag` Wave-A2 lands the -// non-empty refinement, the six sites adopt +// non-empty refinement, the fourteen sites adopt // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The six spec-non-empty sites (back-pointers to this note): -// 1. NetDeclaration.declarators (Β§A.2.1.3) -// 2. VariableDeclaration.{Reg,Integer,Real,Time,RealTime}Variable.declarators +// The fourteen spec-non-empty sites (back-pointers to this note): +// 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) +// 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) +// 3. NetDeclaration.TriregIdentifierForm.identifiers (Β§A.2.1.3) +// 4. NetDeclaration.TriregAssignForm.assignments (Β§A.2.1.3) +// 5. VariableDeclaration.{Reg,Integer,Real,Time,RealTime}Variable.declarators // (Β§A.2.4 / Β§7.4) -// 3. ParameterDeclaration.assignments (Β§A.2.1.1) -// 4. LocalParameterDeclaration.assignments (Β§A.2.1.1) -// 5. SpecparamDeclaration.assignments (Β§A.2.1.1) -// 6. ModuleParameters.parameters (Β§12.1) -// 7. AlwaysBlockSensitivity.ExplicitEventList.items (Β§9.7.2) -// 8. ParameterOverrides.OrderedParameterOverrides.actuals (Β§12.1.3) -// 9. ParameterOverrides.NamedParameterOverrides.overrides (Β§12.1.3) -// 10. ContinuousAssign.assignments (Β§6.1) -// 11. ModuleInstantiation.instances (Β§A.4.1.1) -// -// Sites 7-9 added 2026-05-16 per codex REQUEST_CHANGES on PR #3176 -// at sha f87fdf189; site 10 added 2026-05-16 per codex BLOCKING on -// PR #3176 at sha bcc6b5f89 (ContinuousAssign restructured to carry -// drive_strength + delay + list_of_net_assignments per Β§6.1, with -// the non-empty assignments list deferred under the same RQ-3 -// disposition); site 11 added 2026-05-16 per codex BLOCKING on -// PR #3176 at sha 2bf0024ba (ModuleInstantiation restructured to -// carry shared module_name + parameter_overrides + non-empty -// instances per Β§A.4.1.1 multi-instance form). Codex's motivation -// is spec-correct in each case; the FORM is the deferred refinement, -// not a verilog-local mint. +// 6. ParameterDeclaration.assignments (Β§A.2.1.1) +// 7. LocalParameterDeclaration.assignments (Β§A.2.1.1) +// 8. SpecparamDeclaration.assignments (Β§A.2.1.1) +// 9. ModuleParameters.parameters (Β§12.1) +// 10. AlwaysBlockSensitivity.ExplicitEventList.items (Β§9.7.2) +// 11. ParameterOverrides.OrderedParameterOverrides.actuals (Β§12.1.3) +// 12. ParameterOverrides.NamedParameterOverrides.overrides (Β§12.1.3) +// 13. ContinuousAssign.assignments (Β§6.1) +// 14. ModuleInstantiation.instances (Β§A.4.1.1) +// +// Sites previously numbered 7-9 added 2026-05-16 per codex +// REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 +// added 2026-05-16 per codex BLOCKING on PR #3176 at sha bcc6b5f89 +// (ContinuousAssign restructured to carry drive_strength + delay + +// list_of_net_assignments per Β§6.1, with the non-empty assignments +// list deferred under the same RQ-3 disposition); site previously 11 +// added 2026-05-16 per codex BLOCKING on PR #3176 at sha 2bf0024ba +// (ModuleInstantiation restructured to carry shared module_name + +// parameter_overrides + non-empty instances per Β§A.4.1.1 multi- +// instance form). Sites 1-4 (formerly the single site +// `NetDeclaration.declarators`) added 2026-05-16 per openai-pro +// REQUEST_CHANGES on PR #3176 at sha 6f587e6c β€” NetDeclaration +// dissolved into the IEEE 1364-2005 Β§A.2.1.3 four-way +// {trireg?}Γ—{form} structural Disj making spec-impossible states +// (drive_strength on the identifier-only form, charge_strength on +// a non-trireg form, mixed init/non-init declarator lists, +// identifier-only-with-initializer, assignment-form-without- +// initializer) unrepresentable; the four per-variant +// list_of_net_decl_assignments / list_of_net_identifiers fields +// inherit the Β§A.2.1.3 spec-non-empty constraint and ride the same +// RQ-3 deferral. Codex's / openai-pro's motivation is spec-correct +// in each case; the FORM is the deferred refinement, not a verilog- +// local mint. // ───────────────────────────────────────────────────────────────────── From cba903a3ecac4db9a7fdb0994df042da86979ad4 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 13:37:32 +0000 Subject: [PATCH 39/56] v4 T-4.9 verilog: address openai-pro 4-pack BLOCKING inline reviews on PR #3176 sha 1eb241a2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four spec-right findings, all in-pattern declaration-class spec- fidelity, fixed in one bundle: 1. PortConnections (Β§A.4.1.1) β€” added `NoPortConnections` nullary variant. The Β§A.4.1.1 grammar makes `[list_of_port_connections]` optional at module_instance, so `Adder a1 ();` (empty parens) is legal spec syntax. The prior 2-variant shape made this state representable two ways (positional-empty vs named-empty lists), violating P2 representation-duality. The 3-way Disj makes the empty-`()` form structurally distinct from non-empty ordered/ named lists; the two inner lists (`actuals`, `connections`) ride the established RQ-3 / std/collection.dag Wave-A2 spec-non-empty deferral as new sites 15-16. 2. DefparamDeclaration / EventDeclaration / GenvarDeclaration (Β§A.2.5 / Β§A.2.1.4 / Β§A.2.1.1) β€” each refactored from singular- entry to non-empty list of per-entry sub-records mirroring the ParameterDeclaration / SpecparamDeclaration / LocalParameter Declaration / ModuleParameters pattern. New `DefparamAssignment` Conj sub-record for Β§A.2.5 list_of_defparam_assignments; `event_names: List` for Β§A.2.1.4 list_of_event_ identifiers; `genvar_names: List` for Β§A.2.1.1 list_of_ genvar_identifiers. Restores the spec statement-boundary (shared keyword across multi-entry forms) that the prior singular shape lost. New non-empty sites 17-19 in the shared scaffold note. 3. UdpInstantiation (Β§A.5.2) β€” refactored to the same shared-header + non-empty-instance-list pattern as ModuleInstantiation: shared (udp_name, drive_strength, delay) clause + non-empty List with per-instance (instance_name, body_lexeme). The prior singular-instance shape lost the Β§A.5.2 statement- boundary for `udp_identifier [drive_strength] [delay2] udp_instance { , udp_instance } ;`. Reuses the existing DriveStrengthClause / DelayClause Disjs (delay2-vs-delay3 sub- grammar distinction is a bundled-LanguageModel concern via the lexeme payload, not a new substrate Disj). New non-empty site 20. 4. VerilogModule (Β§A.1.2) β€” added `module_keyword: ModuleKeyword` to both NonAnsiVerilogModule and AnsiVerilogModule variants. New closed `ModuleKeyword` Disj { ModuleKw | MacromoduleKw } with full Practice-4 ledger; carries the Β§A.1.2 module-keyword distinction (module vs macromodule) that the prior shape collapsed before emission. parse ∘ emit now preserves which keyword the writer used (macromodule simulator hint can no longer silently flatten to module). Shared NonEmptyList scaffold-note header count: "Fourteen" β†’ "Twenty"; enumeration: 14 β†’ 20 entries; provenance addendum documenting all four findings at sha 1eb241a2. grep -c '🟑 spec- non-empty (Β§' invariant: 20 (verified). All four inherit the established RQ-3 / std/collection.dag Wave-A2 `List where non_empty` deferral; NO verilog-local NonEmptyList mint. NonEmptyList + design-element deferrals unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 367 +++++++++++++++++++++------ 1 file changed, 289 insertions(+), 78 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 409d4c84300..eaade2af79d 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1687,7 +1687,7 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Fourteen sites in this file carry `List` payloads where IEEE +// Twenty sites in this file carry `List` payloads where IEEE // 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty // state is structurally representable, the same INVARIANTS P2 // illegal-states-unrepresentable concern codex / openai-pro @@ -1714,16 +1714,16 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the fourteen spec-non-empty sites keeps `List` for now. +// - Each of the twenty spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. // - DISSOLUTION TRIGGER: when `std/collection.dag` Wave-A2 lands the -// non-empty refinement, the fourteen sites adopt +// non-empty refinement, the twenty sites adopt // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The fourteen spec-non-empty sites (back-pointers to this note): +// The twenty spec-non-empty sites (back-pointers to this note): // 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) // 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) // 3. NetDeclaration.TriregIdentifierForm.identifiers (Β§A.2.1.3) @@ -1739,6 +1739,12 @@ type ParameterTypeKind // 12. ParameterOverrides.NamedParameterOverrides.overrides (Β§12.1.3) // 13. ContinuousAssign.assignments (Β§6.1) // 14. ModuleInstantiation.instances (Β§A.4.1.1) +// 15. PortConnections.PositionalConnections.actuals (Β§A.4.1.1) +// 16. PortConnections.NamedConnections.connections (Β§A.4.1.1) +// 17. DefparamDeclaration.assignments (Β§A.2.5) +// 18. EventDeclaration.event_names (Β§A.2.1.4) +// 19. GenvarDeclaration.genvar_names (Β§A.2.1.1) +// 20. UdpInstantiation.instances (Β§A.5.2) // // Sites previously numbered 7-9 added 2026-05-16 per codex // REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 @@ -1760,9 +1766,27 @@ type ParameterTypeKind // initializer) unrepresentable; the four per-variant // list_of_net_decl_assignments / list_of_net_identifiers fields // inherit the Β§A.2.1.3 spec-non-empty constraint and ride the same -// RQ-3 deferral. Codex's / openai-pro's motivation is spec-correct -// in each case; the FORM is the deferred refinement, not a verilog- -// local mint. +// RQ-3 deferral. Sites 15-20 added 2026-05-16 per openai-pro +// REQUEST_CHANGES on PR #3176 at sha 1eb241a2 (inline BLOCKING +// findings at lines 2156 / 2315 / 2604): PortConnections gained the +// NoPortConnections nullary variant β€” the Β§A.4.1.1 empty `()` +// connection-list form is now structurally distinct from non-empty +// ordered/named lists (P2 representation-duality dissolution); the +// two non-empty inner lists ride the same RQ-3 deferral. +// DefparamDeclaration / EventDeclaration / GenvarDeclaration each +// gained a non-empty list of per-entry sub-records (new +// DefparamAssignment Conj for Β§A.2.5 list_of_defparam_assignments; +// `event_names: List` for Β§A.2.1.4 list_of_event_identifiers; +// `genvar_names: List` for Β§A.2.1.1 list_of_genvar_ +// identifiers) β€” restoring the spec statement-boundary lost by the +// prior singular-entry shape. UdpInstantiation refactored to the +// same shared-header + non-empty-instance-list pattern as +// ModuleInstantiation, per Β§A.5.2 `udp_identifier [drive_strength] +// [delay2] udp_instance { , udp_instance } ;` β€” shared +// (udp_name, drive_strength, delay) clause + per-instance +// (instance_name, body_lexeme) UdpInstance entries. Codex's / +// openai-pro's motivation is spec-correct in each case; the FORM +// is the deferred refinement, not a verilog-local mint. // ───────────────────────────────────────────────────────────────────── @@ -2099,29 +2123,48 @@ type NamedPortConnection { // ───────────────────────────────────────────────────────────────────── // PortConnections β€” the closed Verilog port-binding-list form -// classifier (IEEE 1364-2005 Β§12.1.2). The spec admits exactly TWO -// port-connection forms; each module-instance picks ONE form for the -// entire instance (mixing positional and named in a single instance -// is forbidden by the grammar β€” `Adder a1 (x, .b(y))` is a syntax -// error). The Disj-with-named-payloads makes "mixed positional/named" -// structurally unrepresentable (codex BLOCKING fix on PR #3176 -// 2026-05-16: the prior NAMED-ONLY model had positional connections -// scope-negative, which excluded valid spec syntax and violated -// INVARIANTS P1 modeling-faithfulness). -// -// - PositionalConnections β€” `Adder a1 (sig1, sig2, sig3)` β€” -// actuals listed in declaration-order -// position; the i-th signal binds to -// the i-th port of the instantiated -// module. Spec Β§12.1.2 "Ordered port -// connections". +// classifier (IEEE 1364-2005 Β§12.1.2 / Β§A.4.1.1). The spec admits +// THREE forms per the Β§A.4.1.1 grammar: +// +// module_instance ::= name_of_instance ( [list_of_port_connections] ) ; +// list_of_port_connections ::= +// ordered_port_connection { , ordered_port_connection } +// | named_port_connection { , named_port_connection } +// +// where the `[list_of_port_connections]` brackets make the entire +// connection list OPTIONAL (`Adder a1 ();` β€” empty parens β€” is legal +// spec syntax), and when present the inner list is a NON-EMPTY list +// of ordered_port_connection OR a NON-EMPTY list of named_port_ +// connection β€” mixing the two is forbidden (`Adder a1 (x, .b(y))` +// is a syntax error). +// +// The empty `()` form is modeled as a STRUCTURAL `NoPortConnections` +// variant rather than as an `[]` empty list inside either of the +// other two variants β€” otherwise the empty connection-list state is +// representable TWO ways (positional-empty vs named-empty) and +// violates INVARIANTS P2 representation-duality (openai-pro +// REQUEST_CHANGES on PR #3176 2026-05-16 at line 2156). Sibling +// non-empty lists ride the established RQ-3 / std/collection.dag +// Wave-A2 `List where non_empty` deferral (see shared TRACKED- +// SCAFFOLD note above). +// +// - NoPortConnections β€” `Adder a1 ();` β€” empty parens; the +// spec's "[list_of_port_connections]" +// bracket-absent form. +// - PositionalConnections β€” `Adder a1 (sig1, sig2, sig3)` β€” +// actuals listed in declaration-order +// position; the i-th signal binds to +// the i-th port. Spec Β§12.1.2 +// "Ordered port connections". The +// `actuals` list is spec-non-empty. // - NamedConnections β€” `Adder a1 (.a(x), .b(y), .sum(z))` -// β€” actuals explicitly bound to formals -// by name. Spec Β§12.1.2 "Named port -// connections". +// β€” actuals explicitly bound to +// formals by name. Spec Β§12.1.2 +// "Named port connections". The +// `connections` list is spec-non-empty. // -// CLOSED (C1 stop-signal). IEEE 1364-2005 admits exactly these two -// port-connection forms; a third would be an edit to THIS declaration +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.4.1.1 admits exactly +// these three forms; a fourth would be an edit to THIS declaration // under the L-2 pin discipline (SystemVerilog adds `.port` shorthand // for `.port(port)` and `.*` for "connect all matching names" β€” a // future language-version model would EDIT this Disj explicitly). @@ -2130,32 +2173,45 @@ type NamedPortConnection { // 🟒 GREEN (terminal). Ledger β€” five patterns attempted: // 1. Fact placement β€” FAILS: every instance-emission consumer and // every port-binding resolver reads the connection form -// uniformly to know whether to align by position or by name; -// shared classifier, not scattered. +// uniformly to know whether to emit `()`, align by position, +// or align by name; shared classifier, not scattered. // 2. Variant-is-data β€” FAILS: collapsing the variants to a uniform // `List` where each entry has `kind: Form` // ratifies the illegal state "mixed positional+named within -// one instance" β€” exactly the spec-forbidden form. The -// Disj-with-heterogeneous-payloads makes the per-instance -// uniform-form choice structural. -// 3. Algebraic form β€” N/A by construction: the two forms are the -// IEEE 1364-2005 spec's primitive port-connection partition; -// they do not trace to a richer std/ algebraic structure. +// one instance" β€” exactly the spec-forbidden form. Replacing +// `NoPortConnections` with empty inner lists ratifies the +// double-spelling of `()`. Disj-with-heterogeneous-payloads- +// plus-nullary-empty-variant makes both partitions structural. +// 3. Algebraic form β€” N/A by construction: the three forms are +// the IEEE 1364-2005 Β§A.4.1.1 spec's primitive port-connection +// partition; they do not trace to a richer std/ algebraic +// structure. // 4. Dimensional β€” FAILS: a single module instance is EXACTLY -// ONE form; mutually-exclusive alternatives. (Mixed-form is a -// syntax error per spec.) -// 5. Parameterized family β€” FAILS: the two variants carry -// structurally heterogeneous payloads (PositionalConnections -// carries `List` β€” the actuals by -// position; NamedConnections carries -// `List` β€” each with formal+actual) β€” -// NOT one generic `F` / projection over a separately- -// declared source set (Practice 7). -// Terminal: the closed two-way Verilog port-connection-form -// classifier of the IEEE 1364-2005 spec. +// ONE form; mutually-exclusive alternatives. (Mixed-form and +// multi-form-per-instance are syntax errors per spec.) +// 5. Parameterized family β€” FAILS: the three variants carry +// structurally heterogeneous payloads (NoPortConnections is +// nullary; PositionalConnections carries +// `List`; NamedConnections carries +// `List`) β€” NOT one generic `F` +// projection over a separately-declared source set +// (Practice 7). +// Terminal: the closed three-way Verilog port-connection-form +// classifier of the IEEE 1364-2005 Β§A.4.1.1 spec. type PortConnections - = PositionalConnections { actuals: List } - | NamedConnections { connections: List } + = NoPortConnections + | PositionalConnections { + // 🟑 spec-non-empty (Β§A.4.1.1 ordered_port_connection list) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + actuals: List + } + | NamedConnections { + // 🟑 spec-non-empty (Β§A.4.1.1 named_port_connection list) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + connections: List + } // ───────────────────────────────────────────────────────────────────── @@ -2300,24 +2356,51 @@ type ModuleInstantiation { // ───────────────────────────────────────────────────────────────────── -// DefparamDeclaration β€” a Verilog `defparam` statement -// (`defparam top.sub.WIDTH = 8;`). IEEE 1364-2005 Β§12.2 + -// Β§4.10.2.1. Deprecated per spec but admitted. Conj record (no -// Practice-4 ledger). +// DefparamAssignment β€” one (target_path, value) pair in a `defparam` +// statement's defparam_assignment list (IEEE 1364-2005 Β§A.2.5: +// `defparam_assignment ::= hierarchical_parameter_identifier = +// mintypmax_expression`). Conj record (no Practice-4 ledger). // // - target_path the hierarchical target-parameter path as a // verbatim lexeme (sub-grammar deferred to the // T-4 LanguageModel β€” hierarchical identifier -// resolution is its concern) +// resolution is its concern). // - value_lexeme the override value as a verbatim expression -// lexeme (same body_lexeme precedent as -// ParameterDeclaration.default_lexeme) -type DefparamDeclaration { +// lexeme. +type DefparamAssignment { target_path: String value_lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// DefparamDeclaration β€” a Verilog `defparam` statement +// (`defparam top.sub.WIDTH = 8, top.sub.DEPTH = 16;`). IEEE 1364-2005 +// Β§12.2 + Β§A.2.5 (deprecated per spec but admitted). Per spec a +// single `defparam` statement carries a NON-EMPTY list of +// defparam_assignment entries: +// +// defparam_assignment_list ::= defparam_assignment +// { , defparam_assignment } ; +// +// The prior singular-entry shape lost the Β§12.2 statement-boundary +// (shared `defparam` keyword across multi-assignment forms) and made +// repeated DefparamDeclaration items in a module's ModuleItems +// ambiguous about whether two adjacent defparams came from one +// statement or two (openai-pro REQUEST_CHANGES on PR #3176 +// 2026-05-16 at line 2315). Conj record (no Practice-4 ledger). +// +// - assignments the non-empty list of defparam assignments +// declared under this single `defparam` +// statement. +type DefparamDeclaration { + // 🟑 spec-non-empty (Β§A.2.5 defparam_assignment list) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + assignments: List +} + + // ───────────────────────────────────────────────────────────────────── // GenerateRegion β€” a Verilog `generate ... endgenerate` block // (IEEE 1364-2005 Β§12.4, Β§12.1.3.3). Generate regions admit @@ -2439,26 +2522,58 @@ type FunctionDeclaration { // ───────────────────────────────────────────────────────────────────── -// EventDeclaration β€” a Verilog named-event declaration (`event ev;`). -// IEEE 1364-2005 Β§9.7.3 / Β§10.3. Named events are explicitly- -// triggered control-flow primitives (`-> ev;` triggers, `@ev` waits). -// Conj record (no Practice-4 ledger). +// EventDeclaration β€” a Verilog named-event declaration (`event ev1, +// ev2, ev3;`). IEEE 1364-2005 Β§9.7.3 / Β§10.3 / Β§A.2.1.4. Named events +// are explicitly-triggered control-flow primitives (`-> ev;` triggers, +// `@ev` waits). Per spec Β§A.2.1.4 grammar: +// +// event_declaration ::= event list_of_event_identifiers ; +// list_of_event_identifiers ::= event_identifier +// { , event_identifier } // -// - name the event identifier (K-1-opaque Symbol) +// a single `event` statement declares a NON-EMPTY list of event +// identifiers under a shared `event` keyword. The prior singular-name +// shape lost the Β§A.2.1.4 statement-boundary (shared `event` keyword +// across multi-identifier forms) β€” openai-pro REQUEST_CHANGES on +// PR #3176 2026-05-16 at line 2315 (grouped with DefparamDeclaration +// / GenvarDeclaration). Conj record (no Practice-4 ledger). +// +// - event_names the non-empty list of event identifiers (K-1- +// opaque Symbols) declared under this single +// `event` statement. type EventDeclaration { - name: Symbol + // 🟑 spec-non-empty (Β§A.2.1.4 list_of_event_identifiers) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + event_names: List } // ───────────────────────────────────────────────────────────────────── -// GenvarDeclaration β€” a Verilog `genvar` declaration (`genvar i;`). -// IEEE 1364-2005 Β§12.4.2. Generate variables drive elaboration-time -// loop iteration in `generate-for` constructs. Conj record (no -// Practice-4 ledger). +// GenvarDeclaration β€” a Verilog `genvar` declaration (`genvar i, j, +// k;`). IEEE 1364-2005 Β§12.4.2 / Β§A.2.1.1. Generate variables drive +// elaboration-time loop iteration in `generate-for` constructs. Per +// spec Β§A.2.1.1 grammar: // -// - name the genvar identifier (K-1-opaque Symbol) +// genvar_declaration ::= genvar list_of_genvar_identifiers ; +// list_of_genvar_identifiers ::= genvar_identifier +// { , genvar_identifier } +// +// a single `genvar` statement declares a NON-EMPTY list of genvar +// identifiers under a shared `genvar` keyword. The prior singular- +// name shape lost the Β§A.2.1.1 statement-boundary β€” openai-pro +// REQUEST_CHANGES on PR #3176 2026-05-16 at line 2315 (grouped with +// DefparamDeclaration / EventDeclaration). Conj record (no Practice-4 +// ledger). +// +// - genvar_names the non-empty list of genvar identifiers (K-1- +// opaque Symbols) declared under this single +// `genvar` statement. type GenvarDeclaration { - name: Symbol + // 🟑 spec-non-empty (Β§A.2.1.1 list_of_genvar_identifiers) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. + genvar_names: List } @@ -2586,25 +2701,71 @@ type GateInstantiation { } +// ───────────────────────────────────────────────────────────────────── +// UdpInstance β€” one (instance_name, port-list body) entry in a UDP +// instantiation's udp_instance list (IEEE 1364-2005 Β§A.5.2: +// `udp_instance ::= name_of_udp_instance ( output_terminal , +// input_terminal { , input_terminal } )`). Conj record (no Practice-4 +// ledger). +// +// - instance_name this instance's local name (K-1-opaque Symbol) +// - body_lexeme the per-instance terminal list (`( out , in1, +// in2, ... )`) as a verbatim lexeme; sub-grammar +// (output_terminal + input_terminal_list per +// Β§A.5.4) deferred to the bundled T-4 +// LanguageModel. +type UdpInstance { + instance_name: Symbol + body_lexeme: String +} + + // ───────────────────────────────────────────────────────────────────── // UdpInstantiation β€” a Verilog user-defined-primitive instantiation // (a UDP defined via `primitive ... endprimitive` at the file level // per IEEE 1364-2005 Β§8 is instantiated like a gate at the module- -// body level). Conj record (no Practice-4 ledger). +// body level). Per spec Β§A.5.2 grammar: +// +// udp_instantiation ::= udp_identifier [drive_strength] [delay2] +// udp_instance { , udp_instance } ; +// +// the spec form is ONE shared (udp_identifier + drive_strength + +// delay) clause followed by a NON-EMPTY list of udp_instance entries +// β€” multi-instance UDP statements share the statement's udp-name and +// strength/delay authority across all listed instances. The prior +// singular-instance shape lost the Β§A.5.2 statement-boundary (shared +// udp_identifier + shared strength/delay) for multi-instance forms +// (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 at line 2604; +// same shape as the ModuleInstantiation refactor above per +// Β§A.4.1.1). Conj record (no Practice-4 ledger). // // - udp_name the UDP identifier (K-1-opaque Symbol; // resolves through the namespace to the // matching file-level UdpDefinition β€” see // below; the UDP and Module sibling design- -// elements share the same name-space). -// - instance_name this instance's local name (K-1-opaque Symbol) -// - body_lexeme port list + drive strength + delay as a -// verbatim lexeme (sub-grammar deferred to the -// bundled T-4 LanguageModel) +// elements share the same name-space). Shared +// across all instances in this statement. +// - drive_strength optional drive_strength clause; reuses the +// DriveStrengthClause Disj shared with +// NetDeclaration / ContinuousAssign. Shared +// across all instances. +// - delay optional delay clause; reuses the DelayClause +// Disj. Per spec Β§A.5.2 this is `delay2` (rise/ +// fall) where net_declaration uses `delay3` +// (rise/fall/turn-off); the delay2-vs-delay3 +// sub-grammar distinction lives in the bundled +// T-4 LanguageModel productions. Shared across +// all instances. +// - instances the per-instance entries β€” each carries its +// own (instance_name, body_lexeme). type UdpInstantiation { udp_name: Symbol - instance_name: Symbol - body_lexeme: String + drive_strength: DriveStrengthClause + delay: DelayClause + // 🟑 spec-non-empty (Β§A.5.2 udp_instance list) β€” deferred to + // std/collection.dag Wave-A2 `List where non_empty` refinement; + // see shared TRACKED-SCAFFOLD note above. + instances: List } @@ -2953,9 +3114,57 @@ type ModuleParameterPortList | ModuleParameters { parameters: List } +// ───────────────────────────────────────────────────────────────────── +// ModuleKeyword β€” the closed Verilog module-declaration-keyword +// classifier (IEEE 1364-2005 Β§A.1.2): a module declaration begins +// with either `module` or `macromodule`. The two keywords select +// distinct simulator-elaboration semantics β€” `macromodule` requests +// the implementation to "treat the module as a macromodule" (a +// hint that the simulator MAY flatten the module's hierarchy for +// performance) while `module` is the standard hierarchical form. +// The two are syntactically distinct on the spec surface and +// `parse ∘ emit` must preserve which keyword the writer used +// (otherwise a `macromodule` declaration emitted as `module` +// silently loses a simulator hint β€” openai-pro REQUEST_CHANGES on +// PR #3176 2026-05-16 at line 3046). +// +// - ModuleKw β€” `module` β€” the standard module-declaration +// keyword. +// - MacromoduleKw β€” `macromodule` β€” the macromodule-declaration +// keyword. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.1.2 admits exactly the +// two keywords. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every module-emission consumer reads +// the keyword tag to choose `module` vs `macromodule`; shared +// classifier at the module-declaration boundary. +// 2. Variant-is-data β€” FAILS: a `{ is_macromodule: Bool }` proxy +// ratifies the K-1-forbidden Bool-as-keyword anti-pattern; a +// `{ keyword: Symbol }` proxy reopens the readable-string +// heuristic surface K-1 forecloses. The 2-variant Disj IS the +// dissolved form. +// 3. Algebraic form β€” N/A by construction: the two keywords are +// the IEEE 1364-2005 spec's irreducible module-keyword +// partition. +// 4. Dimensional β€” FAILS: a single module declaration uses +// EXACTLY ONE keyword; mutually-exclusive alternatives. +// 5. Parameterized family β€” FAILS: both variants are nullary; +// they are spec-distinct keyword identities, not a generic +// `F` projection over a richer source set (Practice 7). +// Terminal: the closed two-way Verilog module-declaration-keyword +// classifier of the IEEE 1364-2005 Β§A.1.2 spec. +type ModuleKeyword + = ModuleKw + | MacromoduleKw + + // ───────────────────────────────────────────────────────────────────── // VerilogModule β€” a top-level Verilog module (`module Name -// #(parameters) (ports); items endmodule`). IEEE 1364-2005 Β§12.1. +// #(parameters) (ports); items endmodule`, or `macromodule Name …`). +// IEEE 1364-2005 Β§12.1 / Β§A.1.2. // Per-style Disj β€” each variant carries its own header-port-list type // AND its own admissible body-items list type. The Β§12.3.4 module- // style partition is the dimensional axis of VerilogModule itself; @@ -3045,12 +3254,14 @@ type ModuleParameterPortList // codex BLOCKING on PR #3176 2026-05-16. type VerilogModule = NonAnsiVerilogModule { + module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, header_ports: List, items: List } | AnsiVerilogModule { + module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, header_ports: List, From 51b9d49cc305f8b67ee80e3641544c62d790eba5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 13:42:43 +0000 Subject: [PATCH 40/56] v4 T-4.9 verilog: delete orphaned PortAnsiTypeKind per codex non-blocking improvement on PR #3176 sha 6f587e6c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PortAnsiTypeKind was the predecessor generic 6-variant ANSI-port type/kind classifier. After the earlier direction-specific AnsiPortDeclaration split landed (AnsiInputPort + AnsiInoutPort using AnsiNetPortType for net-only; AnsiOutputPort using OutputPortAnsiTypeKind for the Β§12.3.3 output-admissible subset), PortAnsiTypeKind had zero field-position uses and existed only as a parallel-authority carrier modeling the same ANSI-port type/kind space as the direction-specific classifiers. Codex non-blocking improvement on PR #3176 sha 6f587e6c flagged the parallel-authority risk; deletion is the resolution. Deleted: the 84-line PortAnsiTypeKind type + ledger block. Updated: OutputPortAnsiTypeKind ledger patterns 2 and 5 rewritten to stand alone (no parent-set back-reference); AnsiPortDeclaration ledger commentary updated to drop PortAnsiTypeKind / AnsiRegType / AnsiIntegerType back-references. grep -c '🟑 spec-non-empty (Β§' invariant: 20 (unchanged, this commit is type-declaration cleanup only). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 172 ++++++++------------------- 1 file changed, 51 insertions(+), 121 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index eaade2af79d..bd32ea67c85 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1289,104 +1289,29 @@ type VariableDeclarator { // ───────────────────────────────────────────────────────────────────── -// PortAnsiTypeKind β€” the closed Verilog ANSI-port type/kind -// classifier (IEEE 1364-2005 Β§12.3.3, Β§5.6, Β§5.7). An ANSI-style port -// declares EITHER a net-type or a variable-kind; spec-admissibility -// of `packing` and `signedness` modifiers DIFFERS per variant β€” only -// net-types and `reg` admit them, the spec-fixed-width variable kinds -// (integer/real/time/realtime) forbid them. The kind Γ— packing Γ— sign -// admissibility is modeled STRUCTURALLY via Disj-with-heterogeneous- -// payloads: only the variants whose spec form admits packing/sign -// carry those payloads (codex BLOCKING fix on PR #3176 β€” the prior -// uniform `packing + signedness` on every ANSI-port admitted spec- -// forbidden states like `output integer signed [N:0]`, mirroring -// what the body-side VariableDeclaration Disj already dissolves). -// -// - AnsiNetType { net_type: NetType, packing: PackingShape, -// signedness: Signedness } -// β€” `input wire`, `output wand`, `inout tri0`, etc. Net ports -// admit any net-type from the closed NetType set, any -// PackingShape, and any signedness (per IEEE 1364-2005 Β§5.6). -// - AnsiRegType { packing: PackingShape, signedness: Signedness } -// β€” `output reg [N:0]`, `output reg signed`, etc. Reg-typed -// ANSI ports admit both packing and signedness (Β§5.6). -// - AnsiIntegerType -// β€” `output integer`. Spec-fixed 32-bit signed (Β§3.7.2); NO -// packing, NO signedness modifier. -// - AnsiRealType -// β€” `output real`. IEEE-754 double; NO packing, NO signedness -// (sign is internal to IEEE-754). -// - AnsiTimeType -// β€” `output time`. Spec-fixed 64-bit unsigned (Β§3.7.2); NO -// packing, NO signedness modifier. -// - AnsiRealTimeType -// β€” `output realtime`. Aliased to `real` per Β§3.7.2; NO -// packing, NO signedness modifier (parse∘emit preserves the -// keyword choice). -// -// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits this six- -// way ANSI-port type/kind partition; a future language-version model -// (SystemVerilog `logic`/`bit`/etc.) would EDIT this Disj explicitly. -// -// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: -// 1. Fact placement β€” FAILS: ANSI-port consumers branch on the -// kind uniformly to dispatch emission / type-check legality / -// eventual algebra inhabitance; shared classifier, not -// scattered. -// 2. Variant-is-data β€” FAILS: collapsing to a uniform `{ kind: -// Symbol, packing: PackingShape, signedness: Signedness }` -// record reopens BOTH (a) the readable-string K-1 heuristic -// surface AND (b) the spec-forbidden illegal states like -// "AnsiIntegerType with signedness=Signed" that the per-variant -// payload-presence rule dissolves. Disj-with-heterogeneous- -// payloads is the dissolved form (P2 + Practice 2/6 + M4) β€” -// same shape as body-side VariableDeclaration's kind Γ— packing -// Γ— signedness dissolution. -// 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ -// algebra structure (AnsiNetType / AnsiRegType β†’ Semiring or -// OrderedRing per packing Γ— signedness; AnsiIntegerType β†’ -// OrderedRing>; AnsiRealType / AnsiRealTimeType β†’ -// ApproximateField; AnsiTimeType β†’ Semiring>); -// D2-deferred per "Owned ELSEWHERE". -// 4. Dimensional β€” FAILS: an ANSI port has EXACTLY ONE type/kind; -// mutually-exclusive alternatives. The shapes differ across -// variants (net + reg carry packing+signedness; integer/real/ -// time/realtime carry neither) β€” they cannot be coordinates of -// a single record without the illegal-state smell. -// 5. Parameterized family β€” FAILS: the six are structurally -// heterogeneous in BOTH their payload shapes AND their -// algebraic groundings (Semiring/OrderedRing depending on -// packingΓ—signedness / OrderedRing> / ApproximateField -// / Semiring> / aliased ApproximateField β€” five -// distinct std/algebra groundings plus an additional NetType- -// payload-bearing variant). NOT one generic `F` / projection -// over a separately-declared source set (Practice 7). -// Terminal: the closed six-variant Verilog ANSI-port type/kind -// classifier; illegal kind Γ— packing / kind Γ— signedness combinations -// are unrepresentable by construction. -type PortAnsiTypeKind - = AnsiNetType { net_type: NetType, packing: PackingShape, signedness: Signedness } - | AnsiRegType { packing: PackingShape, signedness: Signedness } - | AnsiIntegerType - | AnsiRealType - | AnsiTimeType - | AnsiRealTimeType +// (PortAnsiTypeKind was DELETED on PR #3176 2026-05-16 per codex +// non-blocking improvement. The earlier generic-set carrier became +// orphaned once AnsiPortDeclaration adopted direction-specific +// payload types β€” input/inout use AnsiNetPortType, output uses +// OutputPortAnsiTypeKind. Keeping the unused 6-way generic carrier +// risked a parallel-authority drift between two carriers modeling +// the same ANSI-port type/kind space. The direction-specific +// classifiers below are the SOLE authority; future ANSI-port +// type/kind extensions (SystemVerilog `logic`, etc.) edit the +// direction-specific classifiers directly.) // ───────────────────────────────────────────────────────────────────── // OutputPortAnsiTypeKind β€” the closed Verilog ANSI-OUTPUT-port -// type/kind classifier. IEEE 1364-2005 Β§12.3.3 admits ALL six -// PortAnsiTypeKind variants for outputs MINUS real / realtime (the -// spec explicitly states "An output port can be of any net or -// variable type EXCEPT a real type" β€” floating-point types are not -// admitted as output ports because they have no well-defined -// inter-module wire representation). The OUTPUT-specific subset is -// modeled here; the spec-illegal AnsiRealType / AnsiRealTimeType -// outputs are unrepresentable by construction (codex BLOCKING fix on -// PR #3176 2026-05-16 β€” the prior AnsiOutputPort reused -// PortAnsiTypeKind directly, admitting `output real` / `output -// realtime` which the spec forbids). +// type/kind classifier. IEEE 1364-2005 Β§12.3.3: "An output port can +// be of any net or variable type EXCEPT a real type" β€” floating- +// point types are not admitted as output ports because they have no +// well-defined inter-module wire representation. The output-specific +// admissible four-way partition is modeled here; the spec-illegal +// real / realtime output variants are unrepresentable by construction +// (codex BLOCKING fix on PR #3176 2026-05-16 β€” the prior shape +// reused a generic-output-port carrier admitting `output real` / +// `output realtime` which the spec forbids). // // - OutputAnsiNetType { net_type: NetType, packing: PackingShape, // signedness: Signedness } @@ -1408,10 +1333,11 @@ type PortAnsiTypeKind // 1. Fact placement β€” FAILS: every output-port consumer reads the // kind to dispatch emission / type-check legality; shared // classifier, not scattered. -// 2. Variant-is-data β€” FAILS: reusing PortAnsiTypeKind directly -// (the prior shape) admits AnsiRealType / AnsiRealTimeType -// outputs β€” exactly the Β§12.3.3 illegal state this Disj -// dissolves. P2 illegal-states-unrepresentable. +// 2. Variant-is-data β€” FAILS: reusing a generic 6-variant output- +// port carrier (the prior shape, predecessor to the direction- +// specific split) admits `output real` / `output realtime` β€” +// exactly the Β§12.3.3 illegal state this Disj dissolves. P2 +// illegal-states-unrepresentable. // 3. Algebraic form β€” PARTIAL: each variant grounds in a std/ // algebra structure (OutputAnsiNetType / OutputAnsiRegType β†’ // Semiring or OrderedRing per packing Γ— signedness; @@ -1420,12 +1346,14 @@ type PortAnsiTypeKind // "Owned ELSEWHERE". // 4. Dimensional β€” FAILS: an ANSI output port has EXACTLY ONE // type/kind; mutually-exclusive alternatives. -// 5. Parameterized family β€” PARTIAL: this Disj is a SUBSET -// projection of PortAnsiTypeKind (the 6-variant general -// partition minus real/realtime). The projection is the spec's -// output-port-admissibility filter β€” not a generic `F` over -// a richer source set (Practice 7), because the real/realtime -// exclusion IS the partition's defining filter. +// 5. Parameterized family β€” FAILS: the four variants are +// structurally heterogeneous (OutputAnsiNetType carries net_type +// + packing + signedness; OutputAnsiRegType carries packing + +// signedness; OutputAnsiIntegerType + OutputAnsiTimeType are +// nullary). NOT one generic `F` projection over a richer +// source set (Practice 7); the real/realtime exclusion is the +// Β§12.3.3 spec's output-port-admissibility partition, not a +// derived projection. // Terminal: the closed four-way Verilog ANSI-output-port type/kind // classifier; real/realtime outputs unrepresentable by construction // per IEEE 1364-2005 Β§12.3.3. @@ -1570,13 +1498,13 @@ type AnsiNetPortType // β€” input ports are net-typed only (the spec forbids // `input reg`). // - AnsiOutputPort { name: Symbol, type_kind: OutputPortAnsiTypeKind } -// β€” output ports admit the OutputPortAnsiTypeKind subset (net, -// reg, integer, time per Β§12.3.3 β€” REAL / REALTIME outputs -// are excluded per spec). The closed 4-way subset is structural -// per the OutputPortAnsiTypeKind ledger below; corrected per -// codex BLOCKING on PR #3176 2026-05-16 β€” the prior reuse of -// the full 6-way PortAnsiTypeKind admitted spec-forbidden -// `output real` / `output realtime`. +// β€” output ports admit the OutputPortAnsiTypeKind 4-way set +// (net, reg, integer, time per Β§12.3.3 β€” REAL / REALTIME +// outputs are excluded per spec). The closed 4-way partition +// is structural per the OutputPortAnsiTypeKind ledger below; +// corrected per codex BLOCKING on PR #3176 2026-05-16 β€” the +// prior reuse of a generic 6-way ANSI-port carrier admitted +// spec-forbidden `output real` / `output realtime`. // - AnsiInoutPort { name: Symbol, net: AnsiNetPortType } // β€” inout ports are net-typed only (bidirectional requires // nets; `inout reg` is a spec violation). @@ -1592,22 +1520,24 @@ type AnsiNetPortType // legality / drive net-vs-reg-assignment-legality; shared // classifier, not scattered. // 2. Variant-is-data β€” FAILS: collapsing to a uniform -// `{ direction: PortDirection, name: Symbol, type_kind: -// PortAnsiTypeKind }` ratifies spec-forbidden combinations -// (Input + AnsiRegType, Inout + AnsiIntegerType, etc.) β€” the -// product-axis admits illegal states this per-direction Disj -// dissolves. INVARIANTS P2 illegal-states-unrepresentable. +// `{ direction: PortDirection, name: Symbol, type_payload: +// }` ratifies spec-forbidden +// combinations (Input + reg-typed payload, Inout + integer- +// typed payload, etc.) β€” the product-axis admits illegal states +// this per-direction Disj dissolves. INVARIANTS P2 illegal- +// states-unrepresentable. // 3. Algebraic form β€” N/A by construction: the three direction- // bearing ANSI forms are the spec's primitive direction Γ— type // admissibility table β€” not a richer std/ algebraic structure. // 4. Dimensional β€” FAILS: a single ANSI port is EXACTLY ONE // direction variant; mutually-exclusive alternatives. // 5. Parameterized family β€” FAILS: AnsiInputPort and AnsiInoutPort -// carry `net: AnsiNetPortType` (net-only); AnsiOutputPort -// carries `type_kind: PortAnsiTypeKind` (full type-kind set -// including reg/integer/real/time/realtime). The payload -// types differ structurally β€” NOT one generic `F` / -// projection over a single source set (Practice 7). +// carry `net: AnsiNetPortType` (net-only, 1-variant); AnsiOutputPort +// carries `type_kind: OutputPortAnsiTypeKind` (the 4-way output- +// admissible type-kind set: net / reg / integer / time). The +// payload types differ structurally β€” NOT one generic +// `F` projection over a single source set +// (Practice 7). // Terminal: the closed three-way Verilog ANSI-port direction-kind // classifier; illegal direction Γ— type-kind combinations are // unrepresentable by construction. From de7ddec02c0ccf22fb09ffdc7aa9ef33a0c18e88 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 10:34:12 -0400 Subject: [PATCH 41/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 246 +++++++++++++++++++++------ 1 file changed, 190 insertions(+), 56 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index bd32ea67c85..5bd74510610 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -554,46 +554,53 @@ type ProceduralAssignKind // ───────────────────────────────────────────────────────────────────── // VectorRange β€” a packed bit-vector index range `[msb:lsb]` -// (IEEE 1364-2005 Β§3.10). Conj record (no Practice-4 ledger β€” only -// coproducts dissolve). -// -// - msb, lsb the most- / least-significant bit positions -// -// 🟑 SCAFFOLD (same bridge as std/diagnostic.dag's `Extent.ByteRange` -// and ptx Dim3 raw-Int axes). With only kernel-ambient `Int` -// available at the T-4.9 phase, `{ msb: Int, lsb: Int }` -// STRUCTURALLY ADMITS some states the substrate cannot reject -// (extreme magnitudes far beyond any plausible bus width; degenerate -// gaps the spec doesn't formally forbid in the type system but that -// no synthesizable design uses). PER IEEE 1364-2005 Β§3.10, msb and -// lsb constant expressions ARE ALLOWED to be positive, negative, or -// zero β€” the spec explicitly admits `reg [-1:4] b;` as a legal -// example. Negative indices are NOT illegal; the prior scaffold -// bound forbidding them was a misstatement of the spec (openai-pro -// REQUEST_CHANGES on PR #3176 corrected this). The remaining -// scaffold property is that the refined substrate (when it lands) -// can carry per-axis precision and any synthesizable-subset checks -// the consumer tooling needs, while the spec-level value space β€” -// signed Int for msb/lsb β€” stays admissible. `[7:0]` is little- -// endian, `[0:7]` is big-endian, `[-1:4]` is signed-msb; -// all legal. It is a TRACKED scaffold, declared with the three -// bridge properties (the precedent diagnostic.dag established -// 2026-05-15): -// (a) scaffold doc β€” THIS note; the carrier is provisional. The -// bounded-Cardinality refinement is the terminal shape; for -// now the spec's full Int range is the producer-side bound. -// (b) bounds on use β€” a producer MUST construct only ranges -// admitted by IEEE 1364-2005 Β§3.10 (msb and lsb are any -// signed Int per spec; negative values are legal); until the -// substrate enforces additional per-synthesis-tool bounds, -// those tighter bounds (if any) are producer-side. -// (c) dissolution trigger β€” when std/cardinality.dag's refinement -// substrate lands (T-3, P4 decidability), `msb` / `lsb` become -// refined signed-Int axes (admitting the spec's full range -// including negatives), and this scaffold dissolves. +// (IEEE 1364-2005 Β§3.10 / Β§A.8.3). Conj record (no Practice-4 ledger β€” +// only coproducts dissolve). +// +// Per spec Β§A.8.3 grammar: +// +// range ::= [ constant_expression : constant_expression ] +// +// where `constant_expression` admits integer literals, constant- +// identifier references (e.g. `WIDTH`, parameter names), arithmetic +// (`WIDTH-1`, `1< where @@ -1059,9 +1127,8 @@ type NetDeclaration | NonTriregAssignForm { kind: NonTriregNetKind drive_strength: DriveStrengthClause - vectoredness: VectorednessClause + net_packing: NetVectoredPacking signedness: Signedness - packing: PackingShape delay: DelayClause // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_decl_assignments) β€” // deferred to std/collection.dag Wave-A2 `List where @@ -1070,9 +1137,8 @@ type NetDeclaration } | TriregIdentifierForm { charge_strength: ChargeStrengthClause - vectoredness: VectorednessClause + net_packing: NetVectoredPacking signedness: Signedness - packing: PackingShape delay: DelayClause // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_identifiers) β€” // deferred to std/collection.dag Wave-A2 `List where @@ -1081,9 +1147,8 @@ type NetDeclaration } | TriregAssignForm { drive_strength: DriveStrengthClause - vectoredness: VectorednessClause + net_packing: NetVectoredPacking signedness: Signedness - packing: PackingShape delay: DelayClause // 🟑 spec-non-empty (Β§A.2.1.3 list_of_net_decl_assignments) β€” // deferred to std/collection.dag Wave-A2 `List where @@ -1426,9 +1491,28 @@ type NonAnsiPort { // BLOCKING on PR #3176 2026-05-16 β€” the prior shape mis-located // PortDeclaration on the header port-list, conflating the spec's // header-vs-body partition. +// +// Per spec Β§A.2.1.2 grammar a single direction-only port_declaration +// admits a NON-EMPTY list of port identifiers under one shared +// direction keyword (`input a, b, c;` is one statement declaring +// three ports, not three statements). The prior singular-name shape +// lost the Β§A.2.1.2 statement-boundary (shared direction keyword +// across multi-identifier forms) β€” openai-pro REQUEST_CHANGES on +// PR #3176 2026-05-16 at line 1429; same shape as the +// DefparamDeclaration / EventDeclaration / GenvarDeclaration list- +// form precedent. +// +// - direction the port-direction keyword (input | output | +// inout); shared across all declared names in +// this statement. +// - names the non-empty list of declared port identifiers +// (K-1-opaque Symbols). type PortDeclaration { direction: PortDirection - name: Symbol + // 🟑 spec-non-empty (Β§A.2.1.2 list_of_port_identifiers) β€” deferred + // to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note below. + names: List } @@ -2144,21 +2228,71 @@ type PortConnections } +// ───────────────────────────────────────────────────────────────────── +// ParameterOverrideActual β€” the closed Verilog named-parameter- +// override actual classifier (IEEE 1364-2005 Β§A.4.1 named_parameter_ +// assignment). Per spec grammar: +// +// named_parameter_assignment ::= . parameter_identifier +// ( [ mintypmax_expression ] ) +// +// the `[ mintypmax_expression ]` brackets make the actual OPTIONAL β€” +// `.PARAM()` (blank parens) is legal spec syntax that documents the +// override list while retaining the parameter's declared default +// value. Modeling the actual as a mandatory String collapsed the +// spec's blank-actual form, making `.WIDTH()` unrepresentable +// (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 at line 2161). +// Sibling Disj of PortConnectionActual.BlankConnection β€” same shape +// for the same "optional sub-expression in a named binding" axis. +// +// - BlankParameterOverride +// β€” `.PARAM()` form: blank parens; retains the declared +// default. +// - ParameterOverrideExpression { lexeme: String } +// β€” `.PARAM(expr)` form: the override value as a verbatim +// mintypmax_expression lexeme; sub-grammar deferred to the +// bundled T-4 LanguageModel. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape +// as PortConnectionActual.BlankConnection; abbreviated for brevity +// (each pattern's argument is identical modulo "named-parameter" +// vs "ordered port-connection"). +// 1. Fact placement β€” FAILS: shared across instance-emission + +// parameter-resolution consumers. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected +// (same BlankConnection precedent argument). +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one actual state per binding. +// 5. Parameterized family β€” FAILS: BlankParameterOverride is +// nullary; ParameterOverrideExpression carries a `lexeme: +// String` payload β€” structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog named-parameter-override- +// actual classifier. +type ParameterOverrideActual + = BlankParameterOverride + | ParameterOverrideExpression { lexeme: String } + + // ───────────────────────────────────────────────────────────────────── // NamedParameterOverride β€” one named parameter override on a module -// instantiation (`.WIDTH(8)`). IEEE 1364-2005 Β§12.1.3. Conj record -// (no Practice-4 ledger). +// instantiation (`.WIDTH(8)`, `.PARAM()`). IEEE 1364-2005 Β§12.1.3 / +// Β§A.4.1. Conj record (no Practice-4 ledger). // // - parameter the formal parameter name on the instantiated // module (K-1-opaque Symbol; resolves to a matching -// ParameterDeclaration on the target module) -// - actual the override value as a verbatim lexeme (expression -// sub-grammar deferred to the T-4 LanguageModel β€” -// same precedent as PortConnectionActual / -// ParameterDeclaration.default_lexeme) +// ParameterDeclaration on the target module). +// - actual the override value as a closed Disj over the +// blank-vs-lexeme spec choice (ParameterOverrideActual +// above). Replaces the prior mandatory-String shape +// that collapsed the `.PARAM()` blank-actual form +// per openai-pro REQUEST_CHANGES on PR #3176 +// 2026-05-16. type NamedParameterOverride { parameter: Symbol - actual: String + actual: ParameterOverrideActual } From 0d6d71454b651f9f1e952ba50a6561137952fbe9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 14:38:08 +0000 Subject: [PATCH 42/56] v4 T-4.9 verilog: address openai-pro 7-pack BLOCKING inline reviews on PR #3176 sha cba903a3e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seven spec-right declaration-class spec-fidelity findings, all in- pattern, fixed in one bundle: 1. VectorRange (Β§A.8.3) β€” msb/lsb scaffold reshape from Int-pair to lexeme-pair (msb_lexeme/lsb_lexeme: String). Per Β§A.8.3 range ::= [constant_expression : constant_expression], constant_expression admits constant-identifier references (e.g. WIDTH), arithmetic (WIDTH-1), conditional, etc. β€” the Int-pair shape collapsed spec-legal parameterized declarations like reg [WIDTH-1:0] into unrepresentable states. Lexeme follows the established body_lexeme/rhs_lexeme/default_lexeme precedent; dissolution trigger updated: bundled T-4 LanguageModel constant_expression productions parse the lexeme into an AST (the bounded-Cardinality refinement was wrong-shape because it couldn't capture parameterized expressions). 2. NetDeclaration vectoredness Γ— range coupling (Β§A.2.1.3 / Β§3.7.1) β€” new NetVectoredPacking Disj couples vectoredness to range- presence structurally. Per Β§3.7.1: "The vectored keyword can be used only with a vector declaration." The prior independent vectoredness + packing fields admitted spec-illegal `wire vectored a;` (unranged-with-vectoredness); refactored all 4 NetDeclaration variants to carry `net_packing: NetVectoredPacking = NetUnranged | NetRanged { vectoredness, range: VectorRange }`, making the illegal state unrepresentable. 3. PortDeclaration (Β§A.2.1.2) β€” singular-name β†’ non-empty list-form mirroring the established Defparam/Event/Genvar pattern. `input a, b, c;` per Β§A.2.1.2 list_of_port_identifiers is one statement declaring multiple ports under a shared direction keyword; new site 21 in the spec-non-empty enumeration. 4. NamedParameterOverride (Β§A.4.1) β€” actual: String β†’ actual: ParameterOverrideActual (new 2-way Disj {BlankParameterOverride | ParameterOverrideExpression{lexeme}}). Per Β§A.4.1: named_ parameter_assignment ::= .parameter_identifier ( [mintypmax_ expression] ); the optional brackets make `.PARAM()` (blank actual, retain default) legal spec syntax. Sibling Disj of PortConnectionActual.BlankConnection. 5. ModuleInstance (Β§A.4.1.1) β€” added instance_range: InstanceRangeClause field. Per Β§A.4.1.1 name_of_module_instance ::= module_instance_identifier [range]; instance arrays like `Adder a[7:0] (...)` were unrepresentable. New InstanceRangeClause Disj (NoInstanceRange | InstanceRange{range: VectorRange}) reused by ModuleInstance + UdpInstanceName. 6. UdpInstance (Β§A.5.2) β€” reshape to optional name+range via new UdpInstanceName Disj. Per Β§A.5.2 udp_instance ::= [name_of_udp_instance] ( ... ) with name_of_udp_instance ::= udp_instance_identifier [range]; unnamed UDP instances (`xor (o, a, b)`) and instance arrays were both unrepresentable. New UdpInstanceName Disj (NoUdpInstanceName | NamedUdpInstance{name, instance_range: InstanceRangeClause}) carries both spec-legal forms. 7. AnsiModuleItem + NonAnsiModuleItem (Β§A.1.4 / Β§A.9.1) β€” added attributes: AttributeInstanceClause first field on each variant payload. Per Β§A.1.4 most module_or_generate_items admit {attribute_instance} prefix (e.g. `(* keep *) assign x = y;`); the prior shape made attributes unrepresentable except via unrelated lexeme leaks. New closed AttributeInstanceClause Disj (NoAttributeInstances | AttributeInstanceLexeme{lexeme}) carried per-variant on 20 AnsiModuleItem variants + 2 NonAnsiModuleItem variants (NonAnsiAnsiCompatItem inherits via its wrapped AnsiModuleItem). Shared NonEmptyList scaffold-note: "Twenty" β†’ "Twenty-one" sites, new site 21 (PortDeclaration.names) added with byte-identical 🟑 spec-non-empty marker. grep -c invariant: 21 (verified). File-header scaffold-residual prose updated: VectorRange now lexeme-pair-bridge to constant_expression sub-grammar, not raw-Int. All deferrals continue under established RQ-3 / std/collection.dag Wave-A2 disposition; NO verilog-local NonEmptyList carrier mint. NonEmptyList + design-element + LanguageModel-spine deferral notes intact. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 255 ++++++++++++++++++++++----- 1 file changed, 214 insertions(+), 41 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 5bd74510610..467b2600ff6 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -270,9 +270,10 @@ import v4.std.node { Symbol } // discipline.md Β§4 (operator-ratified binding 2026-05-15, gate (b); // PR #3163 made the 4-pattern miss the proof case β€” do not omit // Practice-7). Conj records carry no ledger (only coproducts -// dissolve); scaffold-residual raw-Int fields (VectorRange, VerilogCost) -// carry a 🟑 bridge note mirroring the std/diagnostic.dag / -// ptx Dim3 precedent. +// dissolve); scaffold-residual fields (VectorRange's lexeme-pair +// bridge to the constant_expression sub-grammar, VerilogCost's +// raw-Int axes) carry a 🟑 bridge note mirroring the std/ +// diagnostic.dag / ptx Dim3 precedent. // ───────────────────────────────────────────────────────────────────── @@ -891,6 +892,57 @@ type DelayClause | DelayLexeme { lexeme: String } +// ───────────────────────────────────────────────────────────────────── +// AttributeInstanceClause β€” the closed Verilog attribute_instance- +// list-presence classifier (IEEE 1364-2005 Β§A.9.1 / Β§A.1.4). Most +// syntactic constructs in Β§A.1.4 (module_items, generate_items, +// statements, declarations, port_declarations, expression operators) +// admit an OPTIONAL list of attribute_instance prefixes: +// +// attribute_instance ::= (* attr_spec { , attr_spec } *) +// attr_spec ::= attr_name [ = constant_expression ] +// +// Examples: `(* keep *) assign x = y;`, `(* synthesis_full_case *) +// always @(...) ...`, `(* dont_touch *) Adder a1 (...)`. The prior +// shape made attribute_instances unrepresentable on structured +// module_item carriers β€” they could only leak into unrelated lexeme +// payloads (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 at +// line 2884). The fix carries this Disj per-variant on +// AnsiModuleItem / NonAnsiModuleItem. +// +// - NoAttributeInstances +// β€” no `(* … *)` prefix on the item. +// - AttributeInstanceLexeme { lexeme: String } +// β€” one or more `(* attr_spec, … *)` prefixes as a verbatim +// lexeme; sub-grammar (the attr_name + constant_expression +// internal structure of each attribute_instance) deferred to +// the bundled T-4 LanguageModel via the established body_lexeme +// precedent. Multiple `(* a *)(* b *)` prefixes per spec are +// carried as one concatenated lexeme β€” the parser splits. +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape +// as DriveStrengthClause / DelayClause; abbreviated for brevity. +// 1. Fact placement β€” FAILS: shared across every module-item / +// generate-item / statement / declaration carrier; not +// scattered. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected +// (same BlankConnection precedent argument). +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one attribute-instance-list state per +// item; mutually exclusive (present vs absent at the boundary). +// 5. Parameterized family β€” FAILS: NoAttributeInstances is +// nullary; AttributeInstanceLexeme carries a `lexeme: String` +// payload β€” structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog attribute_instance-list +// classifier of the IEEE 1364-2005 Β§A.9.1 spec. +type AttributeInstanceClause + = NoAttributeInstances + | AttributeInstanceLexeme { lexeme: String } + + // ───────────────────────────────────────────────────────────────────── // VectorednessClause β€” the closed Verilog vectored/scalared // declaration-boundary classifier on a net_declaration (IEEE @@ -1701,7 +1753,7 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Twenty sites in this file carry `List` payloads where IEEE +// Twenty-one sites in this file carry `List` payloads where IEEE // 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty // state is structurally representable, the same INVARIANTS P2 // illegal-states-unrepresentable concern codex / openai-pro @@ -1728,16 +1780,16 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the twenty spec-non-empty sites keeps `List` for now. +// - Each of the twenty-one spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. // - DISSOLUTION TRIGGER: when `std/collection.dag` Wave-A2 lands the -// non-empty refinement, the twenty sites adopt +// non-empty refinement, the twenty-one sites adopt // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The twenty spec-non-empty sites (back-pointers to this note): +// The twenty-one spec-non-empty sites (back-pointers to this note): // 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) // 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) // 3. NetDeclaration.TriregIdentifierForm.identifiers (Β§A.2.1.3) @@ -1759,6 +1811,7 @@ type ParameterTypeKind // 18. EventDeclaration.event_names (Β§A.2.1.4) // 19. GenvarDeclaration.genvar_names (Β§A.2.1.1) // 20. UdpInstantiation.instances (Β§A.5.2) +// 21. PortDeclaration.names (Β§A.2.1.2) // // Sites previously numbered 7-9 added 2026-05-16 per codex // REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 @@ -1800,7 +1853,12 @@ type ParameterTypeKind // (udp_name, drive_strength, delay) clause + per-instance // (instance_name, body_lexeme) UdpInstance entries. Codex's / // openai-pro's motivation is spec-correct in each case; the FORM -// is the deferred refinement, not a verilog-local mint. +// is the deferred refinement, not a verilog-local mint. Site 21 +// added 2026-05-16 per openai-pro REQUEST_CHANGES on PR #3176 at +// sha cba903a3e (inline BLOCKING at line 1429): PortDeclaration +// reshape from singular-name to list-form mirrors the Defparam/ +// Event/Genvar list-form precedent under Β§A.2.1.2 list_of_port_ +// identifiers; the non-empty list rides the same RQ-3 deferral. // ───────────────────────────────────────────────────────────────────── @@ -2365,20 +2423,70 @@ type ParameterOverrides | NamedParameterOverrides { overrides: List } +// ───────────────────────────────────────────────────────────────────── +// InstanceRangeClause β€” the closed Verilog instance-array range +// classifier on a module / UDP instance (IEEE 1364-2005 Β§A.4.1.1 / +// Β§A.5.2): a single instance identifier may optionally carry a +// `[msb:lsb]` range to declare an ARRAY of instances (`Adder a[7:0] +// (...)`), elaborated to multiple bit-replicated instances at compile +// time. Sibling Disj of DriveStrengthClause / DelayClause / etc. β€” +// optional-clause present/absent partition. +// +// - NoInstanceRange +// β€” `Adder a1 (...)` form: single-instance declaration. +// - InstanceRange { range: VectorRange } +// β€” `Adder a[7:0] (...)` form: instance-array; the range +// drives elaboration-time instance replication. Reuses the +// VectorRange carrier (constant_expression-pair via lexeme). +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape +// as DriveStrengthClause / DelayClause; abbreviated for brevity. +// 1. Fact placement β€” FAILS: shared classifier across module- +// instance / UDP-instance emitters + elaboration-time +// replication consumers. +// 2. Variant-is-data β€” FAILS: empty-VectorRange sentinel +// reintroduces the spec-illegal "zero-width array" state and +// mixes the no-range form with a degenerate range form. +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one instance-range state per instance +// name; mutually exclusive. +// 5. Parameterized family β€” FAILS: NoInstanceRange is nullary; +// InstanceRange carries a `range: VectorRange` payload β€” +// structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog instance-array-range-presence +// classifier. Added 2026-05-16 per openai-pro REQUEST_CHANGES on +// PR #3176 β€” the prior shape dropped the optional range, making +// instance arrays unrepresentable. +type InstanceRangeClause + = NoInstanceRange + | InstanceRange { range: VectorRange } + + // ───────────────────────────────────────────────────────────────────── // ModuleInstance β€” one instance within a module_instantiation -// statement (`a1 (.a(x), .b(y), .sum(z))`). IEEE 1364-2005 Β§12.1 + -// Β§A.4.1.1. A single module_instantiation can declare MULTIPLE -// instances sharing a common (module_name, parameter_overrides); -// each instance carries its own (instance_name, port_connections). +// statement (`a1 (.a(x), .b(y), .sum(z))`, `a[7:0] (...)`). IEEE +// 1364-2005 Β§12.1 + Β§A.4.1.1. A single module_instantiation can +// declare MULTIPLE instances sharing a common (module_name, +// parameter_overrides); each instance carries its own (instance_name, +// optional instance-array range, port_connections). Per spec +// Β§A.4.1.1 `name_of_module_instance ::= module_instance_identifier +// [range]` β€” the prior shape dropped the optional range, making +// spec-legal `Adder a[7:0] (...)` instance arrays unrepresentable +// (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 at line 2247). // Conj record (no Practice-4 ledger). // // - instance_name this instance's local name (K-1-opaque Symbol) +// - instance_range optional instance-array range +// (NoInstanceRange | InstanceRange{range}) // - connections the port-binding list per spec Β§12.1.2 // (PositionalConnections OR NamedConnections; // uniform per instance). type ModuleInstance { instance_name: Symbol + instance_range: InstanceRangeClause connections: PortConnections } @@ -2766,20 +2874,70 @@ type GateInstantiation { // ───────────────────────────────────────────────────────────────────── -// UdpInstance β€” one (instance_name, port-list body) entry in a UDP -// instantiation's udp_instance list (IEEE 1364-2005 Β§A.5.2: -// `udp_instance ::= name_of_udp_instance ( output_terminal , -// input_terminal { , input_terminal } )`). Conj record (no Practice-4 -// ledger). +// UdpInstanceName β€” the closed Verilog UDP-instance name-of-instance +// classifier (IEEE 1364-2005 Β§A.5.2): +// +// udp_instance ::= [ name_of_udp_instance ] ( output_terminal , +// input_terminal +// { , input_terminal } ) +// name_of_udp_instance ::= udp_instance_identifier [ range ] +// +// the brackets around `name_of_udp_instance` make the entire name +// clause OPTIONAL β€” unnamed UDP instances are legal spec syntax +// (`xor ( o, a, b )` without an instance name). When present, the +// name itself may carry an optional instance-array range. The prior +// shape required `instance_name: Symbol` and dropped the range, +// making both spec-legal forms unrepresentable (openai-pro +// REQUEST_CHANGES on PR #3176 2026-05-16 at line 2648). +// +// - NoUdpInstanceName +// β€” `xor ( o, a, b )` form: no instance name; the spec's +// bracket-absent form. +// - NamedUdpInstance { name: Symbol, instance_range: InstanceRangeClause } +// β€” `xor x1 ( o, a, b )` / `xor x[7:0] ( o, a, b )` form: +// instance name present, optionally with an array range +// (reuses the shared InstanceRangeClause Disj). +// +// CLOSED (C1 stop-signal). Two-way name-present/absent partition. // -// - instance_name this instance's local name (K-1-opaque Symbol) +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: same shape +// as the optional-clause Disj family. +// 1. Fact placement β€” FAILS: shared across UDP-emitter + +// elaboration consumers reading the optional name. +// 2. Variant-is-data β€” FAILS: empty-Symbol sentinel rejected +// (same K-1 readable-string heuristic surface concern). +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one name-of-udp-instance state per +// udp_instance; mutually exclusive. +// 5. Parameterized family β€” FAILS: NoUdpInstanceName is nullary; +// NamedUdpInstance carries `{ name, instance_range }` payload β€” +// structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog UDP-instance name-of-instance +// classifier of the IEEE 1364-2005 Β§A.5.2 spec. +type UdpInstanceName + = NoUdpInstanceName + | NamedUdpInstance { name: Symbol, instance_range: InstanceRangeClause } + + +// ───────────────────────────────────────────────────────────────────── +// UdpInstance β€” one (optional-instance-name, port-list body) entry +// in a UDP instantiation's udp_instance list (IEEE 1364-2005 Β§A.5.2: +// `udp_instance ::= [name_of_udp_instance] ( output_terminal , +// input_terminal { , input_terminal } )`). The optional name (with +// optional array range when present) is carried via the +// UdpInstanceName Disj above. Conj record (no Practice-4 ledger). +// +// - instance_name optional name-of-udp-instance per Β§A.5.2 +// (NoUdpInstanceName | NamedUdpInstance{name, +// instance_range}). // - body_lexeme the per-instance terminal list (`( out , in1, // in2, ... )`) as a verbatim lexeme; sub-grammar // (output_terminal + input_terminal_list per // Β§A.5.4) deferred to the bundled T-4 // LanguageModel. type UdpInstance { - instance_name: Symbol + instance_name: UdpInstanceName body_lexeme: String } @@ -3015,27 +3173,42 @@ type SpecparamDeclaration { // declarations (`PortDeclarationItem` / `BodyPortDeclarationItem`) // are a SYNTAX ERROR in ANSI-style modules β€” they are admitted only // in the NonAnsiModuleItem set below. +// +// Per spec Β§A.1.4 / Β§A.6.1 most module_or_generate_items admit an +// `{ attribute_instance }` prefix (`(* keep *) assign net = expr;`, +// `(* synthesis_full_case *) always @(...) ...`, `(* dont_touch *) +// Adder a1 (...);`). The prior shape collapsed this fact β€” +// attribute_instances were unrepresentable except by leaking into +// unrelated lexeme payloads (openai-pro REQUEST_CHANGES on PR #3176 +// 2026-05-16 at line 2884). The fix: each variant carries an +// `attributes: AttributeInstanceClause` first field (closed Disj +// over the Β§A.9.1 attribute_instance-list-present/absent partition). +// Carried per-variant (rather than as a wrapping Conj outside the +// Disj) keeps the structural per-variant payload-heterogeneity that +// the Practice-4 ledger relies on, and mirrors the established +// per-variant clause-field convention (drive_strength, delay, +// etc.). type AnsiModuleItem - = ContinuousAssignItem { assign: ContinuousAssign } - | AlwaysBlockItem { always_block: AlwaysBlock } - | InitialBlockItem { initial_block: InitialBlock } - | NetDeclarationItem { net: NetDeclaration } - | VariableDeclarationItem { variable: VariableDeclaration } - | ParameterDeclarationItem { parameter: ParameterDeclaration } - | LocalParameterDeclarationItem { local_parameter: LocalParameterDeclaration } - | ModuleInstantiationItem { instantiation: ModuleInstantiation } - | DefparamDeclarationItem { defparam: DefparamDeclaration } - | GenerateRegionItem { generate_region: GenerateRegion } - | LoopGenerateConstructItem { loop_generate: LoopGenerateConstruct } - | ConditionalGenerateConstructItem { conditional_generate: ConditionalGenerateConstruct } - | SpecifyBlockItem { specify_block: SpecifyBlock } - | TaskDeclarationItem { task: TaskDeclaration } - | FunctionDeclarationItem { function_decl: FunctionDeclaration } - | EventDeclarationItem { event_decl: EventDeclaration } - | GenvarDeclarationItem { genvar_decl: GenvarDeclaration } - | GateInstantiationItem { gate: GateInstantiation } - | UdpInstantiationItem { udp_instance: UdpInstantiation } - | SpecparamDeclarationItem { specparam: SpecparamDeclaration } + = ContinuousAssignItem { attributes: AttributeInstanceClause, assign: ContinuousAssign } + | AlwaysBlockItem { attributes: AttributeInstanceClause, always_block: AlwaysBlock } + | InitialBlockItem { attributes: AttributeInstanceClause, initial_block: InitialBlock } + | NetDeclarationItem { attributes: AttributeInstanceClause, net: NetDeclaration } + | VariableDeclarationItem { attributes: AttributeInstanceClause, variable: VariableDeclaration } + | ParameterDeclarationItem { attributes: AttributeInstanceClause, parameter: ParameterDeclaration } + | LocalParameterDeclarationItem { attributes: AttributeInstanceClause, local_parameter: LocalParameterDeclaration } + | ModuleInstantiationItem { attributes: AttributeInstanceClause, instantiation: ModuleInstantiation } + | DefparamDeclarationItem { attributes: AttributeInstanceClause, defparam: DefparamDeclaration } + | GenerateRegionItem { attributes: AttributeInstanceClause, generate_region: GenerateRegion } + | LoopGenerateConstructItem { attributes: AttributeInstanceClause, loop_generate: LoopGenerateConstruct } + | ConditionalGenerateConstructItem { attributes: AttributeInstanceClause, conditional_generate: ConditionalGenerateConstruct } + | SpecifyBlockItem { attributes: AttributeInstanceClause, specify_block: SpecifyBlock } + | TaskDeclarationItem { attributes: AttributeInstanceClause, task: TaskDeclaration } + | FunctionDeclarationItem { attributes: AttributeInstanceClause, function_decl: FunctionDeclaration } + | EventDeclarationItem { attributes: AttributeInstanceClause, event_decl: EventDeclaration } + | GenvarDeclarationItem { attributes: AttributeInstanceClause, genvar_decl: GenvarDeclaration } + | GateInstantiationItem { attributes: AttributeInstanceClause, gate: GateInstantiation } + | UdpInstantiationItem { attributes: AttributeInstanceClause, udp_instance: UdpInstantiation } + | SpecparamDeclarationItem { attributes: AttributeInstanceClause, specparam: SpecparamDeclaration } // ───────────────────────────────────────────────────────────────────── @@ -3110,8 +3283,8 @@ type AnsiModuleItem // codex BLOCKING on PR #3176 2026-05-16. type NonAnsiModuleItem = NonAnsiAnsiCompatItem { item: AnsiModuleItem } - | NonAnsiPortDeclarationItem { port_decl: PortDeclaration } - | NonAnsiBodyPortDeclarationItem { body_port: AnsiPortDeclaration } + | NonAnsiPortDeclarationItem { attributes: AttributeInstanceClause, port_decl: PortDeclaration } + | NonAnsiBodyPortDeclarationItem { attributes: AttributeInstanceClause, body_port: AnsiPortDeclaration } // ───────────────────────────────────────────────────────────────────── From 4ccc626751c734148095248080e753966bbbdc4f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 14:43:37 +0000 Subject: [PATCH 43/56] v4 T-4.9 verilog: address codex scheduled-review extensions on PR #3176 sha 51b9d49c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex scheduled review at sha 51b9d49c flagged 7 BLOCKINGs; 5 of 7 mapped 1:1 to the openai-pro inline BLOCKINGs already addressed in HEAD 0d6d71454 (the 7-pack fix). The remaining 2 codex findings extend scope on items I already touched: 1. Finding E ("instance naming ... reuse at module/UDP/gate boundaries"): module + UDP already reshaped in 0d6d71454. For gates, the per-gate-class shape matrix at Β§A.5.4 (cmos_switch forbids drive_strength but allows delay3; n_input/n_output admit delay2 not delay3; pass_switch forbids both; etc.) forbids a uniform structural per-instance carrier at the GateInstantiation level β€” a uniform carrier would re-introduce the admit-then-check anti-pattern on the gate-kind Γ— clause-admissibility product. The per-instance name_of_gate_instance + range + per-class strength/delay structural extraction lives inside body_lexeme, riding the established UdpDefinition.body_lexeme / AlwaysBlock. body_lexeme sub-grammar deferral precedent. Updated GateInstantiation comment block to document the spec mapping explicitly + cite the Β§A.5.4 admissibility-matrix reason for the deferral. 2. Finding G ("attribute_instance at item/declaration/CONNECTION boundaries"): AnsiModuleItem + NonAnsiModuleItem item-boundaries already covered in 0d6d71454. Connection-boundary extension: - PortConnectionActual.ExpressionConnection gains `attributes: AttributeInstanceClause` - PortConnectionActual.BlankConnection gains `attributes: AttributeInstanceClause` - NamedPortConnection (Conj) gains `attributes: AttributeInstanceClause` Per Β§A.4.1.1 `named_port_connection ::= { attribute_instance } . port_identifier ( [expression] )` and `ordered_port_connection ::= { attribute_instance } [expression]` β€” both connection forms admit the prefix. Reuses the AttributeInstanceClause Disj introduced in 0d6d71454. Findings A, B, C, D, F map 1:1 to openai-pro inlines already in 0d6d71454 β€” no new fixes needed. NonEmptyList scaffold-note unchanged (no new list sites). grep -c '🟑 spec-non-empty (Β§' invariant: 21 (unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 48 ++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 467b2600ff6..dc54bd3394b 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -2166,8 +2166,8 @@ type InitialBlock { // classifier; the expression sub-grammar is deferred to T-4 // LanguageModel. type PortConnectionActual - = ExpressionConnection { expression_lexeme: String } - | BlankConnection + = ExpressionConnection { attributes: AttributeInstanceClause, expression_lexeme: String } + | BlankConnection { attributes: AttributeInstanceClause } // ───────────────────────────────────────────────────────────────────── @@ -2188,6 +2188,7 @@ type PortConnectionActual // PR #3176 to admit the full spec-mandated set of // expression actuals + blank. type NamedPortConnection { + attributes: AttributeInstanceClause port: Symbol actual: PortConnectionActual } @@ -2854,19 +2855,46 @@ type PrimitiveGateKind // ───────────────────────────────────────────────────────────────────── // GateInstantiation β€” a Verilog built-in primitive instantiation // (`and g1(out, a, b);` / `not n1(o, i);` / `bufif1 b1(out, in, en);`, -// etc.). IEEE 1364-2005 Β§7. Conj record (no Practice-4 ledger). +// etc.). IEEE 1364-2005 Β§7 / Β§A.5.4. Conj record (no Practice-4 ledger). // // - gate_kind which built-in primitive gate (PrimitiveGateKind // closed Disj; replaces the prior free-String // gate_keyword that admitted spec-illegal // keywords β€” M4 / INVARIANTS P2 fix per codex -// BLOCKING on PR #3176) -// - body_lexeme instance name + terminal list + drive-strength -// + delay control as a verbatim lexeme (sub- -// grammar deferred β€” the per-primitive terminal -// arity / drive strength / delay control -// admissibility lives in the bundled T-4 -// LanguageModel productions) +// BLOCKING on PR #3176). +// - body_lexeme THE ENTIRE statement body after the gate- +// keyword (per-gate-class drive_strength / +// delay clauses + non-empty list of +// gate_instance entries, where each +// gate_instance carries an optional +// name_of_gate_instance (`identifier [range]`) +// plus its per-instance terminal list) as a +// verbatim lexeme. Sub-grammar deferred to the +// bundled T-4 LanguageModel β€” the per-gate- +// class admissibility table (cmos_switch_type +// forbids drive_strength but allows delay3; +// enable_gatetype allows both; pass_switchtype +// forbids both; n_input_gatetype admits delay2 +// not delay3; etc., per Β§A.5.4) is exactly the +// class-specific grammar productions that owner +// models. The per-instance name_of_gate_ +// instance + range structural extraction +// (codex non-blocking flag re: "name_of_instance +// carrier reuse at gate boundaries") rides this +// SAME sub-grammar deferral β€” the per-gate- +// class shape matrix forbids a uniform +// structural carrier at the GateInstantiation +// level (it would re-introduce admit-then-check +// on the gate-kind Γ— clause admissibility +// product), so the per-instance facts live +// inside body_lexeme until the LanguageModel +// productions structurally encode each +// gate-class's instance shape. Same body_lexeme +// precedent as UdpDefinition.body_lexeme + +// AlwaysBlock.body_lexeme β€” sub-grammar +// defer-via-lexeme is the established pattern +// for spec sub-productions owned by the +// bundled LanguageModel. type GateInstantiation { gate_kind: PrimitiveGateKind body_lexeme: String From a1f45b4f2b7a823e115f76f99aef9105cc540e11 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 11:26:42 -0400 Subject: [PATCH 44/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 137 ++++++++++++++++++++------- 1 file changed, 105 insertions(+), 32 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index dc54bd3394b..5f6dd9eaa7d 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1361,37 +1361,66 @@ type VariableDeclaration // ───────────────────────────────────────────────────────────────────── -// VariableDeclarator β€” one (name, optional-unpacked-dimensions, -// optional-initializer) triple in a variable declaration's +// VariableDeclarator β€” one entry in a variable declaration's // list_of_variable_decl_assignments (IEEE 1364-2005 Β§A.2.4 / Β§3.10). -// A single declaration like `reg [7:0] a = 8'h00, mem[0:1023], c = -// 4'hF;` carries THREE VariableDeclarators (the second of which has -// an unpacked-array dimensions clause). Conj record (no Practice-4 -// ledger). +// Per spec grammar `variable_type` is either `variable_identifier +// { dimension }` (named-with-optional-unpacked-dimensions) OR +// `variable_identifier = constant_expression` (initialized) β€” +// MUTUALLY EXCLUSIVE alternatives, not independent coordinates. The +// prior {name, unpacked_dimensions, initializer} product shape +// admitted the spec-illegal `reg mem[0:1023] = 8'h00` combined +// dimensions+initializer state (openai-pro REQUEST_CHANGES on +// PR #3176 sha 4ccc6267 β€” VariableDeclarator product-shape admits +// illegal states). Split into a closed Disj over the two Β§A.2.4 +// alternatives makes the spec-illegal combined state structurally +// unrepresentable (INVARIANTS P2). +// +// A single declaration like `reg [7:0] a, mem[0:1023], c = 4'hF;` +// carries THREE VariableDeclarators (one NamedVariable per the first +// two names; one InitializedVariable for the last). The Β§7.4 PACKED +// dimensions stay on RegVariable's shared `packing` field at the +// outer level β€” those are TYPE-level, not declarator-level. +// +// - NamedVariable +// β€” `reg a;` / `reg mem[0:1023];` form: identifier with +// OPTIONAL unpacked-array dimensions; NO initializer. +// - InitializedVariable +// β€” `reg c = 4'hF;` form: identifier with REQUIRED initializer +// expression; NO unpacked-array dimensions. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.2.4 admits exactly the +// two variable_type alternatives. // -// - name the variable identifier (K-1- -// opaque Symbol) -// - unpacked_dimensions_lexeme the optional unpacked-array -// dimensions as a verbatim lexeme -// (`[0:1023]`, `[0:15][0:7]`); "" -// denotes a scalar (no unpacked -// array). Per spec Β§7.4 a variable -// can carry both PACKED dimensions -// (on the type β€” RegVariable's -// shared packing field) and UNPACKED -// dimensions (per-declarator β€” -// this field). Sub-grammar deferred -// to T-4 LanguageModel. -// - initializer_lexeme the variable_decl_assignment -// initializer expression as a -// verbatim lexeme; "" denotes the -// absent-initializer form. Sub- -// grammar deferred. -type VariableDeclarator { - name: Symbol - unpacked_dimensions: UnpackedDimensionsClause - initializer: VariableInitializerClause -} +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every variable-declaration emitter +// and elaboration consumer reads the per-declarator form +// uniformly; shared classifier. +// 2. Variant-is-data β€” FAILS: a `{ unpacked_dimensions, +// initializer }` product (prior shape) admits the Β§A.2.4 +// spec-illegal combined dimensions+initializer state β€” exactly +// the P2 illegal-states-representable concern this Disj +// dissolves. +// 3. Algebraic form β€” N/A by construction: the two alternatives +// are the spec's Β§A.2.4 irreducible partition. +// 4. Dimensional β€” FAILS: a single variable_decl_assignment is +// EXACTLY ONE form; mutually exclusive alternatives. +// 5. Parameterized family β€” FAILS: NamedVariable carries +// `unpacked_dimensions: UnpackedDimensionsClause`; +// InitializedVariable carries `initializer: +// VariableInitializerClause` β€” structurally heterogeneous +// (Practice 7). +// Terminal: the closed two-way Verilog variable_decl_assignment +// alternative classifier of the IEEE 1364-2005 Β§A.2.4 spec. +type VariableDeclarator + = NamedVariable { + name: Symbol + unpacked_dimensions: UnpackedDimensionsClause + } + | InitializedVariable { + name: Symbol + initializer_lexeme: String + } // (PortDeclarationStyle has been dissolved into ModulePortsList's @@ -1678,9 +1707,53 @@ type AnsiNetPortType // classifier; illegal direction Γ— type-kind combinations are // unrepresentable by construction. type AnsiPortDeclaration - = AnsiInputPort { name: Symbol, net: AnsiNetPortType } - | AnsiOutputPort { name: Symbol, type_kind: OutputPortAnsiTypeKind } - | AnsiInoutPort { name: Symbol, net: AnsiNetPortType } + = AnsiInputPort { + attributes: AttributeInstanceClause + net: AnsiNetPortType + // 🟑 spec-non-empty (Β§A.1.3 list_of_port_identifiers) β€” deferred + // to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note below. + names: List + } + | AnsiOutputPort { + attributes: AttributeInstanceClause + type_kind: OutputPortAnsiTypeKind + // 🟑 spec-non-empty (Β§A.1.3 list_of_variable_port_identifiers / + // list_of_port_identifiers) β€” deferred to std/collection.dag + // Wave-A2 `List where non_empty` refinement; see shared + // TRACKED-SCAFFOLD note below. + names: List + } + | AnsiInoutPort { + attributes: AttributeInstanceClause + net: AnsiNetPortType + // 🟑 spec-non-empty (Β§A.1.3 list_of_port_identifiers) β€” deferred + // to std/collection.dag Wave-A2 `List where non_empty` + // refinement; see shared TRACKED-SCAFFOLD note below. + names: List + } + + +// ───────────────────────────────────────────────────────────────────── +// AnsiOutputPortDeclarator β€” one (name, optional-initializer) entry +// in an ANSI output port's list_of_variable_port_identifiers (IEEE +// 1364-2005 Β§A.1.3 / Β§A.2.3). Per spec list_of_variable_port_ +// identifiers ::= port_identifier [ = constant_expression ] { , +// port_identifier [ = constant_expression ] } β€” each output-port +// identifier admits an OPTIONAL initializer. Only ANSI output ports +// reach this carrier; input/inout ports use plain `List` +// because the spec form list_of_port_identifiers does NOT admit +// per-port initializers. Conj record (no Practice-4 ledger). +// +// - name the declared port identifier (K-1-opaque +// Symbol). +// - initializer the optional initializer clause (reuses +// VariableInitializerClause); structurally +// optional per the Β§A.2.3 brackets. +type AnsiOutputPortDeclarator { + name: Symbol + initializer: VariableInitializerClause +} // (The standalone ModulePortsList Disj has been dissolved into From 7709c996871738af7d60db33661ab5961c87c5ed Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 15:31:07 +0000 Subject: [PATCH 45/56] v4 T-4.9 verilog: address openai-pro 5-pack on-HEAD verdict BLOCKINGs on PR #3176 sha 4ccc6267 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro's first genuine on-HEAD verdict (4ccc6267) flagged 5 BLOCKINGs. All spec-right declaration-class spec-fidelity findings; 4 mechanical extensions + 1 self-correction of a 4ccc6267 regression: 1. AnsiPortDeclaration multi-name + attributes (Β§A.1.3) β€” all 3 ANSI port direction variants reshape from single-name carriers to non-empty name lists with attribute-instance prefix: - AnsiInputPort/AnsiInoutPort: `List` per list_of_port_identifiers - AnsiOutputPort: `List` per list_of_variable_port_identifiers β€” output variable-ports admit per-port initializers via the existing VariableInitializerClause - All 3 variants gain `attributes: AttributeInstanceClause` The prior single-name-no-attributes shape dropped Β§A.1.3 declaration-boundary facts (multi-identifier statement, attribute prefix). New AnsiOutputPortDeclarator Conj for the output-variant- specific per-port-initializer fact. Sites 22-24 in the spec-non- empty enumeration. 2. VariableDeclarator product β†’ Disj split (Β§A.2.4) β€” prior `{name, unpacked_dimensions, initializer}` product admitted the spec-illegal `reg mem[0:1023] = 8'h00` combined state. Per spec `variable_type ::= identifier { dimension } | identifier = constant_expression` is mutually exclusive. Split into closed Disj `NamedVariable {name, unpacked_dimensions} | InitializedVariable {name, initializer_lexeme}` with full Practice-4 ledger; the InitializedVariable's lexeme is unconditional (not optional) since variant identity = initializer-present (no admit-then-check on a NoInitializer state). 3. NetIdentifierDeclarator + EventDeclaration per-identifier dimensions (Β§A.2.3 / Β§A.2.1.4) β€” both spec productions allow per-identifier `[ dimension { dimension } ]` suffix. NetIdentifierDeclarator gained `unpacked_dimensions: UnpackedDimensionsClause` (reuses existing Disj). EventDeclaration replaced `event_names: List` with `event_declarators: List` where new EventDeclarator Conj carries {name, unpacked_dimensions}. 4. PortConnectionActual / NamedPortConnection β€” fix self-introduced regression at 4ccc62675. The codex-extension commit added attributes on BOTH PortConnectionActual variants AND NamedPortConnection wrapper, creating double-authority for named connections. openai-pro correctly flagged the violation of single-authority. Resolution: strip attributes from PortConnectionActual (the inner blank-vs-expression Disj is shared between ordered and named forms; attributes live at the OUTER wrapping level per Β§A.4.1.1 grammar), and introduce a new OrderedPortConnection Conj wrapper for the positional case that mirrors NamedPortConnection's outer-attribute placement. `PortConnections.PositionalConnections.actuals` now carries `List` instead of `List`. 5. SpecparamAssignment Disj (Β§A.2.4) β€” prior SpecparamDeclaration reused ParameterAssignment, forcing every specparam to claim a `name + value_lexeme` shape and making pulse_control_specparam (the `PATHPULSE$...` form) unrepresentable as a structural variant. Per spec `specparam_assignment ::= identifier = constant_mintypmax_expression | pulse_control_specparam`. New `SpecparamAssignment = NamedSpecparamAssignment{name, value_lexeme} | PulseControlSpecparam{lexeme}` closed Disj with full Practice-4 ledger. SpecparamDeclaration.assignments now carries `List`. ParameterAssignment still validly consumed by ParameterDeclaration + LocalParameterDeclaration (regular parameter declarations use the `name = expr` form). Shared NonEmptyList scaffold-note: "Twenty-one" β†’ "Twenty-four" sites; new sites 22-24 (the three ANSI port name-lists). grep -c '🟑 spec-non-empty (Β§' invariant: 24 (verified). All deferrals continue under established RQ-3 / std/collection.dag Wave-A2; no verilog-local NonEmptyList mint. Stale commentary references to old shapes (singular-name AnsiPortDeclaration variants, Symbol-only EventDeclaration event_names) updated. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 264 +++++++++++++++++++++------ 1 file changed, 211 insertions(+), 53 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 5f6dd9eaa7d..da246fe86bf 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1236,17 +1236,26 @@ type NetAssignmentDeclarator { // ───────────────────────────────────────────────────────────────────── // NetIdentifierDeclarator β€” one element of a net_declaration's // list_of_net_identifiers (IEEE 1364-2005 Β§A.2.3 / Β§A.2.1.3 -// identifier-only form). Carries ONLY the net identifier: the -// identifier-only spec form forbids initializers structurally -// (openai-pro REQUEST_CHANGES on PR #3176 2026-05-16 β€” making -// "identifier-only-with-initializer" unrepresentable rather than a -// runtime check). A single `wire [7:0] a, b, c;` carries THREE -// NetIdentifierDeclarators. Conj record (no Practice-4 ledger). +// identifier-only form). Carries the net identifier and optional +// unpacked-array dimensions: the identifier-only spec form forbids +// initializers structurally (openai-pro REQUEST_CHANGES on PR #3176 +// 2026-05-16 β€” making "identifier-only-with-initializer" +// unrepresentable rather than a runtime check). Per Β§A.2.3: +// `net_identifier [ dimension { dimension } ]` β€” each identifier +// admits an OPTIONAL unpacked-array dimension suffix +// (openai-pro REQUEST_CHANGES on PR #3176 sha 4ccc6267 added this +// field; the prior shape dropped the per-identifier dimensions fact). +// A single `wire [7:0] a, b[0:1023], c;` carries THREE +// NetIdentifierDeclarators (the second with unpacked dimensions). +// Conj record (no Practice-4 ledger). // -// - name the declared net identifier (K-1-opaque -// Symbol). +// - name the declared net identifier (K-1-opaque +// Symbol). +// - unpacked_dimensions optional unpacked-array dimensions per +// Β§A.2.3 (reuses UnpackedDimensionsClause). type NetIdentifierDeclarator { name: Symbol + unpacked_dimensions: UnpackedDimensionsClause } @@ -1659,20 +1668,33 @@ type AnsiNetPortType // illegal combinations structurally unrepresentable, mirroring the // VariableDeclaration kindΓ—packingΓ—signedness dissolution). // -// - AnsiInputPort { name: Symbol, net: AnsiNetPortType } +// - AnsiInputPort { attributes, net: AnsiNetPortType, +// names: List } // β€” input ports are net-typed only (the spec forbids -// `input reg`). -// - AnsiOutputPort { name: Symbol, type_kind: OutputPortAnsiTypeKind } +// `input reg`); names form a Β§A.1.3 list_of_port_identifiers. +// - AnsiOutputPort { attributes, type_kind: OutputPortAnsiTypeKind, +// names: List } // β€” output ports admit the OutputPortAnsiTypeKind 4-way set // (net, reg, integer, time per Β§12.3.3 β€” REAL / REALTIME -// outputs are excluded per spec). The closed 4-way partition -// is structural per the OutputPortAnsiTypeKind ledger below; -// corrected per codex BLOCKING on PR #3176 2026-05-16 β€” the -// prior reuse of a generic 6-way ANSI-port carrier admitted -// spec-forbidden `output real` / `output realtime`. -// - AnsiInoutPort { name: Symbol, net: AnsiNetPortType } +// outputs are excluded per spec). Names form a Β§A.1.3 +// list_of_variable_port_identifiers (each declarator admits +// an optional initializer for variable-typed output ports). +// The closed 4-way partition is structural per the +// OutputPortAnsiTypeKind ledger below; corrected per codex +// BLOCKING on PR #3176 2026-05-16 β€” the prior reuse of a +// generic 6-way ANSI-port carrier admitted spec-forbidden +// `output real` / `output realtime`. +// - AnsiInoutPort { attributes, net: AnsiNetPortType, +// names: List } // β€” inout ports are net-typed only (bidirectional requires -// nets; `inout reg` is a spec violation). +// nets; `inout reg` is a spec violation); names form a +// Β§A.1.3 list_of_port_identifiers. +// +// All three variants gained an `attributes: AttributeInstanceClause` +// prefix and a non-empty `names` list at sha 4ccc6267 per openai-pro +// REQUEST_CHANGES (Layer-Model BLOCKING) β€” the prior single-name-no- +// attributes shape dropped Β§A.1.3 attribute-instance and +// list_of_port_identifiers declaration-boundary facts. // // CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits exactly // these three direction-bearing ANSI-port forms; SystemVerilog @@ -1826,7 +1848,7 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Twenty-one sites in this file carry `List` payloads where IEEE +// Twenty-four sites in this file carry `List` payloads where IEEE // 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty // state is structurally representable, the same INVARIANTS P2 // illegal-states-unrepresentable concern codex / openai-pro @@ -1853,16 +1875,16 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the twenty-one spec-non-empty sites keeps `List` for now. +// - Each of the twenty-four spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. // - DISSOLUTION TRIGGER: when `std/collection.dag` Wave-A2 lands the -// non-empty refinement, the twenty-one sites adopt +// non-empty refinement, the twenty-four sites adopt // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The twenty-one spec-non-empty sites (back-pointers to this note): +// The twenty-four spec-non-empty sites (back-pointers to this note): // 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) // 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) // 3. NetDeclaration.TriregIdentifierForm.identifiers (Β§A.2.1.3) @@ -1885,6 +1907,9 @@ type ParameterTypeKind // 19. GenvarDeclaration.genvar_names (Β§A.2.1.1) // 20. UdpInstantiation.instances (Β§A.5.2) // 21. PortDeclaration.names (Β§A.2.1.2) +// 22. AnsiPortDeclaration.AnsiInputPort.names (Β§A.1.3) +// 23. AnsiPortDeclaration.AnsiOutputPort.names (Β§A.1.3) +// 24. AnsiPortDeclaration.AnsiInoutPort.names (Β§A.1.3) // // Sites previously numbered 7-9 added 2026-05-16 per codex // REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 @@ -1916,10 +1941,11 @@ type ParameterTypeKind // DefparamDeclaration / EventDeclaration / GenvarDeclaration each // gained a non-empty list of per-entry sub-records (new // DefparamAssignment Conj for Β§A.2.5 list_of_defparam_assignments; -// `event_names: List` for Β§A.2.1.4 list_of_event_identifiers; -// `genvar_names: List` for Β§A.2.1.1 list_of_genvar_ -// identifiers) β€” restoring the spec statement-boundary lost by the -// prior singular-entry shape. UdpInstantiation refactored to the +// `event_declarators: List` for Β§A.2.1.4 +// list_of_event_identifiers (later sha 4ccc6267 added per-identifier +// dimensions via EventDeclarator); `genvar_names: List` for +// Β§A.2.1.1 list_of_genvar_identifiers) β€” restoring the spec +// statement-boundary lost by the prior singular-entry shape. UdpInstantiation refactored to the // same shared-header + non-empty-instance-list pattern as // ModuleInstantiation, per Β§A.5.2 `udp_identifier [drive_strength] // [delay2] udp_instance { , udp_instance } ;` β€” shared @@ -1932,6 +1958,18 @@ type ParameterTypeKind // reshape from singular-name to list-form mirrors the Defparam/ // Event/Genvar list-form precedent under Β§A.2.1.2 list_of_port_ // identifiers; the non-empty list rides the same RQ-3 deferral. +// Sites 22-24 added 2026-05-16 per openai-pro REQUEST_CHANGES on +// PR #3176 at sha 4ccc6267 (Layer-Model BLOCKING on +// AnsiPortDeclaration per-single-name carrier): the three ANSI port +// direction variants reshape from `name: Symbol` singletons to +// non-empty name-lists (AnsiInputPort/AnsiInoutPort use +// `List` per Β§A.1.3 list_of_port_identifiers; AnsiOutputPort +// uses `List` per Β§A.1.3 +// list_of_variable_port_identifiers β€” output variable-ports admit +// per-port initializers via the existing VariableInitializerClause +// Disj). All three new non-empty lists ride the same RQ-3 / +// std/collection.dag Wave-A2 deferral; no verilog-local +// NonEmptyList mint. // ───────────────────────────────────────────────────────────────────── @@ -2239,8 +2277,39 @@ type InitialBlock { // classifier; the expression sub-grammar is deferred to T-4 // LanguageModel. type PortConnectionActual - = ExpressionConnection { attributes: AttributeInstanceClause, expression_lexeme: String } - | BlankConnection { attributes: AttributeInstanceClause } + = ExpressionConnection { expression_lexeme: String } + | BlankConnection + + +// ───────────────────────────────────────────────────────────────────── +// OrderedPortConnection β€” one element of a positional port-binding +// list (IEEE 1364-2005 Β§A.4.1.1): +// +// ordered_port_connection ::= { attribute_instance } [ expression ] +// +// The Β§A.4.1.1 grammar places the attribute_instance prefix at the +// ordered_port_connection element level β€” the same level where +// named_port_connection carries its attribute prefix. The earlier +// shape (sha cba903a3e) put attributes ON each PortConnectionActual +// variant, which then double-authoritied named connections +// (NamedPortConnection.attributes + actual.attributes both present +// for one syntactic binding) β€” openai-pro REQUEST_CHANGES on +// PR #3176 sha 4ccc6267 flagged the double-authority. Resolution: +// strip attributes from PortConnectionActual (the inner blank-vs- +// expression Disj is shared between ordered and named forms; +// attributes live at the OUTER wrapping level) and wrap the +// positional case in this OrderedPortConnection Conj that mirrors +// NamedPortConnection's outer-attribute placement. +// Conj record (no Practice-4 ledger). +// +// - attributes the optional attribute_instance prefix per +// Β§A.4.1.1 (reuses AttributeInstanceClause). +// - actual the connection's expression-or-blank inner form +// (PortConnectionActual). +type OrderedPortConnection { + attributes: AttributeInstanceClause + actual: PortConnectionActual +} // ───────────────────────────────────────────────────────────────────── @@ -2350,7 +2419,7 @@ type PortConnections // 🟑 spec-non-empty (Β§A.4.1.1 ordered_port_connection list) β€” // deferred to std/collection.dag Wave-A2 `List where // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. - actuals: List + actuals: List } | NamedConnections { // 🟑 spec-non-empty (Β§A.4.1.1 named_port_connection list) β€” @@ -2767,31 +2836,59 @@ type FunctionDeclaration { } +// ───────────────────────────────────────────────────────────────────── +// EventDeclarator β€” one (name, optional-unpacked-dimensions) entry +// in an event_declaration's list_of_event_identifiers (IEEE 1364-2005 +// Β§A.2.1.4 / Β§A.2.3). Per spec: +// +// list_of_event_identifiers ::= event_identifier [ dimension +// { dimension } ] +// { , event_identifier [ dimension +// { dimension } ] } +// +// each event identifier admits an OPTIONAL unpacked-array dimension +// suffix (openai-pro REQUEST_CHANGES on PR #3176 sha 4ccc6267 β€” the +// prior Symbol-only shape dropped the per-identifier dimensions +// fact). Conj record (no Practice-4 ledger). +// +// - name the event identifier (K-1-opaque Symbol). +// - unpacked_dimensions optional unpacked-array dimensions per +// Β§A.2.3 (reuses UnpackedDimensionsClause). +type EventDeclarator { + name: Symbol + unpacked_dimensions: UnpackedDimensionsClause +} + + // ───────────────────────────────────────────────────────────────────── // EventDeclaration β€” a Verilog named-event declaration (`event ev1, -// ev2, ev3;`). IEEE 1364-2005 Β§9.7.3 / Β§10.3 / Β§A.2.1.4. Named events -// are explicitly-triggered control-flow primitives (`-> ev;` triggers, -// `@ev` waits). Per spec Β§A.2.1.4 grammar: +// ev2, ev3;` / `event log[0:255];`). IEEE 1364-2005 Β§9.7.3 / Β§10.3 / +// Β§A.2.1.4. Named events are explicitly-triggered control-flow +// primitives (`-> ev;` triggers, `@ev` waits). Per spec Β§A.2.1.4 +// grammar: // // event_declaration ::= event list_of_event_identifiers ; -// list_of_event_identifiers ::= event_identifier -// { , event_identifier } -// -// a single `event` statement declares a NON-EMPTY list of event -// identifiers under a shared `event` keyword. The prior singular-name -// shape lost the Β§A.2.1.4 statement-boundary (shared `event` keyword -// across multi-identifier forms) β€” openai-pro REQUEST_CHANGES on -// PR #3176 2026-05-16 at line 2315 (grouped with DefparamDeclaration -// / GenvarDeclaration). Conj record (no Practice-4 ledger). +// list_of_event_identifiers ::= event_identifier [ dimension +// { dimension } ] +// { , event_identifier [ dimension +// { dimension } ] } +// +// a single `event` statement declares a NON-EMPTY list of +// (name, optional-dimensions) entries under a shared `event` keyword +// (sha 4ccc6267 openai-pro REQUEST_CHANGES β€” per-identifier +// dimensions added via EventDeclarator). The prior singular-name +// shape lost the Β§A.2.1.4 statement-boundary; the prior +// Symbol-only-list shape dropped the per-identifier dimensions. +// Conj record (no Practice-4 ledger). // -// - event_names the non-empty list of event identifiers (K-1- -// opaque Symbols) declared under this single -// `event` statement. +// - event_declarators the non-empty list of EventDeclarator +// entries declared under this single +// `event` statement. type EventDeclaration { // 🟑 spec-non-empty (Β§A.2.1.4 list_of_event_identifiers) β€” // deferred to std/collection.dag Wave-A2 `List where // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. - event_names: List + event_declarators: List } @@ -3154,6 +3251,67 @@ type UdpDefinition { } +// ───────────────────────────────────────────────────────────────────── +// SpecparamAssignment β€” one element of a specparam declaration's +// list_of_specparam_assignments (IEEE 1364-2005 Β§A.2.4): +// +// specparam_assignment ::= +// specparam_identifier = constant_mintypmax_expression +// | pulse_control_specparam +// pulse_control_specparam ::= +// PATHPULSE$ = ( reject_limit_value [ , error_limit_value ] ) ; +// | PATHPULSE$specify_input_terminal_descriptor +// $specify_output_terminal_descriptor +// = ( reject_limit_value [ , error_limit_value ] ) ; +// +// The two alternatives have distinct spec syntax β€” pulse_control_ +// specparam is NOT a `name = expr` form; it's the special +// `PATHPULSE$...` family. The prior shape reused ParameterAssignment +// `{ name: Symbol, default_lexeme: String }`, forcing every specparam +// to claim a name+value shape β€” which made pulse_control_specparam +// unrepresentable as a structural variant (openai-pro REQUEST_CHANGES +// on PR #3176 sha 4ccc6267). Split into a specparam-specific Disj +// over the two Β§A.2.4 spec alternatives. +// +// - NamedSpecparamAssignment +// β€” `specparam T_rise = 1.0;` form: identifier + constant +// mintypmax-expression lexeme. +// - PulseControlSpecparam +// β€” `PATHPULSE$ = (1.5, 2.0);` / `PATHPULSE$in$out = +// (1.5);` form: the entire PATHPULSE$... directive as a +// verbatim lexeme (sub-grammar β€” terminal descriptors + +// reject/error limit values β€” deferred to the bundled T-4 +// LanguageModel via the established body_lexeme precedent). +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.2.4 admits exactly the +// two specparam_assignment alternatives. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every specparam-emission consumer +// branches on the form (named-value vs pulse-control); shared +// classifier. +// 2. Variant-is-data β€” FAILS: reusing ParameterAssignment (prior +// shape) forced pulse_control_specparam to claim a `name + +// value_lexeme` shape it doesn't have, losing the PATHPULSE$ +// form as a structural variant. +// 3. Algebraic form β€” N/A by construction: the two alternatives +// are the Β§A.2.4 spec's irreducible partition. +// 4. Dimensional β€” FAILS: a single specparam_assignment is +// EXACTLY ONE form; mutually exclusive alternatives. +// 5. Parameterized family β€” FAILS: NamedSpecparamAssignment +// carries `{ name: Symbol, value_lexeme: String }`; +// PulseControlSpecparam carries `{ lexeme: String }` (no name +// field β€” the PATHPULSE$... directive has its own internal +// identifier structure) β€” structurally heterogeneous +// (Practice 7). +// Terminal: the closed two-way Verilog specparam_assignment +// classifier of the IEEE 1364-2005 Β§A.2.4 spec. +type SpecparamAssignment + = NamedSpecparamAssignment { name: Symbol, value_lexeme: String } + | PulseControlSpecparam { lexeme: String } + + // ───────────────────────────────────────────────────────────────────── // SpecparamDeclaration β€” a Verilog `specparam` declaration. IEEE // 1364-2005 Β§14.3.1 + Β§12.2 + Β§A.2.1.1. Specify parameters are @@ -3161,21 +3319,21 @@ type UdpDefinition { // check values (rise/fall/hi-Z transitions, pulse-control limits) // and CANNOT be used as bit-vector widths or array indices per spec. // Per spec grammar specparam admits an optional range and a list of -// specparam_assignments. Conj record (no Practice-4 ledger). +// specparam_assignments (sha 4ccc6267 openai-pro REQUEST_CHANGES β€” +// specparam_assignment carrier split via SpecparamAssignment Disj +// above to admit both NamedSpecparamAssignment + PulseControlSpecparam +// alternatives per Β§A.2.4). Conj record (no Practice-4 ledger). // // - packing optional range (`specparam [9:0]`); applies to // all assignments in this declaration. -// - assignments the list_of_specparam_assignments β€” each -// ParameterAssignment carries name + default_lexeme. -// Reusing ParameterAssignment per the shared -// (name, value-expression-lexeme) shape; -// specparam-specific pulse-control variants are -// admitted via the assignment's lexeme. +// - assignments the list_of_specparam_assignments per Β§A.2.4; +// each entry is one of the two SpecparamAssignment +// variants (named-value or pulse-control). type SpecparamDeclaration { packing: PackingShape // 🟑 spec-non-empty (Β§A.2.1.1) β€” deferred to std/collection.dag // Wave-A2 refinement; see shared TRACKED-SCAFFOLD note above. - assignments: List + assignments: List } From 7b7dd0b5428a3fc48dbcbd7e68d22146def4c3db Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 15:35:36 +0000 Subject: [PATCH 46/56] v4 T-4.9 verilog: VerilogModule no-ports-form Disj variant + non-empty header_ports per openai-pro BLOCKING on PR #3176 sha 7709c996 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro inline BLOCKING at line 3525 flagged two coupled issues on VerilogModule: (a) `module M; ... endmodule` (no port list) is representable as either NonAnsi{header_ports=[]} or Ansi{header_ports=[]} β€” P2 representation-duality between the two style variants. (b) NonAnsi{header_ports=[], items=[NonAnsiPortDeclarationItem...]} admits a spec-illegal Β§12.3.4 state β€” body port_declarations reference header port names, so empty-header + body-port- declarations is structurally illegal. Resolution: VerilogModule reshaped from 2-way to 3-way closed Disj with a new NoPortsModule style-neutral variant: - NoPortsModule { module_keyword, name, parameter_port_list, items: List } - NonAnsiVerilogModule { ..., header_ports: List (🟑 non-empty), items: List } - AnsiVerilogModule { ..., header_ports: List (🟑 non-empty), items: List } NoPortsModule's `items: List` (reusing the body- port-declaration-excluded set) makes the Β§12.3.4 illegal "no header ports + body port_declarations" state structurally unrepresentable. NonAnsi/Ansi variants' header_ports are now spec-non-empty (the no-ports case routes structurally to NoPortsModule), eliminating the representation-duality of empty-header-list across two style variants. Practice-4 ledger updated to reflect the closed three-way partition (NoPortsModule + per-style variants) with the three structurally- unrepresentable illegal states explicitly enumerated. Shared NonEmptyList scaffold-note: "Twenty-four" β†’ "Twenty-six" sites; new sites 25-26 (NonAnsi/Ansi header_ports). grep -c '🟑 spec-non-empty (Β§' invariant: 26 (verified). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 98 +++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 16 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index da246fe86bf..6593fa32018 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1848,7 +1848,7 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Twenty-four sites in this file carry `List` payloads where IEEE +// Twenty-six sites in this file carry `List` payloads where IEEE // 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty // state is structurally representable, the same INVARIANTS P2 // illegal-states-unrepresentable concern codex / openai-pro @@ -1875,7 +1875,7 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the twenty-four spec-non-empty sites keeps `List` for now. +// - Each of the twenty-six spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. @@ -1884,7 +1884,8 @@ type ParameterTypeKind // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The twenty-four spec-non-empty sites (back-pointers to this note): +// The twenty-six spec-non-empty sites (back-pointers to this note): +// (sites 25-26 below β€” VerilogModule per-style header_ports) // 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) // 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) // 3. NetDeclaration.TriregIdentifierForm.identifiers (Β§A.2.1.3) @@ -1910,6 +1911,8 @@ type ParameterTypeKind // 22. AnsiPortDeclaration.AnsiInputPort.names (Β§A.1.3) // 23. AnsiPortDeclaration.AnsiOutputPort.names (Β§A.1.3) // 24. AnsiPortDeclaration.AnsiInoutPort.names (Β§A.1.3) +// 25. VerilogModule.NonAnsiVerilogModule.header_ports (Β§12.3.4) +// 26. VerilogModule.AnsiVerilogModule.header_ports (Β§12.3.4) // // Sites previously numbered 7-9 added 2026-05-16 per codex // REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 @@ -1969,7 +1972,21 @@ type ParameterTypeKind // per-port initializers via the existing VariableInitializerClause // Disj). All three new non-empty lists ride the same RQ-3 / // std/collection.dag Wave-A2 deferral; no verilog-local -// NonEmptyList mint. +// NonEmptyList mint. Sites 25-26 added 2026-05-16 per openai-pro +// REQUEST_CHANGES on PR #3176 at sha 7709c9968 (inline BLOCKING at +// line 3525 β€” VerilogModule header_ports List representation- +// duality): the no-ports module form (`module M; ... endmodule`) +// was representable as either NonAnsi{header_ports=[]} or +// Ansi{header_ports=[]} (P2 representation-duality), AND empty +// non-ANSI header with body port_declaration items admitted a spec- +// illegal Β§12.3.4 state (body port_declarations reference header +// port names; no header ports β†’ no body port_declarations). +// Resolution: VerilogModule gained a NoPortsModule style-neutral +// variant (3-way Disj) with `items: List` (no body +// port_declaration variants representable). The remaining +// NonAnsiVerilogModule + AnsiVerilogModule variants now have +// spec-non-empty header_ports β€” sites 25-26 β€” riding the same +// RQ-3 deferral. // ───────────────────────────────────────────────────────────────────── @@ -3659,14 +3676,33 @@ type ModuleKeyword // ───────────────────────────────────────────────────────────────────── // VerilogModule β€” a top-level Verilog module (`module Name -// #(parameters) (ports); items endmodule`, or `macromodule Name …`). -// IEEE 1364-2005 Β§12.1 / Β§A.1.2. -// Per-style Disj β€” each variant carries its own header-port-list type -// AND its own admissible body-items list type. The Β§12.3.4 module- -// style partition is the dimensional axis of VerilogModule itself; -// "ANSI port-list module with body PortDeclarationItem" is -// unrepresentable by construction. -// +// #(parameters) (ports); items endmodule`, or `macromodule Name …`, +// or `module Name; items endmodule` with no port list at all). +// IEEE 1364-2005 Β§12.1 / Β§12.3.4 / Β§A.1.2. +// Three-way Disj β€” the Β§12.3.4 module-style partition is the +// dimensional axis of VerilogModule, with a style-neutral +// NoPortsModule variant for the no-port-list form. Each style +// variant carries its own header-port-list type AND its own +// admissible body-items list type. Three illegal states are +// structurally unrepresentable: +// (1) "ANSI port-list module with body PortDeclarationItem" +// (the original 2-way split) +// (2) "No-port-list module with body port_declarations" +// (NoPortsModule items: List β€” no body +// port_declaration variants representable since body +// port_declarations would reference non-existent header +// port names per Β§12.3.4) +// (3) "No-port-list represented two ways" +// (P2 representation-duality between NonAnsi{header_ports=[]} +// and Ansi{header_ports=[]} β€” the NoPortsModule variant is +// the single representation of the no-ports state; the per- +// style variants now have spec-non-empty header_ports) +// +// - NoPortsModule +// β€” `module M; ... endmodule` form: no header port list. +// Style-neutral (the Β§12.3.4 ANSI-vs-non-ANSI distinction +// loses meaning when there are no ports). Items use the +// AnsiModuleItem set, which excludes body port_declarations. // - NonAnsiVerilogModule // β€” non-ANSI style: header carries port-EXPRESSIONS only // (List); body carries the full NonAnsiModuleItem @@ -3745,14 +3781,39 @@ type ModuleKeyword // `F` / projection over a single source set (Practice 7). // The compound payload-type difference IS the partition's // defining structural fact. -// Terminal: the closed two-way Verilog module-declaration-style -// classifier of the IEEE 1364-2005 Β§12.3.4 spec; ledger added per -// codex BLOCKING on PR #3176 2026-05-16. +// Terminal: the closed three-way Verilog module-declaration-style +// classifier of the IEEE 1364-2005 Β§12.3.4 spec (NoPortsModule + +// per-style variants); ledger added per codex BLOCKING on PR #3176 +// 2026-05-16, NoPortsModule variant added at sha 7709c9968 per +// openai-pro REQUEST_CHANGES (line 3525 β€” no-port-list +// representation-duality + non-ANSI body port_declarations with +// empty header). type VerilogModule - = NonAnsiVerilogModule { + = NoPortsModule { + // `module M; ... endmodule` (no port list at all). Style- + // neutral: with no header ports, the Β§12.3.4 ANSI-vs-non-ANSI + // distinction loses meaning (the distinction is defined by + // whether port direction lives in header or body β€” both + // collapse to "no ports anywhere"). Items use the + // AnsiModuleItem set (which excludes NonAnsiPortDeclarationItem + // / NonAnsiBodyPortDeclarationItem) because there are no + // header ports for body port_declarations to reference per + // Β§12.3.4 β€” so admitting body port_declaration items here + // would be a spec-illegal state. module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, + items: List + } + | NonAnsiVerilogModule { + module_keyword: ModuleKeyword, + name: Symbol, + parameter_port_list: ModuleParameterPortList, + // 🟑 spec-non-empty (Β§12.3.4 non-ANSI module-header port list) β€” + // non-ANSI modules WITH a header port-list have at least one + // port (the no-ports case routes to NoPortsModule above); + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. header_ports: List, items: List } @@ -3760,6 +3821,11 @@ type VerilogModule module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, + // 🟑 spec-non-empty (Β§12.3.4 ANSI module-header port list) β€” + // ANSI modules WITH a header port-list have at least one + // port (the no-ports case routes to NoPortsModule above); + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. header_ports: List, items: List } From cf6f6d12e1bb3ce4c767088a3c767bdcafd18b39 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 12:32:45 -0400 Subject: [PATCH 47/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 95 ++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 6593fa32018..84ffde1e4a1 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1509,11 +1509,19 @@ type VariableDeclarator // source set (Practice 7); the real/realtime exclusion is the // Β§12.3.3 spec's output-port-admissibility partition, not a // derived projection. -// Terminal: the closed four-way Verilog ANSI-output-port type/kind -// classifier; real/realtime outputs unrepresentable by construction -// per IEEE 1364-2005 Β§12.3.3. +// Terminal: the closed five-way Verilog ANSI-output-port type/kind +// classifier (the no-net-no-reg variant added at sha 7b7dd0b54+ +// per codex L1600 BLOCKING on PR #3176 β€” Β§A.1.3 output_declaration +// admits `output [net_type] [signed] [range]` AND `output [reg] +// [signed] [range]` where both `net_type` and `reg` are +// syntactically OPTIONAL; "output [signed] [range] name;" with +// neither keyword is a legal spec form that resolves to a net via +// Β§12.3.3 separate-declaration inheritance OR defaults to wire); +// real/realtime outputs unrepresentable by construction per IEEE +// 1364-2005 Β§12.3.3. type OutputPortAnsiTypeKind = OutputAnsiNetType { net_type: NetType, packing: PackingShape, signedness: Signedness } + | OutputAnsiNoNetType { packing: PackingShape, signedness: Signedness } | OutputAnsiRegType { packing: PackingShape, signedness: Signedness } | OutputAnsiIntegerType | OutputAnsiTimeType @@ -1643,10 +1651,17 @@ type PortDeclaration { // 5. Parameterized family β€” FAILS: the single variant's payload is // a structured record (NetType Γ— PackingShape Γ— Signedness), // not one generic `F` projection (Practice 7). -// Terminal: the closed net-only type-payload classifier for input / -// inout ANSI ports; a second variant would be an L-2 pin edit. +// Terminal: the closed two-way net-type-presence-aware type-payload +// classifier for input / inout ANSI ports (the no-net-type variant +// added at sha 7b7dd0b54+ per codex L1600 BLOCKING on PR #3176 β€” +// Β§A.1.3 `input [net_type] [signed] [range]` makes net_type +// SYNTACTICALLY OPTIONAL; the prior single-variant shape forced +// every input/inout port to claim a net_type, dropping the spec's +// "port_declaration without type, type provided by a separate +// later net/reg declaration" Β§12.3.3 form). type AnsiNetPortType = AnsiInputInoutNet { net_type: NetType, packing: PackingShape, signedness: Signedness } + | AnsiInputInoutNoNetType { packing: PackingShape, signedness: Signedness } // ───────────────────────────────────────────────────────────────────── @@ -1668,24 +1683,22 @@ type AnsiNetPortType // illegal combinations structurally unrepresentable, mirroring the // VariableDeclaration kindΓ—packingΓ—signedness dissolution). // -// - AnsiInputPort { attributes, net: AnsiNetPortType, -// names: List } +// - AnsiInputPort { net: AnsiNetPortType, names: List } // β€” input ports are net-typed only (the spec forbids // `input reg`); names form a Β§A.1.3 list_of_port_identifiers. -// - AnsiOutputPort { attributes, type_kind: OutputPortAnsiTypeKind, +// - AnsiOutputPort { type_kind: OutputPortAnsiTypeKind, // names: List } -// β€” output ports admit the OutputPortAnsiTypeKind 4-way set -// (net, reg, integer, time per Β§12.3.3 β€” REAL / REALTIME -// outputs are excluded per spec). Names form a Β§A.1.3 -// list_of_variable_port_identifiers (each declarator admits -// an optional initializer for variable-typed output ports). -// The closed 4-way partition is structural per the +// β€” output ports admit the OutputPortAnsiTypeKind 5-way set +// (net / no-net-type / reg / integer / time per Β§12.3.3 β€” +// REAL / REALTIME outputs are excluded per spec). Names form +// a Β§A.1.3 list_of_variable_port_identifiers (each declarator +// admits an optional initializer for variable-typed output +// ports). The closed 5-way partition is structural per the // OutputPortAnsiTypeKind ledger below; corrected per codex // BLOCKING on PR #3176 2026-05-16 β€” the prior reuse of a // generic 6-way ANSI-port carrier admitted spec-forbidden // `output real` / `output realtime`. -// - AnsiInoutPort { attributes, net: AnsiNetPortType, -// names: List } +// - AnsiInoutPort { net: AnsiNetPortType, names: List } // β€” inout ports are net-typed only (bidirectional requires // nets; `inout reg` is a spec violation); names form a // Β§A.1.3 list_of_port_identifiers. @@ -1728,9 +1741,21 @@ type AnsiNetPortType // Terminal: the closed three-way Verilog ANSI-port direction-kind // classifier; illegal direction Γ— type-kind combinations are // unrepresentable by construction. +// As of sha 7b7dd0b54+ (codex L3563 BLOCKING on PR #3176): the +// `attributes: AttributeInstanceClause` field has been STRIPPED from +// all three variants below β€” AnsiPortDeclaration is now the +// attribute-FREE per-spec port declaration payload, reusable at: +// - ANSI header position via AnsiHeaderPort wrapper (carries the +// Β§A.1.3 outer `{attribute_instance}` prefix) +// - non-ANSI body position via NonAnsiBodyPortDeclarationItem +// (whose outer `attributes` field is the single authority) +// This dissolves the Β§A.1.3 double-authority that arose when both +// the outer wrapper AND the inner AnsiPortDeclaration carried +// attribute slots for one syntactic site (same shape as the +// OrderedPortConnection / NamedPortConnection split that resolved +// the analogous PortConnectionActual double-authority). type AnsiPortDeclaration = AnsiInputPort { - attributes: AttributeInstanceClause net: AnsiNetPortType // 🟑 spec-non-empty (Β§A.1.3 list_of_port_identifiers) β€” deferred // to std/collection.dag Wave-A2 `List where non_empty` @@ -1738,7 +1763,6 @@ type AnsiPortDeclaration names: List } | AnsiOutputPort { - attributes: AttributeInstanceClause type_kind: OutputPortAnsiTypeKind // 🟑 spec-non-empty (Β§A.1.3 list_of_variable_port_identifiers / // list_of_port_identifiers) β€” deferred to std/collection.dag @@ -1747,7 +1771,6 @@ type AnsiPortDeclaration names: List } | AnsiInoutPort { - attributes: AttributeInstanceClause net: AnsiNetPortType // 🟑 spec-non-empty (Β§A.1.3 list_of_port_identifiers) β€” deferred // to std/collection.dag Wave-A2 `List where non_empty` @@ -1756,6 +1779,38 @@ type AnsiPortDeclaration } +// ───────────────────────────────────────────────────────────────────── +// AnsiHeaderPort β€” one ANSI-style module-header port entry (IEEE +// 1364-2005 Β§12.3.3 / Β§A.1.3). Conj wrapper providing the Β§A.1.3 +// `{attribute_instance}` outer prefix around the attribute-free +// AnsiPortDeclaration payload. Sibling pattern of +// OrderedPortConnection / NamedPortConnection β€” outer-attribute +// placement matching the spec grammar's prefix position. +// +// Per Β§A.1.3 grammar: +// +// port_declaration ::= {attribute_instance} +// (input_declaration | output_declaration +// | inout_declaration) +// +// the attributes live at the port_declaration level, ABOVE the +// direction-specific declaration sub-form. This wrapper provides +// that level for ANSI header use; the same AnsiPortDeclaration +// payload is reused at non-ANSI body position via +// NonAnsiBodyPortDeclarationItem (whose outer `attributes` field +// is the single authority for that position). Conj record (no +// Practice-4 ledger). +// +// - attributes the optional {attribute_instance} prefix per +// Β§A.1.3 (reuses AttributeInstanceClause). +// - decl the direction-bearing port declaration payload +// (AnsiPortDeclaration). Attribute-free. +type AnsiHeaderPort { + attributes: AttributeInstanceClause + decl: AnsiPortDeclaration +} + + // ───────────────────────────────────────────────────────────────────── // AnsiOutputPortDeclarator β€” one (name, optional-initializer) entry // in an ANSI output port's list_of_variable_port_identifiers (IEEE @@ -3826,7 +3881,7 @@ type VerilogModule // port (the no-ports case routes to NoPortsModule above); // deferred to std/collection.dag Wave-A2 `List where // non_empty` refinement; see shared TRACKED-SCAFFOLD note above. - header_ports: List, + header_ports: List, items: List } From 98953d5fcbb0ed7e006561f41b939d94437fcdd2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 16:33:53 +0000 Subject: [PATCH 48/56] v4 T-4.9 verilog: address codex on-HEAD BLOCKINGs on PR #3176 sha 7b7dd0b5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex on-HEAD scheduled review at sha 7b7dd0b54 flagged 2 inline BLOCKINGs: 1. L3563 β€” NonAnsiBodyPortDeclarationItem double-authority. The 5-pack landing (7709c9968) had added attributes to all 3 AnsiPortDeclaration variants (originally for ANSI header use), but the same AnsiPortDeclaration is reused at non-ANSI body position via NonAnsiBodyPortDeclarationItem which carries its OWN outer attributes field. Result: two attribute_instance authorities for one syntactic body port_declaration. Same shape as the PortConnectionActual/NamedPortConnection double-authority caught at sha 4ccc6267 β€” applied the same factor-attribute-free-payload + outer-wrapper pattern. 2. L1600 β€” Body port_declaration partition missing the Β§12.3.3 no-net/variable-type form. `input [7:0] a;` followed by a separate `wire [7:0] a;` is a legal Β§12.3.3 pattern where the port_declaration carries direction + range/signed but NO net_type keyword (type provided by a separate later declaration). The prior shape forced every typed port to claim a net_type or variable kind, dropping this spec form. Combined fix (codex's hint: "factor an attribute-free, net-type- presence-aware port declaration payload and wrap it separately at ANSI-header and non-ANSI-body sites"): A. Attribute-strip from AnsiPortDeclaration variants β€” the type becomes the attribute-FREE, type-presence-aware port declaration payload. B. New AnsiHeaderPort wrapper Conj { attributes, decl: AnsiPortDeclaration } providing the Β§A.1.3 outer {attribute_instance} prefix for ANSI header use. Mirrors OrderedPortConnection / NamedPortConnection wrapper pattern. C. VerilogModule.AnsiVerilogModule.header_ports type: List β†’ List. D. NonAnsiBodyPortDeclarationItem unchanged structurally β€” its outer attributes field is now the SINGLE authority for non-ANSI body position (body_port: AnsiPortDeclaration is now attribute- free). E. Net-type-presence extensions to admit the Β§12.3.3 "modifiers- without-net-type" form: - AnsiNetPortType (1 β†’ 2 variants): added `AnsiInputInoutNoNetType { packing, signedness }` for the input/inout port case where net_type keyword is omitted. - OutputPortAnsiTypeKind (4 β†’ 5 variants): added `OutputAnsiNoNetType { packing, signedness }` for the output port case where both `net_type` and `reg` keywords are omitted (Β§A.1.3 makes both syntactically optional per the bracketed productions). - Real/realtime exclusion preserved on OutputPortAnsiTypeKind (Β§12.3.3 forbids them). Net result at both syntactic positions: - ANSI header: single attribute authority via AnsiHeaderPort.attributes - non-ANSI body: single attribute authority via NonAnsiBodyPortDeclarationItem.attributes - Spec form `input [7:0] a;` (and analogous output/inout forms) now structurally representable via the new no-net-type variants. Practice-4 ledger updates: AnsiNetPortType marked closed-2-way; OutputPortAnsiTypeKind closed-5-way; commentary updated for the new no-net-type variants. Stale `List` / attribute-on-variant commentary in VerilogModule + AnsiPortDeclaration ledgers refreshed. grep -c '🟑 spec-non-empty (Β§' invariant: 26 (unchanged β€” no new list sites; the existing 22-24 ANSI port-name sites still hold). Architectural Q surfaced (flag-for-verify class per the surfaced-key-decision rule): the "net-type-presence-aware" extension choice was Option A (variant-add to settled closed Disjs) vs Option B (factor a separate AnsiNetTypeChoice Disj wrapping Optional) vs Option C (hoist payload-typing into a new top-level Disj). Chose Option A as minimum-blast-radius variant-add to the carrier-specific existing Disjs; Option B would have added a fourth sibling Disj parallel to PackingShape/Signedness/NetType (over-spreading); Option C would have re-architected the carrier shape unnecessarily. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 84ffde1e4a1..ae78431240f 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -3765,7 +3765,9 @@ type ModuleKeyword // BodyPortDeclarationItem per Β§12.3.4. // - AnsiVerilogModule // β€” ANSI style: header carries fully-declared ports -// (List); body carries AnsiModuleItem +// (List, where AnsiHeaderPort wraps an +// attribute-free AnsiPortDeclaration payload with the Β§A.1.3 +// outer attribute_instance prefix); body carries AnsiModuleItem // only (the 18 items spec-admitted in any module body // EXCLUDING port_declarations β€” per Β§12.3.3 ANSI ports are // "completely declared" and body redeclarations are a syntax @@ -3827,15 +3829,16 @@ type ModuleKeyword // structure. // 4. Dimensional β€” FAILS: a single module declaration is EXACTLY // ONE style; mutually-exclusive alternatives per Β§12.3.4. -// 5. Parameterized family β€” FAILS: the two variants carry +// 5. Parameterized family β€” FAILS: the variants carry // structurally heterogeneous payloads (NonAnsi.header_ports: // List + items: List vs Ansi. -// header_ports: List + items: -// List) β€” the header port-list type AND the -// body item-set type both differ per style. NOT one generic -// `F` / projection over a single source set (Practice 7). -// The compound payload-type difference IS the partition's -// defining structural fact. +// header_ports: List + items: +// List; NoPortsModule has no header_ports at +// all + items: List) β€” the header port-list +// type AND the body item-set type both differ per variant. +// NOT one generic `F` / projection over a single source set +// (Practice 7). The compound payload-type difference IS the +// partition's defining structural fact. // Terminal: the closed three-way Verilog module-declaration-style // classifier of the IEEE 1364-2005 Β§12.3.4 spec (NoPortsModule + // per-style variants); ledger added per codex BLOCKING on PR #3176 From 6bfc75029cf2d6b38b99269c563359866902374f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 13:05:44 -0400 Subject: [PATCH 49/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 101 +++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index ae78431240f..13f65496c49 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1519,10 +1519,103 @@ type VariableDeclarator // Β§12.3.3 separate-declaration inheritance OR defaults to wire); // real/realtime outputs unrepresentable by construction per IEEE // 1364-2005 Β§12.3.3. -type OutputPortAnsiTypeKind - = OutputAnsiNetType { net_type: NetType, packing: PackingShape, signedness: Signedness } +// (DELETED 2026-05-16 per openai-pro REQUEST_CHANGES on PR #3176 +// sha 98953d5f: this single 5-way Disj conflated two Β§A.1.3 spec- +// alternatives β€” net-form outputs (list_of_port_identifiers, no +// initializers) and variable-form outputs (list_of_variable_port_ +// identifiers, with initializers). Replaced with two sibling Disjs +// OutputPortAnsiNetTypeKind + OutputPortAnsiVariableTypeKind below, +// consumed by separate AnsiOutputNetPort / AnsiOutputVariablePort +// variants of AnsiPortDeclaration, structurally forbidding `output +// wire y = 1'b0` while admitting all spec-legal output forms.) + + +// ───────────────────────────────────────────────────────────────────── +// OutputPortAnsiNetTypeKind β€” the closed Verilog ANSI-output-port +// type/kind classifier for the NET form: `output [net_type] [signed] +// [range] list_of_port_identifiers` (IEEE 1364-2005 Β§A.1.3, first +// output_declaration alternative). The list of identifiers uses +// `list_of_port_identifiers` β€” plain port_identifier elements with +// NO per-port initializers. Per port_declaration spec the net_type +// keyword (when present) excludes `trireg` β€” this carrier therefore +// uses NonTriregNetKind directly, not the broader NetType. Real/ +// realtime are not net types and are not admitted here. +// +// - OutputAnsiNetType { kind: NonTriregNetKind, packing, signedness } +// β€” `output wire [7:0] y`, `output wand a`, etc.; explicit +// non-trireg net-type keyword. +// - OutputAnsiNoNetType { packing, signedness } +// β€” `output [7:0] y` (no net_type keyword); spec Β§A.1.3 makes +// net_type bracketed/optional. Resolves to default wire OR +// inherits from a separate later declaration per Β§12.3.3. +// +// CLOSED (C1 stop-signal). Two-way net-form output partition; a +// third would be an L-2 pin edit. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Five-pattern ledger abbreviated (same shape +// arguments as the prior OutputPortAnsiTypeKind ledger): +// 1. Fact placement β€” FAILS: shared classifier across output-port +// emitters/recognizers. +// 2. Variant-is-data β€” FAILS: collapsing to `{kind: +// Option, packing, signedness}` re-admits the +// illegal "trireg-output" + the "net-form-with-initializer" +// states this Disj exists to dissolve. +// 3. Algebraic form β€” N/A by construction: spec's Β§A.1.3 +// net-output partition. +// 4. Dimensional β€” FAILS: exactly one form per output port; mutually +// exclusive. +// 5. Parameterized family β€” FAILS: heterogeneous payloads +// (OutputAnsiNetType carries `kind`; OutputAnsiNoNetType does +// not). Practice 7. +// Terminal: the closed two-way Verilog ANSI-output-port NET-form +// type/kind classifier. +type OutputPortAnsiNetTypeKind + = OutputAnsiNetType { kind: NonTriregNetKind, packing: PackingShape, signedness: Signedness } | OutputAnsiNoNetType { packing: PackingShape, signedness: Signedness } - | OutputAnsiRegType { packing: PackingShape, signedness: Signedness } + + +// ───────────────────────────────────────────────────────────────────── +// OutputPortAnsiVariableTypeKind β€” the closed Verilog ANSI-output- +// port type/kind classifier for the VARIABLE form: `output [reg] +// [signed] [range] list_of_variable_port_identifiers` / +// `output output_variable_type list_of_variable_port_identifiers` +// (IEEE 1364-2005 Β§A.1.3, second + third output_declaration +// alternatives). The list of identifiers uses +// `list_of_variable_port_identifiers` β€” each port_identifier admits +// an OPTIONAL initializer expression. Real/realtime are excluded +// per Β§12.3.3 ("An output port can be of any net or variable type +// EXCEPT a real type"). +// +// - OutputAnsiRegType { packing, signedness } +// β€” `output reg [7:0] count`; spec-form 2. +// - OutputAnsiIntegerType +// β€” `output integer counter`; 32-bit signed (spec-form 3). +// - OutputAnsiTimeType +// β€” `output time t`; 64-bit unsigned simulation-time +// (spec-form 3). +// +// CLOSED (C1 stop-signal). Three-way variable-form output partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Five-pattern ledger abbreviated: +// 1. Fact placement β€” FAILS: shared output-port classifier. +// 2. Variant-is-data β€” FAILS: collapsing to `{kind, packing?, +// signedness?}` admits the Β§12.3.3 illegal `output real` / +// `output realtime` + reg-fixed-width violations the per-variant +// payload-presence rule dissolves. +// 3. Algebraic form β€” PARTIAL: each variant grounds in std/ +// algebra (Regβ†’Semiring/OrderedRing per packingΓ—signedness; +// Integerβ†’OrderedRing>; Timeβ†’Semiring>); +// D2-deferred per Owned ELSEWHERE. +// 4. Dimensional β€” FAILS: exactly one form per output port. +// 5. Parameterized family β€” FAILS: structurally heterogeneous +// payloads + algebraic groundings (Practice 7). +// Terminal: the closed three-way Verilog ANSI-output-port VARIABLE- +// form type/kind classifier; real/realtime outputs unrepresentable +// by construction per Β§12.3.3. +type OutputPortAnsiVariableTypeKind + = OutputAnsiRegType { packing: PackingShape, signedness: Signedness } | OutputAnsiIntegerType | OutputAnsiTimeType @@ -1660,7 +1753,7 @@ type PortDeclaration { // "port_declaration without type, type provided by a separate // later net/reg declaration" Β§12.3.3 form). type AnsiNetPortType - = AnsiInputInoutNet { net_type: NetType, packing: PackingShape, signedness: Signedness } + = AnsiInputInoutNet { kind: NonTriregNetKind, packing: PackingShape, signedness: Signedness } | AnsiInputInoutNoNetType { packing: PackingShape, signedness: Signedness } From f9159ce8b861986ff146df870b2efa6675aad2e7 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 17:08:21 +0000 Subject: [PATCH 50/56] v4 T-4.9 verilog: address openai-pro on-HEAD 2-pack BLOCKING on PR #3176 sha 98953d5f MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro's FIRST on-HEAD verdict on this PR (sha 98953d5f) flagged 2 BLOCKINGs. Both spec-right. 1. Layer Model / illegal-states-unrepresentable β€” NetType in port positions admits trireg illegal state. Per Verilog 1364 Β§A.1.3 port_declaration uses `net_type?` whose alternatives EXCLUDE trireg (trireg is net-declaration-only per Β§A.2.1.3). The prior shape used the full NetType Disj (which includes both NonTriregNet {kind} AND TriregNet) at AnsiNetPortType.AnsiInputInoutNet and OutputPortAnsiTypeKind.OutputAnsiNetType, making `input trireg p` / `output trireg p` structurally representable. Fix: replace `net_type: NetType` with `kind: NonTriregNetKind` at port positions β€” port_declaration sites now structurally exclude trireg. This is the Β§12.3.3 port-position trireg-exclusion finding that had been noted as out-of-scope in earlier reviews; openai-pro on-HEAD coverage caught it cleanly. 2. INVARIANTS P2 β€” AnsiOutputPort admits illegal net-output-with- initializer. Per Β§A.1.3 output_declaration has THREE alternatives: (1) `output [net_type] [signed] [range] list_of_port_identifiers` (net form β€” NO initializers per port_identifier) (2) `output [reg] [signed] [range] list_of_variable_port_identifiers` (variable form β€” admits per-port initializers) (3) `output output_variable_type list_of_variable_port_identifiers` (variable form β€” admits per-port initializers) The prior unified AnsiOutputPort used `List` (initializer-capable declarator) for all 5 OutputPortAnsiTypeKind variants β€” admitting `output wire y = 1'b0` (net form with initializer, spec-illegal). Fix: structural Disj split. AnsiPortDeclaration grows from 3 β†’ 4 variants: - AnsiInputPort { net: AnsiNetPortType, names: List } - AnsiOutputNetPort { type_kind: OutputPortAnsiNetTypeKind, names: List } // form 1 - AnsiOutputVariablePort { type_kind: OutputPortAnsiVariableTypeKind, names: List } // forms 2+3 - AnsiInoutPort { net: AnsiNetPortType, names: List } OutputPortAnsiTypeKind dissolved into two sibling Disjs: - OutputPortAnsiNetTypeKind (2-way: OutputAnsiNetType{kind: NonTriregNetKind, packing, signedness} | OutputAnsiNoNetType {packing, signedness}) β€” net form - OutputPortAnsiVariableTypeKind (3-way: OutputAnsiRegType{packing, signedness} | OutputAnsiIntegerType | OutputAnsiTimeType) β€” variable form Real/realtime exclusion preserved (Β§12.3.3 forbids them). The OutputAnsiNetType variant also gets the Fix #1 NonTriregNetKind narrowing (trireg-output unrepresentable structurally). Architectural Q surfaced (flag-for-verify class per the surfaced-key-decision rule): the split point for Finding #2 had three viable options: Option A β€” Split AnsiOutputPort into AnsiOutputNetPort + AnsiOutputVariablePort variants of AnsiPortDeclaration; dissolve OutputPortAnsiTypeKind into per-form sibling Disjs. CHOSEN. Option B β€” Keep AnsiOutputPort + OutputPortAnsiTypeKind unified; introduce a per-variant declarator-list-type Disj (split declarator-list-type by output-form). REJECTED: re-introduces admit-then-check on type_kind Γ— declarator cross-product. Option C β€” Move initializer-presence into OutputPortAnsiTypeKind variants (each variant carries the right declarator type). REJECTED: mixes type-kind concern with declarator-list concern; both Disjs grow with mixed-concern variants. Option A is minimum-blast-radius + mirrors the Β§A.1.3 grammar's direct alternative structure (net-form vs variable-form is the spec's primary partition; type_kind is the sub-partition within each form). The split mirrors Β§A.2.1.3 NetDeclaration's per-form 4-way structural pattern (NonTriregIdentifierForm / NonTriregAssignForm / TriregIdentifierForm / TriregAssignForm) β€” same precedent. Shared NonEmptyList scaffold-note: "Twenty-six" β†’ "Twenty-seven" sites; AnsiOutputPort.names (was site 23) split into AnsiOutputNetPort. names (site 23) + AnsiOutputVariablePort.names (site 24); AnsiInoutPort renumbered 24β†’25; VerilogModule header_ports renumbered 25-26β†’26-27. grep -c '🟑 spec-non-empty (Β§' invariant: 27 (verified). Net delta +1 site (the per-form split adds one site). AnsiNetPortType.AnsiInputInoutNet ledger updated to reflect the NonTriregNetKind field (was net_type: NetType). AnsiPortDeclaration 4-way ledger updated for the 4-variant terminal + 5-pattern Practice-4 ledger entries cover the new variants' heterogeneous payloads (no Practice 7 violation β€” the input/inout sides carry {net: AnsiNetPortType, names: List} while the two output sides carry per-form-specific type_kind Disjs with distinct declarator-list types). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 106 ++++++++++++++++++--------- 1 file changed, 73 insertions(+), 33 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 13f65496c49..5fd1ec16bdf 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1716,10 +1716,15 @@ type PortDeclaration { // time / realtime are output-only per spec). This carrier is the // closed type-payload set for input / inout β€” strictly the net family. // -// - AnsiInputInoutNet { net_type: NetType, packing: PackingShape, +// - AnsiInputInoutNet { kind: NonTriregNetKind, packing: PackingShape, // signedness: Signedness } -// β€” any NetType variant (wire/wand/wor/tri/etc.) with optional -// packing + signedness per spec Β§5.6. +// β€” any non-trireg net-type variant (wire/wand/wor/tri/etc.) +// with optional packing + signedness per spec Β§5.6. Per +// port_declaration Β§A.1.3 grammar, `trireg` is excluded at +// port positions (it is a net-declaration-only form); +// NonTriregNetKind enforces this structurally (openai-pro +// REQUEST_CHANGES on PR #3176 sha 98953d5f β€” the prior `NetType` +// field admitted spec-illegal `input trireg p` / `output trireg p`). // // CLOSED (C1 stop-signal). IEEE 1364-2005 Β§12.3.3 admits exactly net // types for input/inout ANSI ports; SystemVerilog `logic` would EDIT @@ -1779,18 +1784,29 @@ type AnsiNetPortType // - AnsiInputPort { net: AnsiNetPortType, names: List } // β€” input ports are net-typed only (the spec forbids // `input reg`); names form a Β§A.1.3 list_of_port_identifiers. -// - AnsiOutputPort { type_kind: OutputPortAnsiTypeKind, -// names: List } -// β€” output ports admit the OutputPortAnsiTypeKind 5-way set -// (net / no-net-type / reg / integer / time per Β§12.3.3 β€” -// REAL / REALTIME outputs are excluded per spec). Names form -// a Β§A.1.3 list_of_variable_port_identifiers (each declarator -// admits an optional initializer for variable-typed output -// ports). The closed 5-way partition is structural per the -// OutputPortAnsiTypeKind ledger below; corrected per codex -// BLOCKING on PR #3176 2026-05-16 β€” the prior reuse of a -// generic 6-way ANSI-port carrier admitted spec-forbidden -// `output real` / `output realtime`. +// - AnsiOutputNetPort { type_kind: OutputPortAnsiNetTypeKind, +// names: List } +// β€” output net-form (Β§A.1.3 output_declaration alternative 1: +// `output [net_type] [signed] [range] list_of_port_identifiers`). +// The 2-way OutputPortAnsiNetTypeKind partition (explicit +// non-trireg net-type / no-net-type) covers the spec alternatives; +// names use plain port_identifiers β€” NO per-port initializers +// structurally representable. +// - AnsiOutputVariablePort { type_kind: OutputPortAnsiVariableTypeKind, +// names: List } +// β€” output variable-form (Β§A.1.3 output_declaration alternatives +// 2+3: `output [reg] [signed] [range]` / +// `output output_variable_type` followed by +// list_of_variable_port_identifiers). The 3-way +// OutputPortAnsiVariableTypeKind partition (reg / integer / time) +// covers spec-admissible variable kinds; names use +// list_of_variable_port_identifiers with optional per-port +// initializers via AnsiOutputPortDeclarator. Real/realtime +// outputs excluded per Β§12.3.3. The net-vs-variable AnsiOutputPort +// split corrected the prior unified-declarator shape per openai-pro +// REQUEST_CHANGES on PR #3176 sha 98953d5f β€” the prior shape +// admitted spec-illegal `output wire y = 1'b0` net-output-with- +// initializer states. // - AnsiInoutPort { net: AnsiNetPortType, names: List } // β€” inout ports are net-typed only (bidirectional requires // nets; `inout reg` is a spec violation); names form a @@ -1825,13 +1841,17 @@ type AnsiNetPortType // 4. Dimensional β€” FAILS: a single ANSI port is EXACTLY ONE // direction variant; mutually-exclusive alternatives. // 5. Parameterized family β€” FAILS: AnsiInputPort and AnsiInoutPort -// carry `net: AnsiNetPortType` (net-only, 1-variant); AnsiOutputPort -// carries `type_kind: OutputPortAnsiTypeKind` (the 4-way output- -// admissible type-kind set: net / reg / integer / time). The +// carry `net: AnsiNetPortType` (net-only, 2-variant: explicit +// non-trireg-kind + no-net-type); AnsiOutputNetPort carries +// `type_kind: OutputPortAnsiNetTypeKind` (2-variant net forms) +// + `names: List`; AnsiOutputVariablePort carries +// `type_kind: OutputPortAnsiVariableTypeKind` (3-variant +// variable forms: reg/integer/time) + `names: List< +// AnsiOutputPortDeclarator>` (with optional initializers). The // payload types differ structurally β€” NOT one generic // `F` projection over a single source set // (Practice 7). -// Terminal: the closed three-way Verilog ANSI-port direction-kind +// Terminal: the closed four-way Verilog ANSI-port direction-kind // classifier; illegal direction Γ— type-kind combinations are // unrepresentable by construction. // As of sha 7b7dd0b54+ (codex L3563 BLOCKING on PR #3176): the @@ -1855,12 +1875,31 @@ type AnsiPortDeclaration // refinement; see shared TRACKED-SCAFFOLD note below. names: List } - | AnsiOutputPort { - type_kind: OutputPortAnsiTypeKind - // 🟑 spec-non-empty (Β§A.1.3 list_of_variable_port_identifiers / - // list_of_port_identifiers) β€” deferred to std/collection.dag - // Wave-A2 `List where non_empty` refinement; see shared - // TRACKED-SCAFFOLD note below. + | AnsiOutputNetPort { + // Spec Β§A.1.3 output_declaration form 1: `output [net_type] + // [signed] [range] list_of_port_identifiers`. Net-form outputs + // use plain port_identifiers β€” NO per-port initializers + // structurally representable (openai-pro REQUEST_CHANGES on + // PR #3176 sha 98953d5f: prior unified AnsiOutputPort admitted + // `output wire y = 1'b0` which the spec forbids). + type_kind: OutputPortAnsiNetTypeKind + // 🟑 spec-non-empty (Β§A.1.3 list_of_port_identifiers) β€” + // deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note below. + names: List + } + | AnsiOutputVariablePort { + // Spec Β§A.1.3 output_declaration forms 2+3: `output [reg] + // [signed] [range] list_of_variable_port_identifiers` / + // `output output_variable_type list_of_variable_port_ + // identifiers`. Variable-form outputs use + // list_of_variable_port_identifiers β€” each port_identifier + // admits an OPTIONAL initializer expression. Real/realtime + // excluded per Β§12.3.3. + type_kind: OutputPortAnsiVariableTypeKind + // 🟑 spec-non-empty (Β§A.1.3 list_of_variable_port_identifiers) + // β€” deferred to std/collection.dag Wave-A2 `List where + // non_empty` refinement; see shared TRACKED-SCAFFOLD note below. names: List } | AnsiInoutPort { @@ -1996,7 +2035,7 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Twenty-six sites in this file carry `List` payloads where IEEE +// Twenty-seven sites in this file carry `List` payloads where IEEE // 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty // state is structurally representable, the same INVARIANTS P2 // illegal-states-unrepresentable concern codex / openai-pro @@ -2023,7 +2062,7 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the twenty-six spec-non-empty sites keeps `List` for now. +// - Each of the twenty-seven spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. @@ -2032,7 +2071,7 @@ type ParameterTypeKind // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The twenty-six spec-non-empty sites (back-pointers to this note): +// The twenty-seven spec-non-empty sites (back-pointers to this note): // (sites 25-26 below β€” VerilogModule per-style header_ports) // 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) // 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) @@ -2056,11 +2095,12 @@ type ParameterTypeKind // 19. GenvarDeclaration.genvar_names (Β§A.2.1.1) // 20. UdpInstantiation.instances (Β§A.5.2) // 21. PortDeclaration.names (Β§A.2.1.2) -// 22. AnsiPortDeclaration.AnsiInputPort.names (Β§A.1.3) -// 23. AnsiPortDeclaration.AnsiOutputPort.names (Β§A.1.3) -// 24. AnsiPortDeclaration.AnsiInoutPort.names (Β§A.1.3) -// 25. VerilogModule.NonAnsiVerilogModule.header_ports (Β§12.3.4) -// 26. VerilogModule.AnsiVerilogModule.header_ports (Β§12.3.4) +// 22. AnsiPortDeclaration.AnsiInputPort.names (Β§A.1.3) +// 23. AnsiPortDeclaration.AnsiOutputNetPort.names (Β§A.1.3) +// 24. AnsiPortDeclaration.AnsiOutputVariablePort.names (Β§A.1.3) +// 25. AnsiPortDeclaration.AnsiInoutPort.names (Β§A.1.3) +// 26. VerilogModule.NonAnsiVerilogModule.header_ports (Β§12.3.4) +// 27. VerilogModule.AnsiVerilogModule.header_ports (Β§12.3.4) // // Sites previously numbered 7-9 added 2026-05-16 per codex // REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 From a22544951958c82d63e1eae8ed18e24c27c1fd49 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 13:32:46 -0400 Subject: [PATCH 51/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 115 +++++++++++++++++++-------- 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 5fd1ec16bdf..5599a65fa81 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1621,38 +1621,75 @@ type OutputPortAnsiVariableTypeKind // ───────────────────────────────────────────────────────────────────── -// NonAnsiPort β€” a non-ANSI-style Verilog module-HEADER port entry -// (`module M (a, b, c);` β€” the header lists port-EXPRESSIONS only; -// direction lives in BODY port_declaration items per IEEE 1364-2005 -// Β§12.3.2). Conj record (no Practice-4 ledger). -// -// - port_expression_lexeme the port_expression as a verbatim -// lexeme (per spec grammar the -// port_expression can be a bare -// identifier `a`, a bit/part-select -// `a[3:0]`, a concatenation `{a, b[3:0]}`, -// or a renamed-port form -// `.external_name(internal_expression)`). -// Sub-grammar deferred to the T-4 -// LanguageModel via the established -// body_lexeme precedent β€” at the -// vocabulary-slice layer the slice -// carries the port-expression text -// losslessly; downstream -// port-binding resolution is the -// LanguageModel grammar's concern. -// -// Per IEEE 1364-2005 Β§12.3.2 the non-ANSI header carries port- -// expressions ONLY β€” port direction (input/output/inout) and any -// inline type/packing/signedness facts live in BODY -// `port_declaration` items (see PortDeclaration below + the -// PortDeclarationItem ModuleItem variant). The prior -// `PortDeclaration { direction, name }` on the header port-list -// collapsed this spec-boundary; corrected per codex BLOCKING on -// PR #3176 2026-05-16. -type NonAnsiPort { - port_expression_lexeme: String -} +// NonAnsiPort β€” one entry in a non-ANSI-style Verilog module-HEADER +// port list (`module M (a, b, c);` / `module M (.ext(internal));` / +// `module M (a, , c);`). IEEE 1364-2005 Β§12.3.2 / Β§A.1.3: +// +// port ::= [port_expression] +// | .port_identifier ( [port_expression] ) +// +// The spec admits TWO port forms (regular-position vs external-named- +// binding), each with an OPTIONAL inner port_expression (the brackets +// in both alternatives) β€” yielding FOUR closed alternatives. The +// prior single-String shape collapsed all four into one mandatory +// lexeme, losing the blank-port + external-named-binding spec forms +// and forcing empty-string sentinel for blanks (openai-pro +// REQUEST_CHANGES on PR #3176 sha f9159ce8b at line 1654). +// +// Per Β§12.3.2 the non-ANSI header carries port-EXPRESSIONS only β€” +// port direction (input/output/inout) and any inline +// type/packing/signedness facts live in BODY `port_declaration` items +// (see PortDeclaration below + the PortDeclarationItem ModuleItem +// variant). The prior `PortDeclaration { direction, name }` on the +// header port-list collapsed this spec-boundary; corrected per codex +// BLOCKING on PR #3176 2026-05-16. The 4-way alternative split per +// Β§A.1.3 is the structural completion of that prior correction. +// +// - BlankNonAnsiPort +// β€” `module M (a, , c);` β€” the empty header position +// (port_expression absent on the regular form). +// - ExpressionNonAnsiPort { expression_lexeme: String } +// β€” `module M (a);` β€” port_expression present on the regular +// form (bare identifier, bit/part-select, or concatenation; +// sub-grammar deferred via the body_lexeme precedent). +// - ExternalNamedBlankPort { external_name: Symbol } +// β€” `module M (.ext());` β€” external-named-binding form with +// blank inner port_expression. +// - ExternalNamedExpressionPort { external_name: Symbol, expression_lexeme: String } +// β€” `module M (.ext(internal));` β€” external-named-binding form +// with port_expression present. +// +// CLOSED (C1 stop-signal). IEEE 1364-2005 Β§A.1.3 admits exactly these +// four port-list-entry alternatives. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 1. Fact placement β€” FAILS: every header-port-list emitter + +// port-binding resolver branches on the form (blank / regular / +// external-named-blank / external-named-expr) uniformly; shared +// classifier at the port-list-entry boundary. +// 2. Variant-is-data β€” FAILS: collapsing to one mandatory lexeme +// reintroduces the empty-string sentinel for blank ports AND +// drops the spec's external-named-binding form as a distinct +// structural fact β€” exactly the Β§A.1.3 illegal-collapse +// INVARIANTS P2 concern this Disj exists to dissolve. +// 3. Algebraic form β€” N/A by construction: the four alternatives +// are the Β§A.1.3 spec's irreducible port-form partition. +// 4. Dimensional β€” FAILS: a single port-list entry is EXACTLY ONE +// form; mutually exclusive alternatives. +// 5. Parameterized family β€” FAILS: the four variants carry +// heterogeneous payloads β€” BlankNonAnsiPort is nullary; +// ExpressionNonAnsiPort carries `{ expression_lexeme }`; +// ExternalNamedBlankPort carries `{ external_name }`; +// ExternalNamedExpressionPort carries +// `{ external_name, expression_lexeme }`. Practice 7. +// Terminal: the closed four-way Verilog non-ANSI port-list-entry +// classifier of the IEEE 1364-2005 Β§A.1.3 spec. +type NonAnsiPort + = BlankNonAnsiPort + | ExpressionNonAnsiPort { expression_lexeme: String } + | ExternalNamedBlankPort { external_name: Symbol } + | ExternalNamedExpressionPort { external_name: Symbol, expression_lexeme: String } // ───────────────────────────────────────────────────────────────────── @@ -3662,10 +3699,20 @@ type AnsiModuleItem | LocalParameterDeclarationItem { attributes: AttributeInstanceClause, local_parameter: LocalParameterDeclaration } | ModuleInstantiationItem { attributes: AttributeInstanceClause, instantiation: ModuleInstantiation } | DefparamDeclarationItem { attributes: AttributeInstanceClause, defparam: DefparamDeclaration } - | GenerateRegionItem { attributes: AttributeInstanceClause, generate_region: GenerateRegion } + // GenerateRegionItem carries NO attributes field β€” per Β§A.1.4 + // generate_region is one of the module_items without an + // {attribute_instance} prefix in the spec grammar (openai-pro + // REQUEST_CHANGES on PR #3176 sha f9159ce8b β€” the 4ccc62675 + // uniform-application over-admitted attributes on this variant). + | GenerateRegionItem { generate_region: GenerateRegion } | LoopGenerateConstructItem { attributes: AttributeInstanceClause, loop_generate: LoopGenerateConstruct } | ConditionalGenerateConstructItem { attributes: AttributeInstanceClause, conditional_generate: ConditionalGenerateConstruct } - | SpecifyBlockItem { attributes: AttributeInstanceClause, specify_block: SpecifyBlock } + // SpecifyBlockItem carries NO attributes field β€” per Β§A.1.4 + // specify_block is one of the module_items without an + // {attribute_instance} prefix in the spec grammar (openai-pro + // REQUEST_CHANGES on PR #3176 sha f9159ce8b β€” same over-application + // correction as GenerateRegionItem above). + | SpecifyBlockItem { specify_block: SpecifyBlock } | TaskDeclarationItem { attributes: AttributeInstanceClause, task: TaskDeclaration } | FunctionDeclarationItem { attributes: AttributeInstanceClause, function_decl: FunctionDeclaration } | EventDeclarationItem { attributes: AttributeInstanceClause, event_decl: EventDeclaration } From e0ee1931a737b738b710658132f34e3aa2209c32 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 17:37:21 +0000 Subject: [PATCH 52/56] v4 T-4.9 verilog: add top-level attributes on VerilogModule + UdpDefinition per openai-pro BLOCKING on PR #3176 sha f9159ce8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro on-HEAD verdict at sha f9159ce8 flagged 2 BLOCKINGs: A. Top-level module + UDP declarations have no typed home for {attribute_instance}. Per IEEE 1364-2005: - Syntax 3-4: `module_declaration ::= { attribute_instance } module_keyword ... endmodule` β€” `(* optimize_power *) module M ...` is legal spec form. - Syntax 3-9: `udp_declaration ::= { attribute_instance } primitive ... endprimitive` β€” `(* attr *) primitive ...` is legal spec form. Resolution: add `attributes: AttributeInstanceClause` to all 3 VerilogModule variants (NoPortsModule, NonAnsiVerilogModule, AnsiVerilogModule) and to UdpDefinition. Reuses the existing AttributeInstanceClause Disj. No double-authority concern: the source_text design-element classifier is deferred to the bundled T-4 LanguageModel and doesn't yet wrap these top-level carriers (so no outer wrapper exists that could create a placement conflict; the attribute field on the carriers themselves is the single authority for the Β§3-4 / Β§3-9 prefix). B. GenerateRegionItem + SpecifyBlockItem over-admit attributes per Β§A.1.4 β€” already addressed at HEAD a22544951 (the immediately- prior fix); this finding was at the pre-fix sha f9159ce8. Rolling- HEAD discipline: no new fix needed; the consolidated PR reply (#issuecomment-4467626483) and inline replies tied to the threads already document the address. This is the dual-of-shared-payload pattern from feedback_shared_payload_attribute_placement_pattern.md applied in reverse: at the top-level VerilogModule + UdpDefinition positions the spec DOES carry attribute_instance prefix at those exact boundaries β€” under-admission rather than over-admission. The same preventive (check the per-spec-boundary attribute admissibility) identified the fix shape directly (variant-add the attribute field where the spec admits the prefix, no admit-then-check). Shared NonEmptyList scaffold-note unchanged. grep -c '🟑 spec-non- empty (Β§' invariant: 27 (no new list sites β€” pure attribute-field additions). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 5599a65fa81..7f84f0f5957 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -3488,6 +3488,15 @@ type UdpInstantiation { // name-reference resolution target). This NOTE is the single // source-of-truth deferral marker for the missing aggregator. type UdpDefinition { + // Per IEEE 1364-2005 Syntax 3-9, udp_declaration carries + // a top-level `{ attribute_instance }` prefix: `(* attr *) primitive + // ... endprimitive` is legal spec form. Field added at sha 7b7dd0b54+ + // per openai-pro REQUEST_CHANGES on PR #3176 sha f9159ce8b (Layer- + // Model BLOCKING: top-level UDP attributes had no typed home; reuses + // the existing AttributeInstanceClause Disj). No double-authority + // concern: the source_text design-element classifier is deferred to + // the bundled T-4 LanguageModel and doesn't yet wrap UdpDefinition. + attributes: AttributeInstanceClause name: Symbol body_lexeme: String } @@ -4026,6 +4035,16 @@ type ModuleKeyword // openai-pro REQUEST_CHANGES (line 3525 β€” no-port-list // representation-duality + non-ANSI body port_declarations with // empty header). +// All 3 variants carry `attributes: AttributeInstanceClause` per +// IEEE 1364-2005 Syntax 3-4: `module_declaration ::= { attribute_ +// instance } module_keyword ... endmodule` β€” `(* optimize_power *) +// module M ... endmodule` is legal spec form. Field added at sha +// 7b7dd0b54+ per openai-pro REQUEST_CHANGES on PR #3176 sha +// f9159ce8b (Layer-Model BLOCKING: top-level module attributes had +// no typed home; reuses the existing AttributeInstanceClause Disj). +// No double-authority concern: the source_text design-element +// classifier is deferred to the bundled T-4 LanguageModel and +// doesn't yet wrap VerilogModule. type VerilogModule = NoPortsModule { // `module M; ... endmodule` (no port list at all). Style- @@ -4038,12 +4057,14 @@ type VerilogModule // header ports for body port_declarations to reference per // Β§12.3.4 β€” so admitting body port_declaration items here // would be a spec-illegal state. + attributes: AttributeInstanceClause, module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, items: List } | NonAnsiVerilogModule { + attributes: AttributeInstanceClause, module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, @@ -4056,6 +4077,7 @@ type VerilogModule items: List } | AnsiVerilogModule { + attributes: AttributeInstanceClause, module_keyword: ModuleKeyword, name: Symbol, parameter_port_list: ModuleParameterPortList, From 0a27a44bc4dd579f1ea9d996e540f515dd9acdd5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 14:27:36 -0400 Subject: [PATCH 53/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 237 +++++++++++++++++++-------- 1 file changed, 172 insertions(+), 65 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 7f84f0f5957..99c2ef46384 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -1693,55 +1693,38 @@ type NonAnsiPort // ───────────────────────────────────────────────────────────────────── -// PortDeclaration β€” a non-ANSI-style Verilog BODY port_declaration -// (`input a;`, `output b;`, `inout c;`). IEEE 1364-2005 Β§12.3.4 + -// Β§12.2 admit these as module-body items. Each declares port -// direction + name; the type/packing/signedness facts come from a -// MATCHING `NetDeclaration` / `VariableDeclaration` in the same -// module body (the non-ANSI separated form), OR β€” per spec β€” a body -// port_declaration may combine direction + type inline (`input wire -// [7:0] a;`). The combined form is structurally equivalent to ANSI -// and is admitted by the same `AnsiPortDeclaration` carrier surfaced -// as `BodyPortDeclarationItem` in ModuleItem; this PortDeclaration -// record covers the direction-only form. -// -// - direction input / output / inout -// - name the port identifier (K-1-opaque Symbol; resolves -// through the namespace to the matching body -// Net/Variable declaration that carries the type- -// fact, when separated) -// -// Per IEEE 1364-2005 Β§12.3.4 / Β§12.2 PortDeclaration is a MODULE -// BODY item (PortDeclarationItem in ModuleItem), NOT a module- -// header element. The non-ANSI header carries port-EXPRESSIONS via -// NonAnsiPort above; this body declaration carries the direction -// fact that the non-ANSI form requires. Corrected per codex -// BLOCKING on PR #3176 2026-05-16 β€” the prior shape mis-located -// PortDeclaration on the header port-list, conflating the spec's -// header-vs-body partition. -// -// Per spec Β§A.2.1.2 grammar a single direction-only port_declaration -// admits a NON-EMPTY list of port identifiers under one shared -// direction keyword (`input a, b, c;` is one statement declaring -// three ports, not three statements). The prior singular-name shape -// lost the Β§A.2.1.2 statement-boundary (shared direction keyword -// across multi-identifier forms) β€” openai-pro REQUEST_CHANGES on -// PR #3176 2026-05-16 at line 1429; same shape as the -// DefparamDeclaration / EventDeclaration / GenvarDeclaration list- -// form precedent. -// -// - direction the port-direction keyword (input | output | -// inout); shared across all declared names in -// this statement. -// - names the non-empty list of declared port identifiers -// (K-1-opaque Symbols). -type PortDeclaration { - direction: PortDirection - // 🟑 spec-non-empty (Β§A.2.1.2 list_of_port_identifiers) β€” deferred - // to std/collection.dag Wave-A2 `List where non_empty` - // refinement; see shared TRACKED-SCAFFOLD note below. - names: List -} +// (PortDeclaration was DISSOLVED on PR #3176 sha cb028c7d+ per +// openai-pro REQUEST_CHANGES. Per spec Β§A.2.1.2: +// +// input_declaration ::= input [net_type] [signed] [range] list_of_port_identifiers +// output_declaration ::= output ... (multiple forms) +// inout_declaration ::= inout [net_type] [signed] [range] list_of_port_identifiers +// +// the SAME spec production covers BOTH the bare form (`input a;`) +// AND the with-modifiers form (`input [7:0] a;`) AND the with-type +// form (`input wire [7:0] a;`) β€” net_type / signed / range are all +// independently optional. The prior partition (PortDeclaration = +// direction+names only, AnsiPortDeclaration reused for with-type +// forms via NonAnsiBodyPortDeclarationItem) collapsed the +// with-modifiers-without-type form (`output [7:0] y;` followed by +// separate `reg [7:0] y;`) β€” PortDeclaration path lost range/signed, +// AnsiPortDeclaration path made the carrier "falsely complete" +// (openai-pro REQUEST_CHANGES on PR #3176 sha cb028c7d at line 1710). +// +// Resolution: AnsiPortDeclaration's existing no-net-type variants +// (AnsiInputInoutNoNetType for input/inout, OutputAnsiNoNetType for +// output) ALREADY cover the direction+modifiers-without-type form +// with the full {packing, signedness} payload β€” the bare-form +// `input a;` is the same carrier with packing=Scalar + +// signedness=Unsigned. PortDeclaration's direction+names shape is +// thus a strict subset (the {packing=Scalar, signedness=Unsigned} +// projection) of AnsiPortDeclaration's no-net-type variants. +// Keeping PortDeclaration as a separate carrier was +// representation-duality and a partition gap; dissolving it +// collapses both NonAnsiPortDeclarationItem + +// NonAnsiBodyPortDeclarationItem in NonAnsiModuleItem into one +// variant using AnsiPortDeclaration uniformly. Single carrier, +// single authority, full Β§A.2.1.2 spec form coverage.) // ───────────────────────────────────────────────────────────────────── @@ -3041,18 +3024,118 @@ type SpecifyBlock { // ───────────────────────────────────────────────────────────────────── -// TaskDeclaration β€” a Verilog `task ... endtask` declaration -// (IEEE 1364-2005 Β§10.2, Β§12.2). A task is a procedural sub-routine -// callable from procedural code; it can carry input/output/inout -// arguments and contain delay/event controls (unlike `function`). -// Conj record (no Practice-4 ledger). +// LifetimeClause β€” the closed Verilog task/function lifetime +// classifier (IEEE 1364-2005 Β§10.2 / Β§10.3 / Β§A.2.6): tasks and +// functions admit an OPTIONAL `automatic` keyword: +// +// task_declaration ::= task [automatic] task_identifier ; ... endtask +// function_declaration ::= function [automatic] +// [function_range_or_type] +// function_identifier ; ... endfunction +// +// `automatic` declares per-call storage (recursive-safe); the +// default is `static` (single shared storage, default keyword +// absent). Modeled as a closed Disj rather than a Bool to avoid +// the K-1 Bool-as-keyword anti-pattern. Field added at sha +// cb028c7d+ per openai-pro REQUEST_CHANGES β€” TaskDeclaration / +// FunctionDeclaration previously collapsed this into body_lexeme, +// losing the Β§10.2/Β§10.3 declaration-boundary fact. +// +// - StaticLifetime +// β€” `task t;` / `function f;` (default; `automatic` keyword +// absent). +// - AutomaticLifetime +// β€” `task automatic t;` / `function automatic f;` (per-call +// storage; spec keyword present). +// +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Five-pattern ledger abbreviated. +// 1. Fact placement β€” FAILS: shared classifier across task / +// function emitters + elaboration consumers. +// 2. Variant-is-data β€” FAILS: collapsing to `is_automatic: Bool` +// reintroduces the K-1-forbidden Bool-as-keyword anti-pattern; +// string sentinel ditto. +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one lifetime per declaration; mutually +// exclusive. +// 5. Parameterized family β€” FAILS: both variants are nullary β€” +// spec-distinct keyword identities (Practice 7). +// Terminal: the closed two-way Verilog task/function lifetime +// classifier. +type LifetimeClause + = StaticLifetime + | AutomaticLifetime + + +// ───────────────────────────────────────────────────────────────────── +// FunctionReturnTypeClause β€” the closed Verilog function return- +// type-or-range classifier (IEEE 1364-2005 Β§10.3 / Β§A.2.6): function +// declarations admit an OPTIONAL `function_range_or_type` between +// `[automatic]` and the function name: +// +// function_range_or_type ::= [ signed ] [ range ] +// | integer | real | realtime | time +// +// The clause is OPTIONAL per spec; when absent, the function returns +// a single-bit (default) result. When present, the spec form is +// either a signed/range pair (returning a bit-vector) or one of the +// spec-fixed-width variable types. Field added at sha cb028c7d+ per +// openai-pro REQUEST_CHANGES β€” FunctionDeclaration previously +// collapsed this declaration-boundary fact into body_lexeme. The +// sub-grammar (signed/range distinction + variable-type keyword +// closure) is deferred to the bundled T-4 LanguageModel via the +// established body_lexeme precedent. +// +// - NoFunctionReturnType +// β€” `function f;` form: default single-bit return. +// - FunctionReturnTypeLexeme { lexeme: String } +// β€” `function [7:0] f;` / `function signed [7:0] f;` / +// `function integer f;` / etc.; the function_range_or_type as +// a verbatim lexeme. Sub-grammar deferred. // +// CLOSED (C1 stop-signal). Two-way present/absent partition. +// +// Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” +// 🟒 GREEN (terminal). Five-pattern ledger abbreviated. +// 1. Fact placement β€” FAILS: shared function-emitter / return- +// type-resolution consumers. +// 2. Variant-is-data β€” FAILS: empty-string sentinel rejected +// (BlankConnection precedent). +// 3. Algebraic form β€” N/A by construction. +// 4. Dimensional β€” FAILS: one return-type-or-range state per +// function declaration. +// 5. Parameterized family β€” FAILS: NoFunctionReturnType is +// nullary; FunctionReturnTypeLexeme carries `lexeme: String` +// β€” structurally heterogeneous (Practice 7). +// Terminal: the closed two-way Verilog function-return-type-clause +// classifier. +type FunctionReturnTypeClause + = NoFunctionReturnType + | FunctionReturnTypeLexeme { lexeme: String } + + +// ───────────────────────────────────────────────────────────────────── +// TaskDeclaration β€” a Verilog `task ... endtask` declaration +// (IEEE 1364-2005 Β§10.2, Β§12.2 / Β§A.2.6). A task is a procedural +// sub-routine callable from procedural code; it can carry +// input/output/inout arguments and contain delay/event controls +// (unlike `function`). Conj record (no Practice-4 ledger). +// +// - lifetime the optional `automatic` keyword +// (LifetimeClause); per Β§10.2 task admits +// `[automatic]` as a declaration-boundary +// modifier (added at sha cb028c7d+ per openai-pro +// REQUEST_CHANGES; prior shape collapsed this +// into body_lexeme). // - name the task identifier (K-1-opaque Symbol) // - body_lexeme the procedural body (port list + statements -// between `task name;` and `endtask`) as a -// verbatim lexeme (sub-grammar deferred to the -// T-4 LanguageModel) +// between `task [automatic] name;` and `endtask`) +// as a verbatim lexeme (sub-grammar deferred to +// the T-4 LanguageModel) type TaskDeclaration { + lifetime: LifetimeClause name: Symbol body_lexeme: String } @@ -3060,19 +3143,31 @@ type TaskDeclaration { // ───────────────────────────────────────────────────────────────────── // FunctionDeclaration β€” a Verilog `function ... endfunction` -// declaration (IEEE 1364-2005 Β§10.3, Β§12.2). A function is a pure -// (synthesizable) sub-routine that returns a value; the spec +// declaration (IEEE 1364-2005 Β§10.3, Β§12.2 / Β§A.2.6). A function is +// a pure (synthesizable) sub-routine that returns a value; the spec // forbids delay/event controls inside the body (distinguishing // functions from tasks). Conj record (no Practice-4 ledger). // +// - lifetime the optional `automatic` keyword +// (LifetimeClause); per Β§10.3 function admits +// `[automatic]` (added at sha cb028c7d+ per +// openai-pro REQUEST_CHANGES). +// - return_type the optional function_range_or_type clause +// (FunctionReturnTypeClause); per Β§10.3 function +// admits `[function_range_or_type]` between +// `[automatic]` and the function name (added at +// sha cb028c7d+ per openai-pro REQUEST_CHANGES; +// prior shape collapsed this into body_lexeme). // - name the function identifier (K-1-opaque Symbol) -// - body_lexeme the function body (return-type + arguments + -// statements between `function name;` and +// - body_lexeme the function body (arguments + statements +// between the declaration header and // `endfunction`) as a verbatim lexeme (sub- // grammar deferred to the T-4 LanguageModel β€” -// the return-type declaration + the pure-body -// constraint enforcement live there) +// the pure-body constraint enforcement lives +// there) type FunctionDeclaration { + lifetime: LifetimeClause + return_type: FunctionReturnTypeClause name: Symbol body_lexeme: String } @@ -3803,8 +3898,20 @@ type AnsiModuleItem // codex BLOCKING on PR #3176 2026-05-16. type NonAnsiModuleItem = NonAnsiAnsiCompatItem { item: AnsiModuleItem } - | NonAnsiPortDeclarationItem { attributes: AttributeInstanceClause, port_decl: PortDeclaration } - | NonAnsiBodyPortDeclarationItem { attributes: AttributeInstanceClause, body_port: AnsiPortDeclaration } + | NonAnsiPortDeclarationItem { + // PortDeclaration was dissolved at sha cb028c7d+ per openai-pro + // REQUEST_CHANGES β€” AnsiPortDeclaration's no-net-type variants + // cover the Β§A.2.1.2 input/output/inout [net_type] [signed] + // [range] list_of_port_identifiers production uniformly (bare + // / with-modifiers / with-type-and-modifiers), making the prior + // 2-variant split (PortDeclaration direction-only vs + // AnsiPortDeclaration with-type) a partition gap that lost + // range/signed on `output [7:0] y;` forms. Single AnsiPort + // Declaration carrier here = single authority for non-ANSI + // body port_declarations under Β§12.3.4. + attributes: AttributeInstanceClause, + port_decl: AnsiPortDeclaration + } // ───────────────────────────────────────────────────────────────────── From 83e9f284397b801edb7434c55acb719827235f1c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 18:30:28 +0000 Subject: [PATCH 54/56] v4 T-4.9 verilog: 3-pack openai-pro on-HEAD BLOCKINGs at sha cb028c7d + phrasing sharpening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openai-pro on-HEAD verdict at sha cb028c7d flagged 3 BLOCKINGs: 1. L1710 β€” PortDeclaration partition gap. PortDeclaration carries direction+names only; NonAnsiBodyPortDeclarationItem reuses AnsiPortDeclaration (complete-port). The middle form `output [7:0] y;` (direction + modifiers, no type, type provided by separate later declaration per Β§12.3.3) either loses range/signed (through PortDeclaration) or becomes "falsely complete" (through AnsiPortDeclaration). Per Β§A.2.1.2 input_declaration ::= input [net_type] [signed] [range] list_of_port_identifiers β€” ONE spec production covers all forms via independently-optional net_type / signed / range. Resolution: dissolve PortDeclaration entirely; consolidate NonAnsiPortDeclarationItem + NonAnsiBodyPortDeclarationItem into one variant using AnsiPortDeclaration uniformly. AnsiPortDeclaration's existing no-net-type variants (AnsiInputInoutNoNetType, OutputAnsiNoNetType) cover the direction+modifiers form; the bare form is the {packing=Scalar, signedness=Unsigned} projection. PortDeclaration was a strict subset (representation-duality); dissolution = single carrier, single authority, full Β§A.2.1.2 coverage. 2. L3027 β€” TaskDeclaration/FunctionDeclaration lose Β§10.2/Β§10.3 declaration-boundary facts into body_lexeme. Per spec: - task_declaration: `task [automatic] task_identifier ; ...` - function_declaration: `function [automatic] [function_range_or_type] function_identifier ; ...` Resolution: add two clause Disjs reusing the established pattern: - LifetimeClause = StaticLifetime | AutomaticLifetime (covers `[automatic]` keyword for BOTH task + function) - FunctionReturnTypeClause = NoFunctionReturnType | FunctionReturnTypeLexeme{lexeme} (covers function's optional return range/type; sub-grammar deferred to T-4 LanguageModel via established body_lexeme precedent) TaskDeclaration gains lifetime field; FunctionDeclaration gains lifetime + return_type fields. Full Practice-4 5-pattern ledgers for both new closed Disjs. 3. L4021 β€” NoPortsModule conflates two distinct Β§A.1.2 spec surfaces: `module M;` (port-list brackets entirely absent) vs `module M ();` (brackets present, list empty). Per Β§A.1.2 these are surface-distinct spec forms (parens-absent vs parens- present-empty). Resolution: structural split β€” NoPortsModule renamed and split into NoPortListModule (no parens) + EmptyPortListModule (parens present, empty inner list). VerilogModule grows from 3 β†’ 4 variants. Both new variants carry the same {attributes, module_keyword, name, parameter_port_list, items} shape (style- neutral; items use AnsiModuleItem set excluding body port_declarations per Β§12.3.4). VerilogModule Practice-4 ledger + commentary updated for the 4-way partition. Architectural Qs surfaced (flag-for-verify per surfaced-key-decision rule): - Fix #1: option-space considered: A. Dissolve PortDeclaration; consolidate via AnsiPortDeclaration uniformly. CHOSEN β€” single carrier, single authority; the no-net-type variants already cover the partition gap; PortDeclaration was strict-subset representation-duality. B. Extend PortDeclaration with optional range/signed fields. REJECTED β€” creates parallel representation of the same state- space as AnsiPortDeclaration's no-net-type variants (representation-duality). C. Add 3rd middle-variant for "direction+modifiers-no-type". REJECTED β€” Β§A.2.1.2 has ONE production where net_type / signed / range are independently optional; treating them as discrete spec forms over-partitions. - Fix #3: NoPortListModule + EmptyPortListModule vs Bool flag β€” chose structural split per K-1 no-Bool-as-discriminator. Manager-mandated PHRASING SHARPENING applied (msg_40aefa3d): the UdpDefinition + VerilogModule attribute-rationale comments replaced the temporal "doesn't yet wrap" framing with the structural grammar-level distinction: Β§A.1.2 / Syntax 3-4 / Syntax 3-9 attribute_instance is INTRINSIC to the declaration production (attaching at the declaration boundary); the source_text design- element classifier is the description-level kind-selector at a DIFFERENT grammar level that structurally NEVER carries attribute_instance. So no double-authority NOW NOR AFTER the wrapper lands β€” by spec grammar levels, not by deferral-timing. Forecloses the concern permanently. Shared NonEmptyList scaffold-note: "Twenty-seven" β†’ "Twenty-six" sites. Site 21 (PortDeclaration.names) dissolved with PortDeclaration; remaining 22-27 renumbered to 21-26. grep -c '🟑 spec-non-empty (Β§' invariant: 26 (verified). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 121 +++++++++++++++++++-------- 1 file changed, 85 insertions(+), 36 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 99c2ef46384..33f87d2ec0b 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -2055,7 +2055,7 @@ type ParameterTypeKind // 🟑 TRACKED-SCAFFOLD: spec-non-empty list fields (relayed // disposition from T-4 mgr vivid-carp-207 msg_30a7ec7c, 2026-05-16). // -// Twenty-seven sites in this file carry `List` payloads where IEEE +// Twenty-six sites in this file carry `List` payloads where IEEE // 1364-2005 requires AT LEAST ONE entry β€” the spec-illegal empty // state is structurally representable, the same INVARIANTS P2 // illegal-states-unrepresentable concern codex / openai-pro @@ -2082,7 +2082,7 @@ type ParameterTypeKind // SANCTIONED DEFERRAL (the deferral middle-path, mirroring // collection.dag's own Wave-A2 scaffold + the ptx #3170 / spice #3168 // inhabitance-deferral pattern): -// - Each of the twenty-seven spec-non-empty sites keeps `List` for now. +// - Each of the twenty-six spec-non-empty sites keeps `List` for now. // - Each site carries a back-pointer comment to THIS shared note. // - The empty-list illegal state is a PRODUCER-SIDE invariant // pending the refinement substrate landing. @@ -2091,7 +2091,7 @@ type ParameterTypeKind // `List where non_empty` uniformly in one sweep β€” single- // authority preserved. // -// The twenty-seven spec-non-empty sites (back-pointers to this note): +// The twenty-six spec-non-empty sites (back-pointers to this note): // (sites 25-26 below β€” VerilogModule per-style header_ports) // 1. NetDeclaration.NonTriregIdentifierForm.identifiers (Β§A.2.1.3) // 2. NetDeclaration.NonTriregAssignForm.assignments (Β§A.2.1.3) @@ -2114,13 +2114,17 @@ type ParameterTypeKind // 18. EventDeclaration.event_names (Β§A.2.1.4) // 19. GenvarDeclaration.genvar_names (Β§A.2.1.1) // 20. UdpInstantiation.instances (Β§A.5.2) -// 21. PortDeclaration.names (Β§A.2.1.2) -// 22. AnsiPortDeclaration.AnsiInputPort.names (Β§A.1.3) -// 23. AnsiPortDeclaration.AnsiOutputNetPort.names (Β§A.1.3) -// 24. AnsiPortDeclaration.AnsiOutputVariablePort.names (Β§A.1.3) -// 25. AnsiPortDeclaration.AnsiInoutPort.names (Β§A.1.3) -// 26. VerilogModule.NonAnsiVerilogModule.header_ports (Β§12.3.4) -// 27. VerilogModule.AnsiVerilogModule.header_ports (Β§12.3.4) +// (Former site 21 PortDeclaration.names was DISSOLVED at sha +// cb028c7d+ β€” PortDeclaration itself dissolved into AnsiPortDeclaration +// per openai-pro REQUEST_CHANGES; the Β§A.2.1.2 list_of_port_identifiers +// fact is now uniformly carried by AnsiPortDeclaration's per-direction +// variants at sites 21-24 below.) +// 21. AnsiPortDeclaration.AnsiInputPort.names (Β§A.1.3) +// 22. AnsiPortDeclaration.AnsiOutputNetPort.names (Β§A.1.3) +// 23. AnsiPortDeclaration.AnsiOutputVariablePort.names (Β§A.1.3) +// 24. AnsiPortDeclaration.AnsiInoutPort.names (Β§A.1.3) +// 25. VerilogModule.NonAnsiVerilogModule.header_ports (Β§12.3.4) +// 26. VerilogModule.AnsiVerilogModule.header_ports (Β§12.3.4) // // Sites previously numbered 7-9 added 2026-05-16 per codex // REQUEST_CHANGES on PR #3176 at sha f87fdf189; site previously 10 @@ -3589,8 +3593,16 @@ type UdpDefinition { // per openai-pro REQUEST_CHANGES on PR #3176 sha f9159ce8b (Layer- // Model BLOCKING: top-level UDP attributes had no typed home; reuses // the existing AttributeInstanceClause Disj). No double-authority - // concern: the source_text design-element classifier is deferred to - // the bundled T-4 LanguageModel and doesn't yet wrap UdpDefinition. + // concern by grammar-level distinction (not by deferral-timing): + // the Β§A.1.2 / Syntax 3-9 attribute_instance prefix is INTRINSIC + // to the udp_declaration production, attaching at the declaration + // boundary itself. The source_text design-element classifier (when + // the bundled T-4 LanguageModel lands it) is the description-level + // {module | udp | config} KIND-SELECTOR β€” a different grammar level + // that structurally NEVER carries attribute_instance. So there is + // no double-authority NOW NOR AFTER the wrapper lands: by spec + // grammar levels, the attribute_instance lives ON the declaration + // (here) and not on the kind-selector. attributes: AttributeInstanceClause name: Symbol body_lexeme: String @@ -4049,11 +4061,18 @@ type ModuleKeyword // the single representation of the no-ports state; the per- // style variants now have spec-non-empty header_ports) // -// - NoPortsModule -// β€” `module M; ... endmodule` form: no header port list. -// Style-neutral (the Β§12.3.4 ANSI-vs-non-ANSI distinction -// loses meaning when there are no ports). Items use the -// AnsiModuleItem set, which excludes body port_declarations. +// - NoPortListModule +// β€” `module M; ... endmodule` form: Β§A.1.2 port-list brackets +// entirely absent (no parens). Style-neutral. +// - EmptyPortListModule +// β€” `module M (); ... endmodule` form: Β§A.1.2 port-list +// brackets PRESENT but inner list EMPTY. Distinct spec +// surface from NoPortListModule per Β§A.1.2 (split at sha +// cb028c7d+ per openai-pro REQUEST_CHANGES β€” prior single +// NoPortsModule variant conflated the two distinct spec +// forms, losing surface fidelity for parse/emit). Style- +// neutral; items use the AnsiModuleItem set (excludes body +// port_declarations). // - NonAnsiVerilogModule // β€” non-ANSI style: header carries port-EXPRESSIONS only // (List); body carries the full NonAnsiModuleItem @@ -4135,35 +4154,65 @@ type ModuleKeyword // NOT one generic `F` / projection over a single source set // (Practice 7). The compound payload-type difference IS the // partition's defining structural fact. -// Terminal: the closed three-way Verilog module-declaration-style -// classifier of the IEEE 1364-2005 Β§12.3.4 spec (NoPortsModule + -// per-style variants); ledger added per codex BLOCKING on PR #3176 -// 2026-05-16, NoPortsModule variant added at sha 7709c9968 per +// Terminal: the closed four-way Verilog module-declaration-style +// classifier of the IEEE 1364-2005 Β§A.1.2 / Β§12.3.4 spec +// (NoPortListModule + EmptyPortListModule + per-style variants); +// the NoPortListModule/EmptyPortListModule split (sha cb028c7d+, +// openai-pro REQUEST_CHANGES) distinguishes parens-absent from +// parens-present-empty per Β§A.1.2. Original ledger added per codex +// BLOCKING on PR #3176 2026-05-16, NoPortsModule variant added at +// sha 7709c9968 per // openai-pro REQUEST_CHANGES (line 3525 β€” no-port-list // representation-duality + non-ANSI body port_declarations with // empty header). -// All 3 variants carry `attributes: AttributeInstanceClause` per +// All 4 variants carry `attributes: AttributeInstanceClause` per // IEEE 1364-2005 Syntax 3-4: `module_declaration ::= { attribute_ // instance } module_keyword ... endmodule` β€” `(* optimize_power *) // module M ... endmodule` is legal spec form. Field added at sha // 7b7dd0b54+ per openai-pro REQUEST_CHANGES on PR #3176 sha // f9159ce8b (Layer-Model BLOCKING: top-level module attributes had // no typed home; reuses the existing AttributeInstanceClause Disj). -// No double-authority concern: the source_text design-element -// classifier is deferred to the bundled T-4 LanguageModel and -// doesn't yet wrap VerilogModule. +// No double-authority concern by grammar-level distinction (not by +// deferral-timing): the Β§A.1.2 / Syntax 3-4 attribute_instance +// prefix is INTRINSIC to the module_declaration production, +// attaching at the declaration boundary itself. The source_text +// design-element classifier (when the bundled T-4 LanguageModel +// lands it) is the description-level {module | udp | config} +// KIND-SELECTOR β€” a different grammar level that structurally +// NEVER carries attribute_instance. So there is no double-authority +// NOW NOR AFTER the wrapper lands: by spec grammar levels, the +// attribute_instance lives ON the declaration (here) and not on +// the kind-selector. type VerilogModule - = NoPortsModule { - // `module M; ... endmodule` (no port list at all). Style- - // neutral: with no header ports, the Β§12.3.4 ANSI-vs-non-ANSI - // distinction loses meaning (the distinction is defined by - // whether port direction lives in header or body β€” both - // collapse to "no ports anywhere"). Items use the - // AnsiModuleItem set (which excludes NonAnsiPortDeclarationItem - // / NonAnsiBodyPortDeclarationItem) because there are no - // header ports for body port_declarations to reference per - // Β§12.3.4 β€” so admitting body port_declaration items here - // would be a spec-illegal state. + = NoPortListModule { + // `module M; ... endmodule` β€” the Β§A.1.2 `[list_of_ports]` / + // `[list_of_port_declarations]` brackets are ENTIRELY absent + // (no parens around the port-list position in the spec form). + // Style-neutral: with no header port-list, the Β§12.3.4 + // ANSI-vs-non-ANSI distinction loses meaning. Distinct from + // EmptyPortListModule below per Β§A.1.2 surface fact (parens- + // absent vs parens-present-empty) β€” openai-pro REQUEST_CHANGES + // on PR #3176 sha cb028c7d at line 4021: prior NoPortsModule + // conflated these two distinct spec forms, losing a Β§A.1.2 + // surface fact the language model otherwise preserves for + // parse/emit fidelity. Items use the AnsiModuleItem set + // (excludes body port_declaration variants β€” body + // port_declarations would reference non-existent header port + // names per Β§12.3.4). + attributes: AttributeInstanceClause, + module_keyword: ModuleKeyword, + name: Symbol, + parameter_port_list: ModuleParameterPortList, + items: List + } + | EmptyPortListModule { + // `module M (); ... endmodule` β€” the Β§A.1.2 port-list brackets + // are PRESENT but the inner list is EMPTY. Distinct spec + // surface from NoPortListModule above (parens-present-empty + // vs parens-absent). Same style-neutrality and item-set + // reasoning as NoPortListModule (no header ports β†’ no body + // port_declarations admissible). Variant added at sha + // cb028c7d+ per openai-pro REQUEST_CHANGES (line 4021). attributes: AttributeInstanceClause, module_keyword: ModuleKeyword, name: Symbol, From ec33a09339c39d12c1c24daea644a7ebbd52323e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 16:23:49 -0400 Subject: [PATCH 55/56] WIP: T-4.9 verilog --- src/v4/extdeps/languages/verilog.dag | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index 33f87d2ec0b..f5fd64b3caf 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -359,7 +359,10 @@ type PortDirection // as a distinct top-level NetType variant rather than here. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 🟑 YELLOW (deferred-on-consumer; re-scoped under #3200 rule-change +// 2026-05-16 β€” namable richer source exists; see #3200 RE-SCOPE +// footer before the type declaration below). Ledger β€” five patterns +// attempted: // 1. Fact placement β€” FAILS: every net-declaration emitter + // every driver-resolution consumer reads the net-type tag // uniformly; shared classifier. From 20deaa48c0ce3466e0ee8da30220027bc8722477 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 16 May 2026 20:25:43 +0000 Subject: [PATCH 56/56] =?UTF-8?q?v4=20T-4.9=20verilog:=20re-scope=205=20Ti?= =?UTF-8?q?er-1=20Practice-4=20ledgers=20=F0=9F=9F=A2=20GREEN=20=E2=86=92?= =?UTF-8?q?=20=F0=9F=9F=A1=20YELLOW=20per=20#3200=20rule-change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #3200 (docs/modeling-discipline.md rule-change MERGED on origin/main 2026-05-16 19:53:37Z): GREEN is now consumer-INDEPENDENT. A coproduct is GREEN only if NO richer source EXISTS; "no consumer needs the decomposition yet" is no longer GREEN β€” it is 🟑 YELLOW deferred-on-consumer with a named first-meaning-consumer trigger and a pre-assigned obligation on that consumer. Per merry-ibex-337's authoritative cross-PR audit, #3176's Tier-1 mis-GREEN list under #3200 is exactly FIVE: 1. NonTriregNetKind β€” axes: {resolution_function, default_when_undriven, driver_arity, designer_intent_marker}; trigger: first consumer of net-resolution semantics; obligation: {resolution, default, arity} record at consumer. 2. VariableDeclaration β€” axes: {storage-class, width, signedness, algebra-grounding}; trigger: first consumer of variable-storage / algebra semantics (D2 inhabitance pathway); obligation: structural decomposition into the storage-class matrix at consumer. 3. OutputPortAnsiVariableTypeKind β€” same storage-class family as VariableDeclaration (output-admissible subset; real/realtime excluded per Β§12.3.3); same D2 trigger + obligation. 4. ParameterTypeKind β€” same storage-class family as VariableDeclaration (compile-time-constant variant at parameter position); same D2 trigger + obligation. 5. PrimitiveGateKind β€” axes: {gate-family, logic-function, inversion, polarity, controllable-enable, resistive, transmission}; trigger: first consumer of gate-class semantics (elaboration / simulation dispatch); obligation: gate-family matrix at consumer. Comment-only edit: 5 Practice-4 ledger headers flipped 🟒 GREEN β†’ 🟑 YELLOW + 5 "#3200 RE-SCOPE" footers added before each type's declaration with axes + trigger + obligation. NO carrier shape / field-type / code / import changes β€” purely the Practice-4 classification labels updated. The 14 over-flagged in the worker's duplicate sweep (PortDirection, EdgeTrigger, ProceduralAssignKind, Signedness, VectorednessClause, NonAnsiPort, AnsiPortDeclaration, AlwaysBlockSensitivity, PortConnections, ParameterOverrides, LifetimeClause, AnsiModuleItem, ModuleKeyword, VerilogModule) STAND DOWN β€” clean per merry-ibex-337's authoritative cross-PR list (small binary present/absent partitions and presence-form Disjs are terminal under #3200's namable-richer-source test). Rule-change-attributed: each footer explicitly notes "correct under pre-#3200 consumer-DEPENDENT rule, re-scoped under post-#3200 consumer-INDEPENDENT rule." Not a prior error; a rule re-scope. grep -c '🟒 GREEN' = 36 (was 41); grep -c '🟑 YELLOW (deferred-on-consumer; re-scoped under #3200' = 5; grep -c '^// #3200 RE-SCOPE (rule-change' = 5. Invariants intact. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4/extdeps/languages/verilog.dag | 130 ++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 4 deletions(-) diff --git a/src/v4/extdeps/languages/verilog.dag b/src/v4/extdeps/languages/verilog.dag index f5fd64b3caf..94f064907b5 100644 --- a/src/v4/extdeps/languages/verilog.dag +++ b/src/v4/extdeps/languages/verilog.dag @@ -380,6 +380,31 @@ type PortDirection // preserves writer intent). // Terminal: the closed eleven-way non-trireg net-type-keyword // classifier of the IEEE 1364-2005 spec. +// +// #3200 RE-SCOPE (rule-change 2026-05-16, docs/modeling-discipline.md +// merged on origin/main): under the pre-#3200 consumer-DEPENDENT +// GREEN rule this Disj was correctly GREEN (no consumer needed the +// decomposition yet, so structural extraction was deferred). Under +// the post-#3200 consumer-INDEPENDENT rule this is 🟑 YELLOW +// because a namable richer source EXISTS: +// Axes: {resolution_function, default_when_undriven, driver_arity, +// designer_intent_marker} +// Resolution: Wire/Tri=X-on-conflict; Wand/TriAnd=AND; +// Wor/TriOr=OR; Tri0=pull0; Tri1=pull1; Supply0=const0; +// Supply1=const1; Uwire=single-driver-required +// Default-when-undriven: Wire/Tri/Wand/Wor=X; Tri0=0; Tri1=1; +// Supply0=0; Supply1=1; Uwire=N/A +// Driver-arity: multi-driver-resolution (Wire/Wand/Wor/Tri*); +// power-rail (Supply0/1); exactly-one (Uwire) +// Designer-intent marker: Tri/TriAnd/TriOr (semantically- +// equivalent partner variants kept distinct for parse∘emit +// writer-intent preservation) +// Trigger: first consumer of net-resolution semantics (synthesizer +// dispatch / driver-resolution walker). +// Obligation: the first meaning-consumer owes structural +// decomposition into a {resolution, default, arity} record AT +// the consumer site β€” NOT a local match-over-keyword lookup in +// this carrier. type NonTriregNetKind = Wire | Tri @@ -1318,7 +1343,10 @@ type NetIdentifierDeclarator { // would EDIT this Disj explicitly). // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 🟑 YELLOW (deferred-on-consumer; re-scoped under #3200 rule-change +// 2026-05-16 β€” namable richer source exists; see #3200 RE-SCOPE +// footer before the type declaration below). Ledger β€” five patterns +// attempted: // 1. Fact placement β€” FAILS: every variable-declaration emitter, // every procedural-assignment legality check (only RegVariable // is a legal procedural-assignment destination), every signed- @@ -1361,6 +1389,31 @@ type NetIdentifierDeclarator { // Terminal: the closed five-variant Verilog variable-declaration // classifier; illegal kindΓ—packing AND kindΓ—signedness combinations // are unrepresentable by construction. +// +// #3200 RE-SCOPE (rule-change 2026-05-16, docs/modeling-discipline.md +// merged on origin/main): under the pre-#3200 consumer-DEPENDENT +// GREEN rule this Disj was correctly GREEN (D2 inhabitance not yet +// landed). Under the post-#3200 consumer-INDEPENDENT rule this is +// 🟑 YELLOW because a namable richer source EXISTS: +// Axes: {storage-class, width, signedness, algebra-grounding} +// RegVariable: storage=mutable-bit-vector; width=packing-payload; +// signedness=signedness-payload; algebra=Semiring/OrderedRing +// per packingΓ—signedness +// IntegerVariable: storage=fixed-int; width=32; signedness= +// signed-fixed; algebra=OrderedRing> +// RealVariable: storage=ieee754-double; width=64; signedness= +// ieee754-internal; algebra=ApproximateField +// TimeVariable: storage=sim-time-counter; width=64; signedness= +// unsigned-fixed; algebra=Semiring> +// RealTimeVariable: aliased to RealVariable per spec Β§3.7.2 +// (parse∘emit preserves the keyword); same algebra-grounding +// as RealVariable +// Trigger: first consumer of variable-storage / algebra semantics +// (algebra inhabitance lens β€” D2 pathway). +// Obligation: the first meaning-consumer (D2 inhabitance work) owes +// structural decomposition into a {storage-class, width, +// signedness, algebra} record AT that consumer β€” NOT a local +// match-over-kind lookup in this carrier. type VariableDeclaration // declarators: 🟑 spec-non-empty (Β§A.2.4 / Β§7.4) β€” deferred to // std/collection.dag Wave-A2 `List where non_empty` refinement; @@ -1601,7 +1654,10 @@ type OutputPortAnsiNetTypeKind // CLOSED (C1 stop-signal). Three-way variable-form output partition. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Five-pattern ledger abbreviated: +// 🟑 YELLOW (deferred-on-consumer; re-scoped under #3200 rule-change +// 2026-05-16 β€” namable richer source exists; see #3200 RE-SCOPE +// footer before the type declaration below). Five-pattern ledger +// abbreviated: // 1. Fact placement β€” FAILS: shared output-port classifier. // 2. Variant-is-data β€” FAILS: collapsing to `{kind, packing?, // signedness?}` admits the Β§12.3.3 illegal `output real` / @@ -1617,6 +1673,24 @@ type OutputPortAnsiNetTypeKind // Terminal: the closed three-way Verilog ANSI-output-port VARIABLE- // form type/kind classifier; real/realtime outputs unrepresentable // by construction per Β§12.3.3. +// +// #3200 RE-SCOPE (rule-change 2026-05-16, docs/modeling-discipline.md +// merged on origin/main): under the pre-#3200 consumer-DEPENDENT +// GREEN rule this Disj was correctly GREEN. Under the post-#3200 +// consumer-INDEPENDENT rule this is 🟑 YELLOW because a namable +// richer source EXISTS β€” same {storage-class, width, signedness, +// algebra-grounding} matrix as VariableDeclaration (output-admissible +// subset: real/realtime structurally excluded per Β§12.3.3): +// OutputAnsiRegType: same as RegVariable +// OutputAnsiIntegerType: same as IntegerVariable +// OutputAnsiTimeType: same as TimeVariable +// Trigger: first consumer of variable-storage / algebra semantics +// (D2 inhabitance pathway β€” shared with VariableDeclaration +// consumer). +// Obligation: the first meaning-consumer owes structural +// decomposition into the same {storage-class, width, signedness, +// algebra} record consumed for VariableDeclaration β€” single- +// authority across the storage-kind family. type OutputPortAnsiVariableTypeKind = OutputAnsiRegType { packing: PackingShape, signedness: Signedness } | OutputAnsiIntegerType @@ -2021,7 +2095,10 @@ type AnsiOutputPortDeclarator { // this five-way parameter-type partition. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 🟑 YELLOW (deferred-on-consumer; re-scoped under #3200 rule-change +// 2026-05-16 β€” namable richer source exists; see #3200 RE-SCOPE +// footer before the type declaration below). Ledger β€” five patterns +// attempted: // 1. Fact placement β€” FAILS: every parameter consumer (override- // conversion per Β§12.1.3, type-check legality, emission) // reads the type kind uniformly; shared classifier. @@ -2046,6 +2123,27 @@ type AnsiOutputPortDeclarator { // VariableDeclaration's kind Γ— packing Γ— signedness // dissolution. // Terminal: the closed five-way Verilog parameter-type classifier. +// +// #3200 RE-SCOPE (rule-change 2026-05-16, docs/modeling-discipline.md +// merged on origin/main): under the pre-#3200 consumer-DEPENDENT +// GREEN rule this Disj was correctly GREEN. Under the post-#3200 +// consumer-INDEPENDENT rule this is 🟑 YELLOW because a namable +// richer source EXISTS β€” same {storage-class, width, signedness, +// algebra-grounding} matrix as VariableDeclaration / OutputPortAnsi +// VariableTypeKind (compile-time-constant variant at parameter +// position): +// UntypedParameter: packing-payload + signedness-payload +// (inferred from default-value expression) +// IntegerParameter: same as IntegerVariable +// RealParameter: same as RealVariable +// TimeParameter: same as TimeVariable +// RealTimeParameter: same as RealTimeVariable (aliased to Real) +// Trigger: first consumer of parameter-storage / algebra semantics +// (D2 inhabitance pathway β€” shared with the +// VariableDeclaration / OutputPortAnsiVariableTypeKind family). +// Obligation: the first meaning-consumer owes structural +// decomposition into the same storage-class matrix used for +// VariableDeclaration β€” single-authority across the family. type ParameterTypeKind = UntypedParameter { packing: PackingShape, signedness: Signedness } | IntegerParameter @@ -3313,7 +3411,10 @@ type LocalParameterDeclaration { // primitive-gate partition; SystemVerilog adds no new primitives. // // Coproduct dissolution (Practice 4 / modeling-discipline.md Β§4) β€” -// 🟒 GREEN (terminal). Ledger β€” five patterns attempted: +// 🟑 YELLOW (deferred-on-consumer; re-scoped under #3200 rule-change +// 2026-05-16 β€” namable richer source exists; see #3200 RE-SCOPE +// footer before the type declaration below). Ledger β€” five patterns +// attempted: // 1. Fact placement β€” FAILS: every gate-emission consumer + every // per-gate terminal-arity check + every per-gate drive-strength // legality check reads the kind tag uniformly; shared @@ -3337,6 +3438,27 @@ type LocalParameterDeclaration { // partition is irreducible. // Terminal: the closed twenty-six-way Verilog primitive-gate-kind // classifier of the IEEE 1364-2005 Β§7 spec. +// +// #3200 RE-SCOPE (rule-change 2026-05-16, docs/modeling-discipline.md +// merged on origin/main): under the pre-#3200 consumer-DEPENDENT +// GREEN rule this Disj was correctly GREEN. Under the post-#3200 +// consumer-INDEPENDENT rule this is 🟑 YELLOW because a namable +// richer source EXISTS: +// Axes: {gate-family, logic-function, inversion, polarity, +// controllable-enable, resistive, transmission} +// Logic-family + inversion: and/or/not/buf/nand/nor/xor/xnor +// Controllable-enable + polarity: bufif0/bufif1/notif0/notif1 +// CMOS-switch + resistive + polarity: cmos/rcmos/nmos/rnmos/ +// pmos/rpmos +// Transmission-gate + resistive + controllable + polarity: +// tran/rtran/tranif0/tranif1/rtranif0/rtranif1 +// Pull-resistor + polarity: pulldown/pullup +// Trigger: first consumer of gate-class semantics (elaboration / +// simulation dispatch β€” the per-gate-class admissibility table +// for drive_strength / delay / terminal-arity). +// Obligation: the first meaning-consumer owes structural +// decomposition into the gate-family matrix AT that consumer β€” +// NOT a local match-over-keyword lookup in this carrier. type PrimitiveGateKind = GateAnd | GateNand