Skip to content

Verilog: confine positional instance parameters to Classic foreign calls#1021

Closed
nanavati wants to merge 1 commit into
B-Lang-org:mainfrom
nanavati:noinline-foreign-params
Closed

Verilog: confine positional instance parameters to Classic foreign calls#1021
nanavati wants to merge 1 commit into
B-Lang-org:mainfrom
nanavati:noinline-foreign-params

Conversation

@nanavati

@nanavati nanavati commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to the discussion on #997 about whether the Either in vi_inst_params could become named-only.

Analysis of all construction sites: two of the three are the -v95 fallback (they disappear if #719 relands), and the third — the noinline-function instantiation path in AVerilogUtil — was positional unconditionally. That site serves two populations:

  • BSV (* noinline *) functions are enforced monomorphic (T0111), so their ANoInlineFun never carries numeric type arguments and no parameters are emitted at all. This PR routes that always-empty case through the named side.
  • Classic foreign functions applied at numeric types (in-tree example: Forkforeign vfork :: Bit n -> Bit m = "Fork",("i","o")) pass their ITNum type arguments as instance parameters, and these are positional by necessity: the declaration syntax names only ports, so the compiler never learns the hand-written module's parameter names (Fork.v's iw/ow); the values pass in type-argument order matching the parameter declaration order.

So after #719, the residual Left is exactly the Classic-foreign contract, now documented at the emission site and on the ANoInlineFun type. Collapsing the Either entirely would require extending the Classic foreign declaration syntax to name parameters (or retiring numeric-polymorphic foreign) — likely not worth it for one legacy feature.

No change to generated output: empty parameter lists render identically on either side (verified: bsc.verilog/noinline 62 PASS, bsc.lib/fork 5 PASS, goldens unchanged).

Related: #997, #719, #400.

🤖 Generated with Claude Code


Update: superseded by #1022, which collapses the Either entirely (the parameter names turn out to exist: the declaration's type variables). If #1022 is preferred, this can close; if this lands first, #1022 rebases trivially.

The noinline-function instantiation path was the only site emitting
positional instance parameters unconditionally.  It serves two
populations: BSV noinline functions, which are enforced monomorphic
(T0111) and so never have parameters at all, and Classic foreign
functions applied at numeric types (e.g. Fork), whose ITNum type
arguments are passed as instance parameters.  The latter are positional
by necessity, not style: the foreign declaration syntax names only
ports, so the hand-written Verilog module's parameter names (Fork.v's
iw/ow) are unknown to the compiler, and the values are passed in
type-argument order matching the parameter declaration order.

Route the always-empty noinline case through the named side and
document the Classic-foreign contract at both the emission site and the
ANoInlineFun type.  No change to generated output (empty parameter
lists render identically on either side).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nanavati

nanavati commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #1022 which is a more complete solution.

@nanavati nanavati closed this Jul 6, 2026
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