Reserve definition parameter names in the module namespace - #721
Open
Shubham-Padkonde wants to merge 1 commit into
Open
Shubham-Padkonde wants to merge 1 commit into
Shubham-Padkonde wants to merge 1 commit into
Conversation
SystemVerilog.definitionParameters names were emitted straight into the module header without ever passing through the module's Namer, so they did not participate in the shared namespace that ports, signals and instances share. A parameter could therefore take a name that was already in use, and the generated module declared the same identifier twice: module Colliding #( parameter int a = 3 input logic [7:0] a, ... Reserve the parameter names alongside the port names when the Namer for a module is built. A signal or instance that would have picked the same name is now uniquified away from it, and a parameter that collides with a name which cannot move -- a port, or a reserved internal signal -- throws UnavailableReservedNameException during build instead of producing an illegal module. Fixes intel#611 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This branch has not been deployed
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.
Description & Motivation
SystemVerilog.definitionParametersare emitted straight into the module header by_verilogParameters, without ever passing through the module'sNamer. Ports, internal signals and submodule instances all share one namespace managed by thatNamer/Uniquifier; parameters were simply not part of it. So a parameter could take a name that was already in use, and the generated module declared the same identifier twice.On
mainatd22fe80, a module with inputa, outputband an internal signalmyInternal:aparameter int a = 3alongsideinput logic [7:0] a,bparameter int b = 3alongsideoutput logic [7:0] bmyInternalparameter int myInternal = 3alongsidelogic [7:0] myInternal;All three are illegal SystemVerilog — a parameter and a port/variable cannot share an identifier in the same scope.
The fix reserves the parameter names in the shared namespace when the
Namerfor a module is built, right after the port names. That gives the three outcomes the namespace already implies for everything else:a,b)UnavailableReservedNameExceptionat build — a port name cannot movemyInternal_0;parameter int myInternal = 3stands, and the module is legalUnavailableReservedNameException— the user asked for both names explicitly, so neither can moveThis also means a duplicate parameter name within one module now throws rather than emitting the declaration twice.
I put the reservation in
Namer.forModulerather than in the SystemVerilog synthesis result because that is where the namespace is established, so instances and signals allocated later automatically route around the parameter names instead of needing a second collision check at emit time.Related Issue(s)
Fixes #611
Testing
New
test/sv_param_naming_test.dartcovers all four rows of the table above:The three throwing cases fail on the unpatched tree (they generate the illegal module instead of throwing).
Full suite,
dart test -j 3, cleanmainversus this branch:The +5 is exactly the new tests here; skips and failures are identical. All 772 failures are Icarus Verilog missing from my machine — 743 report
ProcessException ... Command: iverilog -g2012 ...and no other exception type appears in either log. CONTRIBUTING notes iverilog is required for the complete suite, and CI has it.dart format --output=none --set-exit-if-changedreports no changes, anddart analyzeover the package finds no issues.Notably,
sv_param_passthrough_test.dartkeeps passing: its parameters areA,B,Cagainst portsa,b, and SystemVerilog identifiers are case-sensitive, so they do not collide.Backwards-compatibility
This turns two cases that previously produced silently-illegal SystemVerilog into build-time exceptions, so a design that was relying on such a name today will now fail loudly. That is the enforcement #611 asks for, and the output it replaces would not have compiled anyway.
The renameable-signal case is not a breaking change in the same way, but it does change generated signal names (
myInternalbecomesmyInternal_0) for designs that had this collision.I reused
UnavailableReservedNameExceptionrather than introducing a new exception type, since that is already how reserved-name conflicts surface elsewhere in the namer. If you would prefer a dedicated exception that names the parameter and module explicitly, that is an easy change — the message today is the genericUnable to use reserved name "a" because something else already has this name.Documentation
Yes, and included: the
Namer.forModuledoc comment now explains that definition parameters are reserved along with ports and what happens on a collision. No user-guide page coversdefinitionParametersnaming, so nothing outside the API docs needed updating.Disclosure: this change was written by Claude Code (Claude Opus 5) working as my agent, at my direction. The generated SystemVerilog and test output quoted above come from real runs in my local environment; I am accountable for the content of this PR and happy to iterate on review feedback.
🤖 Generated with Claude Code