mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Support clocking blocks (#3674)
This commit is contained in:
@@ -60,6 +60,8 @@ private:
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current task
|
||||
AstNodeDType* m_dtypep = nullptr; // Current data type
|
||||
AstNodeExpr* m_defaultInSkewp = nullptr; // Current default input skew
|
||||
AstNodeExpr* m_defaultOutSkewp = nullptr; // Current default output skew
|
||||
int m_genblkAbove = 0; // Begin block number of if/case/for above
|
||||
int m_genblkNum = 0; // Begin block number, 0=none seen
|
||||
VLifetime m_lifetime = VLifetime::STATIC; // Propagating lifetime
|
||||
@@ -632,6 +634,66 @@ private:
|
||||
nodep->classOrPackagep(m_stdPackagep);
|
||||
}
|
||||
}
|
||||
void visit(AstClocking* nodep) override {
|
||||
VL_RESTORER(m_defaultInSkewp);
|
||||
VL_RESTORER(m_defaultOutSkewp);
|
||||
// Find default input and output skews
|
||||
AstClockingItem* nextItemp = nodep->itemsp();
|
||||
for (AstClockingItem* itemp = nextItemp; itemp; itemp = nextItemp) {
|
||||
nextItemp = VN_AS(itemp->nextp(), ClockingItem);
|
||||
if (itemp->exprp() || itemp->assignp()) continue;
|
||||
if (itemp->skewp()) {
|
||||
if (itemp->direction() == VDirection::INPUT) {
|
||||
// Disallow default redefinition; note some simulators allow this
|
||||
if (m_defaultInSkewp) {
|
||||
itemp->skewp()->v3error("Multiple default input skews not allowed");
|
||||
}
|
||||
m_defaultInSkewp = itemp->skewp();
|
||||
} else if (itemp->direction() == VDirection::OUTPUT) {
|
||||
if (AstConst* const constp = VN_CAST(itemp->skewp(), Const)) {
|
||||
if (constp->num().is1Step()) {
|
||||
itemp->skewp()->v3error("1step not allowed as output skew");
|
||||
}
|
||||
}
|
||||
// Disallow default redefinition; note some simulators allow this
|
||||
if (m_defaultOutSkewp) {
|
||||
itemp->skewp()->v3error("Multiple default output skews not allowed");
|
||||
}
|
||||
m_defaultOutSkewp = itemp->skewp();
|
||||
} else {
|
||||
itemp->v3fatalSrc("Incorrect direction");
|
||||
}
|
||||
}
|
||||
pushDeletep(itemp->unlinkFrBack());
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstClockingItem* nodep) override {
|
||||
if (nodep->direction() == VDirection::OUTPUT) {
|
||||
if (!nodep->skewp()) {
|
||||
if (m_defaultOutSkewp) {
|
||||
nodep->skewp(m_defaultOutSkewp->cloneTree(false));
|
||||
} else {
|
||||
// Default is 0 (IEEE 1800-2017 14.3)
|
||||
nodep->skewp(new AstConst{nodep->fileline(), 0});
|
||||
}
|
||||
} else if (AstConst* const constp = VN_CAST(nodep->skewp(), Const)) {
|
||||
if (constp->num().is1Step()) {
|
||||
nodep->skewp()->v3error("1step not allowed as output skew");
|
||||
}
|
||||
}
|
||||
} else if (nodep->direction() == VDirection::INPUT) {
|
||||
if (!nodep->skewp()) {
|
||||
if (m_defaultInSkewp) {
|
||||
nodep->skewp(m_defaultInSkewp->cloneTree(false));
|
||||
} else {
|
||||
// Default is 1step (IEEE 1800-2017 14.3)
|
||||
nodep->skewp(new AstConst{nodep->fileline(), AstConst::OneStep{}});
|
||||
}
|
||||
}
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstNode* nodep) override {
|
||||
// Default: Just iterate
|
||||
|
||||
Reference in New Issue
Block a user