Skip to content

v0.23.1 - #500

Merged
soronpo merged 6 commits into
mainfrom
training
Aug 25, 2026
Merged

v0.23.1#500
soronpo merged 6 commits into
mainfrom
training

Conversation

@soronpo

@soronpo soronpo commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

soronpo and others added 6 commits August 25, 2026 00:32
…process

DropLocalDcls Rule 5 recognized a combinational scope only as a
process(all) block, but the stage really runs pre-lowering (the
ExplicitState dependency edge pulls it in before ToED, and the
BackendPrepStage slot is then deduped), so a variable hoisted out of a
conditional sitting directly in an RT domain body received no don't-care
default and inferred a latch in the generated always_comb.

A non-process RT domain body (design or domain block) is combinational
by construction and is wrapped in process(all) by ToED, so it now
receives the same default. A DF domain body stays excluded:
ExplicitState resolves an undriven path there to implied state, which a
per-activation default would break.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mpiler-named selections

A value the compiler names for backend syntax (e.g. NamedVerilogSelection
naming a bit-selection prefix) becomes a declared signal, so verilator's
UNUSEDSIGNAL reports its unread bits, a warning the user's anonymous
source has no handle on. Unused.Quiet now carries an optional bit range,
and NamedAliases annotates the bits none of the group's readers
statically select, one annotation per contiguous range. The verilator
config printer turns these into bit-precise waivers, joining a signal's
ranges the way verilator prints them in one message ('x'[7:5,2:0]).
Being a printed annotation rather than a tag, a printed stage output
re-elaborates to the same waivers (print-safe fix-point).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…are linters quiet

Reading the sign bit by shift leaves a width-wide result whose consumers in the
signed ordering macros (`!`, `&&`) are 1-bit logical operators, so verilator's
WIDTHTRUNC flagged every use site (32 warnings on util.SignedCmpSim, an error
under --Werror-tool). The shift leaves only the sign bit, so a reduction-OR
equals it exactly while producing a genuine 1-bit value, with no 32-bit
constant mixing to trade in a WIDTHEXPAND instead. Conformance verified by
util.SignedCmpSim under both verilator and iverilog on v95.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on checks pin relative positions

With `Werror` the warnings ARE errors: they now travel the error channel with their full
content (trapped as an exception or printed per `OnError`), instead of being unconditionally
pre-printed to stderr with only a generic error taking their place. ElaborationChecksSpec sets
`WError = true` file-wide, so its warning-producing designs assert their warnings' full content
like any other error and nothing leaks to the console (the given must be file-scoped: the
plugin-generated `__dfc` cannot capture a method-local given).

`assertElaborationErrors` now rewrites same-file positions in the obtained message to offsets
from the assertion's munit.Location anchor (the line the call's last argument list closes on):
`L-9:17` reads "nine lines above". Expected strings are authored in the same relative form, so
they survive line churn anywhere outside their own test (previously a single inserted line
broke every expectation below it), and a failure's diff shows the correct form to paste. All 68
expectations migrated; the one manual try/catch test routes through the same relativization.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…as phantom ports

A domain member selected on an anonymous container instance (`val r = new
RTDomain: ...`) has no symbol: the refinement-typed selection compiles to a
`scala.reflect.Selectable` call (`r.selectDynamic("q")` cast to the member
type), which the symbol-path-based capture discovery could not see. A `<> DFRET`
method body reading such a member therefore captured the domain OBJECT as a
plain Scala value and kept the member reference in the body, elaborating as an
illegal direct cross-design reference that crashed `directRefCheck` with
`NoSuchElementException: key not found: "OW_..."` (issue #493).

The capture machinery now recognizes the reflective-selection shape (path
elements widened to `Symbol | String`, the literal member name standing in for
the missing symbol) across discovery, phantom replacement, and PureCheck's
phantom-name prediction, and `directRefCheck` resolves a referenced member's
owner defensively, reporting a foreign member as the direct-reference error it
is instead of crashing on the per-design sub-DB refTable miss.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Class designs have no phantom rigging for non-constant captures (unlike
methods), so a nested design class reading the enclosing design's values
elaborated as an illegal direct cross-design reference, and a captured PORT
crashed the foreign-port reference machinery outright (`None.get` in
`foreignPortSelectOpt`, which models child instances only) — the issue #493
follow-up shape. `MetaContextPlacerPhase.prepareForTypeDef` now rejects the
declaration at compile time, next to the final/case-class/anonymous-interface
rules.

Named classes only: an anonymous design instance with a body is the
via-connection idiom (`val id = new ID(): this.x <> ...`) and stays legal, and
the plugin's own instantiation anon-classes never reach this hook. The
ClassDesignKeySpec local-class capture-key test now hosts its local class in a
factory def outside the design, preserving the identical printed output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@soronpo
soronpo merged commit 0423aae into main Aug 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant