Skip to content

Commit

Permalink
Support inside array constraints (verilator#5448)
Browse files Browse the repository at this point in the history
Signed-off-by: Arkadiusz Kozdra <[email protected]>
  • Loading branch information
kozdra authored Sep 19, 2024
1 parent 371a405 commit dd95e03
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 78 deletions.
49 changes: 45 additions & 4 deletions src/V3Randomize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,21 @@ class ConstraintExprVisitor final : public VNVisitor {
return new AstSFormatF{fl, fmt.str(), false, exprsp};
}

AstNodeExpr* newSel(FileLine* fl, AstNodeExpr* arrayp, AstNodeExpr* idxp) {
// similar to V3WidthSel.cpp
AstNodeDType* const arrDtp = arrayp->unlinkFrBack()->dtypep();
AstNodeExpr* selp = nullptr;
if (VN_IS(arrDtp, QueueDType) || VN_IS(arrDtp, DynArrayDType))
selp = new AstCMethodHard{fl, arrayp, "at", idxp};
else if (VN_IS(arrDtp, UnpackArrayDType))
selp = new AstArraySel{fl, arrayp, idxp};
else if (VN_IS(arrDtp, AssocArrayDType))
selp = new AstAssocSel{fl, arrayp, idxp};
UASSERT_OBJ(selp, arrayp, "Selecting from non-array?");
selp->dtypep(arrDtp->subDTypep());
return selp;
}

// VISITORS
void visit(AstNodeVarRef* nodep) override {
AstVar* const varp = nodep->varp();
Expand Down Expand Up @@ -699,8 +714,7 @@ class ConstraintExprVisitor final : public VNVisitor {
new AstForeach{fl, nodep->arrayp()->unlinkFrBack(), new AstCStmt{fl, cstmtp}},
false, true});
exprsp->addNext(
new AstText{fl, "return ret.empty() ? \"#b1\" : \"(bvand \" + ret + \")\";"});
exprsp->addNext(new AstText{fl, "return ret + \")\"; })()"});
new AstText{fl, "return ret.empty() ? \"#b1\" : \"(bvand\" + ret + \")\";})()"});
AstNodeExpr* const newp = new AstCExpr{fl, exprsp};
newp->dtypeSetString();
nodep->replaceWith(new AstSFormatF{fl, "%@", false, newp});
Expand Down Expand Up @@ -741,18 +755,45 @@ class ConstraintExprVisitor final : public VNVisitor {
}
void visit(AstCMethodHard* nodep) override {
if (editFormat(nodep)) return;
FileLine* const fl = nodep->fileline();

if (nodep->name() == "at" && nodep->fromp()->user1()) {
iterateChildren(nodep);
AstNodeExpr* const argsp
= AstNode::addNext(nodep->fromp()->unlinkFrBack(), nodep->pinsp()->unlinkFrBack());
AstSFormatF* const newp
= new AstSFormatF{nodep->fileline(), "(select %@ %@)", false, argsp};
AstSFormatF* const newp = new AstSFormatF{fl, "(select %@ %@)", false, argsp};
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
return;
}

if (nodep->name() == "inside") {
bool randArr = nodep->fromp()->user1();

AstVar* const newVarp
= new AstVar{fl, VVarType::BLOCKTEMP, "__Vinside", nodep->findSigned32DType()};
AstNodeExpr* const idxRefp = new AstVarRef{nodep->fileline(), newVarp, VAccess::READ};
AstSelLoopVars* const arrayp
= new AstSelLoopVars{fl, nodep->fromp()->cloneTreePure(false), newVarp};
AstNodeExpr* const selp = newSel(nodep->fileline(), nodep->fromp(), idxRefp);
selp->user1(randArr);
AstNode* const itemp = new AstEq{fl, selp, nodep->pinsp()->unlinkFrBack()};
itemp->user1(true);
AstNode* const cstmtp = new AstText{fl, "ret += \" \" + "};
cstmtp->addNext(iterateSubtreeReturnEdits(itemp));
cstmtp->addNext(new AstText{fl, ";"});
AstNode* const exprsp = new AstText{fl, "([&]{ std::string ret;"};
exprsp->addNext(new AstBegin{
fl, "", new AstForeach{fl, arrayp, new AstCStmt{fl, cstmtp}}, false, true});
exprsp->addNext(
new AstText{fl, "return ret.empty() ? \"#b0\" : \"(bvor\" + ret + \")\";})()"});
AstNodeExpr* const newp = new AstCExpr{fl, exprsp};
newp->dtypeSetString();
nodep->replaceWith(new AstSFormatF{fl, "%@", false, newp});
VL_DO_DANGLING(nodep->deleteTree(), nodep);
return;
}

nodep->v3warn(CONSTRAINTIGN,
"Unsupported: randomizing this expression, treating as state");
nodep->user1(false);
Expand Down
10 changes: 9 additions & 1 deletion test_regress/t/t_constraint_dist.v
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,27 @@ begin \
end

class C;
rand int x, y;
rand int x, y, z, w;
int que[$] = '{3, 4, 5};
int arr[3] = '{5, 6, 7};
constraint distrib {
x dist { [1:3] := 0, [5:6], [9:15] :/ 0 };
y dist { [1:3] := 0, 5, 6 := 8, [9:15] :/ 0 };
x < 20;
};
constraint distinside {
z dist {que};
w dist {arr};
};
endclass

module t;
initial begin
C c = new;
`check_rand(c, c.x, 5 <= c.x && c.x <= 6);
`check_rand(c, c.y, 5 <= c.y && c.y <= 6);
`check_rand(c, c.z, 3 <= c.z && c.z <= 5);
`check_rand(c, c.w, 5 <= c.w && c.w <= 7);
$write("*-* All Finished *-*\n");
$finish;
end
Expand Down
17 changes: 0 additions & 17 deletions test_regress/t/t_constraint_dist_unsup.out

This file was deleted.

16 changes: 0 additions & 16 deletions test_regress/t/t_constraint_dist_unsup.py

This file was deleted.

40 changes: 0 additions & 40 deletions test_regress/t/t_constraint_dist_unsup.v

This file was deleted.

0 comments on commit dd95e03

Please sign in to comment.