parent
2c5ff3f63f
commit
f2e05bc0b7
|
|
@ -2931,6 +2931,31 @@ class ConstVisitor final : public VNVisitor {
|
|||
replaceWithSimulation(nodep);
|
||||
}
|
||||
|
||||
void visit(AstStructSel* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
|
||||
if (VN_IS(nodep->fromp(), ConsPackUOrStruct)) {
|
||||
const AstConsPackUOrStruct* const consp = VN_AS(nodep->fromp(), ConsPackUOrStruct);
|
||||
for (AstConsPackMember* memberp = consp->membersp(); memberp;
|
||||
memberp = VN_AS(memberp->nextp(), ConsPackMember)) {
|
||||
|
||||
if (memberp->dtypep() && memberp->dtypep()->name() == nodep->name()) {
|
||||
AstNode* const valuep = memberp->rhsp();
|
||||
|
||||
if (VN_IS(valuep, Const)) {
|
||||
const V3Number& num = VN_AS(valuep, Const)->num();
|
||||
VL_DO_DANGLING(replaceNum(nodep, num), nodep);
|
||||
} else {
|
||||
AstNode* const newp = valuep->cloneTree(false);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visit(AstCAwait* nodep) override {
|
||||
m_hasJumpDelay = true;
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -2976,6 +3001,11 @@ class ConstVisitor final : public VNVisitor {
|
|||
nodep->replaceWithKeepDType(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
did = true;
|
||||
} else if (m_params && VN_IS(valuep, ConsPackUOrStruct)) {
|
||||
AstNode* const newp = valuep->cloneTree(false);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
did = true;
|
||||
} else if (nodep->varp()->isParam() && VN_IS(valuep, Unbounded)) {
|
||||
AstNode* const newp = valuep->cloneTree(false);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
|
|
@ -3654,6 +3684,8 @@ class ConstVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
void visit(AstInitArray* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstConsPackUOrStruct* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstConsPackMember* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstInitItem* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstUnbounded* nodep) override { iterateChildren(nodep); }
|
||||
// These are converted by V3Param. Don't constify as we don't want the
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2025 by Jonathan Drolet.
|
||||
// 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\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module t;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
} subsubstruct_t;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
subsubstruct_t subsub;
|
||||
int c;
|
||||
} substruct_t;
|
||||
|
||||
typedef substruct_t substruct_t_t;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
substruct_t_t sub;
|
||||
int c;
|
||||
} struct_t;
|
||||
|
||||
// Constant value unpacked struct support is limited at the moment.
|
||||
// Only localparams are supported, returning constant unpacked structure
|
||||
// from function or passing unpacked structure as parameters is not
|
||||
// (yet) supported
|
||||
localparam struct_t MY_STRUCT = '{a: 10, b: 5, c: 20, sub: '{a: 100, b: 200, c: 150, subsub: '{default: 10}}};
|
||||
|
||||
// Make standalone localparam to ensure MY_STRUCT is const
|
||||
localparam int C = MY_STRUCT.c;
|
||||
localparam int S_A = MY_STRUCT.sub.a;
|
||||
localparam int SS_B = MY_STRUCT.sub.subsub.b;
|
||||
|
||||
initial begin
|
||||
`checkd(MY_STRUCT.a, 10);
|
||||
`checkd(MY_STRUCT.b, 5);
|
||||
`checkd(MY_STRUCT.c, 20);
|
||||
`checkd(MY_STRUCT.sub.c, 150);
|
||||
`checkd(C, 20);
|
||||
`checkd(S_A, 100);
|
||||
`checkd(SS_B, 10);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue