Fix C++ types of non-inlined module ports (#7002)

We use special C++ types for ports, e.g. SystemC types in --sc mode, and native C arrays for unpacked arrays in --cc mode. These types are not substitutable for internal types, e.g. VlUnpacked, however all the runtime primitives expect internal types.

I think the intention was to use these special IO types only for top level ports, but the current implementation also uses them for the ports of all non-inlined modules. This means the output C++ will not compile if such a port is passed to a runtime primitive (e.g. array 'sort' as in the new test) or DPI import.

Changed to use the special IO types only on the top level ports.

Note these are likely still broken if attempting to invoke on a top level port (we might be saved by wrapTop, but later optimizations might eliminate the intermediary)
This commit is contained in:
Geza Lore 2026-02-05 14:49:07 +00:00 committed by GitHub
parent 4aa0ea3f27
commit 4e9792c34c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 2 deletions

View File

@ -176,7 +176,7 @@ void EmitCBaseVisitorConst::emitVarDecl(const AstVar* nodep, bool asRef) {
}
};
if (nodep->isIO() && nodep->isSc()) {
if (nodep->isPrimaryIO() && nodep->isSc()) {
UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
if (nodep->isInout()) {
putns(nodep, "sc_core::sc_inout<");
@ -197,7 +197,7 @@ void EmitCBaseVisitorConst::emitVarDecl(const AstVar* nodep, bool asRef) {
if (asRef && refNeedParens) puts(")");
emitDeclArrayBrackets(nodep);
puts(";\n");
} else if (nodep->isIO() && basicp && !basicp->isOpaque()) {
} else if (nodep->isPrimaryIO() && basicp && !basicp->isOpaque()) {
if (nodep->isInout()) {
putns(nodep, "VL_INOUT");
} else if (nodep->isWritable()) {

View File

@ -0,0 +1,18 @@
#!/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.compile(verilator_flags2=['--binary'])
test.execute()
test.passes()

View File

@ -0,0 +1,48 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
module top;
int x, y, z;
int out [3];
sub sub_i(x, y, z, out);
initial begin
x = 2;
y = 1;
z = 3;
#1;
`checkh(out[0], 1);
`checkh(out[1], 2);
`checkh(out[2], 3);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module sub(
input int a,
input int b,
input int c,
output int sorted [3]
);
/* verilator no_inline_module */
always_comb begin
sorted = '{a, b, c};
sorted.sort;
end
endmodule