Repository navigation
Test generate-block names that bind to their own block (§6.18, §8.13, §14.3, §15.5.1, §16.8, §23.6, §25.9) - #989
Open
philipaxer wants to merge 32 commits into
Open
philipaxer wants to merge 32 commits into
philipaxer wants to merge 32 commits into
Conversation
The object model builds the tree on its own parse and reads each construct's implicit name. A directly nested branch opens no generate scope; its inner blocks are walked in the enclosing scope.
Each HierarchicalIdentifier built by the simulator starts unbound. The audit variable is listed in the env var registry.
…§23.9) The function declaration built for a compiled task carries the task's `decl`.
… §13.5.3, §18.7, §18.12, §3.12.1) New `generate_block_hiding` runs programs where an inner scope hides a block's subroutine, and programs where a name still binds to it. `bind_audit` expects `target=` on each line and no rename of the hidden name, which no longer disagrees.
…l block, gate, property, sequence, let and constraint (§23.9, §8, §9.2.3, §11.13, §16.12, §18.5.11, §28) The bind audit test's final-block call now reads as renamed to g.f, with no group.
…11, §26.3) Ten programs: a child in a block, a block function before the module's, a parent instance's before the top's, generate loops in an instance, nested and unlabelled blocks, a grandchild and a bound instance, task enables, function bodies and continuous assigns of the child. The child's unit and imports come first, a parent's import is not visible, rooted and dotted calls are unchanged. The bind audit prints where each upward call resolves.
Core names the data of an unlabelled generate block `genblk1.x`, so a read of `genblk1.x` finds its signal directly. The value lookup and the sensitivity lookup no longer retry a missed name with its `genblk<n>` segments removed, which would read a module-level `x` for `genblk1.x`.
…§23.9) Two unlabelled blocks or case arms each own their variable, parameter and net; a block's variable hides the module's, at the top and in an instance; a labelled block in two unlabelled ones is two scopes; ports filled by `.*` and `.d, .q` read the block's net; `genblk1.x` and `genblk02.x` reach the data from outside. A bare read of a direct nest's data from the module is undeclared (§23.9).
Core's `VarDeclarator` carries the declaration id the binder writes (§23.9). The declarators the simulator builds for a function's result variable and for scalarized struct members are not in any scope tree.
…§6.21, §23.8.1) A nested local of a block task hides the block's variable. Final blocks, gates, classes, clocking blocks, properties and sequences of a block read the block's own variable or parameter, at the top, in instances and in loop iterations. A block parameter sizes a process local. A class member, local or formal named like a block hides its data in an instance. A constraint reads block data by its bare name. A bare call from a child passes a variable of that name in its parent's block.
Two blocks each size their variables, function formals and results, casts and struct members by their own typedef, at the top, in an instance and in unlabelled blocks. A block's typedef hides the module's inside the block only, reaches a nested block, a process local, a task local, a loop variable and a constraint cast, and is hidden by a procedural typedef. A block struct reaches a child port in two instances. An enum typedef of a block names its members.
The audit pin of a block function's calls reads `pos=process/call` and `pos=final/call`; the local of the same name keeps `pos=process`.
The lint skips an implicit block name it has no record of, such as a block holding only processes. Core rejects an implicit name that names no block.
….9, §26.6, §27.6) - `tests/hierarchy/undeclared_names_by_binding.rs`: bare reads, writes and calls of names in a generate block, a child instance or the parent are undeclared in an instance; an upward call that the search does not find is undeclared; `genblk1` and `genblk7` naming no block are undeclared; a net initializer, a continuous assignment and a module read of a block's implicit net with no declaration are errors. Upward calls and paths, existing implicit block names, concatenated implicit nets, a block's implicit net in its own block, the built-in randomization methods, a randsequence value, a design-unit name, the bare names 6a binds and names read through `export *::*` stay accepted; a name a package imports without exporting stays undeclared through it. A parameter-bounded enum range declares no names (A.2.4). - `tests/types/package_scope_resolution.rs`: the chained-import program is illegal without an export (§26.6) and is now an error; the width assertions move to the same program with `export core_pkg::*`.
A type name the simulator builds carries `bound: UNSET`; only the binder writes a binding.
… §14.3, §15.5.1, §16.8, §23.6, §25.9) A nested block's typedef, property, sequence, class base, clocking event and event keep that block's declaration through both renames; a path through the outer block calls the outer block's function; an interface instance of a block passed to a class is declared. Outputs as Verilator 5.055 prints them.
This was referenced Nov 9, 2026
Closed
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 12 of the series for #952, which replaces name-string scoping in generate blocks with a scope tree and a binder.
Depends on #981: until that merges, this branch also shows its commits. New here:
3893d6d1Give synthesized type names an unset binding (§23.9)7570b07eTest generate-block names that bind to their own block (§6.18, §8.13, §14.3, §15.5.1, §16.8, §23.6, §25.9)5fdfdc2aSync core revisionCore side: aionhw/xezim-core#184 (pinned at
6980742; the last commit, "Sync core revision", sets the pin).Changes:
Tests:
tests/hierarchy/generate_rename_by_binding.rs(7 tests): in a block nested in another, the block's typedef, property and sequence, class base, clocking event and event are its own through both renames; a path through the outer block calls the outer block's function (11); an interface instance of a block passed to a class is declared and written through (value=17). Each output is Verilator 5.055's.The results and what is not covered are in the core PR.
Tests after the rebase onto main
Rebased onto core
5b0b02eand xezim2e4e7f99. The results above were measured before the rebase, against the previous PR of the series.cargo test: 502 passed, 0 failed.cargo test --release --test hierarchy(built without LTO): 938 passed, 0 failed.The series
This PR is one part of a stacked series for #952. This section is the same in every part, so each PR can be read on its own.
Problem. A generate block is a scope (§23.9, §27.5, §27.6), but xezim resolved names in generate blocks by string. The elaborator renamed declarations textually (
f→g.f) from per-block name lists, and the simulator retried a missed name by its last segment at run time. Each fix to that scheme, including the one for #897, broke other legal programs: a local hiding a block function was renamed anyway, items outside the copied list kept the bare name, two unlabelled blocks with the same variable collided, a child instance's call reached the wrong parent, anddisable g.tmatched by leaf.Approach.
scope_tree.rs).elaborate/bind.rs).g.f,u.g[1].x,genblk2.t) are the keys the runtime already uses, so xezim needs almost no source change.XEZIM_BIND_AUDIT=1prints each binding next to what the rename did, so every disagreement can be listed.Parts (core / xezim; each depends on the one before and repeats its commits until that merges):
genblk<n>, §27.6 zero padding, §27.5 direct nesting) come from itdisableby path and by label is bound like other names (§9.6.2)genblk<n>Independent of the series: #969 (time scope and clocking of a block in an instance) and #970 (a subroutine with no written lifetime stays static on the compiled tier).
Still to come.
The run-time retries by leaf name stay. They serve shapes the binder cannot decide before the run (a class method calling its instance's task,
g[k].f()with a variable index, virtual interfaces) and name resolution outside generate blocks (interface ports,$root, packages).Size so far (parts 1 to 13 against main): core +4,476/-1,066 outside tests (net +3,410), +2,458 tests; xezim +198/-101 outside tests, mostly the core pin, +3,550 tests.
Testing. Every part passed the full xezim suite and the core suite before the rebase onto main. After the rebase, part 7 passed the full suites on main, and parts 8 to 13 passed the
hierarchyand core suites. CI runs the rest. Each part's audit and artifact identity against the previous part are in its own text. Expected values come from IEEE 1800-2023 and are checked against Verilator 5.055 where it accepts the program.Review order. Parts 1 and 2 are the base; the rest read from them. Reviewing those two first settles the direction.