mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
This commit is contained in:
+18
-7
@@ -4157,17 +4157,28 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
void makeModeInit(AstVar* modeVarp, AstClass* classp, uint32_t modeCount) {
|
||||
AstNodeModule* const modeVarModp = VN_AS(modeVarp->user2p(), NodeModule);
|
||||
FileLine* fl = modeVarp->fileline();
|
||||
AstVar* const oldSizeVarp = new AstVar{
|
||||
fl, VVarType::BLOCKTEMP, m_uniqueNames.get("__VoldSize"), modeVarp->findUInt32DType()};
|
||||
oldSizeVarp->funcLocal(true);
|
||||
oldSizeVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
|
||||
AstCMethodHard* const oldSizep
|
||||
= new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::READ},
|
||||
VCMethod::DYN_SIZE, nullptr};
|
||||
oldSizep->dtypeSetUInt32();
|
||||
AstCMethodHard* const dynarrayNewp
|
||||
= new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE},
|
||||
VCMethod::DYN_RESIZE, new AstConst{fl, modeCount}};
|
||||
dynarrayNewp->dtypeSetVoid();
|
||||
AstNodeFTask* const ctorNewp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask);
|
||||
UASSERT_OBJ(ctorNewp, classp, "No new() in class");
|
||||
// Build init chain: resize -> set-all-to-1 loop
|
||||
AstNode* const initFirstp = dynarrayNewp->makeStmt();
|
||||
// Preserve inherited modes set by super.new() and initialize only newly added entries.
|
||||
AstNode* const initFirstp = oldSizeVarp;
|
||||
initFirstp->addNext(
|
||||
makeModeSetLoop(fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE},
|
||||
new AstConst{fl, 1}, true));
|
||||
new AstAssign{fl, new AstVarRef{fl, oldSizeVarp, VAccess::WRITE}, oldSizep});
|
||||
initFirstp->addNext(dynarrayNewp->makeStmt());
|
||||
initFirstp->addNext(makeModeSetLoop(
|
||||
fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE}, new AstConst{fl, 1},
|
||||
true, new AstVarRef{fl, oldSizeVarp, VAccess::READ}));
|
||||
// Prepend init code before user statements in constructor body, but after
|
||||
// var declarations and super.new(). This ensures that user's constraint_mode()
|
||||
// or rand_mode() calls in the constructor execute after mode arrays are initialized.
|
||||
@@ -4216,7 +4227,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
newp->addStmtsp(ifp);
|
||||
}
|
||||
AstNode* makeModeSetLoop(FileLine* const fl, AstNodeExpr* const lhsp, AstNodeExpr* const rhsp,
|
||||
bool inTask) {
|
||||
bool inTask, AstNodeExpr* const startp = nullptr) {
|
||||
AstVar* const iterVarp = new AstVar{fl, VVarType::BLOCKTEMP, "i", lhsp->findUInt32DType()};
|
||||
iterVarp->funcLocal(inTask);
|
||||
iterVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
|
||||
@@ -4227,8 +4238,8 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
new AstVarRef{fl, iterVarp, VAccess::READ}};
|
||||
setp->dtypeSetUInt32();
|
||||
AstNode* const stmtsp = iterVarp;
|
||||
stmtsp->addNext(
|
||||
new AstAssign{fl, new AstVarRef{fl, iterVarp, VAccess::WRITE}, new AstConst{fl, 0}});
|
||||
stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, iterVarp, VAccess::WRITE},
|
||||
startp ? startp : new AstConst{fl, 0}});
|
||||
|
||||
AstLoop* const loopp = new AstLoop{fl};
|
||||
stmtsp->addNext(loopp);
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#!/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')
|
||||
|
||||
if not test.have_solver:
|
||||
test.skip("No constraint solver installed")
|
||||
|
||||
test.compile()
|
||||
test.execute()
|
||||
test.passes()
|
||||
@@ -0,0 +1,93 @@
|
||||
// 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
|
||||
|
||||
// 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
|
||||
|
||||
typedef enum int {
|
||||
FIRST,
|
||||
SECOND,
|
||||
THIRD
|
||||
} Kind;
|
||||
|
||||
class Base;
|
||||
rand Kind kind;
|
||||
|
||||
constraint c_kind { kind inside {FIRST, SECOND, THIRD}; }
|
||||
endclass
|
||||
|
||||
class Intermediate extends Base;
|
||||
rand int value;
|
||||
|
||||
constraint c_value { value == 31; }
|
||||
|
||||
function new;
|
||||
kind = THIRD;
|
||||
kind.rand_mode(0);
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class Derived extends Intermediate;
|
||||
rand int extra;
|
||||
|
||||
constraint c_extra { extra == 15; }
|
||||
endclass
|
||||
|
||||
class CombinedModes;
|
||||
rand int value;
|
||||
|
||||
constraint c_value { value == 7; }
|
||||
|
||||
function new;
|
||||
value = 9;
|
||||
value.rand_mode(0);
|
||||
c_value.constraint_mode(0);
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
automatic Intermediate intermediate = new;
|
||||
automatic Derived derived = new;
|
||||
automatic CombinedModes combined_modes = new;
|
||||
automatic int randomize_result;
|
||||
|
||||
`checkd(combined_modes.value, 9)
|
||||
`checkd(combined_modes.value.rand_mode(), 0)
|
||||
`checkd(combined_modes.c_value.constraint_mode(), 0)
|
||||
randomize_result = combined_modes.randomize();
|
||||
`checkd(randomize_result, 1)
|
||||
`checkd(combined_modes.value, 9)
|
||||
|
||||
`checkd(intermediate.kind, THIRD)
|
||||
`checkd(intermediate.kind.rand_mode(), 0)
|
||||
`checkd(derived.kind, THIRD)
|
||||
`checkd(derived.kind.rand_mode(), 0)
|
||||
|
||||
repeat (20) begin
|
||||
randomize_result = intermediate.randomize();
|
||||
`checkd(randomize_result, 1)
|
||||
`checkd(intermediate.kind, THIRD)
|
||||
`checkd(intermediate.kind.rand_mode(), 0)
|
||||
`checkd(intermediate.value, 31)
|
||||
`checkd(intermediate.value.rand_mode(), 1)
|
||||
|
||||
randomize_result = derived.randomize();
|
||||
`checkd(randomize_result, 1)
|
||||
`checkd(derived.kind, THIRD)
|
||||
`checkd(derived.kind.rand_mode(), 0)
|
||||
`checkd(derived.value, 31)
|
||||
`checkd(derived.value.rand_mode(), 1)
|
||||
`checkd(derived.extra, 15)
|
||||
`checkd(derived.extra.rand_mode(), 1)
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Reference in New Issue
Block a user