Support $sampled (#3569)

This commit is contained in:
Aleksander Kiryk
2022-08-29 08:39:41 -04:00
committed by GitHub
parent 2af5304884
commit 24ec84851a
16 changed files with 456 additions and 4 deletions
+39 -1
View File
@@ -45,6 +45,7 @@ private:
VDouble0 m_statAsNotImm; // Statistic tracking
VDouble0 m_statAsImm; // Statistic tracking
VDouble0 m_statAsFull; // Statistic tracking
bool m_inSampled = false; // True inside a sampled expression
// METHODS
string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) {
@@ -66,6 +67,11 @@ private:
nodep->fmtp()->scopeNamep(new AstScopeName{nodep->fileline(), true});
}
}
AstSampled* newSampledExpr(AstNode* nodep) {
const auto sampledp = new AstSampled{nodep->fileline(), nodep};
sampledp->dtypeFrom(nodep);
return sampledp;
}
AstVarRef* newMonitorNumVarRefp(AstNode* nodep, VAccess access) {
if (!m_monitorNumVarp) {
m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum",
@@ -332,7 +338,8 @@ private:
ticks = VN_AS(nodep->ticksp(), Const)->toUInt();
}
UASSERT_OBJ(ticks >= 1, nodep, "0 tick should have been checked in V3Width");
AstNode* inp = nodep->exprp()->unlinkFrBack();
AstNode* const exprp = nodep->exprp()->unlinkFrBack();
AstNode* inp = newSampledExpr(exprp);
AstVar* invarp = nullptr;
AstSenTree* const sentreep = nodep->sentreep();
sentreep->unlinkFrBack();
@@ -353,10 +360,41 @@ private:
}
nodep->replaceWith(inp);
}
//========== Move $sampled down to read-only variables
virtual void visit(AstSampled* nodep) override {
if (nodep->user1()) return;
VL_RESTORER(m_inSampled);
{
m_inSampled = true;
iterateChildren(nodep);
}
nodep->replaceWith(nodep->exprp()->unlinkFrBack());
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
virtual void visit(AstVarRef* nodep) override {
iterateChildren(nodep);
if (m_inSampled) {
if (!nodep->access().isReadOnly()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Write to variable in sampled expression");
} else {
VNRelinker relinkHandle;
nodep->unlinkFrBack(&relinkHandle);
AstSampled* const newp = newSampledExpr(nodep);
relinkHandle.relink(newp);
newp->user1(1);
}
}
}
// Don't sample sensitivities
virtual void visit(AstSenItem* nodep) override {
VL_RESTORER(m_inSampled);
{
m_inSampled = false;
iterateChildren(nodep);
}
}
//========== Statements
virtual void visit(AstDisplay* nodep) override {