more tests and fixes
This commit is contained in:
parent
de0236be2f
commit
7a9563db57
|
|
@ -2178,6 +2178,50 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve `class::member` Dots in `rootp`'s tree, and also in any deferred
|
||||||
|
// lparam reachable transitively through VarRefs from `rootp`. By V3Param
|
||||||
|
// time the surviving such Dots are paramed-class refs that need
|
||||||
|
// linkDotParamed for scope, but `resolveDotToTypedef` can handle the
|
||||||
|
// typedef-aliased subset inline. Resolving them here turns a deferred
|
||||||
|
// lparam's value into a Const so subsequent constify on `rootp` can fold
|
||||||
|
// expressions that reference the lparam.
|
||||||
|
// `modp` is the enclosing module — resolveDotToTypedef may call into
|
||||||
|
// classRefDeparam which needs m_modp set for level/recursion bookkeeping.
|
||||||
|
void resolveDeferredDotsReachableFrom(AstNode* rootp, AstNodeModule* modp) {
|
||||||
|
std::vector<AstDot*> dotps;
|
||||||
|
const auto& deferredVarps = v3Global.rootp()->deferredParamVarps();
|
||||||
|
std::set<AstVar*> reachedDeferred;
|
||||||
|
auto collectDots = [&](AstNode* p) {
|
||||||
|
p->foreach([&](AstDot* dotp) {
|
||||||
|
if (VN_IS(dotp->lhsp(), ClassOrPackageRef)) dotps.push_back(dotp);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
std::vector<AstVar*> workVarps;
|
||||||
|
auto enqueueRefs = [&](AstNode* p) {
|
||||||
|
p->foreach([&](const AstVarRef* refp) {
|
||||||
|
AstVar* const refVarp = refp->varp();
|
||||||
|
if (refVarp && refVarp->varType() == VVarType::LPARAM
|
||||||
|
&& deferredVarps.count(refVarp) && reachedDeferred.insert(refVarp).second) {
|
||||||
|
workVarps.push_back(refVarp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
collectDots(rootp);
|
||||||
|
enqueueRefs(rootp);
|
||||||
|
while (!workVarps.empty()) {
|
||||||
|
AstVar* const varp = workVarps.back();
|
||||||
|
workVarps.pop_back();
|
||||||
|
if (!varp->valuep()) continue;
|
||||||
|
collectDots(varp->valuep());
|
||||||
|
enqueueRefs(varp->valuep());
|
||||||
|
}
|
||||||
|
if (dotps.empty()) return;
|
||||||
|
VL_RESTORER(m_modp);
|
||||||
|
m_modp = modp;
|
||||||
|
// Reverse-iterate so inner Dots resolve before outer.
|
||||||
|
for (auto it = dotps.rbegin(); it != dotps.rend(); ++it) resolveDotToTypedef(*it);
|
||||||
|
}
|
||||||
|
|
||||||
AstNodeModule* nodeDeparam(AstNode* nodep, AstNodeModule* srcModp, AstNodeModule* modp,
|
AstNodeModule* nodeDeparam(AstNode* nodep, AstNodeModule* srcModp, AstNodeModule* modp,
|
||||||
const string& someInstanceName) {
|
const string& someInstanceName) {
|
||||||
// Return new or reused de-parameterized module
|
// Return new or reused de-parameterized module
|
||||||
|
|
@ -2218,14 +2262,9 @@ public:
|
||||||
}
|
}
|
||||||
// Create new module name with _'s between the constants
|
// Create new module name with _'s between the constants
|
||||||
UINFOTREE(10, nodep, "", "cell");
|
UINFOTREE(10, nodep, "", "cell");
|
||||||
// Resolve `class::member` Dots in pin values so constify sees Consts.
|
// Resolve `class::member` Dots in pin values, and in any deferred
|
||||||
// Single-pass: filter-collect class-scoped Dots, then reverse-iterate so inner
|
// lparam reachable from the pin tree, so constify sees Consts.
|
||||||
// Dots resolve before outer (vector stays empty for cells with no class Dots).
|
resolveDeferredDotsReachableFrom(nodep, modp);
|
||||||
std::vector<AstDot*> dotps;
|
|
||||||
nodep->foreach([&](AstDot* dotp) {
|
|
||||||
if (VN_IS(dotp->lhsp(), ClassOrPackageRef)) dotps.push_back(dotp);
|
|
||||||
});
|
|
||||||
for (auto it = dotps.rbegin(); it != dotps.rend(); ++it) resolveDotToTypedef(*it);
|
|
||||||
// Evaluate all module constants
|
// Evaluate all module constants
|
||||||
V3Const::constifyParamsEdit(nodep);
|
V3Const::constifyParamsEdit(nodep);
|
||||||
// Set name for warnings for when we param propagate the module
|
// Set name for warnings for when we param propagate the module
|
||||||
|
|
@ -3173,6 +3212,9 @@ class ParamVisitor final : public VNVisitor {
|
||||||
void visit(AstGenIf* nodep) override {
|
void visit(AstGenIf* nodep) override {
|
||||||
UINFO(9, " GENIF " << nodep);
|
UINFO(9, " GENIF " << nodep);
|
||||||
iterateAndNextNull(nodep->condp());
|
iterateAndNextNull(nodep->condp());
|
||||||
|
// condp may reference deferred lparams whose Dot is still pending;
|
||||||
|
// resolve them so widthing/constify can see Consts.
|
||||||
|
m_processor.resolveDeferredDotsReachableFrom(nodep->condp(), m_modp);
|
||||||
// We suppress errors when widthing params since short-circuiting in
|
// We suppress errors when widthing params since short-circuiting in
|
||||||
// the conditional evaluation may mean these error can never occur. We
|
// the conditional evaluation may mean these error can never occur. We
|
||||||
// then make sure that short-circuiting is used by constifyParamsEdit.
|
// then make sure that short-circuiting is used by constifyParamsEdit.
|
||||||
|
|
@ -3208,6 +3250,9 @@ class ParamVisitor final : public VNVisitor {
|
||||||
iterateAndNextNull(forp->initsp());
|
iterateAndNextNull(forp->initsp());
|
||||||
iterateAndNextNull(forp->condp());
|
iterateAndNextNull(forp->condp());
|
||||||
iterateAndNextNull(forp->incsp());
|
iterateAndNextNull(forp->incsp());
|
||||||
|
// Cond/init/inc may reference deferred lparams whose Dot is still
|
||||||
|
// pending; resolve them so widthing/constify can see Consts.
|
||||||
|
m_processor.resolveDeferredDotsReachableFrom(forp, m_modp);
|
||||||
V3Width::widthParamsEdit(forp); // Param typed widthing will NOT recurse the body
|
V3Width::widthParamsEdit(forp); // Param typed widthing will NOT recurse the body
|
||||||
// Outer wrapper around generate used to hold genvar, and to ensure genvar
|
// Outer wrapper around generate used to hold genvar, and to ensure genvar
|
||||||
// doesn't conflict in V3LinkDot resolution with other genvars
|
// doesn't conflict in V3LinkDot resolution with other genvars
|
||||||
|
|
@ -3241,6 +3286,9 @@ class ParamVisitor final : public VNVisitor {
|
||||||
AstNode* keepp = nullptr;
|
AstNode* keepp = nullptr;
|
||||||
iterateAndNextNull(nodep->exprp());
|
iterateAndNextNull(nodep->exprp());
|
||||||
V3Case::caseLint(nodep);
|
V3Case::caseLint(nodep);
|
||||||
|
// expr / case items may reference deferred lparams whose Dot is still
|
||||||
|
// pending; resolve them so widthing/constify can see Consts.
|
||||||
|
m_processor.resolveDeferredDotsReachableFrom(nodep, m_modp);
|
||||||
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the
|
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the
|
||||||
// body, don't trigger errors yet.
|
// body, don't trigger errors yet.
|
||||||
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
|
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
|
||||||
|
|
|
||||||
|
|
@ -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 Edmund Lam
|
||||||
|
# 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,65 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// Generate-for / generate-if / generate-case conditions that reference
|
||||||
|
// a class-scope-resolved deferred localparam (e.g. inst::b). V3Param's
|
||||||
|
// visit(AstGenIf/Block/Case) calls V3Width::widthParamsEdit /
|
||||||
|
// constify on the cond/expr; the same transitive Dot-resolution used
|
||||||
|
// for cell pins must be applied here so the deferred lparam folds.
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Edmund Lam
|
||||||
|
// 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='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
// Cell whose presence is observable, used inside generate blocks
|
||||||
|
// below to confirm each generate flavour elaborated the right way.
|
||||||
|
module Tag #(
|
||||||
|
parameter int ID
|
||||||
|
) ();
|
||||||
|
initial $write("Tag ID=%0d\n", ID);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t;
|
||||||
|
virtual class C #(
|
||||||
|
parameter int a
|
||||||
|
);
|
||||||
|
localparam int b = a;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
typedef C#(3) c3;
|
||||||
|
typedef C#(5) c5;
|
||||||
|
|
||||||
|
// Deferred lparams
|
||||||
|
localparam int b3 = c3::b;
|
||||||
|
localparam int b5 = c5::b;
|
||||||
|
|
||||||
|
// (1) Generate-for bound = deferred lparam
|
||||||
|
for (genvar i = 0; i < b3; i++) begin : gf
|
||||||
|
Tag #(100 + i) inst ();
|
||||||
|
end
|
||||||
|
|
||||||
|
// (2) Generate-if cond = deferred lparam
|
||||||
|
if (b5 > b3) begin : gi_t
|
||||||
|
Tag #(200) inst ();
|
||||||
|
end else begin : gi_f
|
||||||
|
Tag #(201) inst ();
|
||||||
|
end
|
||||||
|
|
||||||
|
// (3) Generate-case selector = deferred lparam
|
||||||
|
case (b5)
|
||||||
|
3: begin : gc Tag #(303) inst (); end
|
||||||
|
5: begin : gc Tag #(305) inst (); end
|
||||||
|
default: begin : gc Tag #(399) inst (); end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkh(b3, 32'd3);
|
||||||
|
`checkh(b5, 32'd5);
|
||||||
|
$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 Edmund Lam
|
||||||
|
# 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,66 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// Interface-instance parameter pins whose value chains through a
|
||||||
|
// class-scope-resolved localparam (typedef alias of a parameterized
|
||||||
|
// class, e.g. inst::b). Same cell-deparam fix that handles module
|
||||||
|
// instances must also handle interface instances and downstream
|
||||||
|
// port-bound consumers.
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Edmund Lam
|
||||||
|
// 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='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
interface SubIface #(
|
||||||
|
parameter int IW
|
||||||
|
) ();
|
||||||
|
logic [IW-1:0] data;
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
// Module that takes an interface port — must elaborate after the iface
|
||||||
|
// cell pin is fully constified.
|
||||||
|
module Consumer (
|
||||||
|
SubIface si
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t;
|
||||||
|
virtual class C #(
|
||||||
|
parameter int a
|
||||||
|
);
|
||||||
|
localparam int b = a;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
typedef C#(8) c8;
|
||||||
|
typedef C#(13) c13;
|
||||||
|
|
||||||
|
// Deferred lparams
|
||||||
|
localparam int b8 = c8::b;
|
||||||
|
localparam int b13 = c13::b;
|
||||||
|
// Chained
|
||||||
|
localparam int b8_alias = b8;
|
||||||
|
|
||||||
|
// Iface pin = bare VarRef to deferred lparam
|
||||||
|
SubIface #(b8) i_bare ();
|
||||||
|
// Iface pin = chained VarRef
|
||||||
|
SubIface #(b8_alias) i_chain ();
|
||||||
|
// Iface pin = expression mixing deferred lparams
|
||||||
|
SubIface #(b8 + b13) i_expr ();
|
||||||
|
// Iface used as a module port — exercises the iface-cell-first path
|
||||||
|
Consumer cons (.si(i_bare));
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkh(b8, 32'd8);
|
||||||
|
`checkh(b13, 32'd13);
|
||||||
|
`checkh(b8_alias, 32'd8);
|
||||||
|
`checkh($bits(i_bare.data), 32'd8);
|
||||||
|
`checkh($bits(i_chain.data), 32'd8);
|
||||||
|
`checkh($bits(i_expr.data), 32'd21);
|
||||||
|
$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 Edmund Lam
|
||||||
|
# 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,71 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// Module-instance parameter pins whose value chains through a
|
||||||
|
// class-scope-resolved localparam (typedef alias of a parameterized
|
||||||
|
// class, e.g. inst::b). V3LinkDot defers the inst::b Dot until
|
||||||
|
// post-V3Param; the cell deparam must follow VarRefs into any
|
||||||
|
// deferred lparam reachable from the pin tree and resolve its Dots
|
||||||
|
// inline so constify on the cell can fold.
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Edmund Lam
|
||||||
|
// 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='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
module Sub #(
|
||||||
|
parameter int WIDTH
|
||||||
|
) ();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Two-level: outer module forwards its param to an inner cell, so the
|
||||||
|
// deferred lparam value must flow through the cell-deparam chain.
|
||||||
|
module SubL1 #(
|
||||||
|
parameter int W
|
||||||
|
) ();
|
||||||
|
Sub #(W) inner ();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t;
|
||||||
|
virtual class C #(
|
||||||
|
parameter int a
|
||||||
|
);
|
||||||
|
localparam int b = a;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
typedef C#(4) c4;
|
||||||
|
typedef C#(5) c5;
|
||||||
|
typedef C#(8) c8;
|
||||||
|
|
||||||
|
// Deferred lparams (value contains class::member Dot)
|
||||||
|
localparam int b4 = c4::b;
|
||||||
|
localparam int b5 = c5::b;
|
||||||
|
localparam int b8 = c8::b;
|
||||||
|
// Chained: value references another deferred lparam
|
||||||
|
localparam int c8_ref = b8;
|
||||||
|
localparam int d8_ref = c8_ref + 1;
|
||||||
|
|
||||||
|
// Pin is bare VarRef to a deferred lparam
|
||||||
|
Sub #(b8) m_bare ();
|
||||||
|
// Pin chains through multiple deferred lparams (b8 -> c8_ref -> d8_ref)
|
||||||
|
Sub #(d8_ref) m_chain ();
|
||||||
|
// Pin is an expression mixing two deferred lparams
|
||||||
|
Sub #(b4 + b5) m_expr ();
|
||||||
|
// Pin mixes a Dot and a deferred lparam in the same expression
|
||||||
|
Sub #(c4::b + b5) m_mix ();
|
||||||
|
// Two-level: outer module forwards param to inner cell
|
||||||
|
SubL1 #(b8) m_l1 ();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkh(b4, 32'd4);
|
||||||
|
`checkh(b5, 32'd5);
|
||||||
|
`checkh(b8, 32'd8);
|
||||||
|
`checkh(c8_ref, 32'd8);
|
||||||
|
`checkh(d8_ref, 32'd9);
|
||||||
|
$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 Edmund Lam
|
||||||
|
# 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,60 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// Typedefs and class type parameters that resolve through a
|
||||||
|
// class-scope-resolved localparam (typedef alias of a parameterized
|
||||||
|
// class, e.g. inst::b). Exercises three sub-cases:
|
||||||
|
// - Deferred lparam used as a packed range bound in a typedef
|
||||||
|
// - Deferred lparam used as a value argument to a parameterized class
|
||||||
|
// - Class-scope-resolved typedef that itself depends on the param
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Edmund Lam
|
||||||
|
// 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='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
module t;
|
||||||
|
virtual class C #(
|
||||||
|
parameter int a
|
||||||
|
);
|
||||||
|
localparam int b = a;
|
||||||
|
typedef logic [a-1:0] inner_t;
|
||||||
|
// localparam derived from a typedef inside the same class —
|
||||||
|
// resolveDotToTypedef must constify this when reached via CFG::width.
|
||||||
|
localparam int width = $bits(inner_t);
|
||||||
|
endclass
|
||||||
|
|
||||||
|
typedef C#(8) c8;
|
||||||
|
|
||||||
|
// Deferred lparam (direct Dot)
|
||||||
|
localparam int b8 = c8::b;
|
||||||
|
|
||||||
|
// (1) typedef range driven by a deferred lparam
|
||||||
|
typedef logic [b8-1:0] data_t;
|
||||||
|
data_t data_value;
|
||||||
|
|
||||||
|
// (2) class type-arg uses a deferred lparam value
|
||||||
|
typedef C#(b8) c_from_def;
|
||||||
|
localparam int from_def_b = c_from_def::b;
|
||||||
|
|
||||||
|
// (3) class-scope-resolved typedef computed via $bits(inner_t)
|
||||||
|
localparam int via_bits = c8::width;
|
||||||
|
|
||||||
|
// Wire whose range comes from a deferred lparam
|
||||||
|
logic [b8-1:0] wide_bus;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkh(b8, 32'd8);
|
||||||
|
`checkh(from_def_b, 32'd8);
|
||||||
|
`checkh(via_bits, 32'd8);
|
||||||
|
data_value = '1;
|
||||||
|
`checkh(data_value, 8'hff);
|
||||||
|
wide_bus = '1;
|
||||||
|
`checkh(wide_bus, 8'hff);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue