Fix randomize on function-local variable (#6234).
This commit is contained in:
parent
54efa86a6c
commit
e32108713d
1
Changes
1
Changes
|
|
@ -75,6 +75,7 @@ Verilator 5.039 devel
|
|||
* Fix `--stats` overridden by skipping identical build (#6220). [Geza Lore]
|
||||
* Fix MODDUP with duplicate packages to take first package (#6222).
|
||||
* Fix replicate with unsigned count but MSB set (#6231) (#6233). [Geza Lore]
|
||||
* Fix randomize on function-local variable (#6234).
|
||||
* Fix queue typedef with unbounded slice (#6236).
|
||||
* Fix error when force assignment is used with ref function args (#6244). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix write of 0 in '%c' (#6248) (#6249). [Rodrigo Batista de Moraes]
|
||||
|
|
|
|||
|
|
@ -1373,6 +1373,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
AstVar* const stdgenp
|
||||
= new AstVar{modp->fileline(), VVarType::MEMBER, "stdrand",
|
||||
modp->findBasicDType(VBasicDTypeKwd::RANDOM_STDGENERATOR)};
|
||||
stdgenp->fileline()->warnOff(V3ErrorCode::IMPURE, true);
|
||||
modp->addStmtsp(stdgenp);
|
||||
m_stdMap.emplace(modp, stdgenp);
|
||||
return stdgenp;
|
||||
|
|
@ -2283,6 +2284,8 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
if (nodep->name() != "randomize") return;
|
||||
|
||||
if (nodep->classOrPackagep() && nodep->classOrPackagep()->name() == "std") {
|
||||
// Handle std::randomize; create wrapper function that calls basicStdRandomization on
|
||||
// each varref argument, then transform nodep to call that wrapper
|
||||
AstVar* const stdrand = createStdRandomGenerator(m_modp);
|
||||
AstFunc* const randomizeFuncp = V3Randomize::newRandomizeStdFunc(
|
||||
m_memberMap, m_modp, m_inlineUniqueStdName.get(nodep));
|
||||
|
|
@ -2291,19 +2294,32 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var),
|
||||
VAccess::WRITE},
|
||||
new AstConst{nodep->fileline(), AstConst::WidthedValue{}, 32, 1}});
|
||||
int argn = 0;
|
||||
for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) {
|
||||
AstArg* const argp = VN_CAST(pinp, Arg);
|
||||
if (!argp) continue;
|
||||
AstNodeExpr* exprp = argp->exprp();
|
||||
|
||||
AstCMethodHard* const basicMethodp = new AstCMethodHard{
|
||||
nodep->fileline(),
|
||||
new AstVarRef{nodep->fileline(), stdrand, VAccess::READWRITE},
|
||||
"basicStdRandomization"};
|
||||
AstVar* const refvarp
|
||||
= new AstVar{exprp->fileline(), VVarType::MEMBER,
|
||||
"__Varg"s + std::to_string(++argn), exprp->dtypep()};
|
||||
refvarp->direction(VDirection::REF);
|
||||
refvarp->funcLocal(true);
|
||||
refvarp->lifetime(VLifetime::AUTOMATIC);
|
||||
randomizeFuncp->addStmtsp(refvarp);
|
||||
|
||||
const size_t width = exprp->width();
|
||||
basicMethodp->addPinsp(exprp->unlinkFrBack());
|
||||
basicMethodp->addPinsp(
|
||||
new AstVarRef{exprp->fileline(), refvarp, VAccess::READWRITE});
|
||||
|
||||
basicMethodp->addPinsp(
|
||||
new AstConst{nodep->fileline(), AstConst::Unsized64{}, width});
|
||||
basicMethodp->dtypeSetBit();
|
||||
|
||||
randomizeFuncp->addStmtsp(new AstAssign{
|
||||
nodep->fileline(),
|
||||
new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var),
|
||||
|
|
@ -2318,7 +2334,8 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
nodep->taskp(randomizeFuncp);
|
||||
nodep->dtypeFrom(randomizeFuncp->dtypep());
|
||||
if (VN_IS(m_modp, Class)) nodep->classOrPackagep(m_modp);
|
||||
if (nodep->pinsp()) pushDeletep(nodep->pinsp()->unlinkFrBackWithNext());
|
||||
UINFOTREE(9, nodep, "", "std::rnd-call");
|
||||
UINFOTREE(9, randomizeFuncp, "", "std::rnd-func");
|
||||
return;
|
||||
}
|
||||
handleRandomizeArgs(nodep);
|
||||
|
|
|
|||
|
|
@ -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,28 @@
|
|||
// 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
|
||||
|
||||
class Cls;
|
||||
function int do_randomize();
|
||||
int flocal, success;
|
||||
success = std::randomize(flocal);
|
||||
if (success !== 1) $stop;
|
||||
do_randomize = flocal;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t;
|
||||
int r1, r2, r3;
|
||||
initial begin
|
||||
Cls c;
|
||||
c = new;
|
||||
r1 = c.do_randomize();
|
||||
r2 = c.do_randomize();
|
||||
r3 = c.do_randomize();
|
||||
$display("%x %x %x", r1, r2, r3);
|
||||
if (r1 == r2 && r2 == r3) $stop; // Not impossible but 2^63 odds of failure
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue