[#74021] move activity accumulating code to its own class
This commit is contained in:
parent
b383f64cff
commit
c71f5b42e3
|
|
@ -94,7 +94,9 @@ VerilatedSaifActivityBit& VerilatedSaifActivityVar::bit(const std::size_t index)
|
|||
//=============================================================================
|
||||
// Opening/Closing
|
||||
|
||||
VerilatedSaif::VerilatedSaif(void* filep) {}
|
||||
VerilatedSaif::VerilatedSaif(void* filep) {
|
||||
m_activityAccumulators.emplace_back();
|
||||
}
|
||||
|
||||
void VerilatedSaif::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
|
|
@ -178,14 +180,26 @@ void VerilatedSaif::closeInstanceScope() {
|
|||
}
|
||||
|
||||
void VerilatedSaif::printScopeActivities(const VerilatedSaifActivityScope& scope) {
|
||||
bool anyNetValid{false};
|
||||
for (const auto& childSignal : scope.childActivities()) {
|
||||
const uint32_t code = childSignal.first;
|
||||
const char* const name = childSignal.second.c_str();
|
||||
anyNetValid = printActivityStats(code, name, anyNetValid);
|
||||
bool anyNetWritten{false};
|
||||
|
||||
for (auto& accumulator : m_activityAccumulators) {
|
||||
anyNetWritten |= printScopeActivitiesFromAccumulatorIfPresent(scope.path(), accumulator, anyNetWritten);
|
||||
}
|
||||
|
||||
if (anyNetValid) closeNetScope();
|
||||
if (anyNetWritten) closeNetScope();
|
||||
}
|
||||
|
||||
bool VerilatedSaif::printScopeActivitiesFromAccumulatorIfPresent(const std::string& absoluteScopePath, VerilatedSaifActivityAccumulator& accumulator, bool anyNetWritten) {
|
||||
if (accumulator.m_scopeToActivities.count(absoluteScopePath) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& childSignal : accumulator.m_scopeToActivities.at(absoluteScopePath)) {
|
||||
VerilatedSaifActivityVar& activityVariable = accumulator.m_activity.at(childSignal.first);
|
||||
anyNetWritten = printActivityStats(activityVariable, childSignal.second.c_str(), anyNetWritten);
|
||||
}
|
||||
|
||||
return anyNetWritten;
|
||||
}
|
||||
|
||||
void VerilatedSaif::openNetScope() {
|
||||
|
|
@ -200,9 +214,8 @@ void VerilatedSaif::closeNetScope() {
|
|||
printStr(")\n");
|
||||
}
|
||||
|
||||
bool VerilatedSaif::printActivityStats(const uint32_t activityCode, const char* activityName,
|
||||
bool anyNetValid) {
|
||||
VerilatedSaifActivityVar& activity = m_activity.at(activityCode);
|
||||
bool VerilatedSaif::printActivityStats(VerilatedSaifActivityVar& activity, const char* activityName,
|
||||
bool anyNetWritten) {
|
||||
for (size_t i = 0; i < activity.width(); ++i) {
|
||||
VerilatedSaifActivityBit& bit = activity.bit(i);
|
||||
|
||||
|
|
@ -213,9 +226,9 @@ bool VerilatedSaif::printActivityStats(const uint32_t activityCode, const char*
|
|||
|
||||
bit.aggregateVal(currentTime() - activity.lastUpdateTime(), bit.bitValue());
|
||||
|
||||
if (!anyNetValid) {
|
||||
if (!anyNetWritten) {
|
||||
openNetScope();
|
||||
anyNetValid = true;
|
||||
anyNetWritten = true;
|
||||
}
|
||||
|
||||
printIndent();
|
||||
|
|
@ -239,15 +252,14 @@ bool VerilatedSaif::printActivityStats(const uint32_t activityCode, const char*
|
|||
|
||||
activity.updateLastTime(currentTime());
|
||||
|
||||
return anyNetValid;
|
||||
return anyNetWritten;
|
||||
}
|
||||
|
||||
void VerilatedSaif::clearCurrentlyCollectedData() {
|
||||
m_currentScope = -1;
|
||||
m_scopes.clear();
|
||||
m_topScopes.clear();
|
||||
m_activity.clear();
|
||||
m_activityArena.clear();
|
||||
m_activityAccumulators.clear();
|
||||
}
|
||||
|
||||
void VerilatedSaif::printStr(const char* str) { ::write(m_filep, str, strlen(str)); }
|
||||
|
|
@ -287,7 +299,11 @@ void VerilatedSaif::pushPrefix(const std::string& name, VerilatedTracePrefixType
|
|||
} else {
|
||||
m_topScopes.emplace_back(newScopeIndex);
|
||||
}
|
||||
m_scopes.emplace_back(lastWord(m_prefixStack.back().first + pname), m_currentScope);
|
||||
|
||||
std::string scopePath = m_prefixStack.back().first + pname;
|
||||
std::string scopeName = lastWord(scopePath);
|
||||
|
||||
m_scopes.emplace_back(std::move(scopePath), std::move(scopeName), m_currentScope);
|
||||
m_currentScope = newScopeIndex;
|
||||
}
|
||||
|
||||
|
|
@ -310,15 +326,7 @@ void VerilatedSaif::popPrefix() {
|
|||
m_prefixStack.pop_back();
|
||||
}
|
||||
|
||||
void VerilatedSaif::declare(const uint32_t code, const char* name, const char* wirep,
|
||||
const bool array, const int arraynum, const bool bussed, const int msb,
|
||||
const int lsb) {
|
||||
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
|
||||
|
||||
const std::string hierarchicalName = m_prefixStack.back().first + name;
|
||||
|
||||
if (!Super::declCode(code, hierarchicalName, bits)) return;
|
||||
|
||||
void VerilatedSaifActivityAccumulator::declare(uint32_t code, const std::string& absoluteScopePath, std::string variableName, int bits, bool array, int arraynum) {
|
||||
const size_t block_size = 1024;
|
||||
if (m_activityArena.empty()
|
||||
|| m_activityArena.back().size() + bits > m_activityArena.back().capacity()) {
|
||||
|
|
@ -328,56 +336,70 @@ void VerilatedSaif::declare(const uint32_t code, const char* name, const char* w
|
|||
const size_t bitsIdx = m_activityArena.back().size();
|
||||
m_activityArena.back().resize(m_activityArena.back().size() + bits);
|
||||
|
||||
std::string finalName = lastWord(hierarchicalName);
|
||||
if (array) {
|
||||
finalName += '[';
|
||||
finalName += std::to_string(arraynum);
|
||||
finalName += ']';
|
||||
variableName += '[';
|
||||
variableName += std::to_string(arraynum);
|
||||
variableName += ']';
|
||||
}
|
||||
|
||||
assert(m_currentScope >= 0);
|
||||
m_scopes.at(m_currentScope).addActivityVar(code, std::move(finalName));
|
||||
m_scopeToActivities[absoluteScopePath].emplace_back(code, variableName);
|
||||
m_activity.emplace(code, VerilatedSaifActivityVar{
|
||||
static_cast<uint32_t>(bits), m_activityArena.back().data() + bitsIdx});
|
||||
}
|
||||
|
||||
m_activity.emplace(code, VerilatedSaifActivityVar{static_cast<uint32_t>(bits),
|
||||
m_activityArena.back().data() + bitsIdx});
|
||||
void VerilatedSaif::declare(const uint32_t code, uint32_t fidx, const char* name, const char* wirep,
|
||||
const bool array, const int arraynum, const bool bussed, const int msb,
|
||||
const int lsb) {
|
||||
VerilatedSaifActivityAccumulator& accumulator = m_activityAccumulators.at(fidx);
|
||||
|
||||
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
|
||||
|
||||
const std::string hierarchicalName = m_prefixStack.back().first + name;
|
||||
|
||||
if (!Super::declCode(code, hierarchicalName, bits)) return;
|
||||
|
||||
std::string variableName = lastWord(hierarchicalName);
|
||||
m_scopes.at(m_currentScope).addActivityVar(code, variableName);
|
||||
|
||||
accumulator.declare(code, m_scopes.at(m_currentScope).path(), std::move(variableName), bits, array, arraynum);
|
||||
}
|
||||
|
||||
void VerilatedSaif::declEvent(const uint32_t code, const uint32_t fidx, const char* name,
|
||||
const int dtypenum, const VerilatedTraceSigDirection,
|
||||
const VerilatedTraceSigKind, const VerilatedTraceSigType,
|
||||
const bool array, const int arraynum) {
|
||||
declare(code, name, "event", array, arraynum, false, 0, 0);
|
||||
declare(code, fidx, name, "event", array, arraynum, false, 0, 0);
|
||||
}
|
||||
|
||||
void VerilatedSaif::declBit(const uint32_t code, const uint32_t fidx, const char* name,
|
||||
const int dtypenum, const VerilatedTraceSigDirection,
|
||||
const VerilatedTraceSigKind, const VerilatedTraceSigType,
|
||||
const bool array, const int arraynum) {
|
||||
declare(code, name, "wire", array, arraynum, false, 0, 0);
|
||||
declare(code, fidx, name, "wire", array, arraynum, false, 0, 0);
|
||||
}
|
||||
void VerilatedSaif::declBus(const uint32_t code, const uint32_t fidx, const char* name,
|
||||
const int dtypenum, const VerilatedTraceSigDirection,
|
||||
const VerilatedTraceSigKind, const VerilatedTraceSigType,
|
||||
const bool array, const int arraynum, const int msb, const int lsb) {
|
||||
declare(code, name, "wire", array, arraynum, true, msb, lsb);
|
||||
declare(code, fidx, name, "wire", array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedSaif::declQuad(const uint32_t code, const uint32_t fidx, const char* name,
|
||||
const int dtypenum, const VerilatedTraceSigDirection,
|
||||
const VerilatedTraceSigKind, const VerilatedTraceSigType,
|
||||
const bool array, const int arraynum, const int msb, const int lsb) {
|
||||
declare(code, name, "wire", array, arraynum, true, msb, lsb);
|
||||
declare(code, fidx, name, "wire", array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedSaif::declArray(const uint32_t code, const uint32_t fidx, const char* name,
|
||||
const int dtypenum, const VerilatedTraceSigDirection,
|
||||
const VerilatedTraceSigKind, const VerilatedTraceSigType,
|
||||
const bool array, const int arraynum, const int msb, const int lsb) {
|
||||
declare(code, name, "wire", array, arraynum, true, msb, lsb);
|
||||
declare(code, fidx, name, "wire", array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedSaif::declDouble(const uint32_t code, const uint32_t fidx, const char* name,
|
||||
const int dtypenum, const VerilatedTraceSigDirection,
|
||||
const VerilatedTraceSigKind, const VerilatedTraceSigType,
|
||||
const bool array, const int arraynum) {
|
||||
declare(code, name, "real", array, arraynum, false, 63, 0);
|
||||
declare(code, fidx, name, "real", array, arraynum, false, 63, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -404,43 +426,43 @@ void VerilatedSaifBuffer::emitEvent(const uint32_t code) {
|
|||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedSaifBuffer::emitBit(const uint32_t code, const CData newval) {
|
||||
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code);
|
||||
assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
|
||||
activity.emitBit(m_owner.currentTime(), newval);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedSaifBuffer::emitCData(const uint32_t code, const CData newval, const int bits) {
|
||||
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code);
|
||||
assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
|
||||
activity.emitData<CData>(m_owner.currentTime(), newval, bits);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedSaifBuffer::emitSData(const uint32_t code, const SData newval, const int bits) {
|
||||
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code);
|
||||
assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
|
||||
activity.emitData<SData>(m_owner.currentTime(), newval, bits);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedSaifBuffer::emitIData(const uint32_t code, const IData newval, const int bits) {
|
||||
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code);
|
||||
assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
|
||||
activity.emitData<IData>(m_owner.currentTime(), newval, bits);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedSaifBuffer::emitQData(const uint32_t code, const QData newval, const int bits) {
|
||||
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code);
|
||||
assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
|
||||
activity.emitData<QData>(m_owner.currentTime(), newval, bits);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedSaifBuffer::emitWData(const uint32_t code, const WData* newvalp, const int bits) {
|
||||
assert(m_owner.m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activity.at(code);
|
||||
assert(m_owner.m_activityAccumulators.at(m_fidx).m_activity.count(code) && "Activity must be declared earlier");
|
||||
VerilatedSaifActivityVar& activity = m_owner.m_activityAccumulators.at(m_fidx).m_activity.at(code);
|
||||
activity.emitWData(m_owner.currentTime(), newvalp, bits);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,16 +106,22 @@ private:
|
|||
|
||||
class VerilatedSaifActivityScope final {
|
||||
// MEMBERS
|
||||
std::string m_scopeName{}; // name of the activity scope
|
||||
std::vector<int32_t> m_childScopesIndices{}; // array indices of child scopes
|
||||
std::vector<std::pair<uint32_t, std::string>>
|
||||
m_childActivities{}; // children signals codes mapped to their names in the current scope
|
||||
int32_t m_parentScopeIndex{-1}; // array index of parent scope
|
||||
// absolute path to the scope
|
||||
std::string m_scopePath{};
|
||||
// name of the activity scope
|
||||
std::string m_scopeName{};
|
||||
// array indices of child scopes
|
||||
std::vector<int32_t> m_childScopesIndices{};
|
||||
// children signals codes mapped to their names in the current scope
|
||||
std::vector<std::pair<uint32_t, std::string>> m_childActivities{};
|
||||
// array index of parent scope
|
||||
int32_t m_parentScopeIndex{-1};
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedSaifActivityScope(std::string name, int32_t parentScopeIndex = -1)
|
||||
: m_scopeName{std::move(name)}
|
||||
VerilatedSaifActivityScope(std::string scopePath, std::string name, int32_t parentScopeIndex = -1)
|
||||
: m_scopePath{std::move(scopePath)}
|
||||
, m_scopeName{std::move(name)}
|
||||
, m_parentScopeIndex{parentScopeIndex} {}
|
||||
|
||||
VerilatedSaifActivityScope(VerilatedSaifActivityScope&&) = default;
|
||||
|
|
@ -131,6 +137,7 @@ public:
|
|||
VL_ATTR_ALWINLINE bool hasParent() const { return m_parentScopeIndex >= 0; }
|
||||
|
||||
// ACCESSORS
|
||||
VL_ATTR_ALWINLINE const std::string& path() const { return m_scopePath; }
|
||||
VL_ATTR_ALWINLINE const std::string& name() const { return m_scopeName; }
|
||||
VL_ATTR_ALWINLINE const std::vector<int32_t>& childScopesIndices() const {
|
||||
return m_childScopesIndices;
|
||||
|
|
@ -146,6 +153,33 @@ private:
|
|||
VL_UNCOPYABLE(VerilatedSaifActivityScope);
|
||||
};
|
||||
|
||||
class VerilatedSaifActivityAccumulator {
|
||||
// Give access to the private activities
|
||||
friend class VerilatedSaifBuffer;
|
||||
friend class VerilatedSaif;
|
||||
|
||||
// MEMBERS
|
||||
// map of scopes paths to codes of activities inside
|
||||
std::unordered_map<std::string, std::vector<std::pair<uint32_t, std::string>>> m_scopeToActivities;
|
||||
// map of variables codes mapped to their activity objects
|
||||
std::unordered_map<uint32_t, VerilatedSaifActivityVar> m_activity;
|
||||
// memory pool for signals bits objects
|
||||
std::vector<std::vector<VerilatedSaifActivityBit>> m_activityArena;
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
void declare(uint32_t code, const std::string& absoluteScopePath, std::string variableName, int bits, bool array, int arraynum);
|
||||
|
||||
// CONSTRUCTORS
|
||||
VerilatedSaifActivityAccumulator() = default;
|
||||
|
||||
VerilatedSaifActivityAccumulator(VerilatedSaifActivityAccumulator&&) = default;
|
||||
VerilatedSaifActivityAccumulator& operator=(VerilatedSaifActivityAccumulator&&) = default;
|
||||
|
||||
private:
|
||||
VL_UNCOPYABLE(VerilatedSaifActivityAccumulator);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSaif
|
||||
// Base class to create a Verilator SAIF dump
|
||||
|
|
@ -167,14 +201,14 @@ private:
|
|||
|
||||
int m_indent = 0; // indentation size in spaces
|
||||
|
||||
int32_t m_currentScope{-1}; // currently active scope
|
||||
std::vector<VerilatedSaifActivityScope> m_scopes{}; // array of declared scopes
|
||||
std::vector<int32_t> m_topScopes{}; // array of top scopes
|
||||
|
||||
std::unordered_map<uint32_t, VerilatedSaifActivityVar>
|
||||
m_activity; // map of variables codes mapped to their activity objects
|
||||
std::vector<std::vector<VerilatedSaifActivityBit>>
|
||||
m_activityArena; // memory pool for signals bits objects
|
||||
// currently active scope
|
||||
int32_t m_currentScope{-1};
|
||||
// array of declared scopes
|
||||
std::vector<VerilatedSaifActivityScope> m_scopes{};
|
||||
// array of top scopes
|
||||
std::vector<int32_t> m_topScopes{};
|
||||
// activity accumulators used to store variables statistics over simulation time
|
||||
std::vector<VerilatedSaifActivityAccumulator> m_activityAccumulators{};
|
||||
|
||||
uint64_t m_time{0}; // total time of the currently traced simulation
|
||||
|
||||
|
|
@ -191,9 +225,10 @@ private:
|
|||
void openInstanceScope(const std::string& instanceName);
|
||||
void closeInstanceScope();
|
||||
void printScopeActivities(const VerilatedSaifActivityScope& scope);
|
||||
bool printScopeActivitiesFromAccumulatorIfPresent(const std::string& absoluteScopePath, VerilatedSaifActivityAccumulator& accumulator, bool anyNetWritten);
|
||||
void openNetScope();
|
||||
void closeNetScope();
|
||||
bool printActivityStats(uint32_t activityCode, const char* activityName, bool anyNetValid);
|
||||
bool printActivityStats(VerilatedSaifActivityVar& activity, const char* activityName, bool anyNetWritten);
|
||||
|
||||
void incrementIndent();
|
||||
void decrementIndent();
|
||||
|
|
@ -204,7 +239,7 @@ private:
|
|||
|
||||
void clearCurrentlyCollectedData();
|
||||
|
||||
void declare(uint32_t code, const char* name, const char* wirep, bool array, int arraynum,
|
||||
void declare(uint32_t code, uint32_t fidx, const char* name, const char* wirep, bool array, int arraynum,
|
||||
bool bussed, int msb, int lsb);
|
||||
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -236,11 +271,6 @@ public:
|
|||
explicit VerilatedSaif(void* filep = nullptr);
|
||||
~VerilatedSaif();
|
||||
|
||||
// ACCESSORS
|
||||
// Set size in bytes after which new file should be created.
|
||||
void rolloverSize(uint64_t size) VL_MT_SAFE { /* noop */
|
||||
}
|
||||
|
||||
// METHODS - All must be thread safe
|
||||
// Open the file; call isOpen() to see if errors
|
||||
void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
|
|
@ -304,10 +334,13 @@ class VerilatedSaifBuffer VL_NOT_FINAL {
|
|||
friend VerilatedSaif::OffloadBuffer;
|
||||
|
||||
VerilatedSaif& m_owner; // Trace file owning this buffer. Required by subclasses.
|
||||
uint32_t m_fidx; // Index of target activity accumulator
|
||||
|
||||
// CONSTRUCTOR
|
||||
explicit VerilatedSaifBuffer(VerilatedSaif& owner)
|
||||
: m_owner{owner} {}
|
||||
: m_owner{owner}, m_fidx{0} {}
|
||||
explicit VerilatedSaifBuffer(VerilatedSaif& owner, uint32_t fidx)
|
||||
: m_owner{owner}, m_fidx{fidx} {}
|
||||
virtual ~VerilatedSaifBuffer() = default;
|
||||
|
||||
//=========================================================================
|
||||
|
|
@ -351,8 +384,7 @@ public:
|
|||
/// just as if this object was deleted and reconstructed.
|
||||
virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); }
|
||||
|
||||
void rolloverSize(size_t size) VL_MT_SAFE { /* noop */
|
||||
}
|
||||
void rolloverSize(size_t size) VL_MT_SAFE {/* noop */}
|
||||
|
||||
/// Close dump
|
||||
void close() VL_MT_SAFE {
|
||||
|
|
|
|||
Loading…
Reference in New Issue