mirror of
https://github.com/verilator/verilator.git
synced 2026-09-03 16:28:53 +02:00
This commit is contained in:
@@ -3135,6 +3135,24 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
}
|
||||
};
|
||||
|
||||
// Wrap obj.randomize() with null guard: (obj != null) ? obj.randomize() : 0
|
||||
// IEEE 1800 requires randomize() on null handle to return 0.
|
||||
// Uses user4() to prevent re-wrapping during iterateChildren.
|
||||
void wrapRandomizeCallWithNullGuard(AstNodeFTaskRef* nodep) {
|
||||
AstMethodCall* const callp = VN_CAST(nodep, MethodCall);
|
||||
if (!callp) return;
|
||||
if (callp->user4()) return;
|
||||
callp->user4(true);
|
||||
FileLine* const fl = callp->fileline();
|
||||
AstNodeExpr* const checkp
|
||||
= new AstNeq{fl, callp->fromp()->cloneTree(false), new AstConst{fl, AstConst::Null{}}};
|
||||
VNRelinker relinker;
|
||||
callp->unlinkFrBack(&relinker);
|
||||
AstCond* const condp = new AstCond{fl, checkp, callp, new AstConst{fl, 0}};
|
||||
condp->dtypeFrom(callp);
|
||||
relinker.relink(condp);
|
||||
}
|
||||
|
||||
// Handle inline random variable control. After this, the randomize() call has no args
|
||||
void handleRandomizeArgs(AstNodeFTaskRef* const nodep) {
|
||||
if (!nodep->pinsp()) return;
|
||||
@@ -3593,6 +3611,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
AstWith* const withp = VN_CAST(nodep->pinsp(), With);
|
||||
if (!withp) {
|
||||
iterateChildren(nodep);
|
||||
wrapRandomizeCallWithNullGuard(nodep);
|
||||
return;
|
||||
}
|
||||
withp->unlinkFrBack();
|
||||
@@ -3730,6 +3749,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
nodep->dtypeFrom(randomizeFuncp->dtypep());
|
||||
nodep->classOrPackagep(classp);
|
||||
UINFO(9, "Added `%s` randomization procedure");
|
||||
wrapRandomizeCallWithNullGuard(nodep);
|
||||
VL_DO_DANGLING(withp->deleteTree(), withp);
|
||||
}
|
||||
void visit(AstConstraint* nodep) override {
|
||||
|
||||
Reference in New Issue
Block a user