Initial work of the std::rand with {}
This commit is contained in:
parent
92d47ca23a
commit
a043e9b673
|
|
@ -504,7 +504,7 @@ void VlRandomizer::hard(std::string&& constraint) {
|
||||||
m_constraints.emplace_back(std::move(constraint));
|
m_constraints.emplace_back(std::move(constraint));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VlRandomizer::clear() { m_constraints.clear(); }
|
void VlRandomizer::clear() { m_constraints.clear(); m_vars.clear(); }
|
||||||
|
|
||||||
#ifdef VL_DEBUG
|
#ifdef VL_DEBUG
|
||||||
void VlRandomizer::dump() const {
|
void VlRandomizer::dump() const {
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ public:
|
||||||
};
|
};
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VlRandomizer is the object holding constraints and variable references.
|
// VlRandomizer is the object holding constraints and variable references.
|
||||||
class VlRandomizer final {
|
class VlRandomizer {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
std::vector<std::string> m_constraints; // Solver-dependent constraints
|
std::vector<std::string> m_constraints; // Solver-dependent constraints
|
||||||
std::map<std::string, std::shared_ptr<const VlRandomVar>> m_vars; // Solver-dependent
|
std::map<std::string, std::shared_ptr<const VlRandomVar>> m_vars; // Solver-dependent
|
||||||
|
|
@ -583,7 +583,7 @@ public:
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VlStdRandomizer provides a light wrapper for RNG used by std::randomize()
|
// VlStdRandomizer provides a light wrapper for RNG used by std::randomize()
|
||||||
// to support scope-level randomization.
|
// to support scope-level randomization.
|
||||||
class VlStdRandomizer final {
|
class VlStdRandomizer final : public VlRandomizer {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
VlRNG m_rng; // Random number generator
|
VlRNG m_rng; // Random number generator
|
||||||
|
|
||||||
|
|
@ -597,5 +597,8 @@ public:
|
||||||
value = VL_MASK_I(width) & VL_RANDOM_RNG_I(m_rng);
|
value = VL_MASK_I(width) & VL_RANDOM_RNG_I(m_rng);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool next(){
|
||||||
|
return VlRandomizer::next(m_rng);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
AstNode* m_constraintExprGenp = nullptr; // Current constraint or constraint if expression
|
AstNode* m_constraintExprGenp = nullptr; // Current constraint or constraint if expression
|
||||||
AstNodeModule* m_modp; // Current module
|
AstNodeModule* m_modp; // Current module
|
||||||
AstNodeStmt* m_stmtp = nullptr; // Current statement
|
AstNodeStmt* m_stmtp = nullptr; // Current statement
|
||||||
|
AstNodeFTaskRef* stdrandcall = nullptr;
|
||||||
|
bool instdwith = false;
|
||||||
std::set<AstNodeVarRef*> m_staticRefs; // References to static variables under `with` clauses
|
std::set<AstNodeVarRef*> m_staticRefs; // References to static variables under `with` clauses
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
@ -215,7 +217,25 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (!nodep->backp()) VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
if (!nodep->backp()) VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
}
|
}
|
||||||
|
void visit(AstWith* nodep) override {
|
||||||
|
|
||||||
|
cout<<" Whattttt "<< stdrandcall <<endl;
|
||||||
|
for (AstNode* pinp = stdrandcall ? stdrandcall->pinsp(): nullptr; pinp; pinp = pinp->nextp()) {
|
||||||
|
AstArg* const argp = VN_CAST(pinp, Arg);
|
||||||
|
//AstNodeExpr* exprp = argp->exprp();
|
||||||
|
AstWith* const withp = VN_CAST(pinp, With);
|
||||||
|
if(withp == nodep){
|
||||||
|
cout<<"YAYYYY same "<<endl;
|
||||||
|
instdwith = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterateChildrenConst(nodep);
|
||||||
|
instdwith = false;
|
||||||
|
}
|
||||||
void visit(AstNodeFTaskRef* nodep) override {
|
void visit(AstNodeFTaskRef* nodep) override {
|
||||||
|
if (nodep->classOrPackagep()->name() == "std") {
|
||||||
|
stdrandcall = nodep;}
|
||||||
|
|
||||||
iterateChildrenConst(nodep);
|
iterateChildrenConst(nodep);
|
||||||
if (nodep->name() == "rand_mode") {
|
if (nodep->name() == "rand_mode") {
|
||||||
AstMethodCall* const methodCallp = VN_CAST(nodep, MethodCall);
|
AstMethodCall* const methodCallp = VN_CAST(nodep, MethodCall);
|
||||||
|
|
@ -373,10 +393,14 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
markMembers(classp);
|
markMembers(classp);
|
||||||
}
|
}
|
||||||
if (nodep->classOrPackagep()->name() == "std") {
|
if (nodep->classOrPackagep()->name() == "std") {
|
||||||
|
cout<<"yesssss"<<endl;
|
||||||
|
stdrandcall = nullptr;
|
||||||
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();
|
||||||
|
AstWith* const withp = VN_CAST(pinp, With);
|
||||||
|
|
||||||
while (exprp) {
|
while (exprp) {
|
||||||
AstVar* randVarp = nullptr;
|
AstVar* randVarp = nullptr;
|
||||||
if (AstMemberSel* const memberSelp = VN_CAST(exprp, MemberSel)) {
|
if (AstMemberSel* const memberSelp = VN_CAST(exprp, MemberSel)) {
|
||||||
|
|
@ -386,6 +410,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
AstVarRef* const varrefp = VN_AS(exprp, VarRef);
|
AstVarRef* const varrefp = VN_AS(exprp, VarRef);
|
||||||
randVarp = varrefp->varp();
|
randVarp = varrefp->varp();
|
||||||
exprp = nullptr;
|
exprp = nullptr;
|
||||||
|
varrefp->user1(true);
|
||||||
|
cout<<" QUACKKKKKKK "<<varrefp<< endl;
|
||||||
}
|
}
|
||||||
UASSERT_OBJ(randVarp, nodep, "No rand variable found");
|
UASSERT_OBJ(randVarp, nodep, "No rand variable found");
|
||||||
AstNode* backp = randVarp;
|
AstNode* backp = randVarp;
|
||||||
|
|
@ -453,7 +479,7 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
|
|
||||||
if (nodep->varp()->lifetime().isStatic()) m_staticRefs.emplace(nodep);
|
if (nodep->varp()->lifetime().isStatic()) m_staticRefs.emplace(nodep);
|
||||||
|
|
||||||
if (nodep->varp()->rand().isRandomizable()) nodep->user1(true);
|
if (nodep->varp()->rand().isRandomizable() || (instdwith && stdrandcall )) nodep->user1(true);
|
||||||
}
|
}
|
||||||
void visit(AstMemberSel* nodep) override {
|
void visit(AstMemberSel* nodep) override {
|
||||||
if (!m_constraintExprGenp) return;
|
if (!m_constraintExprGenp) return;
|
||||||
|
|
@ -462,7 +488,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
// Variable references in with clause are converted to member selects and their from() is
|
// Variable references in with clause are converted to member selects and their from() is
|
||||||
// of type AstLambdaArgRef. They are randomized too.
|
// of type AstLambdaArgRef. They are randomized too.
|
||||||
const bool randObject = nodep->fromp()->user1() || VN_IS(nodep->fromp(), LambdaArgRef);
|
const bool randObject = nodep->fromp()->user1() || VN_IS(nodep->fromp(), LambdaArgRef);
|
||||||
nodep->user1(randObject && nodep->varp()->rand().isRandomizable());
|
// nodep->user1((randObject && nodep->varp()->rand().isRandomizable()));
|
||||||
|
nodep->user1((randObject && nodep->varp()->rand().isRandomizable()) || (instdwith && stdrandcall ));
|
||||||
nodep->user2p(m_modp);
|
nodep->user2p(m_modp);
|
||||||
}
|
}
|
||||||
void visit(AstNodeModule* nodep) override {
|
void visit(AstNodeModule* nodep) override {
|
||||||
|
|
@ -690,8 +717,8 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
dimension = 1;
|
dimension = 1;
|
||||||
}
|
}
|
||||||
methodp->dtypeSetVoid();
|
methodp->dtypeSetVoid();
|
||||||
AstClass* const classp
|
AstNodeModule* const classp
|
||||||
= membersel ? VN_AS(membersel->user2p(), Class) : VN_AS(varp->user2p(), Class);
|
= membersel ? VN_AS(membersel->user2p(), NodeModule) : VN_AS(varp->user2p(), NodeModule);
|
||||||
AstVarRef* const varRefp
|
AstVarRef* const varRefp
|
||||||
= new AstVarRef{varp->fileline(), classp, varp, VAccess::WRITE};
|
= new AstVarRef{varp->fileline(), classp, varp, VAccess::WRITE};
|
||||||
varRefp->classOrPackagep(classOrPackagep);
|
varRefp->classOrPackagep(classOrPackagep);
|
||||||
|
|
@ -755,6 +782,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
iterate(sump);
|
iterate(sump);
|
||||||
}
|
}
|
||||||
void visit(AstNodeBiop* nodep) override {
|
void visit(AstNodeBiop* nodep) override {
|
||||||
|
cout<<endl<<" HAHAH I AMHERE"<< nodep->user1()<<endl;
|
||||||
if (editFormat(nodep)) return;
|
if (editFormat(nodep)) return;
|
||||||
editSMT(nodep, nodep->lhsp(), nodep->rhsp());
|
editSMT(nodep, nodep->lhsp(), nodep->rhsp());
|
||||||
}
|
}
|
||||||
|
|
@ -911,7 +939,11 @@ class ConstraintExprVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
void visit(AstMemberSel* nodep) override {
|
void visit(AstMemberSel* nodep) override {
|
||||||
if (nodep->user1()) {
|
if (nodep->user1()) {
|
||||||
nodep->v3warn(CONSTRAINTIGN, "Global constraints ignored (unsupported)");
|
// nodep->v3warn(CONSTRAINTIGN, "Global constraints ignored (unsupported)");
|
||||||
|
cout<<" WOWOWOWOWOWWOWOWOWOWO"<<endl;
|
||||||
|
iterateChildren(nodep);
|
||||||
|
nodep->replaceWith(nodep->fromp()->unlinkFrBack());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (VN_IS(nodep->fromp(), NodeVarRef) && nodep->varp()->isRand() && m_inlineInitTaskp) {
|
if (VN_IS(nodep->fromp(), NodeVarRef) && nodep->varp()->isRand() && m_inlineInitTaskp) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
|
|
@ -1110,7 +1142,8 @@ class CaptureVisitor final : public VNVisitor {
|
||||||
newVarp->fileline(fileline);
|
newVarp->fileline(fileline);
|
||||||
newVarp->varType(VVarType::BLOCKTEMP);
|
newVarp->varType(VVarType::BLOCKTEMP);
|
||||||
newVarp->funcLocal(true);
|
newVarp->funcLocal(true);
|
||||||
newVarp->direction(VDirection::INPUT);
|
if( m_targetp) newVarp->direction(VDirection::INPUT);
|
||||||
|
else newVarp->direction(VDirection::REF);
|
||||||
newVarp->lifetime(VLifetime::AUTOMATIC);
|
newVarp->lifetime(VLifetime::AUTOMATIC);
|
||||||
|
|
||||||
m_varCloneMap.emplace(varrefp->varp(), newVarp);
|
m_varCloneMap.emplace(varrefp->varp(), newVarp);
|
||||||
|
|
@ -1173,6 +1206,7 @@ class CaptureVisitor final : public VNVisitor {
|
||||||
// Static var in function (will not be inlined, because it's in class)
|
// Static var in function (will not be inlined, because it's in class)
|
||||||
if (callerIsClass && varIsFuncLocal) return CaptureMode::CAP_VALUE;
|
if (callerIsClass && varIsFuncLocal) return CaptureMode::CAP_VALUE;
|
||||||
if (callerIsClass && varIsFieldOfCaller) return CaptureMode::CAP_THIS;
|
if (callerIsClass && varIsFieldOfCaller) return CaptureMode::CAP_THIS;
|
||||||
|
// if( !m_targetp) return CaptureMode::CAP_THIS;
|
||||||
UASSERT_OBJ(!callerIsClass, varRefp, "Invalid reference?");
|
UASSERT_OBJ(!callerIsClass, varRefp, "Invalid reference?");
|
||||||
return CaptureMode::CAP_VALUE;
|
return CaptureMode::CAP_VALUE;
|
||||||
}
|
}
|
||||||
|
|
@ -1206,6 +1240,7 @@ class CaptureVisitor final : public VNVisitor {
|
||||||
m_ignore.emplace(thisRefp);
|
m_ignore.emplace(thisRefp);
|
||||||
AstMemberSel* const memberSelp
|
AstMemberSel* const memberSelp
|
||||||
= new AstMemberSel{nodep->fileline(), thisRefp, nodep->varp()};
|
= new AstMemberSel{nodep->fileline(), thisRefp, nodep->varp()};
|
||||||
|
memberSelp->user1(true);
|
||||||
memberSelp->user2p(m_targetp);
|
memberSelp->user2p(m_targetp);
|
||||||
nodep->replaceWith(memberSelp);
|
nodep->replaceWith(memberSelp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
|
|
@ -2291,9 +2326,48 @@ 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}});
|
||||||
|
CaptureVisitor *captured = nullptr;
|
||||||
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;
|
AstWith* const withp = VN_CAST(pinp, With);
|
||||||
|
if(withp){
|
||||||
|
cout<<"OH YEAH"<<endl;
|
||||||
|
// Detach the expression and prepare variable copies
|
||||||
|
captured = new CaptureVisitor{withp->exprp(), m_modp, nullptr};
|
||||||
|
// Add function arguments
|
||||||
|
captured->addFunctionArguments(randomizeFuncp);
|
||||||
|
|
||||||
|
// Add constraints clearing code
|
||||||
|
if (stdrand) {
|
||||||
|
randomizeFuncp->addStmtsp(
|
||||||
|
implementConstraintsClear(randomizeFuncp->fileline(), stdrand));
|
||||||
|
|
||||||
|
// AstTask* setupAllTaskp = new AstTask{m_modp->fileline(), "__Vsetup_constraints_hehe", nullptr};
|
||||||
|
// setupAllTaskp->classMethod(true);
|
||||||
|
// setupAllTaskp->isVirtual(true);
|
||||||
|
// m_modp->addStmtsp(setupAllTaskp);
|
||||||
|
// AstTaskRef* const callp = new AstTaskRef{nodep->fileline(), setupAllTaskp, nullptr};
|
||||||
|
// randomizeFuncp->addStmtsp(callp->makeStmt());
|
||||||
|
}
|
||||||
|
AstNode* const capturedTreep = withp->exprp()->unlinkFrBackWithNext();
|
||||||
|
capturedTreep->dumpTreeJson(cout);
|
||||||
|
randomizeFuncp->addStmtsp(capturedTreep);
|
||||||
|
{
|
||||||
|
ConstraintExprVisitor{m_memberMap, capturedTreep, randomizeFuncp, stdrand,
|
||||||
|
nullptr};
|
||||||
|
}
|
||||||
|
AstVarRef* const randNextp
|
||||||
|
= new AstVarRef{nodep->fileline(), stdrand, VAccess::READWRITE};
|
||||||
|
randNextp->AstNode::addNext(new AstText{nodep->fileline(), ".next()"});
|
||||||
|
AstNodeExpr* const solverCallp = new AstCExpr{nodep->fileline(), randNextp};
|
||||||
|
solverCallp->dtypeSetBit();
|
||||||
|
randomizeFuncp->addStmtsp(new AstAssign{
|
||||||
|
nodep->fileline(),
|
||||||
|
new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var), VAccess::WRITE},
|
||||||
|
new AstAnd{nodep->fileline(), new AstVarRef{nodep->fileline(), VN_AS(randomizeFuncp->fvarp(), Var), VAccess::READ}, solverCallp}});
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
|
@ -2301,6 +2375,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
"basicStdRandomization"};
|
"basicStdRandomization"};
|
||||||
const size_t width = exprp->width();
|
const size_t width = exprp->width();
|
||||||
basicMethodp->addPinsp(exprp->unlinkFrBack());
|
basicMethodp->addPinsp(exprp->unlinkFrBack());
|
||||||
|
if(VN_IS(exprp, VarRef)) VN_AS(exprp, VarRef)->access(VAccess::READWRITE);
|
||||||
basicMethodp->addPinsp(
|
basicMethodp->addPinsp(
|
||||||
new AstConst{nodep->fileline(), AstConst::Unsized64{}, width});
|
new AstConst{nodep->fileline(), AstConst::Unsized64{}, width});
|
||||||
basicMethodp->dtypeSetBit();
|
basicMethodp->dtypeSetBit();
|
||||||
|
|
@ -2319,6 +2394,11 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
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());
|
if (nodep->pinsp()) pushDeletep(nodep->pinsp()->unlinkFrBackWithNext());
|
||||||
|
if (captured) nodep->addPinsp(captured->getArgs());
|
||||||
|
if (captured) {cout<<"What ARGS HUHHHHHH " <<captured->getArgs()<<endl;
|
||||||
|
captured->getArgs()->dumpTreeJson(cout);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleRandomizeArgs(nodep);
|
handleRandomizeArgs(nodep);
|
||||||
|
|
|
||||||
|
|
@ -6481,10 +6481,10 @@ class WidthVisitor final : public VNVisitor {
|
||||||
userIterateAndNext(VN_AS(argp, Arg)->exprp(), WidthVP{SELF, BOTH}.p());
|
userIterateAndNext(VN_AS(argp, Arg)->exprp(), WidthVP{SELF, BOTH}.p());
|
||||||
handleStdRandomizeArgs(nodep); // Provided args should be in current scope
|
handleStdRandomizeArgs(nodep); // Provided args should be in current scope
|
||||||
if (withp) {
|
if (withp) {
|
||||||
nodep->v3warn(CONSTRAINTIGN, "Unsupported: std::randomize()'s 'with'");
|
// nodep->v3warn(CONSTRAINTIGN, "Unsupported: std::randomize()'s 'with'");
|
||||||
nodep->replaceWith(new AstConst{nodep->fileline(), 0});
|
// nodep->replaceWith(new AstConst{nodep->fileline(), 0});
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
// VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
return;
|
// return;
|
||||||
}
|
}
|
||||||
processFTaskRefArgs(nodep);
|
processFTaskRefArgs(nodep);
|
||||||
nodep->addPinsp(withp);
|
nodep->addPinsp(withp);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue