[#73220] clean up SAIF content printing code
This commit is contained in:
parent
8878197759
commit
40bfe54ebc
|
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
ActivityBit& ActivityVar::getBit(std::size_t index)
|
ActivityBit& ActivityVar::getBit(std::size_t index)
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index < m_width);
|
assert(index < m_width);
|
||||||
return m_bits[index];
|
return m_bits[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,20 +107,7 @@ void VerilatedSaif::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
openNextImp(m_rolloverSize != 0);
|
openNextImp(m_rolloverSize != 0);
|
||||||
if (!isOpen()) return;
|
if (!isOpen()) return;
|
||||||
|
|
||||||
// NOTE: maybe extract those keywords to some variables to keep them in one place
|
initializeSaifFileContents();
|
||||||
printStr("(SAIFILE\n");
|
|
||||||
printStr("(SAIFVERSION \"2.0\")\n");
|
|
||||||
printStr("(DIRECTION \"backward\")\n");
|
|
||||||
printStr("(DESIGN \"foo\")\n");
|
|
||||||
//printStr("(DATE \"foo\")\n");
|
|
||||||
//printStr("(VENDOR \"foo\")\n");
|
|
||||||
printStr("(PROGRAM_NAME \"Verilator\")\n");
|
|
||||||
//printStr("(PROGRAM_VERSION \"foo\")\n");
|
|
||||||
printStr("(VERSION \"5.032\")\n");
|
|
||||||
printStr("(DIVIDER / )\n");
|
|
||||||
printStr("(TIMESCALE ");
|
|
||||||
printStr(timeResStr().c_str());
|
|
||||||
printStr(")\n");
|
|
||||||
|
|
||||||
Super::traceInit();
|
Super::traceInit();
|
||||||
|
|
||||||
|
|
@ -178,6 +165,19 @@ void VerilatedSaif::openNextImp(bool incFilename) {
|
||||||
fullDump(true); // First dump must be full
|
fullDump(true); // First dump must be full
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::initializeSaifFileContents() {
|
||||||
|
printStr("(SAIFILE\n");
|
||||||
|
printStr("(SAIFVERSION \"2.0\")\n");
|
||||||
|
printStr("(DIRECTION \"backward\")\n");
|
||||||
|
printStr("(DESIGN \"foo\")\n");
|
||||||
|
printStr("(PROGRAM_NAME \"Verilator\")\n");
|
||||||
|
printStr("(VERSION \"5.032\")\n");
|
||||||
|
printStr("(DIVIDER / )\n");
|
||||||
|
printStr("(TIMESCALE ");
|
||||||
|
printStr(timeResStr().c_str());
|
||||||
|
printStr(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
bool VerilatedSaif::preChangeDump() {
|
bool VerilatedSaif::preChangeDump() {
|
||||||
if (VL_UNLIKELY(m_rolloverSize)) openNextImp(true);
|
if (VL_UNLIKELY(m_rolloverSize)) openNextImp(true);
|
||||||
return isOpen();
|
return isOpen();
|
||||||
|
|
@ -211,6 +211,20 @@ void VerilatedSaif::closeErr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedSaif::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
void VerilatedSaif::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
|
// This function is on the flush() call path
|
||||||
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
|
if (!isOpen()) return;
|
||||||
|
|
||||||
|
finalizeSaifFileContents();
|
||||||
|
clearCurrentlyCollectedData();
|
||||||
|
|
||||||
|
closePrev();
|
||||||
|
// closePrev() called Super::flush(), so we just
|
||||||
|
// need to shut down the tracing thread here.
|
||||||
|
Super::closeBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::finalizeSaifFileContents() {
|
||||||
printStr("(DURATION ");
|
printStr("(DURATION ");
|
||||||
printStr(std::to_string(m_time).c_str());
|
printStr(std::to_string(m_time).c_str());
|
||||||
printStr(")\n");
|
printStr(")\n");
|
||||||
|
|
@ -222,90 +236,98 @@ void VerilatedSaif::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
decrementIndent();
|
decrementIndent();
|
||||||
|
|
||||||
printStr(")\n"); // SAIFILE
|
printStr(")\n"); // SAIFILE
|
||||||
|
|
||||||
clearCurrentlyCollectedData();
|
|
||||||
|
|
||||||
// This function is on the flush() call path
|
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
|
||||||
if (!isOpen()) return;
|
|
||||||
closePrev();
|
|
||||||
// closePrev() called Super::flush(), so we just
|
|
||||||
// need to shut down the tracing thread here.
|
|
||||||
Super::closeBase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedSaif::recursivelyPrintScopes(uint32_t scopeIndex) {
|
void VerilatedSaif::recursivelyPrintScopes(uint32_t scopeIndex) {
|
||||||
const ActivityScope& saifScope = m_scopes.at(scopeIndex);
|
const ActivityScope& scope = m_scopes.at(scopeIndex);
|
||||||
|
|
||||||
printIndent();
|
openInstanceScope(scope.getName().c_str());
|
||||||
printStr("(INSTANCE ");
|
|
||||||
printStr(saifScope.getName().c_str());
|
|
||||||
printStr("\n");
|
|
||||||
|
|
||||||
incrementIndent();
|
printScopeActivities(scope);
|
||||||
|
|
||||||
bool anyNetValid{false};
|
for (uint32_t childScopeIndex : scope.getChildScopesIndices()) {
|
||||||
|
|
||||||
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.getWidth(); i++) {
|
|
||||||
ActivityBit& bit = activity.getBit(i);
|
|
||||||
|
|
||||||
if (bit.getToggleCount() <= 0) {
|
|
||||||
// Skip bits with no transitions
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bit.aggregateVal(m_time - activity.getLastUpdateTime(), bit.getBitValue());
|
|
||||||
|
|
||||||
assert(m_time >= bit.getHighTime());
|
|
||||||
|
|
||||||
if (!anyNetValid) {
|
|
||||||
printIndent();
|
|
||||||
printStr("(NET\n");
|
|
||||||
anyNetValid = true;
|
|
||||||
|
|
||||||
incrementIndent();
|
|
||||||
}
|
|
||||||
|
|
||||||
printIndent();
|
|
||||||
printStr("(");
|
|
||||||
printStr(name);
|
|
||||||
if (activity.getWidth() > 1) {
|
|
||||||
printStr("\\[");
|
|
||||||
printStr(std::to_string(i).c_str());
|
|
||||||
printStr("\\]");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only have two-value logic so TZ, TX and TB will always be 0
|
|
||||||
printStr(" (T0 ");
|
|
||||||
printStr(std::to_string(m_time - bit.getHighTime()).c_str());
|
|
||||||
printStr(") (T1 ");
|
|
||||||
printStr(std::to_string(bit.getHighTime()).c_str());
|
|
||||||
printStr(") (TZ 0) (TX 0) (TB 0) (TC ");
|
|
||||||
printStr(std::to_string(bit.getToggleCount()).c_str());
|
|
||||||
printStr("))\n");
|
|
||||||
}
|
|
||||||
activity.updateLastTime(m_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anyNetValid) {
|
|
||||||
decrementIndent();
|
|
||||||
|
|
||||||
printIndent();
|
|
||||||
printStr(")\n"); // NET
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t childScopeIndex : saifScope.getChildScopesIndices()) {
|
|
||||||
recursivelyPrintScopes(childScopeIndex);
|
recursivelyPrintScopes(childScopeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeInstanceScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::openInstanceScope(const char* instanceName) {
|
||||||
|
printIndent();
|
||||||
|
printStr("(INSTANCE ");
|
||||||
|
printStr(instanceName);
|
||||||
|
printStr("\n");
|
||||||
|
incrementIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::closeInstanceScope() {
|
||||||
decrementIndent();
|
decrementIndent();
|
||||||
printIndent();
|
printIndent();
|
||||||
printStr(")\n"); // INSTANCE
|
printStr(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::printScopeActivities(const ActivityScope& scope) {
|
||||||
|
bool anyNetValid{false};
|
||||||
|
for (auto& childSignal : scope.getChildActivities()) {
|
||||||
|
uint32_t code = childSignal.first;
|
||||||
|
const char* name = childSignal.second.c_str();
|
||||||
|
anyNetValid = printActivityStats(code, name, anyNetValid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anyNetValid) {
|
||||||
|
closeNetScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::openNetScope() {
|
||||||
|
printIndent();
|
||||||
|
printStr("(NET\n");
|
||||||
|
incrementIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedSaif::closeNetScope() {
|
||||||
|
decrementIndent();
|
||||||
|
printIndent();
|
||||||
|
printStr(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VerilatedSaif::printActivityStats(uint32_t activityCode, const char* activityName, bool anyNetValid){
|
||||||
|
ActivityVar& activity = m_activity.at(activityCode);
|
||||||
|
for (size_t i = 0; i < activity.getWidth(); i++) {
|
||||||
|
ActivityBit& bit = activity.getBit(i);
|
||||||
|
|
||||||
|
if (bit.getToggleCount() <= 0) {
|
||||||
|
// Skip bits with no toggles
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bit.aggregateVal(m_time - activity.getLastUpdateTime(), bit.getBitValue());
|
||||||
|
|
||||||
|
if (!anyNetValid) {
|
||||||
|
openNetScope();
|
||||||
|
anyNetValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
printIndent();
|
||||||
|
printStr("(");
|
||||||
|
printStr(activityName);
|
||||||
|
if (activity.getWidth() > 1) {
|
||||||
|
printStr("\\[");
|
||||||
|
printStr(std::to_string(i).c_str());
|
||||||
|
printStr("\\]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only have two-value logic so TZ, TX and TB will always be 0
|
||||||
|
printStr(" (T0 ");
|
||||||
|
printStr(std::to_string(m_time - bit.getHighTime()).c_str());
|
||||||
|
printStr(") (T1 ");
|
||||||
|
printStr(std::to_string(bit.getHighTime()).c_str());
|
||||||
|
printStr(") (TZ 0) (TX 0) (TB 0) (TC ");
|
||||||
|
printStr(std::to_string(bit.getToggleCount()).c_str());
|
||||||
|
printStr("))\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return anyNetValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedSaif::clearCurrentlyCollectedData()
|
void VerilatedSaif::clearCurrentlyCollectedData()
|
||||||
|
|
|
||||||
|
|
@ -142,12 +142,24 @@ private:
|
||||||
std::string m_filename; // Filename we're writing to (if open)
|
std::string m_filename; // Filename we're writing to (if open)
|
||||||
uint64_t m_rolloverSize = 0; // File size to rollover at
|
uint64_t m_rolloverSize = 0; // File size to rollover at
|
||||||
|
|
||||||
|
void initializeSaifFileContents();
|
||||||
|
void finalizeSaifFileContents();
|
||||||
|
void recursivelyPrintScopes(uint32_t scopeIndex);
|
||||||
|
void openInstanceScope(const char* instanceName);
|
||||||
|
void closeInstanceScope();
|
||||||
|
void printScopeActivities(const ActivityScope& scope);
|
||||||
|
void openNetScope();
|
||||||
|
void closeNetScope();
|
||||||
|
bool printActivityStats(uint32_t activityCode, const char* activityName, bool anyNetValid);
|
||||||
|
|
||||||
void incrementIndent();
|
void incrementIndent();
|
||||||
void decrementIndent();
|
void decrementIndent();
|
||||||
void printIndent();
|
void printIndent();
|
||||||
|
|
||||||
int m_indent = 0; // Indentation depth
|
int m_indent = 0; // Indentation depth
|
||||||
|
|
||||||
|
void printStr(const char* str);
|
||||||
|
|
||||||
void clearCurrentlyCollectedData();
|
void clearCurrentlyCollectedData();
|
||||||
|
|
||||||
int32_t m_currentScope{-1};
|
int32_t m_currentScope{-1};
|
||||||
|
|
@ -158,19 +170,15 @@ private:
|
||||||
std::vector<std::vector<ActivityBit>> m_activityArena;
|
std::vector<std::vector<ActivityBit>> m_activityArena;
|
||||||
uint64_t m_time;
|
uint64_t m_time;
|
||||||
|
|
||||||
// Prefixes to add to signal names/scope types
|
|
||||||
std::vector<std::pair<std::string, VerilatedTracePrefixType>> m_prefixStack{
|
std::vector<std::pair<std::string, VerilatedTracePrefixType>> m_prefixStack{
|
||||||
{"", VerilatedTracePrefixType::SCOPE_MODULE}};
|
{"", VerilatedTracePrefixType::SCOPE_MODULE}};
|
||||||
|
|
||||||
void openNextImp(bool incFilename);
|
void openNextImp(bool incFilename);
|
||||||
void closePrev();
|
void closePrev();
|
||||||
void closeErr();
|
void closeErr();
|
||||||
void printStr(const char* str);
|
|
||||||
void declare(uint32_t code, const char* name, const char* wirep, bool array, int arraynum,
|
void declare(uint32_t code, const char* name, const char* wirep, bool array, int arraynum,
|
||||||
bool bussed, int msb, int lsb);
|
bool bussed, int msb, int lsb);
|
||||||
|
|
||||||
void recursivelyPrintScopes(uint32_t scopeIndex);
|
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VL_UNCOPYABLE(VerilatedSaif);
|
VL_UNCOPYABLE(VerilatedSaif);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue