Optimize modport resolution with many interface instances (#8496) (#8497)

This commit is contained in:
Deanyone Su
2026-09-25 14:38:18 -04:00
committed by GitHub
parent 3a76b29cb3
commit 8b663f9c84
4 changed files with 66 additions and 0 deletions
+1
View File
@@ -69,6 +69,7 @@ David Ledger
David Metz
David Stanford
David Turner
Deanyone Su
dependabot[bot]
Dercury
Demin Han
+6
View File
@@ -3130,6 +3130,10 @@ class LinkDotIfaceVisitor final : public VNVisitor {
nodep->v3error("Modport item is not a clocking block: " << nodep->prettyNameQ());
}
}
void visit(AstScope* nodep) override { // IfaceVisitor::
if (nodep->user3SetOnce()) return;
iterateChildren(nodep);
}
void visit(AstNode* nodep) override { iterateChildren(nodep); } // IfaceVisitor::
public:
@@ -3144,6 +3148,8 @@ public:
};
void LinkDotState::computeIfaceModSyms() {
// AstScope::user3() // bool. Already iterated by a LinkDotIfaceVisitor
const VNUser3InUse user3InUse;
for (const auto& itr : m_ifaceModSyms) {
AstIface* const nodep = itr.first;
VSymEnt* const symp = itr.second;
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of either the GNU Lesser General Public License Version 3
# or the Perl Artistic License Version 2.0.
# SPDX-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.lint(verilator_flags2=['--stats'])
test.passes()
+43
View File
@@ -0,0 +1,43 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Deanyone Su
// SPDX-License-Identifier: CC0-1.0
// Many instances of one interface, each with modports and some logic
// (performance test for modport resolution after scoping)
interface ctrl_if;
logic [31:0] data;
logic valid;
logic ready;
logic [31:0] data_q;
always_comb ready = !valid || data[0];
assign data_q = data ^ 32'h5a5a5a5a;
modport master_mp(output data, output valid, input ready);
modport slave_mp(input data, input valid, output ready);
endinterface
module sink (
ctrl_if.slave_mp s,
output logic o
);
assign o = s.valid & s.data[3];
endmodule
module t #(
parameter int N = 4000
) (
input logic [31:0] in,
output logic [N-1:0] out
);
ctrl_if intfs[N] ();
for (genvar i = 0; i < N; i++) begin : g
assign intfs[i].data = in + i;
assign intfs[i].valid = in[i%32];
sink u_sink (
.s(intfs[i]),
.o(out[i])
);
end
endmodule