Repository navigation
Test that generate-block data is hidden and named by binding (§23.9, §6.21, §23.8.1) - #971
philipaxer wants to merge 22 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.
|
Integrated by cherry-pick with @philipaxer's authorship preserved, as the whole series: xezim-core 38f31c3…d802056 (core #171–#183) and xezim 163df958…554812e6 (#962–#981). Each layer has a code commit and a test commit, with #952 in the subjects. The per-layer "Sync core revision" commits were replaced by one sync to the final core revision. Follow-ups for gaps found in review, each checked against the reference simulator:
Two cases are left: a Published in xezim 603c9bf3 with xezim-core 212dde0. |
Part 8 of the series for #952, which replaces name-string scoping in generate blocks with a scope tree and a binder.
Depends on #968: until that merges, this branch also shows its commits. New here:
fdab8e3aLeave the declaration id unset on synthesized variable declarators7760987fTest that generate-block data is hidden and named by binding (§23.9, §6.21, §23.8.1)33188b58Sync core revisionCore side: aionhw/xezim-core#180 (pinned at
38136ff; the last commit, "Sync core revision", sets the pin).Changes:
declfield to unset.Tests:
tests/hierarchy/generate_block_data_hiding.rs: 19 tests. 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 and formal hide block data, also when named like the block in an instance (§23.9, §8.3). 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. Verilator 5.055 agrees on each program but the upward call, which it rejects.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: 477 passed, 0 failed.cargo test --release --test hierarchy(built without LTO): 887 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.