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 `--stats` overridden by skipping identical build (#6220). [Geza Lore]
|
||||||
* Fix MODDUP with duplicate packages to take first package (#6222).
|
* Fix MODDUP with duplicate packages to take first package (#6222).
|
||||||
* Fix replicate with unsigned count but MSB set (#6231) (#6233). [Geza Lore]
|
* 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 queue typedef with unbounded slice (#6236).
|
||||||
* Fix error when force assignment is used with ref function args (#6244). [Ryszard Rozak, Antmicro Ltd.]
|
* 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]
|
* Fix write of 0 in '%c' (#6248) (#6249). [Rodrigo Batista de Moraes]
|
||||||
|
|
|
||||||
|
|
@ -1373,6 +1373,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
AstVar* const stdgenp
|
AstVar* const stdgenp
|
||||||
= new AstVar{modp->fileline(), VVarType::MEMBER, "stdrand",
|
= new AstVar{modp->fileline(), VVarType::MEMBER, "stdrand",
|
||||||
modp->findBasicDType(VBasicDTypeKwd::RANDOM_STDGENERATOR)};
|
modp->findBasicDType(VBasicDTypeKwd::RANDOM_STDGENERATOR)};
|
||||||
|
stdgenp->fileline()->warnOff(V3ErrorCode::IMPURE, true);
|
||||||
modp->addStmtsp(stdgenp);
|
modp->addStmtsp(stdgenp);
|
||||||
m_stdMap.emplace(modp, stdgenp);
|
m_stdMap.emplace(modp, stdgenp);
|
||||||
return stdgenp;
|
return stdgenp;
|
||||||
|
|
@ -2283,6 +2284,8 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
if (nodep->name() != "randomize") return;
|
if (nodep->name() != "randomize") return;
|
||||||
|
|
||||||
if (nodep->classOrPackagep() && nodep->classOrPackagep()->name() == "std") {
|
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);
|
AstVar* const stdrand = createStdRandomGenerator(m_modp);
|
||||||
AstFunc* const randomizeFuncp = V3Randomize::newRandomizeStdFunc(
|
AstFunc* const randomizeFuncp = V3Randomize::newRandomizeStdFunc(
|
||||||
m_memberMap, m_modp, m_inlineUniqueStdName.get(nodep));
|
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),
|
new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var),
|
||||||
VAccess::WRITE},
|
VAccess::WRITE},
|
||||||
new AstConst{nodep->fileline(), AstConst::WidthedValue{}, 32, 1}});
|
new AstConst{nodep->fileline(), AstConst::WidthedValue{}, 32, 1}});
|
||||||
|
int argn = 0;
|
||||||
for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) {
|
for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) {
|
||||||
AstArg* const argp = VN_CAST(pinp, Arg);
|
AstArg* const argp = VN_CAST(pinp, Arg);
|
||||||
if (!argp) continue;
|
if (!argp) continue;
|
||||||
AstNodeExpr* exprp = argp->exprp();
|
AstNodeExpr* exprp = argp->exprp();
|
||||||
|
|
||||||
AstCMethodHard* const basicMethodp = new AstCMethodHard{
|
AstCMethodHard* const basicMethodp = new AstCMethodHard{
|
||||||
nodep->fileline(),
|
nodep->fileline(),
|
||||||
new AstVarRef{nodep->fileline(), stdrand, VAccess::READWRITE},
|
new AstVarRef{nodep->fileline(), stdrand, VAccess::READWRITE},
|
||||||
"basicStdRandomization"};
|
"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();
|
const size_t width = exprp->width();
|
||||||
basicMethodp->addPinsp(exprp->unlinkFrBack());
|
basicMethodp->addPinsp(
|
||||||
|
new AstVarRef{exprp->fileline(), refvarp, VAccess::READWRITE});
|
||||||
|
|
||||||
basicMethodp->addPinsp(
|
basicMethodp->addPinsp(
|
||||||
new AstConst{nodep->fileline(), AstConst::Unsized64{}, width});
|
new AstConst{nodep->fileline(), AstConst::Unsized64{}, width});
|
||||||
basicMethodp->dtypeSetBit();
|
basicMethodp->dtypeSetBit();
|
||||||
|
|
||||||
randomizeFuncp->addStmtsp(new AstAssign{
|
randomizeFuncp->addStmtsp(new AstAssign{
|
||||||
nodep->fileline(),
|
nodep->fileline(),
|
||||||
new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var),
|
new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var),
|
||||||
|
|
@ -2318,7 +2334,8 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
nodep->taskp(randomizeFuncp);
|
nodep->taskp(randomizeFuncp);
|
||||||
nodep->dtypeFrom(randomizeFuncp->dtypep());
|
nodep->dtypeFrom(randomizeFuncp->dtypep());
|
||||||
if (VN_IS(m_modp, Class)) nodep->classOrPackagep(m_modp);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
handleRandomizeArgs(nodep);
|
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