mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Support $sampled (#3569)
This commit is contained in:
+39
-1
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user