mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Associate trace codes with function indices (#4610)
For each traced variable, also register the trace function index that will write it.
This commit is contained in:
@@ -3192,7 +3192,8 @@ class AstTraceDecl final : public AstNodeStmt {
|
||||
// Expression being traced - Moved to AstTraceInc by V3Trace
|
||||
// @astgen op1 := valuep : Optional[AstNodeExpr]
|
||||
private:
|
||||
uint32_t m_code = 0; // Trace identifier code; converted to ASCII by trace routines
|
||||
uint32_t m_code{0}; // Trace identifier code
|
||||
uint32_t m_fidx{0}; // Trace function index
|
||||
const string m_showname; // Name of variable
|
||||
const VNumRange m_bitRange; // Property of var the trace details
|
||||
const VNumRange m_arrayRange; // Property of var the trace details
|
||||
@@ -3228,6 +3229,8 @@ public:
|
||||
// Details on what we're tracing
|
||||
uint32_t code() const { return m_code; }
|
||||
void code(uint32_t code) { m_code = code; }
|
||||
uint32_t fidx() const { return m_fidx; }
|
||||
void fidx(uint32_t fidx) { m_fidx = fidx; }
|
||||
uint32_t codeInc() const { return m_codeInc; }
|
||||
const VNumRange& bitRange() const { return m_bitRange; }
|
||||
const VNumRange& arrayRange() const { return m_arrayRange; }
|
||||
|
||||
@@ -649,6 +649,8 @@ class EmitCTrace final : EmitCFunc {
|
||||
puts("(c+" + cvtToStr(nodep->code()));
|
||||
if (nodep->arrayRange().ranged()) puts("+i*" + cvtToStr(nodep->widthWords()));
|
||||
puts(",");
|
||||
puts(cvtToStr(nodep->fidx()));
|
||||
puts(",");
|
||||
putsQuoted(VIdProtect::protectWordsIf(nodep->showname(), nodep->protect()));
|
||||
// Direction
|
||||
if (v3Global.opt.traceFormat().fst()) {
|
||||
|
||||
+34
-16
@@ -477,22 +477,28 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
AstCFunc* newCFunc(VTraceType traceType, AstCFunc* topFuncp, unsigned funcNum,
|
||||
AstCFunc* newCFunc(VTraceType traceType, AstCFunc* topFuncp, uint32_t funcNum,
|
||||
uint32_t baseCode = 0) {
|
||||
// Create new function
|
||||
const bool isTopFunc = topFuncp == nullptr;
|
||||
std::string baseName = "trace_";
|
||||
if (traceType == VTraceType::CONSTANT) {
|
||||
baseName += "const_";
|
||||
} else if (traceType == VTraceType::FULL) {
|
||||
baseName += "full_";
|
||||
std::string funcName;
|
||||
if (isTopFunc) {
|
||||
if (traceType == VTraceType::CONSTANT) {
|
||||
funcName = "trace_const";
|
||||
} else if (traceType == VTraceType::FULL) {
|
||||
funcName = "trace_full";
|
||||
} else {
|
||||
funcName = "trace_chg";
|
||||
}
|
||||
} else {
|
||||
baseName += "chg_";
|
||||
funcName = topFuncp->name();
|
||||
funcName += "_sub";
|
||||
}
|
||||
baseName += isTopFunc ? "top_" : "sub_";
|
||||
funcName += "_";
|
||||
funcName += cvtToStr(funcNum);
|
||||
|
||||
FileLine* const flp = m_topScopep->fileline();
|
||||
AstCFunc* const funcp = new AstCFunc{flp, baseName + cvtToStr(funcNum), m_topScopep};
|
||||
AstCFunc* const funcp = new AstCFunc{flp, funcName, m_topScopep};
|
||||
funcp->isTrace(true);
|
||||
funcp->dontCombine(true);
|
||||
funcp->isLoose(true);
|
||||
@@ -526,6 +532,8 @@ private:
|
||||
}
|
||||
m_regFuncp->addStmtsp(new AstText{flp, str, true});
|
||||
m_regFuncp->addStmtsp(new AstAddrOfCFunc{flp, funcp});
|
||||
m_regFuncp->addStmtsp(new AstText{flp, ", ", true});
|
||||
m_regFuncp->addStmtsp(new AstConst{flp, funcNum});
|
||||
m_regFuncp->addStmtsp(new AstText{flp, ", vlSelf);\n", true});
|
||||
} else {
|
||||
// Sub functions
|
||||
@@ -565,7 +573,7 @@ private:
|
||||
: std::numeric_limits<int>::max();
|
||||
|
||||
AstCFunc* const topFuncp = newCFunc(VTraceType::CONSTANT, nullptr, 0);
|
||||
unsigned subFuncNum = 0;
|
||||
uint32_t subFuncNum = 0;
|
||||
AstCFunc* subFuncp = nullptr;
|
||||
int subStmts = 0;
|
||||
for (auto it = traces.cbegin(); it != traces.end(); ++it) {
|
||||
@@ -612,14 +620,16 @@ private:
|
||||
uint32_t parallelism) {
|
||||
const int splitLimit = v3Global.opt.outputSplitCTrace() ? v3Global.opt.outputSplitCTrace()
|
||||
: std::numeric_limits<int>::max();
|
||||
unsigned topFuncNum = 0;
|
||||
unsigned subFuncNum = 0;
|
||||
|
||||
// pre-incremented, so starts at 0
|
||||
uint32_t topFuncNum = std::numeric_limits<uint32_t>::max();
|
||||
TraceVec::const_iterator it = traces.begin();
|
||||
while (it != traces.end()) {
|
||||
AstCFunc* topFulFuncp = nullptr;
|
||||
AstCFunc* topChgFuncp = nullptr;
|
||||
AstCFunc* subFulFuncp = nullptr;
|
||||
AstCFunc* subChgFuncp = nullptr;
|
||||
uint32_t subFuncNum = 0;
|
||||
int subStmts = 0;
|
||||
const uint32_t maxCodes = std::max((nAllCodes + parallelism - 1) / parallelism, 1U);
|
||||
uint32_t nCodes = 0;
|
||||
@@ -627,20 +637,25 @@ private:
|
||||
AstIf* ifp = nullptr;
|
||||
uint32_t baseCode = 0;
|
||||
for (; nCodes < maxCodes && it != traces.end(); ++it) {
|
||||
const TraceTraceVertex* const vtxp = it->second;
|
||||
// This is a duplicate decl, no need to add it
|
||||
if (vtxp->duplicatep()) continue;
|
||||
const ActCodeSet& actSet = it->first;
|
||||
// Traced value never changes, no need to add it
|
||||
if (actSet.count(TraceActivityVertex::ACTIVITY_NEVER)) continue;
|
||||
|
||||
const TraceTraceVertex* const vtxp = it->second;
|
||||
AstTraceDecl* const declp = vtxp->nodep();
|
||||
|
||||
// This is a duplicate decl, no need to add it, but must set the
|
||||
// function index to the same as the canonical node.
|
||||
if (const TraceTraceVertex* const canonVtxp = vtxp->duplicatep()) {
|
||||
declp->fidx(canonVtxp->nodep()->fidx());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create top function if not yet created
|
||||
if (!topFulFuncp) {
|
||||
++topFuncNum;
|
||||
topFulFuncp = newCFunc(VTraceType::FULL, nullptr, topFuncNum);
|
||||
topChgFuncp = newCFunc(VTraceType::CHANGE, nullptr, topFuncNum);
|
||||
++topFuncNum;
|
||||
}
|
||||
|
||||
// Create new sub function if required
|
||||
@@ -682,6 +697,9 @@ private:
|
||||
= new AstTraceInc{flp, declp, VTraceType::CHANGE, baseCode};
|
||||
ifp->addThensp(incChgp);
|
||||
|
||||
// Set the function index of the decl
|
||||
declp->fidx(topFuncNum);
|
||||
|
||||
// Track splitting due to size
|
||||
UASSERT_OBJ(incFulp->nodeCount() == incChgp->nodeCount(), declp,
|
||||
"Should have equal cost");
|
||||
|
||||
Reference in New Issue
Block a user