Fixes #7483.
This commit is contained in:
parent
2cd9b8df66
commit
b1d3d63e9f
|
|
@ -7156,7 +7156,9 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
if (portp->isWritable()) V3LinkLValue::linkLValueSet(pinp);
|
||||
if (!portp->basicp() || portp->basicp()->isOpaque()) {
|
||||
checkClassAssign(nodep, "Function Argument", pinp, portDTypep);
|
||||
// Output args: at return caller = callee, reverse direction.
|
||||
checkClassAssign(nodep, "Function Argument", pinp, portDTypep,
|
||||
portp->direction() == VDirection::OUTPUT);
|
||||
userIterate(pinp, WidthVP{portDTypep, FINAL}.p());
|
||||
} else {
|
||||
iterateCheckAssign(nodep, "Function Argument", pinp, FINAL, portDTypep);
|
||||
|
|
@ -8512,14 +8514,19 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
void checkClassAssign(const AstNode* nodep, const char* side, AstNode* rhsp,
|
||||
AstNodeDType* const lhsDTypep) {
|
||||
AstNodeDType* const lhsDTypep, bool isOutputArg = false) {
|
||||
UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type");
|
||||
const AstNodeDType* const lhsRawDTypep = lhsDTypep->skipRefp();
|
||||
const AstNodeDType* const rhsRawDTypep = rhsp->dtypep()->skipRefp();
|
||||
if (const AstClassRefDType* const lhsClassRefp = VN_CAST(lhsRawDTypep, ClassRefDType)) {
|
||||
if (const AstClassRefDType* const rhsClassRefp
|
||||
= VN_CAST(rhsRawDTypep, ClassRefDType)) {
|
||||
if (isBaseClassRecurse(lhsClassRefp->classp(), rhsClassRefp->classp())) return;
|
||||
// Output arg swaps sides: caller actual = callee formal at return.
|
||||
const AstClass* const dstp
|
||||
= isOutputArg ? rhsClassRefp->classp() : lhsClassRefp->classp();
|
||||
const AstClass* const srcp
|
||||
= isOutputArg ? lhsClassRefp->classp() : rhsClassRefp->classp();
|
||||
if (isBaseClassRecurse(dstp, srcp)) return;
|
||||
} else if (rhsp->isNull()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// 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
|
||||
|
||||
// Output arg of class type-parameter accepts a base handle (upcast).
|
||||
|
||||
class Fifo #(type T = int);
|
||||
T m_val;
|
||||
task get(output T t);
|
||||
t = m_val;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
class Base;
|
||||
int m_id = 10;
|
||||
endclass
|
||||
|
||||
class Deriv extends Base;
|
||||
int m_extra = 20;
|
||||
endclass
|
||||
|
||||
module t;
|
||||
Fifo #(Deriv) f;
|
||||
Base b;
|
||||
Deriv d;
|
||||
initial begin
|
||||
f = new;
|
||||
d = new;
|
||||
d.m_id = 42;
|
||||
d.m_extra = 99;
|
||||
f.m_val = d;
|
||||
f.get(b);
|
||||
if (b === null) $stop;
|
||||
if (b.m_id !== 42) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -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('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
// 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
|
||||
|
||||
// Legal upcasts on class type-parameter args, direct and multi-level.
|
||||
|
||||
class Base;
|
||||
int seq = 0;
|
||||
int b_tag = 'hBAAD;
|
||||
endclass
|
||||
|
||||
class Mid extends Base;
|
||||
int m_tag = 'hDEAD;
|
||||
endclass
|
||||
|
||||
class Leaf extends Mid;
|
||||
int l_tag = 'hBEEF;
|
||||
endclass
|
||||
|
||||
class Unrelated;
|
||||
int u_tag = 0;
|
||||
endclass
|
||||
|
||||
class Fifo #(type T = Unrelated);
|
||||
T m_val;
|
||||
task put(input T t);
|
||||
m_val = t;
|
||||
endtask
|
||||
task get(output T t);
|
||||
t = m_val;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
module t;
|
||||
Fifo #(Leaf) lf;
|
||||
Fifo #(Mid) mf;
|
||||
Fifo #(Base) bf;
|
||||
|
||||
Leaf l1, l2, l3;
|
||||
Mid m1, m2;
|
||||
Base b1, b2, b3;
|
||||
|
||||
initial begin
|
||||
lf = new;
|
||||
mf = new;
|
||||
bf = new;
|
||||
|
||||
// Output upcast Leaf -> Mid.
|
||||
l1 = new; l1.seq = 1;
|
||||
lf.put(l1);
|
||||
lf.get(m1);
|
||||
if (m1 === null) $stop;
|
||||
if (m1.seq !== 1) $stop;
|
||||
|
||||
// Output upcast Leaf -> Base (two levels).
|
||||
l2 = new; l2.seq = 2;
|
||||
lf.put(l2);
|
||||
lf.get(b1);
|
||||
if (b1 === null) $stop;
|
||||
if (b1.seq !== 2) $stop;
|
||||
|
||||
// Output upcast Mid -> Base.
|
||||
m2 = new; m2.seq = 3;
|
||||
mf.put(m2);
|
||||
mf.get(b2);
|
||||
if (b2 === null) $stop;
|
||||
if (b2.seq !== 3) $stop;
|
||||
|
||||
// Input upcast Leaf -> Base.
|
||||
l3 = new; l3.seq = 4;
|
||||
bf.put(l3);
|
||||
bf.get(b3);
|
||||
if (b3 === null) $stop;
|
||||
if (b3.seq !== 4) $stop;
|
||||
|
||||
// Same-type sanity.
|
||||
m1 = new; m1.seq = 5;
|
||||
mf.put(m1);
|
||||
mf.get(m2);
|
||||
if (m2 === null) $stop;
|
||||
if (m2.seq !== 5) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -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('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// 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
|
||||
|
||||
// Output class type-parameter upcast through a 3-level extends chain.
|
||||
|
||||
package x_pkg;
|
||||
virtual class x_t_fifo_base #(type T = int);
|
||||
T m_val;
|
||||
virtual task put(input T t);
|
||||
m_val = t;
|
||||
endtask
|
||||
virtual task get(output T t);
|
||||
t = m_val;
|
||||
endtask
|
||||
endclass
|
||||
class x_t_fifo #(type T = int) extends x_t_fifo_base #(T);
|
||||
endclass
|
||||
class x_t_analysis_fifo #(type T = int) extends x_t_fifo #(T);
|
||||
endclass
|
||||
endpackage
|
||||
|
||||
package s_t_pkg;
|
||||
class s_txn_base;
|
||||
int id = 0;
|
||||
endclass
|
||||
endpackage
|
||||
|
||||
package s_x_pkg;
|
||||
import s_t_pkg::*;
|
||||
class s_x_txn extends s_txn_base;
|
||||
int x_val = 0;
|
||||
endclass
|
||||
endpackage
|
||||
|
||||
package s_core_env_pkg;
|
||||
import x_pkg::*;
|
||||
import s_t_pkg::*;
|
||||
import s_x_pkg::*;
|
||||
class s_p_scoreboard;
|
||||
x_t_analysis_fifo #(s_x_txn) x_r_fifo;
|
||||
s_txn_base observed;
|
||||
extern task process_r();
|
||||
endclass
|
||||
task s_p_scoreboard::process_r();
|
||||
s_txn_base txn1;
|
||||
x_r_fifo.get(txn1);
|
||||
observed = txn1;
|
||||
endtask
|
||||
endpackage
|
||||
|
||||
import x_pkg::*;
|
||||
import s_x_pkg::*;
|
||||
import s_core_env_pkg::*;
|
||||
|
||||
module tb_top;
|
||||
s_p_scoreboard sb;
|
||||
s_x_txn tx;
|
||||
initial begin
|
||||
sb = new;
|
||||
sb.x_r_fifo = new;
|
||||
tx = new;
|
||||
tx.id = 77;
|
||||
tx.x_val = 99;
|
||||
sb.x_r_fifo.put(tx);
|
||||
sb.process_r();
|
||||
if (sb.observed === null) $stop;
|
||||
if (sb.observed.id !== 77) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue