diff --git a/include/verilated_saif_c.cpp b/include/verilated_saif_c.cpp index 2d18ec777..578875fec 100644 --- a/include/verilated_saif_c.cpp +++ b/include/verilated_saif_c.cpp @@ -59,6 +59,17 @@ #undef VL_SUB_T #undef VL_BUF_T +//============================================================================= +//============================================================================= +//============================================================================= +// ActivityVar + +ActivityBit& ActivityVar::getBit(std::size_t index) +{ + assert(index >= 0 && index < m_width); + return m_bits[index]; +} + //============================================================================= //============================================================================= //============================================================================= @@ -224,32 +235,33 @@ void VerilatedSaif::close() VL_MT_SAFE_EXCLUDES(m_mutex) { } void VerilatedSaif::recursivelyPrintScopes(uint32_t scopeIndex) { - const SaifScope& saifScope = m_scopes.at(scopeIndex); + const ActivityScope& saifScope = m_scopes.at(scopeIndex); printIndent(); printStr("(INSTANCE "); - printStr(saifScope.scopeName.c_str()); + printStr(saifScope.getName().c_str()); printStr("\n"); incrementIndent(); bool anyNetValid{false}; - for (auto& childSignal : saifScope.childSignals) { + for (auto& childSignal : saifScope.getChildActivities()) { uint32_t code = childSignal.first; const char* name = childSignal.second.c_str(); ActivityVar& activity = m_activity.at(code); - for (size_t i = 0; i < activity.width; i++) { - ActivityBit& bit = activity.bits[i]; - if (bit.lastVal && activity.lastTime < m_time) { - bit.highTime += m_time - activity.lastTime; - } - if (bit.transitions <= 0) { + for (size_t i = 0; i < activity.getWidth(); i++) { + ActivityBit& bit = activity.getBit(i); + + if (bit.getToggleCount() <= 0) { // Skip bits with no transitions continue; } - assert(m_time >= bit.highTime); + + bit.aggregateVal(m_time - activity.getLastUpdateTime(), bit.getBitValue()); + + assert(m_time >= bit.getHighTime()); if (!anyNetValid) { printIndent(); @@ -262,7 +274,7 @@ void VerilatedSaif::recursivelyPrintScopes(uint32_t scopeIndex) { printIndent(); printStr("("); printStr(name); - if (activity.width > 1) { + if (activity.getWidth() > 1) { printStr("\\["); printStr(std::to_string(i).c_str()); printStr("\\]"); @@ -270,14 +282,14 @@ void VerilatedSaif::recursivelyPrintScopes(uint32_t scopeIndex) { // We only have two-value logic so TZ, TX and TB will always be 0 printStr(" (T0 "); - printStr(std::to_string(m_time - bit.highTime).c_str()); + printStr(std::to_string(m_time - bit.getHighTime()).c_str()); printStr(") (T1 "); - printStr(std::to_string(bit.highTime).c_str()); + printStr(std::to_string(bit.getHighTime()).c_str()); printStr(") (TZ 0) (TX 0) (TB 0) (TC "); - printStr(std::to_string(bit.transitions).c_str()); + printStr(std::to_string(bit.getToggleCount()).c_str()); printStr("))\n"); } - activity.lastTime = m_time; + activity.updateLastTime(m_time); } if (anyNetValid) { @@ -287,7 +299,7 @@ void VerilatedSaif::recursivelyPrintScopes(uint32_t scopeIndex) { printStr(")\n"); // NET } - for (uint32_t childScopeIndex : saifScope.childScopesIndices) { + for (uint32_t childScopeIndex : saifScope.getChildScopesIndices()) { recursivelyPrintScopes(childScopeIndex); } @@ -340,16 +352,12 @@ void VerilatedSaif::pushPrefix(const std::string& name, VerilatedTracePrefixType if (type != VerilatedTracePrefixType::ARRAY_UNPACKED && type != VerilatedTracePrefixType::ARRAY_PACKED) { int32_t newScopeIndex = m_scopes.size(); - m_scopes.emplace_back(); - SaifScope& newScope = m_scopes.back(); - newScope.scopeName = lastWord(m_prefixStack.back().first + pname); - if (m_currentScope >= 0) { - m_scopes.at(m_currentScope).childScopesIndices.emplace_back(newScopeIndex); - newScope.parentScopeIndex = m_currentScope; + m_scopes.at(m_currentScope).addChildScopeIndex(newScopeIndex); } else { m_topScopes.emplace_back(newScopeIndex); } + m_scopes.emplace_back(lastWord(m_prefixStack.back().first + pname), m_currentScope); m_currentScope = newScopeIndex; } @@ -365,7 +373,7 @@ void VerilatedSaif::popPrefix() { assert(m_prefixStack.size() > 1); if (m_prefixStack.back().second != VerilatedTracePrefixType::ARRAY_UNPACKED && m_prefixStack.back().second != VerilatedTracePrefixType::ARRAY_PACKED) { - m_currentScope = m_scopes.at(m_currentScope).parentScopeIndex; + m_currentScope = m_scopes.at(m_currentScope).getParentScopeIndex(); } m_prefixStack.pop_back(); @@ -398,7 +406,7 @@ void VerilatedSaif::declare(uint32_t code, const char* name, const char* wirep, } assert(m_currentScope >= 0); - m_scopes.at(m_currentScope).childSignals.emplace_back(code, std::move(finalName)); + m_scopes.at(m_currentScope).addActivityVar(code, std::move(finalName)); m_activity.emplace(code, ActivityVar{ static_cast(lsb), @@ -472,9 +480,9 @@ void VerilatedSaifBuffer::emitBit(uint32_t code, CData newval) { assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); ActivityVar& activity = m_owner.m_activity.at(code); - ActivityBit& bit = activity.bits[0]; - bit.aggregateVal(m_owner.m_time - activity.lastTime, newval); - activity.lastTime = m_owner.m_time; + ActivityBit& bit = activity.getBit(0); + bit.aggregateVal(m_owner.m_time - activity.getLastUpdateTime(), newval); + activity.updateLastTime(m_owner.m_time); } VL_ATTR_ALWINLINE @@ -482,11 +490,11 @@ void VerilatedSaifBuffer::emitCData(uint32_t code, CData newval, int bits) { assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); ActivityVar& activity = m_owner.m_activity.at(code); - uint64_t dt = m_owner.m_time - activity.lastTime; - for (size_t i = 0; i < activity.width; i++) { - activity.bits[i].aggregateVal(dt, (newval >> i) & 1); + uint64_t dt = m_owner.m_time - activity.getLastUpdateTime(); + for (size_t i = 0; i < activity.getWidth(); i++) { + activity.getBit(i).aggregateVal(dt, (newval >> i) & 1); } - activity.lastTime = m_owner.m_time; + activity.updateLastTime(m_owner.m_time); } VL_ATTR_ALWINLINE @@ -494,11 +502,11 @@ void VerilatedSaifBuffer::emitSData(uint32_t code, SData newval, int bits) { assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); ActivityVar& activity = m_owner.m_activity.at(code); - uint64_t dt = m_owner.m_time - activity.lastTime; - for (size_t i = 0; i < activity.width; i++) { - activity.bits[i].aggregateVal(dt, (newval >> i) & 1); + uint64_t dt = m_owner.m_time - activity.getLastUpdateTime(); + for (size_t i = 0; i < activity.getWidth(); i++) { + activity.getBit(i).aggregateVal(dt, (newval >> i) & 1); } - activity.lastTime = m_owner.m_time; + activity.updateLastTime(m_owner.m_time); } VL_ATTR_ALWINLINE @@ -506,11 +514,11 @@ void VerilatedSaifBuffer::emitIData(uint32_t code, IData newval, int bits) { assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); ActivityVar& activity = m_owner.m_activity.at(code); - uint64_t dt = m_owner.m_time - activity.lastTime; - for (size_t i = 0; i < activity.width; i++) { - activity.bits[i].aggregateVal(dt, (newval >> i) & 1); + uint64_t dt = m_owner.m_time - activity.getLastUpdateTime(); + for (size_t i = 0; i < activity.getWidth(); i++) { + activity.getBit(i).aggregateVal(dt, (newval >> i) & 1); } - activity.lastTime = m_owner.m_time; + activity.updateLastTime(m_owner.m_time); } VL_ATTR_ALWINLINE @@ -518,11 +526,11 @@ void VerilatedSaifBuffer::emitQData(uint32_t code, QData newval, int bits) { assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); ActivityVar& activity = m_owner.m_activity.at(code); - uint64_t dt = m_owner.m_time - activity.lastTime; - for (size_t i = 0; i < activity.width; i++) { - activity.bits[i].aggregateVal(dt, (newval >> i) & 1); + uint64_t dt = m_owner.m_time - activity.getLastUpdateTime(); + for (size_t i = 0; i < activity.getWidth(); i++) { + activity.getBit(i).aggregateVal(dt, (newval >> i) & 1); } - activity.lastTime = m_owner.m_time; + activity.updateLastTime(m_owner.m_time); } VL_ATTR_ALWINLINE @@ -530,13 +538,13 @@ void VerilatedSaifBuffer::emitWData(uint32_t code, const WData* newvalp, int bit assert(m_owner.m_activity.count(code) && "Activity must be declared earlier"); ActivityVar& activity = m_owner.m_activity.at(code); - uint64_t dt = m_owner.m_time - activity.lastTime; - for (std::size_t i = 0; i < activity.width; ++i) { + uint64_t dt = m_owner.m_time - activity.getLastUpdateTime(); + for (std::size_t i = 0; i < activity.getWidth(); ++i) { size_t wordIndex = i / VL_EDATASIZE; - activity.bits[i].aggregateVal(dt, (newvalp[wordIndex] >> VL_BITBIT_E(i)) & 1); + activity.getBit(i).aggregateVal(dt, (newvalp[wordIndex] >> VL_BITBIT_E(i)) & 1); } - activity.lastTime = m_owner.m_time; + activity.updateLastTime(m_owner.m_time); } VL_ATTR_ALWINLINE diff --git a/include/verilated_saif_c.h b/include/verilated_saif_c.h index 0ebf608df..a2a3ac06b 100644 --- a/include/verilated_saif_c.h +++ b/include/verilated_saif_c.h @@ -31,31 +31,94 @@ class VerilatedSaifBuffer; class VerilatedSaifFile; -struct ActivityBit { - bool lastVal = false; - uint64_t highTime = 0; - size_t transitions = 0; +//============================================================================= +// ActivityBit +class ActivityBit { +public: + // METHODS VL_ATTR_ALWINLINE void aggregateVal(uint64_t dt, bool newVal) { - transitions += newVal != lastVal ? 1 : 0; - highTime += lastVal ? dt : 0; - lastVal = newVal; + m_transitions += newVal != m_lastVal ? 1 : 0; + m_highTime += m_lastVal ? dt : 0; + m_lastVal = newVal; } + + // ACCESSORS + VL_ATTR_ALWINLINE bool getBitValue() const { return m_lastVal; } + VL_ATTR_ALWINLINE uint64_t getHighTime() const { return m_highTime; } + VL_ATTR_ALWINLINE uint64_t getToggleCount() const { return m_transitions; } + +private: + // MEMBERS + bool m_lastVal = false; + uint64_t m_highTime = 0; + size_t m_transitions = 0; }; -struct ActivityVar { - uint32_t lsb; - uint32_t width; - ActivityBit* bits; - uint64_t lastTime = 0; +//============================================================================= +// ActivityVar + +class ActivityVar { +public: + // CONSTRUCTORS + ActivityVar(uint32_t lsb, uint32_t width, ActivityBit* bits) + : m_lsb{lsb}, m_width{width}, m_bits{bits} {} + + ActivityVar(ActivityVar&&) = default; + ActivityVar& operator=(ActivityVar&&) = default; + + // METHODS + VL_ATTR_ALWINLINE void updateLastTime(uint64_t val) { m_lastTime = val; } + + // ACCESSORS + VL_ATTR_ALWINLINE uint32_t getWidth() const { return m_width; } + VL_ATTR_ALWINLINE ActivityBit& getBit(std::size_t index); + VL_ATTR_ALWINLINE uint64_t getLastUpdateTime() const { return m_lastTime; } + +private: + // CONSTRUCTORS + VL_UNCOPYABLE(ActivityVar); + + // MEMBERS + uint32_t m_lsb; + uint32_t m_width; + ActivityBit* m_bits; + uint64_t m_lastTime{0}; }; -struct SaifScope { - std::string scopeName{}; - std::vector childScopesIndices{}; - std::vector> childSignals{}; - int32_t parentScopeIndex{-1}; +//============================================================================= +// ActivityScope + +class ActivityScope { +public: + // CONSTRUCTORS + ActivityScope(std::string name, int32_t parentScopeIndex = -1) + : m_scopeName{std::move(name)}, m_parentScopeIndex{parentScopeIndex} {} + + ActivityScope(ActivityScope&&) = default; + ActivityScope& operator=(ActivityScope&&) = default; + + // METHODS + VL_ATTR_ALWINLINE void addChildScopeIndex(int32_t index) { m_childScopesIndices.emplace_back(index); } + VL_ATTR_ALWINLINE void addActivityVar(uint32_t code, std::string name) { m_childActivities.emplace_back(code, std::move(name)); } + VL_ATTR_ALWINLINE bool hasParent() const { return m_parentScopeIndex >= 0; } + + // ACCESSORS + VL_ATTR_ALWINLINE const std::string& getName() const { return m_scopeName; } + VL_ATTR_ALWINLINE const std::vector& getChildScopesIndices() const { return m_childScopesIndices; } + VL_ATTR_ALWINLINE const std::vector>& getChildActivities() const { return m_childActivities; } + VL_ATTR_ALWINLINE int32_t getParentScopeIndex() const { return m_parentScopeIndex; } + +private: + // CONSTRUCTORS + VL_UNCOPYABLE(ActivityScope); + + // MEMBERS + std::string m_scopeName{}; + std::vector m_childScopesIndices{}; + std::vector> m_childActivities{}; + int32_t m_parentScopeIndex{-1}; }; //============================================================================= @@ -88,7 +151,7 @@ private: void clearCurrentlyCollectedData(); int32_t m_currentScope{-1}; - std::vector m_scopes{}; + std::vector m_scopes{}; std::vector m_topScopes{}; std::unordered_map m_activity;