Fix array reference in reduction constraints (#8158)
Signed-off-by: Kornel Uriasz <kuriasz@antmicro.com>
This commit is contained in:
parent
cacadd6c7d
commit
f6f6f84047
|
|
@ -1218,6 +1218,14 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
return preamblep;
|
return preamblep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create SFormatF for array dereference inside solver
|
||||||
|
AstSFormatF* createSolverArrDerefp(FileLine* const fl, AstNodeExpr* const arrExprp,
|
||||||
|
AstNodeExpr* const idxExprp) {
|
||||||
|
AstNodeExpr* const argsp = AstNode::addNext(arrExprp, idxExprp);
|
||||||
|
AstSFormatF* const formatp = new AstSFormatF{fl, "(select %s %s)", false, argsp};
|
||||||
|
return formatp;
|
||||||
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
void visit(AstNodeVarRef* nodep) override {
|
void visit(AstNodeVarRef* nodep) override {
|
||||||
AstVar* varp = nodep->varp();
|
AstVar* varp = nodep->varp();
|
||||||
|
|
@ -2650,9 +2658,9 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
AstNodeExpr* const pinp = nodep->pinsp()->unlinkFrBack();
|
AstNodeExpr* const pinp = nodep->pinsp()->unlinkFrBack();
|
||||||
if (VN_IS(pinp, SFormatF) && m_structSel) VN_AS(pinp, SFormatF)->name("%x");
|
if (VN_IS(pinp, SFormatF) && m_structSel) VN_AS(pinp, SFormatF)->name("%x");
|
||||||
AstNodeExpr* const argsp = AstNode::addNext(nodep->fromp()->unlinkFrBack(), pinp);
|
|
||||||
AstSFormatF* newp;
|
AstSFormatF* newp;
|
||||||
if (m_structSel) {
|
if (m_structSel) {
|
||||||
|
AstNodeExpr* const argsp = AstNode::addNext(nodep->fromp()->unlinkFrBack(), pinp);
|
||||||
sizep->dtypeSetInt();
|
sizep->dtypeSetInt();
|
||||||
AstLogAnd* const condp = new AstLogAnd{
|
AstLogAnd* const condp = new AstLogAnd{
|
||||||
fl,
|
fl,
|
||||||
|
|
@ -2663,7 +2671,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
m_conditionp = m_conditionp ? new AstLogAnd{fl, m_conditionp, condp} : condp;
|
m_conditionp = m_conditionp ? new AstLogAnd{fl, m_conditionp, condp} : condp;
|
||||||
newp = new AstSFormatF{fl, "%s.%s", false, argsp};
|
newp = new AstSFormatF{fl, "%s.%s", false, argsp};
|
||||||
} else {
|
} else {
|
||||||
newp = new AstSFormatF{fl, "(select %s %s)", false, argsp};
|
newp = createSolverArrDerefp(fl, nodep->fromp()->unlinkFrBack(), pinp);
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
|
|
@ -2874,34 +2882,40 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
AstNodeModule* const genModulep = VN_AS(m_genp->user2p(), NodeModule);
|
AstNodeModule* const genModulep = VN_AS(m_genp->user2p(), NodeModule);
|
||||||
arrVarp->user3(true);
|
arrVarp->user3(true);
|
||||||
|
|
||||||
// Create variable name using AstSFormatF
|
// Add write_var call to init task
|
||||||
AstSFormatF* const varNamep = new AstSFormatF{
|
AstNodeExpr* const arrVarNamep
|
||||||
fl, smtArrayName + "_%x", false, new AstVarRef{fl, loopVarp, VAccess::READ}};
|
= new AstCExpr{fl, AstCExpr::Pure{}, "\"" + smtArrayName + "\"", elemWidth};
|
||||||
|
AstCMethodHard* const writeVarCallp
|
||||||
|
= new AstCMethodHard{fl, new AstVarRef{fl, genModulep, m_genp, VAccess::READ},
|
||||||
|
VCMethod::RANDOMIZER_WRITE_VAR};
|
||||||
|
writeVarCallp->addPinsp(new AstVarRef{fl, arrModulep, arrVarp, VAccess::READ});
|
||||||
|
writeVarCallp->addPinsp(
|
||||||
|
new AstConst{fl, AstConst::Unsized64{}, static_cast<uint64_t>(elemWidth)});
|
||||||
|
writeVarCallp->addPinsp(arrVarNamep);
|
||||||
|
const uint32_t unpackedDims = arrVarp->dtypep()->dimensions(false).second;
|
||||||
|
UASSERT_OBJ(unpackedDims == 1, arrVarp, "Array isn't 1-D");
|
||||||
|
writeVarCallp->addPinsp(new AstConst{fl, 1}); // Dimension
|
||||||
|
|
||||||
// Create array element reference: array.atWrite(index)
|
const RandomizeMode randMode = {.asInt = arrVarp->user1()};
|
||||||
AstCMethodHard* const atWritep = new AstCMethodHard{
|
if (randMode.usesMode) {
|
||||||
fl, new AstVarRef{fl, arrModulep, arrVarp, VAccess::READWRITE},
|
writeVarCallp->addPinsp(
|
||||||
VCMethod::ARRAY_AT_WRITE, new AstVarRef{fl, loopVarp, VAccess::READ}};
|
new AstConst{fl, AstConst::Unsized64{}, randMode.index});
|
||||||
atWritep->dtypeFrom(elemDtp);
|
}
|
||||||
|
writeVarCallp->dtypeSetVoid();
|
||||||
|
AstNodeFTask* initTaskp = m_inlineInitTaskp;
|
||||||
|
if (!initTaskp) {
|
||||||
|
initTaskp = VN_AS(m_memberMap.findMember(arrModulep, "new"), NodeFTask);
|
||||||
|
UASSERT_OBJ(initTaskp, arrModulep, "No new() in class");
|
||||||
|
}
|
||||||
|
initTaskp->addStmtsp(writeVarCallp->makeStmt());
|
||||||
|
|
||||||
// Convert std::string to const char* for write_var
|
// Create solver constraints
|
||||||
AstCExpr* const varNameCStrp = new AstCExpr{fl, AstCExpr::Pure{}};
|
AstSFormatF* const idxFormatp = new AstSFormatF{
|
||||||
varNameCStrp->dtypeSetString();
|
fl, "#x%08x", false, new AstVarRef{fl, loopVarp, VAccess::READ}};
|
||||||
varNameCStrp->add("(");
|
iterateChildren(nodep);
|
||||||
varNameCStrp->add(varNamep->cloneTree(false));
|
AstSFormatF* const varNamep
|
||||||
varNameCStrp->add(").c_str()");
|
= createSolverArrDerefp(fl, nodep->fromp()->unlinkFrBack(), idxFormatp);
|
||||||
|
|
||||||
// Create write_var method call: gen.write_var(arrElement, width, name, 0)
|
|
||||||
AstCMethodHard* const writeVarp = new AstCMethodHard{
|
|
||||||
fl, new AstVarRef{fl, genModulep, m_genp, VAccess::READWRITE},
|
|
||||||
VCMethod::RANDOMIZER_WRITE_VAR, atWritep};
|
|
||||||
writeVarp->addPinsp(new AstConst{fl, AstConst::WidthedValue{}, 64,
|
|
||||||
static_cast<uint32_t>(elemWidth)});
|
|
||||||
writeVarp->addPinsp(varNameCStrp);
|
|
||||||
writeVarp->addPinsp(new AstConst{fl, AstConst::WidthedValue{}, 64, 0});
|
|
||||||
writeVarp->dtypeSetVoid();
|
|
||||||
|
|
||||||
cstmtp->add(writeVarp->makeStmt());
|
|
||||||
cstmtp->add("ret += \" \";\n");
|
cstmtp->add("ret += \" \";\n");
|
||||||
cstmtp->add("ret += ");
|
cstmtp->add("ret += ");
|
||||||
cstmtp->add(varNamep);
|
cstmtp->add(varNamep);
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,38 @@ class H;
|
||||||
}
|
}
|
||||||
endclass
|
endclass
|
||||||
|
|
||||||
|
class I;
|
||||||
|
rand int a;
|
||||||
|
rand int arr[];
|
||||||
|
constraint c1 {
|
||||||
|
arr.size() == 5;
|
||||||
|
foreach(arr[i]) {
|
||||||
|
arr[i] inside {[10 : 200]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constraint c2 {
|
||||||
|
a + arr.sum() == 200;
|
||||||
|
}
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class J;
|
||||||
|
rand int a;
|
||||||
|
rand int arr[];
|
||||||
|
|
||||||
|
function new();
|
||||||
|
arr = new [5];
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
constraint c1 {
|
||||||
|
foreach(arr[i]) {
|
||||||
|
arr[i] inside {[10 : 200]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constraint c2 {
|
||||||
|
a + arr.sum() == 200;
|
||||||
|
}
|
||||||
|
endclass
|
||||||
|
|
||||||
module t;
|
module t;
|
||||||
initial begin
|
initial begin
|
||||||
automatic C c = new;
|
automatic C c = new;
|
||||||
|
|
@ -161,6 +193,8 @@ module t;
|
||||||
automatic F f = new;
|
automatic F f = new;
|
||||||
automatic G g = new;
|
automatic G g = new;
|
||||||
automatic H h = new;
|
automatic H h = new;
|
||||||
|
automatic I i = new;
|
||||||
|
automatic J j = new;
|
||||||
|
|
||||||
`check_rand(c, c.x, 4 < c.x && c.x < 7);
|
`check_rand(c, c.x, 4 < c.x && c.x < 7);
|
||||||
`check_rand(d, d.posit, (d.posit ? 4 : -3) < d.x && d.x < (d.posit ? 7 : 0));
|
`check_rand(d, d.posit, (d.posit ? 4 : -3) < d.x && d.x < (d.posit ? 7 : 0));
|
||||||
|
|
@ -176,6 +210,14 @@ module t;
|
||||||
foreach (h.a[i]) begin
|
foreach (h.a[i]) begin
|
||||||
`check_rand(h, h.a[i], (h.a[i] != h.b));
|
`check_rand(h, h.a[i], (h.a[i] != h.b));
|
||||||
end
|
end
|
||||||
|
`check_rand(i, i.a, (i.arr.sum() + i.a == 200));
|
||||||
|
foreach (i.arr[it]) begin
|
||||||
|
`check_rand(i, i.arr[it], (i.arr[it] inside {[10 : 200]}));
|
||||||
|
end
|
||||||
|
`check_rand(j, j.a, (j.arr.sum() + j.a == 200));
|
||||||
|
foreach (j.arr[i]) begin
|
||||||
|
`check_rand(j, j.arr[i], (j.arr[i] inside {[10 : 200]}));
|
||||||
|
end
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue