parent
5244766b7b
commit
3ceac0b37e
|
|
@ -796,7 +796,7 @@ public:
|
|||
void classOrPackagep(AstNodeModule* nodep) {
|
||||
m_classOrPackageNodep = reinterpret_cast<AstNode*>(nodep);
|
||||
}
|
||||
|
||||
bool hasDType() const override VL_MT_SAFE { return false; }
|
||||
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
bool cleanOut() const override { V3ERROR_NA_RETURN(true); }
|
||||
|
|
|
|||
|
|
@ -4138,7 +4138,8 @@ class ConstVisitor final : public VNVisitor {
|
|||
void visit(AstNode* nodep) override {
|
||||
// Default: Just iterate
|
||||
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
|
||||
} else {
|
||||
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->classOrPackagep(foundp->classOrPackagep());
|
||||
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
|
||||
= foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : nullptr) {
|
||||
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,
|
||||
AstVar* ifacePortVarp) {
|
||||
if (!refp) return;
|
||||
|
||||
if (!typedefp) typedefp = refp->typedefp();
|
||||
|
||||
if (!typedefOwnerModp && typedefp) typedefOwnerModp = findOwnerModule(typedefp);
|
||||
|
||||
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*
|
||||
|
|
@ -99,6 +108,18 @@ bool V3LinkDotIfaceCapture::replaceTypedef(const AstRefDType* refp, AstTypedef*
|
|||
if (it == s_map.end()) return false;
|
||||
it->second.typedefp = 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");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,12 @@
|
|||
|
||||
class V3LinkDotIfaceCapture final {
|
||||
public:
|
||||
enum class CaptureType { IFACE, CLASS };
|
||||
struct CapturedIfaceTypedef final {
|
||||
CaptureType captureType = CaptureType::IFACE;
|
||||
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
|
||||
AstNodeModule* ownerModp = nullptr;
|
||||
// Typedef definition being referenced
|
||||
|
|
@ -69,6 +72,9 @@ public:
|
|||
static void add(AstRefDType* refp, AstCell* cellp, AstNodeModule* ownerModp,
|
||||
AstTypedef* typedefp = nullptr, AstNodeModule* typedefOwnerModp = 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 void forEach(const std::function<void(const CapturedIfaceTypedef&)>& fn);
|
||||
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,
|
||||
bool& any_overridesr) {
|
||||
if (!pinp->exprp()) return; // No-connect
|
||||
|
|
@ -869,6 +890,10 @@ class ParamProcessor final {
|
|||
}
|
||||
}
|
||||
} 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);
|
||||
if (rawTypep) V3Width::widthParamsEdit(rawTypep);
|
||||
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