parent
5244766b7b
commit
3ceac0b37e
|
|
@ -796,7 +796,7 @@ public:
|
||||||
void classOrPackagep(AstNodeModule* nodep) {
|
void classOrPackagep(AstNodeModule* nodep) {
|
||||||
m_classOrPackageNodep = reinterpret_cast<AstNode*>(nodep);
|
m_classOrPackageNodep = reinterpret_cast<AstNode*>(nodep);
|
||||||
}
|
}
|
||||||
|
bool hasDType() const override VL_MT_SAFE { return false; }
|
||||||
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||||
bool cleanOut() const override { V3ERROR_NA_RETURN(true); }
|
bool cleanOut() const override { V3ERROR_NA_RETURN(true); }
|
||||||
|
|
|
||||||
|
|
@ -4138,7 +4138,8 @@ class ConstVisitor final : public VNVisitor {
|
||||||
void visit(AstNode* nodep) override {
|
void visit(AstNode* nodep) override {
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
if (m_required) {
|
if (m_required) {
|
||||||
if (VN_IS(nodep, NodeDType) || VN_IS(nodep, Range) || VN_IS(nodep, SliceSel)) {
|
if (VN_IS(nodep, NodeDType) || VN_IS(nodep, Range) || VN_IS(nodep, SliceSel)
|
||||||
|
|| VN_IS(nodep, Dot)) {
|
||||||
// Ignore dtypes for parameter type pins
|
// Ignore dtypes for parameter type pins
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error("Expecting expression to be constant, but can't convert a "
|
nodep->v3error("Expecting expression to be constant, but can't convert a "
|
||||||
|
|
|
||||||
|
|
@ -5345,6 +5345,20 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||||
nodep->typedefp(defp);
|
nodep->typedefp(defp);
|
||||||
nodep->classOrPackagep(foundp->classOrPackagep());
|
nodep->classOrPackagep(foundp->classOrPackagep());
|
||||||
resolvedCapturedTypedef = true;
|
resolvedCapturedTypedef = true;
|
||||||
|
|
||||||
|
// class capture: capture typedef references inside parameterized classes
|
||||||
|
// Only capture if we're referencing from OUTSIDE the class (not
|
||||||
|
// self-references)
|
||||||
|
if (m_statep->forPrimary()) {
|
||||||
|
AstClass* const classp = VN_CAST(nodep->classOrPackagep(), Class);
|
||||||
|
if (classp && classp->hasGParam() && classp != m_modp) {
|
||||||
|
UINFO(9, indent()
|
||||||
|
<< "class capture add typedef name=" << nodep->name()
|
||||||
|
<< " class=" << classp->name() << " typedef=" << defp);
|
||||||
|
V3LinkDotIfaceCapture::addClass(nodep, classp, m_modp, defp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (AstParamTypeDType* const defp
|
} else if (AstParamTypeDType* const defp
|
||||||
= foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : nullptr) {
|
= foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : nullptr) {
|
||||||
if (defp == nodep->backp()) { // Where backp is typically typedef
|
if (defp == nodep->backp()) { // Where backp is typically typedef
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,22 @@ void V3LinkDotIfaceCapture::add(AstRefDType* refp, AstCell* cellp, AstNodeModule
|
||||||
AstTypedef* typedefp, AstNodeModule* typedefOwnerModp,
|
AstTypedef* typedefp, AstNodeModule* typedefOwnerModp,
|
||||||
AstVar* ifacePortVarp) {
|
AstVar* ifacePortVarp) {
|
||||||
if (!refp) return;
|
if (!refp) return;
|
||||||
|
|
||||||
if (!typedefp) typedefp = refp->typedefp();
|
if (!typedefp) typedefp = refp->typedefp();
|
||||||
|
|
||||||
if (!typedefOwnerModp && typedefp) typedefOwnerModp = findOwnerModule(typedefp);
|
if (!typedefOwnerModp && typedefp) typedefOwnerModp = findOwnerModule(typedefp);
|
||||||
|
|
||||||
s_map[refp] = CapturedIfaceTypedef{
|
s_map[refp] = CapturedIfaceTypedef{
|
||||||
refp, cellp, ownerModp, typedefp, typedefOwnerModp, nullptr, ifacePortVarp};
|
CaptureType::IFACE, refp, cellp, nullptr, ownerModp, typedefp,
|
||||||
|
typedefOwnerModp, nullptr, ifacePortVarp};
|
||||||
|
}
|
||||||
|
|
||||||
|
void V3LinkDotIfaceCapture::addClass(AstRefDType* refp, AstClass* origClassp,
|
||||||
|
AstNodeModule* ownerModp, AstTypedef* typedefp,
|
||||||
|
AstNodeModule* typedefOwnerModp) {
|
||||||
|
if (!refp) return;
|
||||||
|
if (!typedefp) typedefp = refp->typedefp();
|
||||||
|
if (!typedefOwnerModp && typedefp) typedefOwnerModp = findOwnerModule(typedefp);
|
||||||
|
s_map[refp] = CapturedIfaceTypedef{CaptureType::CLASS, refp, nullptr,
|
||||||
|
origClassp, ownerModp, typedefp,
|
||||||
|
typedefOwnerModp, nullptr, nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
const V3LinkDotIfaceCapture::CapturedIfaceTypedef*
|
const V3LinkDotIfaceCapture::CapturedIfaceTypedef*
|
||||||
|
|
@ -99,6 +108,18 @@ bool V3LinkDotIfaceCapture::replaceTypedef(const AstRefDType* refp, AstTypedef*
|
||||||
if (it == s_map.end()) return false;
|
if (it == s_map.end()) return false;
|
||||||
it->second.typedefp = newTypedefp;
|
it->second.typedefp = newTypedefp;
|
||||||
it->second.typedefOwnerModp = findOwnerModule(newTypedefp);
|
it->second.typedefOwnerModp = findOwnerModule(newTypedefp);
|
||||||
|
|
||||||
|
// For CLASS captures, update the RefDType node directly
|
||||||
|
if (it->second.captureType == CaptureType::CLASS && it->second.refp) {
|
||||||
|
it->second.refp->typedefp(newTypedefp);
|
||||||
|
// Also update classOrPackagep to point to the specialized class
|
||||||
|
if (AstClass* const newClassp = VN_CAST(it->second.typedefOwnerModp, Class)) {
|
||||||
|
it->second.refp->classOrPackagep(newClassp);
|
||||||
|
}
|
||||||
|
UINFO(9, "class capture updated RefDType typedefp: " << it->second.refp << " -> "
|
||||||
|
<< newTypedefp);
|
||||||
|
}
|
||||||
|
|
||||||
finalizeCapturedEntry(it, "typedef clone");
|
finalizeCapturedEntry(it, "typedef clone");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,12 @@
|
||||||
|
|
||||||
class V3LinkDotIfaceCapture final {
|
class V3LinkDotIfaceCapture final {
|
||||||
public:
|
public:
|
||||||
|
enum class CaptureType { IFACE, CLASS };
|
||||||
struct CapturedIfaceTypedef final {
|
struct CapturedIfaceTypedef final {
|
||||||
|
CaptureType captureType = CaptureType::IFACE;
|
||||||
AstRefDType* refp = nullptr;
|
AstRefDType* refp = nullptr;
|
||||||
AstCell* cellp = nullptr;
|
AstCell* cellp = nullptr; // now for IFACE captures
|
||||||
|
AstClass* origClassp = nullptr; // new for CLASS captures
|
||||||
// Module where the RefDType lives
|
// Module where the RefDType lives
|
||||||
AstNodeModule* ownerModp = nullptr;
|
AstNodeModule* ownerModp = nullptr;
|
||||||
// Typedef definition being referenced
|
// Typedef definition being referenced
|
||||||
|
|
@ -69,6 +72,9 @@ public:
|
||||||
static void add(AstRefDType* refp, AstCell* cellp, AstNodeModule* ownerModp,
|
static void add(AstRefDType* refp, AstCell* cellp, AstNodeModule* ownerModp,
|
||||||
AstTypedef* typedefp = nullptr, AstNodeModule* typedefOwnerModp = nullptr,
|
AstTypedef* typedefp = nullptr, AstNodeModule* typedefOwnerModp = nullptr,
|
||||||
AstVar* ifacePortVarp = nullptr);
|
AstVar* ifacePortVarp = nullptr);
|
||||||
|
static void addClass(AstRefDType* refp, AstClass* origClassp, AstNodeModule* ownerModp,
|
||||||
|
AstTypedef* typedefp = nullptr,
|
||||||
|
AstNodeModule* typedefOwnerModp = nullptr);
|
||||||
static const CapturedIfaceTypedef* find(const AstRefDType* refp);
|
static const CapturedIfaceTypedef* find(const AstRefDType* refp);
|
||||||
static void forEach(const std::function<void(const CapturedIfaceTypedef&)>& fn);
|
static void forEach(const std::function<void(const CapturedIfaceTypedef&)>& fn);
|
||||||
static void forEachOwned(const AstNodeModule* ownerModp,
|
static void forEachOwned(const AstNodeModule* ownerModp,
|
||||||
|
|
|
||||||
|
|
@ -810,6 +810,27 @@ class ParamProcessor final {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to resolve DOT to RefDType for class type references
|
||||||
|
void resolveDotToTypedef(AstNode* exprp) {
|
||||||
|
AstDot* const dotp = VN_CAST(exprp, Dot);
|
||||||
|
if (!dotp) return;
|
||||||
|
const AstClassOrPackageRef* const classRefp = VN_CAST(dotp->lhsp(), ClassOrPackageRef);
|
||||||
|
if (!classRefp) return;
|
||||||
|
const AstClass* const lhsClassp = VN_CAST(classRefp->classOrPackageSkipp(), Class);
|
||||||
|
if (!lhsClassp) return;
|
||||||
|
AstParseRef* const parseRefp = VN_CAST(dotp->rhsp(), ParseRef);
|
||||||
|
if (!parseRefp) return;
|
||||||
|
|
||||||
|
AstTypedef* const tdefp
|
||||||
|
= VN_CAST(m_memberMap.findMember(lhsClassp, parseRefp->name()), Typedef);
|
||||||
|
if (tdefp) {
|
||||||
|
AstRefDType* const refp = new AstRefDType{dotp->fileline(), tdefp->name()};
|
||||||
|
refp->typedefp(tdefp);
|
||||||
|
dotp->replaceWith(refp);
|
||||||
|
VL_DO_DANGLING(dotp->deleteTree(), dotp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cellPinCleanup(AstNode* nodep, AstPin* pinp, AstNodeModule* srcModp, string& longnamer,
|
void cellPinCleanup(AstNode* nodep, AstPin* pinp, AstNodeModule* srcModp, string& longnamer,
|
||||||
bool& any_overridesr) {
|
bool& any_overridesr) {
|
||||||
if (!pinp->exprp()) return; // No-connect
|
if (!pinp->exprp()) return; // No-connect
|
||||||
|
|
@ -869,6 +890,10 @@ class ParamProcessor final {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (AstParamTypeDType* const modvarp = pinp->modPTypep()) {
|
} else if (AstParamTypeDType* const modvarp = pinp->modPTypep()) {
|
||||||
|
// Handle DOT with ParseRef RHS (e.g., p_class#(8)::p_type)
|
||||||
|
// by this point ClassOrPackageRef should be updated to point to the specialized class.
|
||||||
|
resolveDotToTypedef(pinp->exprp());
|
||||||
|
|
||||||
AstNodeDType* rawTypep = VN_CAST(pinp->exprp(), NodeDType);
|
AstNodeDType* rawTypep = VN_CAST(pinp->exprp(), NodeDType);
|
||||||
if (rawTypep) V3Width::widthParamsEdit(rawTypep);
|
if (rawTypep) V3Width::widthParamsEdit(rawTypep);
|
||||||
AstNodeDType* exprp = rawTypep ? rawTypep->skipRefToNonRefp() : nullptr;
|
AstNodeDType* exprp = rawTypep ? rawTypep->skipRefToNonRefp() : nullptr;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,41 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class p_class #(
|
||||||
|
parameter TLEN = 2,
|
||||||
|
localparam type T = logic [TLEN-1:0]
|
||||||
|
);
|
||||||
|
typedef struct packed {
|
||||||
|
T a;
|
||||||
|
} p_type;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module p_mod #(
|
||||||
|
parameter type T = logic
|
||||||
|
);
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
`checkd($bits(T), 8);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module the_top #()();
|
||||||
|
typedef p_class#(8)::p_type p_type_t;
|
||||||
|
p_mod #(p_type_t) p1();
|
||||||
|
|
||||||
|
p_mod #( p_class#(8)::p_type ) p2();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#2;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,44 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class p_class #(
|
||||||
|
parameter TLEN = 2,
|
||||||
|
localparam type T = logic [TLEN-1:0]
|
||||||
|
);
|
||||||
|
typedef struct packed {
|
||||||
|
T a, b;
|
||||||
|
} p_type;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module p_mod #(
|
||||||
|
parameter type T = logic
|
||||||
|
);
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
`checkd($bits(T), 16);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module the_top #() ();
|
||||||
|
p_mod #(.T(p_class#(8)::p_type)) p1();
|
||||||
|
|
||||||
|
typedef p_class#(8) p_class_8;
|
||||||
|
p_mod #(.T(p_class_8::p_type)) p2();
|
||||||
|
|
||||||
|
typedef p_class#(8)::p_type p_class_type_8;
|
||||||
|
p_mod #(.T(p_class_type_8)) p4();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#2;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,41 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class p_class #(
|
||||||
|
parameter TLEN = 2,
|
||||||
|
localparam type T = logic [TLEN-1:0]
|
||||||
|
);
|
||||||
|
typedef struct packed {
|
||||||
|
T a, b;
|
||||||
|
} p_type;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module p_mod #(
|
||||||
|
parameter type T = logic
|
||||||
|
);
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
`checkd($bits(T), 16);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module the_top #() ();
|
||||||
|
|
||||||
|
typedef p_class#(8) p_class_8;
|
||||||
|
typedef p_class_8::p_type p_type_8;
|
||||||
|
p_mod #(.T(p_type_8)) p3();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#2;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,47 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class p_class #(
|
||||||
|
parameter TLEN = 2,
|
||||||
|
localparam type T = logic [TLEN-1:0]
|
||||||
|
);
|
||||||
|
typedef struct packed {
|
||||||
|
T a, b;
|
||||||
|
} p_type;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module p_mod #(
|
||||||
|
parameter type T = logic
|
||||||
|
);
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
`checkd($bits(T), 16);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module the_top #() ();
|
||||||
|
p_mod #(.T(p_class#(8)::p_type)) p1();
|
||||||
|
|
||||||
|
typedef p_class#(8) p_class_8;
|
||||||
|
p_mod #(.T(p_class_8::p_type)) p2();
|
||||||
|
|
||||||
|
typedef p_class_8::p_type p_type_8;
|
||||||
|
p_mod #(.T(p_type_8)) p3();
|
||||||
|
|
||||||
|
typedef p_class#(8)::p_type p_class_type_8;
|
||||||
|
p_mod #(.T(p_class_type_8)) p4();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#2;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,42 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class xxx_class #(parameter int X = 1);
|
||||||
|
typedef logic [X-1:0] cmd_tag_t;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module mod_a #(parameter p_width=16) ();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mod_b #(parameter type io_type_t = logic) (
|
||||||
|
io_type_t io
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
`checkd($bits(io), 16);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module the_top();
|
||||||
|
xxx_class#(16)::cmd_tag_t tag;
|
||||||
|
mod_a #($bits(tag)) t0();
|
||||||
|
|
||||||
|
typedef xxx_class#(16)::cmd_tag_t tag_t;
|
||||||
|
tag_t tag_io;
|
||||||
|
mod_b #(tag_t) t1(tag_io);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#2;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,29 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class xxx_class #(parameter int X = 1);
|
||||||
|
typedef logic [X-1:0] cmd_tag_t;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module mod_a #(parameter p_width=16) ();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module the_top();
|
||||||
|
xxx_class#(16)::cmd_tag_t tag;
|
||||||
|
mod_a #($bits(tag)) t0();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#2;
|
||||||
|
`checkd($bits(tag), 16);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 by Wilson Snyder. 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-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,53 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
package pf;
|
||||||
|
typedef struct packed {
|
||||||
|
int unsigned CcNumTl;
|
||||||
|
int unsigned PqSize;
|
||||||
|
} cfg_t;
|
||||||
|
endpackage
|
||||||
|
|
||||||
|
virtual class xxx_class #(parameter pf::cfg_t Cfg);
|
||||||
|
typedef struct packed {
|
||||||
|
logic [$clog2(Cfg.CcNumTl)-1:0] tl_index;
|
||||||
|
logic [$clog2(Cfg.PqSize)-1:0] pq_index;
|
||||||
|
} cmd_tag_t;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
module mod2 #(parameter p_width=16) (
|
||||||
|
output logic [p_width-1:0] q,
|
||||||
|
input logic [p_width-1:0] d
|
||||||
|
);
|
||||||
|
assign q = d;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
`checkd(p_width, 7);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top();
|
||||||
|
localparam pf::cfg_t Cfg0 = '{
|
||||||
|
CcNumTl:8
|
||||||
|
,PqSize:12
|
||||||
|
};
|
||||||
|
|
||||||
|
xxx_class#(Cfg0)::cmd_tag_t tag, tag_q;
|
||||||
|
|
||||||
|
mod2 #($bits(tag)) t0(tag_q, tag);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#1;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue