Skip to content

[ImportVerilog] Preserve declaration order across regular and interface-modport ports#10468

Open
micprog wants to merge 2 commits into
llvm:mainfrom
micprog:micprog/modport_order
Open

[ImportVerilog] Preserve declaration order across regular and interface-modport ports#10468
micprog wants to merge 2 commits into
llvm:mainfrom
micprog:micprog/modport_order

Conversation

@micprog
Copy link
Copy Markdown
Contributor

@micprog micprog commented May 14, 2026

When a module's port list interleaves an interface-modport port with regular outputs, the instance-port plumbing produced moore.instance / moore.output verifier failures of the form operand N (...) does not match input/output type (...) of module @M.

convertModuleHeader walked the AST port list in order and pushed each port (regular or expanded interface-modport) to modulePorts interleaved by declaration order. But convertModuleBody built the moore.output operand vector by walking lowering.ports first (regular outputs only) and then lowering.ifacePorts (interface outputs only), and the visit-instance code did the same for the moore.instance operand and result vectors. Whenever the declaration order had an interface-modport output before a regular output, the operand vector and the module signature were permutations of each other and verification fired.

Fix: record an output slot index (outputIdx) on PortLowering and FlattenedIfacePort at header time, and a matching input slot index (inputIdx). Track numExplicitOutputs / numExplicitInputs on ModuleLowering. Build outputs / inputValues / outputValues as fixed-size vectors and place values by slot index, both at the module's terminator and at the instance call site. Hierarchical-name ports keep their existing append-after-explicit-ports treatment.

Regression test: interface-port-order.sv exercises a declaration order with an interface-modport output (l32) before a regular output (l64). The widths differ so any swap trips the moore.output terminator's verifier (the terminator is rigid, with no materializeConversion between operands and declared port types).

Assisted-by: Claude Code:claude-opus-4-7

@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 14, 2026

Results of circt-tests run for da1902c compared to results for 537b162:

sv-tests

Changes in emitted diagnostics:

  • 0 total change
  • -1 error: unknown hierarchical name `P`
  • +1 error: unsupported port

@micprog micprog force-pushed the micprog/modport_order branch from da1902c to ae1a819 Compare May 18, 2026 10:10
@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 18, 2026

Results of circt-tests run for ae1a819 compared to results for 23ee54f:

sv-tests

Changes in emitted diagnostics:

  • 0 total change
  • -1 error: unknown hierarchical name `P`
  • +1 error: unsupported port

Copy link
Copy Markdown
Contributor

@fabianschuiki fabianschuiki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice, thanks a lot for fixing this! 🥳 LGTM! Just a few nits.

Comment on lines +595 to +601
if (port.ast.direction == ArgumentDirection::Out) {
assert(port.outputIdx && "output port missing outputIdx");
outputValues[*port.outputIdx] = value;
} else {
assert(port.inputIdx && "input port missing inputIdx");
inputValues[*port.inputIdx] = value;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can drop the asserts here, since std::optional will already assert that the value exists when you * dereference it:

Suggested change
if (port.ast.direction == ArgumentDirection::Out) {
assert(port.outputIdx && "output port missing outputIdx");
outputValues[*port.outputIdx] = value;
} else {
assert(port.inputIdx && "input port missing inputIdx");
inputValues[*port.inputIdx] = value;
}
if (port.ast.direction == ArgumentDirection::Out)
outputValues[*port.outputIdx] = value;
else
inputValues[*port.inputIdx] = value;

Comment on lines +634 to +635
assert(fp.outputIdx && "output iface port missing outputIdx");
outputValues[*fp.outputIdx] = val;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here:

Suggested change
assert(fp.outputIdx && "output iface port missing outputIdx");
outputValues[*fp.outputIdx] = val;
outputValues[*fp.outputIdx] = val;

Comment on lines +641 to +642
assert(fp.inputIdx && "input iface port missing inputIdx");
inputValues[*fp.inputIdx] = val;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here:

Suggested change
assert(fp.inputIdx && "input iface port missing inputIdx");
inputValues[*fp.inputIdx] = val;
inputValues[*fp.inputIdx] = val;

Comment on lines +1375 to +1376
assert(port.outputIdx && "output port missing outputIdx");
outputs[*port.outputIdx] = value;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert(port.outputIdx && "output port missing outputIdx");
outputs[*port.outputIdx] = value;
outputs[*port.outputIdx] = value;

if (!ref)
continue;
outputs.push_back(moore::ReadOp::create(builder, fp.loc, ref).getResult());
assert(fp.outputIdx && "output iface port missing outputIdx");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert(fp.outputIdx && "output iface port missing outputIdx");

@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 21, 2026

Results of circt-tests run for 1bf5389 compared to results for 95535c5:

sv-tests

Changes in emitted diagnostics:

  • +26 total change
  • -41 error: failed to legalize operation 'moore.fmt.string'
  • -16 error: top-level module 'dut' has unconnected interface port 'in'
  • +16 error: unsupported construct in ClassType members: ConstraintBlock
  • +14 error: unsupported system call `$sdf_annotate`
  • +12 error: unsupported statement: ProceduralAssign
  • -10 error: unsupported module member: SpecifyBlock
  • -9 error: top-level module 'memMod' has unconnected interface port 'a'
  • +9 error: unsupported system call `$printtimescale`
  • +6 error: could not resolve hierarchical path name 'med_const'
  • +6 error: could not resolve hierarchical path name 'sml_const'
  • -5 error: unsupported primitive `bufif1`
  • +5 error: unsupported module member: InstanceArray
  • +4 error: failed to legalize operation 'moore.string_cmp'
  • -3 error: 'top_timescale2' is a module definition but is used as a value
  • +3 error: could not resolve hierarchical path name 'med_var'
  • +3 error: could not resolve hierarchical path name 'sml_var'
  • +3 error: unsupported system call `$onehot0`
  • -2 error: 'top_resetall' is a module definition but is used as a value
  • -2 error: 'top_timescale' is a module definition but is used as a value
  • -2 error: 'top_timescale3' is a module definition but is used as a value
  • -2 error: identifier 'in' used before its declaration
  • -2 error: unsupported statement: Invalid
  • +2 error: 'llhd.halt' op expects parent op to be one of 'llhd.process, llhd.final, llhd.coroutine'
  • +2 error: could not resolve hierarchical path name 'lrg_const'
  • +2 error: could not resolve hierarchical path name 'max'
  • +2 error: could not resolve hierarchical path name 'same'
  • +2 error: endianness of selection must match declared range (type is 'logic[21:0]')
  • +2 error: failed to legalize operation 'moore.conversion'
  • +2 error: implicit named port 'clk' of type 'logic' connects to value of inequivalent type 'bit' [-Wimplicit-port-type-mismatch]
  • +2 error: unsupported expression: SequenceWithMatch
  • +2 error: unsupported system call `$dumpfile`
  • -1 error: 'M' is not a valid top-level module
  • -1 error: 'M1' is not a valid top-level module
  • -1 error: could not resolve hierarchical path name 'Test'
  • -1 error: duplicate definition of 'a' [-Wduplicate-definition]
  • -1 error: duplicate definition of 'm' [-Wduplicate-definition]
  • -1 error: top-level module 'M' has unconnected interface port 'i'
  • -1 error: top-level module 'dev1' has unconnected interface port 'b'
  • -1 error: top-level module 'devA' has unconnected interface port 's'
  • -1 error: unsupported construct: Primitive
  • -1 error: unsupported port: does not map to an internal symbol or expression ``
  • -1 error: unsupported system call `$timeformat`
  • +1 error: 'llhd.wait' op operand #1 must be variadic of a known primitive element, but got '!sim.dstring'
  • +1 error: 'moore.blocking_assign' op using value defined outside the region
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_0 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_2 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_3 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_4 has 1 outputs
  • +1 error: cannot read from output clocking signal 'req'
  • +1 error: failed to legalize operation 'moore.concat_ref'
  • +1 error: failed to legalize operation 'moore.fork'
  • +1 error: failed to legalize operation 'moore.fstring_to_string'
  • +1 error: failed to resolve captured variable `CLK` at call site
  • +1 error: failed to resolve captured variable `pass` at call site
  • +1 error: no implicit conversion from 'sub.t_5' to 'sub.t_5'; explicit conversion exists, are you missing a cast?
  • +1 error: no interface connection for port `"a_clk"`
  • +1 error: redefinition of 'm'
  • +1 error: too many errors emitted, stopping now [--error-limit=]
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'y'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'y'
  • +1 error: unknown hierarchical name `value1`
  • +1 error: unknown name `nq1`
  • +1 error: unknown name `x`
  • +1 error: unsupported expression: DisableIff
  • +1 error: unsupported expression: EmptyArgument
  • +1 error: unsupported system call `$bits`
  • +1 error: unsupported system call `$coverage_control`
  • +1 error: unsupported system call `$dist_uniform`
  • +1 error: unsupported system call `$fopen`
  • +1 error: unsupported system call `$readmemh`

Introduced 1 segfault:

  • generated/ivtest/regress-vlg_porttest2_iv.sv

@micprog micprog force-pushed the micprog/modport_order branch from 1bf5389 to 5ff01db Compare May 21, 2026 11:49
@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 21, 2026

Results of circt-tests run for 5ff01db compared to results for 95535c5:

sv-tests

Changes in emitted diagnostics:

  • +16 total change
  • -41 error: failed to legalize operation 'moore.fmt.string'
  • -35 error: unsupported system call `$fopen`
  • -16 error: top-level module 'dut' has unconnected interface port 'in'
  • +16 error: unsupported construct in ClassType members: ConstraintBlock
  • +14 error: unsupported system call `$sdf_annotate`
  • -13 error: unsupported assignment pattern with type '!moore.open_uarray<i32>'
  • +12 error: unsupported statement: ProceduralAssign
  • -10 error: unsupported module member: SpecifyBlock
  • -9 error: top-level module 'memMod' has unconnected interface port 'a'
  • +9 error: failed to legalize operation 'moore.variable'
  • +9 error: unsupported system call `$fdisplay`
  • +9 error: unsupported system call `$printtimescale`
  • +8 error: unsupported system call `$fwrite`
  • -7 error: expression of type '!moore.string' cannot be cast to a simple bit vector
  • +6 error: could not resolve hierarchical path name 'med_const'
  • +6 error: could not resolve hierarchical path name 'sml_const'
  • -5 error: unsupported primitive `bufif1`
  • +5 error: unsupported module member: InstanceArray
  • +4 error: failed to legalize operation 'moore.string_cmp'
  • -3 error: 'top_timescale2' is a module definition but is used as a value
  • +3 error: could not resolve hierarchical path name 'med_var'
  • +3 error: could not resolve hierarchical path name 'sml_var'
  • +3 error: expected a 1-bit integer
  • +3 error: unsupported system call `$fgets`
  • -2 error: 'top_resetall' is a module definition but is used as a value
  • -2 error: 'top_timescale' is a module definition but is used as a value
  • -2 error: 'top_timescale3' is a module definition but is used as a value
  • -2 error: failed to legalize operation 'arith.select'
  • -2 error: identifier 'in' used before its declaration
  • -2 error: unsupported statement: Invalid
  • -2 error: unsupported system call `$onehot0`
  • -2 error: unsupported system call `$onehot`
  • +2 error: 'llhd.halt' op expects parent op to be one of 'llhd.process, llhd.final, llhd.coroutine'
  • +2 error: could not resolve hierarchical path name 'lrg_const'
  • +2 error: could not resolve hierarchical path name 'max'
  • +2 error: could not resolve hierarchical path name 'same'
  • +2 error: endianness of selection must match declared range (type is 'logic[21:0]')
  • +2 error: failed to legalize operation 'moore.conversion'
  • +2 error: implicit named port 'clk' of type 'logic' connects to value of inequivalent type 'bit' [-Wimplicit-port-type-mismatch]
  • +2 error: unsupported assignment pattern with type '!moore.queue<i32, 0>'
  • +2 error: unsupported expression: SequenceWithMatch
  • +2 error: unsupported expression: array `new` with initializer
  • +2 error: unsupported system call `$dumpfile`
  • +2 error: unsupported system call `$fmonitor`
  • +2 error: unsupported system call `$fread`
  • +2 error: unsupported system call `$fscanf`
  • -1 error: 'M' is not a valid top-level module
  • -1 error: 'M1' is not a valid top-level module
  • -1 error: could not resolve hierarchical path name 'Test'
  • -1 error: duplicate definition of 'a' [-Wduplicate-definition]
  • -1 error: duplicate definition of 'm' [-Wduplicate-definition]
  • -1 error: top-level module 'M' has unconnected interface port 'i'
  • -1 error: top-level module 'dev1' has unconnected interface port 'b'
  • -1 error: top-level module 'devA' has unconnected interface port 's'
  • -1 error: unsupported construct: Primitive
  • -1 error: unsupported port
  • -1 error: unsupported port: does not map to an internal symbol or expression ``
  • -1 error: unsupported system call `$timeformat`
  • +1 error: 'llhd.wait' op operand #1 must be variadic of a known primitive element, but got '!sim.dstring'
  • +1 error: 'moore.blocking_assign' op using value defined outside the region
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_0 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_2 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_3 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_4 has 1 outputs
  • +1 error: cannot read from output clocking signal 'req'
  • +1 error: failed to legalize operation 'moore.concat_ref'
  • +1 error: failed to legalize operation 'moore.fork'
  • +1 error: failed to legalize operation 'moore.fstring_to_string'
  • +1 error: failed to resolve captured variable `CLK` at call site
  • +1 error: failed to resolve captured variable `pass` at call site
  • +1 error: no implicit conversion from 'sub.t_5' to 'sub.t_5'; explicit conversion exists, are you missing a cast?
  • +1 error: no interface connection for port `"a_clk"`
  • +1 error: redefinition of 'm'
  • +1 error: too many errors emitted, stopping now [--error-limit=]
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'y'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'y'
  • +1 error: unknown name `nq1`
  • +1 error: unknown name `x`
  • +1 error: unsupported expression: DisableIff
  • +1 error: unsupported expression: EmptyArgument
  • +1 error: unsupported system call `$bits`
  • +1 error: unsupported system call `$coverage_control`
  • +1 error: unsupported system call `$dist_uniform`
  • +1 error: unsupported system call `$fdisplayb`
  • +1 error: unsupported system call `$feof`
  • +1 error: unsupported system call `$ferror`
  • +1 error: unsupported system call `$fflush`
  • +1 error: unsupported system call `$fgetc`
  • +1 error: unsupported system call `$ftell`
  • +1 error: unsupported system call `$fwriteb`
  • +1 error: unsupported system call `$readmemh`
  • +1 error: unsupported system call `$ungetc`
  • +1 error: unsupported system call `find_first_index`
  • +1 error: unsupported system call `find_first`
  • +1 error: unsupported system call `find_index`
  • +1 error: unsupported system call `find_last_index`
  • +1 error: unsupported system call `find_last`
  • +1 error: unsupported system call `find`
  • +1 error: unsupported system call `reverse`

Introduced 1 segfault:

  • generated/ivtest/regress-vlg_porttest2_iv.sv

@fabianschuiki
Copy link
Copy Markdown
Contributor

The changes in error messages in sv-tests in circt-tests is interesting. I guess some of this might be related to failing tests now running further and hitting other issues, which is great. But some new errors are related to hierarchical paths, which could be an issue with the port order potentially?

If you're feeling adventurous @micprog, circt-tests is fairly straightforward to clone and run. That'll allow you to look at that segfault in generated/ivtest/regress-vlg_porttest2_iv.sv and maybe some of the hierarchical path errors that are new. Don't worry if your PR just fixes an earlier issue and now let's the tests run into new ones -- that's expected. But it would be great to fix the segfault and make sure that ports/modports/hierarchical names that worked before are still working 😃

@fabianschuiki
Copy link
Copy Markdown
Contributor

Actually now that I think about this some more: this might be due to a bump in sv-tests. Try rebasing your PR onto current main. (I've noticed that we've picked up one of the segfaults you're seeing since the last sv-tests bump, so this likely has nothing to do with your PR!)

@micprog micprog force-pushed the micprog/modport_order branch from 5ff01db to 0302638 Compare May 21, 2026 18:22
@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 21, 2026

Results of circt-tests run for 0302638 compared to results for 95535c5:

sv-tests

Changes in emitted diagnostics:

  • +16 total change
  • -41 error: failed to legalize operation 'moore.fmt.string'
  • -35 error: unsupported system call `$fopen`
  • -16 error: top-level module 'dut' has unconnected interface port 'in'
  • +16 error: unsupported construct in ClassType members: ConstraintBlock
  • +14 error: unsupported system call `$sdf_annotate`
  • -13 error: unsupported assignment pattern with type '!moore.open_uarray<i32>'
  • +12 error: unsupported statement: ProceduralAssign
  • -10 error: unsupported module member: SpecifyBlock
  • -9 error: top-level module 'memMod' has unconnected interface port 'a'
  • +9 error: failed to legalize operation 'moore.variable'
  • +9 error: unsupported system call `$fdisplay`
  • +9 error: unsupported system call `$printtimescale`
  • +8 error: unsupported system call `$fwrite`
  • -7 error: expression of type '!moore.string' cannot be cast to a simple bit vector
  • +6 error: could not resolve hierarchical path name 'med_const'
  • +6 error: could not resolve hierarchical path name 'sml_const'
  • -5 error: unsupported primitive `bufif1`
  • +5 error: unsupported module member: InstanceArray
  • +4 error: failed to legalize operation 'moore.string_cmp'
  • -3 error: 'top_timescale2' is a module definition but is used as a value
  • +3 error: could not resolve hierarchical path name 'med_var'
  • +3 error: could not resolve hierarchical path name 'sml_var'
  • +3 error: expected a 1-bit integer
  • +3 error: unsupported system call `$fgets`
  • -2 error: 'top_resetall' is a module definition but is used as a value
  • -2 error: 'top_timescale' is a module definition but is used as a value
  • -2 error: 'top_timescale3' is a module definition but is used as a value
  • -2 error: failed to legalize operation 'arith.select'
  • -2 error: identifier 'in' used before its declaration
  • -2 error: unsupported statement: Invalid
  • -2 error: unsupported system call `$onehot0`
  • -2 error: unsupported system call `$onehot`
  • +2 error: 'llhd.halt' op expects parent op to be one of 'llhd.process, llhd.final, llhd.coroutine'
  • +2 error: could not resolve hierarchical path name 'lrg_const'
  • +2 error: could not resolve hierarchical path name 'max'
  • +2 error: could not resolve hierarchical path name 'same'
  • +2 error: endianness of selection must match declared range (type is 'logic[21:0]')
  • +2 error: failed to legalize operation 'moore.conversion'
  • +2 error: implicit named port 'clk' of type 'logic' connects to value of inequivalent type 'bit' [-Wimplicit-port-type-mismatch]
  • +2 error: unsupported assignment pattern with type '!moore.queue<i32, 0>'
  • +2 error: unsupported expression: SequenceWithMatch
  • +2 error: unsupported expression: array `new` with initializer
  • +2 error: unsupported system call `$dumpfile`
  • +2 error: unsupported system call `$fmonitor`
  • +2 error: unsupported system call `$fread`
  • +2 error: unsupported system call `$fscanf`
  • -1 error: 'M' is not a valid top-level module
  • -1 error: 'M1' is not a valid top-level module
  • -1 error: could not resolve hierarchical path name 'Test'
  • -1 error: duplicate definition of 'a' [-Wduplicate-definition]
  • -1 error: duplicate definition of 'm' [-Wduplicate-definition]
  • -1 error: top-level module 'M' has unconnected interface port 'i'
  • -1 error: top-level module 'dev1' has unconnected interface port 'b'
  • -1 error: top-level module 'devA' has unconnected interface port 's'
  • -1 error: unsupported construct: Primitive
  • -1 error: unsupported port
  • -1 error: unsupported port: does not map to an internal symbol or expression ``
  • -1 error: unsupported system call `$timeformat`
  • +1 error: 'llhd.wait' op operand #1 must be variadic of a known primitive element, but got '!sim.dstring'
  • +1 error: 'moore.blocking_assign' op using value defined outside the region
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_0 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_2 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_3 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_4 has 1 outputs
  • +1 error: cannot read from output clocking signal 'req'
  • +1 error: failed to legalize operation 'moore.concat_ref'
  • +1 error: failed to legalize operation 'moore.fork'
  • +1 error: failed to legalize operation 'moore.fstring_to_string'
  • +1 error: failed to resolve captured variable `CLK` at call site
  • +1 error: failed to resolve captured variable `pass` at call site
  • +1 error: no implicit conversion from 'sub.t_5' to 'sub.t_5'; explicit conversion exists, are you missing a cast?
  • +1 error: no interface connection for port `"a_clk"`
  • +1 error: redefinition of 'm'
  • +1 error: too many errors emitted, stopping now [--error-limit=]
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'y'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'y'
  • +1 error: unknown name `nq1`
  • +1 error: unknown name `x`
  • +1 error: unsupported expression: DisableIff
  • +1 error: unsupported expression: EmptyArgument
  • +1 error: unsupported system call `$bits`
  • +1 error: unsupported system call `$coverage_control`
  • +1 error: unsupported system call `$dist_uniform`
  • +1 error: unsupported system call `$fdisplayb`
  • +1 error: unsupported system call `$feof`
  • +1 error: unsupported system call `$ferror`
  • +1 error: unsupported system call `$fflush`
  • +1 error: unsupported system call `$fgetc`
  • +1 error: unsupported system call `$ftell`
  • +1 error: unsupported system call `$fwriteb`
  • +1 error: unsupported system call `$readmemh`
  • +1 error: unsupported system call `$ungetc`
  • +1 error: unsupported system call `find_first_index`
  • +1 error: unsupported system call `find_first`
  • +1 error: unsupported system call `find_index`
  • +1 error: unsupported system call `find_last_index`
  • +1 error: unsupported system call `find_last`
  • +1 error: unsupported system call `find`
  • +1 error: unsupported system call `reverse`

Introduced 1 segfault:

  • generated/ivtest/regress-vlg_porttest2_iv.sv

@micprog micprog force-pushed the micprog/modport_order branch from 0302638 to 32cfab2 Compare May 22, 2026 08:10
@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 22, 2026

Results of circt-tests run for 32cfab2 compared to results for 95535c5:

sv-tests

Changes in emitted diagnostics:

  • +16 total change
  • -41 error: failed to legalize operation 'moore.fmt.string'
  • -35 error: unsupported system call `$fopen`
  • -16 error: top-level module 'dut' has unconnected interface port 'in'
  • +16 error: unsupported construct in ClassType members: ConstraintBlock
  • +14 error: unsupported system call `$sdf_annotate`
  • -13 error: unsupported assignment pattern with type '!moore.open_uarray<i32>'
  • +12 error: unsupported statement: ProceduralAssign
  • -10 error: unsupported module member: SpecifyBlock
  • -9 error: top-level module 'memMod' has unconnected interface port 'a'
  • +9 error: failed to legalize operation 'moore.variable'
  • +9 error: unsupported system call `$fdisplay`
  • +9 error: unsupported system call `$printtimescale`
  • +8 error: unsupported system call `$fwrite`
  • -7 error: expression of type '!moore.string' cannot be cast to a simple bit vector
  • +6 error: could not resolve hierarchical path name 'med_const'
  • +6 error: could not resolve hierarchical path name 'sml_const'
  • -5 error: unsupported primitive `bufif1`
  • +5 error: unsupported module member: InstanceArray
  • +4 error: failed to legalize operation 'moore.string_cmp'
  • -3 error: 'top_timescale2' is a module definition but is used as a value
  • +3 error: could not resolve hierarchical path name 'med_var'
  • +3 error: could not resolve hierarchical path name 'sml_var'
  • +3 error: expected a 1-bit integer
  • +3 error: unsupported system call `$fgets`
  • -2 error: 'top_resetall' is a module definition but is used as a value
  • -2 error: 'top_timescale' is a module definition but is used as a value
  • -2 error: 'top_timescale3' is a module definition but is used as a value
  • -2 error: failed to legalize operation 'arith.select'
  • -2 error: identifier 'in' used before its declaration
  • -2 error: unsupported statement: Invalid
  • -2 error: unsupported system call `$onehot0`
  • -2 error: unsupported system call `$onehot`
  • +2 error: 'llhd.halt' op expects parent op to be one of 'llhd.process, llhd.final, llhd.coroutine'
  • +2 error: could not resolve hierarchical path name 'lrg_const'
  • +2 error: could not resolve hierarchical path name 'max'
  • +2 error: could not resolve hierarchical path name 'same'
  • +2 error: endianness of selection must match declared range (type is 'logic[21:0]')
  • +2 error: failed to legalize operation 'moore.conversion'
  • +2 error: implicit named port 'clk' of type 'logic' connects to value of inequivalent type 'bit' [-Wimplicit-port-type-mismatch]
  • +2 error: unsupported assignment pattern with type '!moore.queue<i32, 0>'
  • +2 error: unsupported expression: SequenceWithMatch
  • +2 error: unsupported expression: array `new` with initializer
  • +2 error: unsupported system call `$dumpfile`
  • +2 error: unsupported system call `$fmonitor`
  • +2 error: unsupported system call `$fread`
  • +2 error: unsupported system call `$fscanf`
  • -1 error: 'M' is not a valid top-level module
  • -1 error: 'M1' is not a valid top-level module
  • -1 error: could not resolve hierarchical path name 'Test'
  • -1 error: duplicate definition of 'a' [-Wduplicate-definition]
  • -1 error: duplicate definition of 'm' [-Wduplicate-definition]
  • -1 error: top-level module 'M' has unconnected interface port 'i'
  • -1 error: top-level module 'dev1' has unconnected interface port 'b'
  • -1 error: top-level module 'devA' has unconnected interface port 's'
  • -1 error: unsupported construct: Primitive
  • -1 error: unsupported port
  • -1 error: unsupported port: does not map to an internal symbol or expression ``
  • -1 error: unsupported system call `$timeformat`
  • +1 error: 'llhd.wait' op operand #1 must be variadic of a known primitive element, but got '!sim.dstring'
  • +1 error: 'moore.blocking_assign' op using value defined outside the region
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_0 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_2 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_3 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_4 has 1 outputs
  • +1 error: cannot read from output clocking signal 'req'
  • +1 error: failed to legalize operation 'moore.concat_ref'
  • +1 error: failed to legalize operation 'moore.fork'
  • +1 error: failed to legalize operation 'moore.fstring_to_string'
  • +1 error: failed to resolve captured variable `CLK` at call site
  • +1 error: failed to resolve captured variable `pass` at call site
  • +1 error: no implicit conversion from 'sub.t_5' to 'sub.t_5'; explicit conversion exists, are you missing a cast?
  • +1 error: no interface connection for port `"a_clk"`
  • +1 error: redefinition of 'm'
  • +1 error: too many errors emitted, stopping now [--error-limit=]
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'y'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'y'
  • +1 error: unknown name `nq1`
  • +1 error: unknown name `x`
  • +1 error: unsupported expression: DisableIff
  • +1 error: unsupported expression: EmptyArgument
  • +1 error: unsupported system call `$bits`
  • +1 error: unsupported system call `$coverage_control`
  • +1 error: unsupported system call `$dist_uniform`
  • +1 error: unsupported system call `$fdisplayb`
  • +1 error: unsupported system call `$feof`
  • +1 error: unsupported system call `$ferror`
  • +1 error: unsupported system call `$fflush`
  • +1 error: unsupported system call `$fgetc`
  • +1 error: unsupported system call `$ftell`
  • +1 error: unsupported system call `$fwriteb`
  • +1 error: unsupported system call `$readmemh`
  • +1 error: unsupported system call `$ungetc`
  • +1 error: unsupported system call `find_first_index`
  • +1 error: unsupported system call `find_first`
  • +1 error: unsupported system call `find_index`
  • +1 error: unsupported system call `find_last_index`
  • +1 error: unsupported system call `find_last`
  • +1 error: unsupported system call `find`
  • +1 error: unsupported system call `reverse`

Introduced 1 segfault:

  • generated/ivtest/regress-vlg_porttest2_iv.sv

@micprog
Copy link
Copy Markdown
Contributor Author

micprog commented May 22, 2026

Thanks for the feedback @fabianschuiki! I removed the asserts and rebased the branch, hoping to clean up the bot's report, but it looks like there are still other issues. The bot originally reported 0 change (+1/-1), I don't see how these changes could affect this large number of items. The segfault is reproducible on the current main, I'm fairly certain it's an issue of the base this PR is comparing to (Could the last run on main that the bot is comparing to still reference an older sv-tests version?). I can dig into the issue (AI-assisted), but I don't think it makes sense to address in this PR as it is a separate issue.

@micprog micprog force-pushed the micprog/modport_order branch from 32cfab2 to 3769996 Compare May 26, 2026 23:21
@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 26, 2026

Results of circt-tests run for 3769996 compared to results for 95535c5:

sv-tests

Changes in emitted diagnostics:

  • +15 total change
  • -41 error: failed to legalize operation 'moore.fmt.string'
  • -35 error: unsupported system call `$fopen`
  • -16 error: top-level module 'dut' has unconnected interface port 'in'
  • +16 error: unsupported construct in ClassType members: ConstraintBlock
  • +14 error: unsupported system call `$sdf_annotate`
  • -13 error: unsupported assignment pattern with type '!moore.open_uarray<i32>'
  • +12 error: unsupported statement: ProceduralAssign
  • -10 error: unsupported module member: SpecifyBlock
  • -9 error: top-level module 'memMod' has unconnected interface port 'a'
  • +9 error: failed to legalize operation 'moore.variable'
  • +9 error: unsupported system call `$fdisplay`
  • +9 error: unsupported system call `$printtimescale`
  • +8 error: unsupported system call `$fwrite`
  • -7 error: expression of type '!moore.string' cannot be cast to a simple bit vector
  • +6 error: could not resolve hierarchical path name 'med_const'
  • +6 error: could not resolve hierarchical path name 'sml_const'
  • -5 error: unsupported primitive `bufif1`
  • +5 error: unsupported module member: InstanceArray
  • +4 error: failed to legalize operation 'moore.string_cmp'
  • -3 error: 'top_timescale2' is a module definition but is used as a value
  • +3 error: could not resolve hierarchical path name 'med_var'
  • +3 error: could not resolve hierarchical path name 'sml_var'
  • +3 error: expected a 1-bit integer
  • +3 error: unsupported system call `$fgets`
  • -2 error: 'top_resetall' is a module definition but is used as a value
  • -2 error: 'top_timescale' is a module definition but is used as a value
  • -2 error: 'top_timescale3' is a module definition but is used as a value
  • -2 error: failed to legalize operation 'arith.select'
  • -2 error: identifier 'in' used before its declaration
  • -2 error: unsupported statement: Invalid
  • -2 error: unsupported system call `$onehot0`
  • -2 error: unsupported system call `$onehot`
  • +2 error: 'llhd.halt' op expects parent op to be one of 'llhd.process, llhd.final, llhd.coroutine'
  • +2 error: could not resolve hierarchical path name 'lrg_const'
  • +2 error: could not resolve hierarchical path name 'max'
  • +2 error: could not resolve hierarchical path name 'same'
  • +2 error: endianness of selection must match declared range (type is 'logic[21:0]')
  • +2 error: failed to legalize operation 'moore.conversion'
  • +2 error: implicit named port 'clk' of type 'logic' connects to value of inequivalent type 'bit' [-Wimplicit-port-type-mismatch]
  • +2 error: unsupported assignment pattern with type '!moore.queue<i32, 0>'
  • +2 error: unsupported expression: SequenceWithMatch
  • +2 error: unsupported expression: array `new` with initializer
  • +2 error: unsupported system call `$dumpfile`
  • +2 error: unsupported system call `$fmonitor`
  • +2 error: unsupported system call `$fread`
  • +2 error: unsupported system call `$fscanf`
  • -1 error: 'M' is not a valid top-level module
  • -1 error: 'M1' is not a valid top-level module
  • -1 error: could not resolve hierarchical path name 'Test'
  • -1 error: duplicate definition of 'a' [-Wduplicate-definition]
  • -1 error: duplicate definition of 'm' [-Wduplicate-definition]
  • -1 error: top-level module 'M' has unconnected interface port 'i'
  • -1 error: top-level module 'dev1' has unconnected interface port 'b'
  • -1 error: top-level module 'devA' has unconnected interface port 's'
  • -1 error: unsupported construct: Primitive
  • -1 error: unsupported port
  • -1 error: unsupported port: does not map to an internal symbol or expression ``
  • -1 error: unsupported system call `$timeformat`
  • +1 error: 'llhd.wait' op operand #1 must be variadic of a known primitive element, but got '!sim.dstring'
  • +1 error: 'moore.blocking_assign' op using value defined outside the region
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_0 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_1 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_2 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_3 has 1 outputs
  • +1 error: 'moore.output' op has 0 operands, but enclosing module @m1_4 has 1 outputs
  • +1 error: cannot read from output clocking signal 'req'
  • +1 error: failed to legalize operation 'moore.concat_ref'
  • +1 error: failed to legalize operation 'moore.fork'
  • +1 error: failed to legalize operation 'moore.fstring_to_string'
  • +1 error: failed to resolve captured variable `CLK` at call site
  • +1 error: failed to resolve captured variable `pass` at call site
  • +1 error: no implicit conversion from 'sub.t_5' to 'sub.t_5'; explicit conversion exists, are you missing a cast?
  • +1 error: no interface connection for port `"a_clk"`
  • +1 error: redefinition of 'm'
  • +1 error: too many errors emitted, stopping now [--error-limit=]
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh20' has unconnected 'ref' port 'y'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'x'
  • +1 error: top-level module 'mh21' has unconnected 'ref' port 'y'
  • +1 error: unknown name `nq1`
  • +1 error: unknown name `x`
  • +1 error: unsupported expression: DisableIff
  • +1 error: unsupported expression: EmptyArgument
  • +1 error: unsupported system call `$bits`
  • +1 error: unsupported system call `$coverage_control`
  • +1 error: unsupported system call `$dist_uniform`
  • +1 error: unsupported system call `$fdisplayb`
  • +1 error: unsupported system call `$feof`
  • +1 error: unsupported system call `$ferror`
  • +1 error: unsupported system call `$fgetc`
  • +1 error: unsupported system call `$ftell`
  • +1 error: unsupported system call `$fwriteb`
  • +1 error: unsupported system call `$readmemh`
  • +1 error: unsupported system call `$ungetc`
  • +1 error: unsupported system call `find_first_index`
  • +1 error: unsupported system call `find_first`
  • +1 error: unsupported system call `find_index`
  • +1 error: unsupported system call `find_last_index`
  • +1 error: unsupported system call `find_last`
  • +1 error: unsupported system call `find`
  • +1 error: unsupported system call `reverse`

Introduced 1 segfault:

  • generated/ivtest/regress-vlg_porttest2_iv.sv

micprog added 2 commits May 27, 2026 13:22
…ce-modport ports

When a module's port list interleaves an interface-modport port with
regular outputs, the instance-port plumbing produced `moore.instance`
/ `moore.output` verifier failures of the form `operand N (...) does
not match input/output type (...) of module @M`.

`convertModuleHeader` walked the AST port list in order and pushed
each port (regular or expanded interface-modport) to `modulePorts`
interleaved by declaration order. But `convertModuleBody` built the
`moore.output` operand vector by walking `lowering.ports` first
(regular outputs only) and then `lowering.ifacePorts` (interface
outputs only), and the visit-instance code did the same for the
`moore.instance` operand and result vectors. Whenever the declaration
order had an interface-modport output before a regular output, the
operand vector and the module signature were permutations of each
other and verification fired.

Fix: record an output slot index (`outputIdx`) on `PortLowering` and
`FlattenedIfacePort` at header time, and a matching input slot index
(`inputIdx`). Track `numExplicitOutputs` / `numExplicitInputs` on
`ModuleLowering`. Build `outputs` / `inputValues` / `outputValues` as
fixed-size vectors and place values by slot index, both at the
module's terminator and at the instance call site. Hierarchical-name
ports keep their existing append-after-explicit-ports treatment.

Regression test: `interface-port-order.sv` exercises a declaration
order with an interface-modport output (l32) before a regular output
(l64). The widths differ so any swap trips the `moore.output`
terminator's verifier (the terminator is rigid, with no
`materializeConversion` between operands and declared port types).

Assisted-by: Claude Code:claude-opus-4-7
@micprog micprog force-pushed the micprog/modport_order branch from 3769996 to 19b380f Compare May 27, 2026 11:22
@circt-bot
Copy link
Copy Markdown

circt-bot Bot commented May 27, 2026

Results of circt-tests run for 19b380f compared to results for cb0a5bb:

sv-tests

Changes in emitted diagnostics:

  • 0 total change
  • -1 error: unknown hierarchical name `P`
  • +1 error: unsupported port

@micprog
Copy link
Copy Markdown
Contributor Author

micprog commented May 27, 2026

@fabianschuiki I think we identified the issue - circt-tests compares to the main branch in the fork's repository, not the target (llvm/circt) repository. My main branch was out of date, causing circt-bot to use an outdated baseline. I opened circt/circt-tests#21 to address this.

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.

2 participants