feat: Add V3Instrumentation-Pass
This commit is contained in:
parent
cb3c2706a8
commit
8cd34bc05b
|
|
@ -115,6 +115,7 @@ set(HEADERS
|
|||
V3Inline.h
|
||||
V3Inst.h
|
||||
V3InstrCount.h
|
||||
V3Instrumentation.h
|
||||
V3Interface.h
|
||||
V3LangCode.h
|
||||
V3LanguageWords.h
|
||||
|
|
@ -285,6 +286,7 @@ set(COMMON_SOURCES
|
|||
V3Inline.cpp
|
||||
V3Inst.cpp
|
||||
V3InstrCount.cpp
|
||||
V3Instrumentation.cpp
|
||||
V3Interface.cpp
|
||||
V3Life.cpp
|
||||
V3LifePost.cpp
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ RAW_OBJS_PCH_ASTNOMT = \
|
|||
V3Inline.o \
|
||||
V3Inst.o \
|
||||
V3InstrCount.o \
|
||||
V3Instrumentation.o \
|
||||
V3Interface.o \
|
||||
V3Life.o \
|
||||
V3LifePost.o \
|
||||
|
|
|
|||
|
|
@ -558,6 +558,7 @@ class V3ControlResolver final {
|
|||
uint8_t m_mode = NONE;
|
||||
std::unordered_map<string, V3ControlResolverHierWorkerEntry> m_hierWorkers;
|
||||
FileLine* m_profileFileLine = nullptr;
|
||||
std::map<string, InstrumentationTarget, LengthThenLexiographic> m_instrCfg;
|
||||
|
||||
V3ControlResolver() = default;
|
||||
~V3ControlResolver() = default;
|
||||
|
|
@ -622,6 +623,41 @@ public:
|
|||
return cost;
|
||||
}
|
||||
}
|
||||
// Helper for adding targets to the instrumentation config map
|
||||
std::pair<string, string> splitPrefixAndVar(const string& target) {
|
||||
auto pos = target.rfind('.');
|
||||
if (pos == string::npos) {
|
||||
// No prefix, return error
|
||||
}
|
||||
string prefix = target.substr(0, pos);
|
||||
string varTarget = target.substr(pos + 1);
|
||||
return {prefix, varTarget};
|
||||
}
|
||||
// Add the instrumentation config data to the map to create the initial map (Used in verilog.y)
|
||||
void addInstrumentationConfigs(FileLine* fl, const string& instrFunction, int instrID,
|
||||
const string& target) {
|
||||
// Error MSG if the instrumentation of the top module is not possible
|
||||
if ((std::count(target.begin(), target.end(), '.') < 2)) {
|
||||
v3fatal("In .vlt defined target tries to instrument the highest MODULE, is not possible!"
|
||||
" ... Target string: " << target);
|
||||
}
|
||||
// Implement custom iterator to remove the last part of the target and insert it into the vector of the map
|
||||
// If the target string is the same as one already in the map, push the var to the vector
|
||||
auto [prefix, varTarget] = splitPrefixAndVar(target);
|
||||
InstrumentationEntry entry{instrID, instrFunction, varTarget};
|
||||
auto it = m_instrCfg.find(prefix);
|
||||
if (it != m_instrCfg.end()) {
|
||||
it->second.entries.push_back(entry);
|
||||
} else {
|
||||
// Create a new entry in the map
|
||||
InstrumentationTarget newTarget;
|
||||
newTarget.entries.push_back(entry);
|
||||
m_instrCfg[prefix] = std::move(newTarget);
|
||||
}
|
||||
}
|
||||
std::map<string, InstrumentationTarget, LengthThenLexiographic>& getInstrumentationConfigs() {
|
||||
return m_instrCfg;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -680,6 +716,11 @@ void V3Control::addModulePragma(const string& module, VPragmaType pragma) {
|
|||
V3ControlResolver::s().modules().at(module).addModulePragma(pragma);
|
||||
}
|
||||
|
||||
void V3Control::addInstrumentationConfigs(FileLine* fl, const string& instrumentationfunc,
|
||||
int instrID, const string& target) {
|
||||
V3ControlResolver::s().addInstrumentationConfigs(fl, instrumentationfunc, instrID, target);
|
||||
}
|
||||
|
||||
void V3Control::addProfileData(FileLine* fl, const string& hierDpi, uint64_t cost) {
|
||||
V3ControlResolver::s().addProfileData(fl, hierDpi, cost);
|
||||
}
|
||||
|
|
@ -810,6 +851,9 @@ int V3Control::getHierWorkers(const string& model) {
|
|||
FileLine* V3Control::getHierWorkersFileLine(const string& model) {
|
||||
return V3ControlResolver::s().getHierWorkersFileLine(model);
|
||||
}
|
||||
std::map<string, InstrumentationTarget, LengthThenLexiographic>& V3Control::getInstrumentationConfigs() {
|
||||
return V3ControlResolver::s().getInstrumentationConfigs();
|
||||
}
|
||||
uint64_t V3Control::getProfileData(const string& hierDpi) {
|
||||
return V3ControlResolver::s().getProfileData(hierDpi);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,31 @@
|
|||
#include "V3Mutex.h"
|
||||
|
||||
//######################################################################
|
||||
struct LengthThenLexiographic final {
|
||||
// Used to sort strings by length, then lexicographically
|
||||
bool operator()(const string& a, const string& b) const {
|
||||
if (a.length() != b.length()) return a.length() < b.length();
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
struct InstrumentationEntry final {
|
||||
int instrID;
|
||||
std::string instrFunc;
|
||||
std::string varTarget;
|
||||
AstVar* origVarps;
|
||||
AstVar* instrVarps;
|
||||
};
|
||||
struct InstrumentationTarget final {
|
||||
std::vector<InstrumentationEntry> entries;
|
||||
AstModule* origModulep;
|
||||
AstModule* instrModulep;
|
||||
AstModule* topModulep;
|
||||
AstModule* pointingModulep;
|
||||
AstCell* cellp;
|
||||
bool processed = false;
|
||||
bool done = false;
|
||||
bool multipleCellps = false;
|
||||
};
|
||||
|
||||
class V3Control final {
|
||||
public:
|
||||
|
|
@ -38,6 +63,9 @@ public:
|
|||
static void addIgnoreMatch(V3ErrorCode code, const string& filename, const string& contents,
|
||||
const string& match);
|
||||
static void addInline(FileLine* fl, const string& module, const string& ftask, bool on);
|
||||
static void addInstrumentationConfigs(FileLine* fl, const string& instrumentationfunc,
|
||||
int instrID, const string& target);
|
||||
static std::map<string, InstrumentationTarget, LengthThenLexiographic>& getInstrumentationConfigs();
|
||||
static void addModulePragma(const string& module, VPragmaType pragma);
|
||||
static void addProfileData(FileLine* fl, const string& hierDpi, uint64_t cost);
|
||||
static void addProfileData(FileLine* fl, const string& model, const string& key,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,33 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator:
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2025 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef VERILATOR_V3INSTRUMENTATION_H_
|
||||
#define VERILATOR_V3INSTRUMENTATION_H_
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
class AstNetlist;
|
||||
|
||||
//=========================================================================
|
||||
|
||||
class V3Instrumentation final {
|
||||
public:
|
||||
static void findTargets(AstNetlist* nodep) VL_MT_DISABLED;
|
||||
static void instrument(AstNetlist* nodep) VL_MT_DISABLED;
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
@ -1919,6 +1919,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
addIncDirUser(parseFileArg(optdir, string{valp}));
|
||||
});
|
||||
|
||||
DECL_OPTION("-instrument", OnOff, &m_instrument);
|
||||
|
||||
parser.finalize();
|
||||
|
||||
for (int i = 0; i < argc;) {
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ private:
|
|||
bool m_waiverMultiline = false; // main switch: --waiver-multiline
|
||||
bool m_xInitialEdge = false; // main switch: --x-initial-edge
|
||||
bool m_xmlOnly = false; // main switch: --xml-only
|
||||
bool m_instrument = false; // main switch: --instrument
|
||||
|
||||
int m_buildJobs = -1; // main switch: --build-jobs, -j
|
||||
int m_coverageExprMax = 32; // main switch: --coverage-expr-max
|
||||
|
|
@ -578,6 +579,7 @@ public:
|
|||
bool xmlOnly() const { return m_xmlOnly; }
|
||||
bool serializeOnly() const { return m_xmlOnly || m_jsonOnly; }
|
||||
bool topIfacesSupported() const { return lintOnly() && !hierarchical(); }
|
||||
bool instrument() const { return m_instrument; }
|
||||
|
||||
int buildJobs() const VL_MT_SAFE { return m_buildJobs; }
|
||||
int convergeLimit() const { return m_convergeLimit; }
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "V3HierBlock.h"
|
||||
#include "V3Inline.h"
|
||||
#include "V3Inst.h"
|
||||
#include "V3Instrumentation.h"
|
||||
#include "V3Interface.h"
|
||||
#include "V3Life.h"
|
||||
#include "V3LifePost.h"
|
||||
|
|
@ -151,6 +152,14 @@ static void process() {
|
|||
v3Global.vlExit(0);
|
||||
}
|
||||
|
||||
// Instrument Design with the configurations given in .vlt file
|
||||
if (v3Global.opt.instrument()) {
|
||||
v3Global.dpi(true);
|
||||
V3Instrumentation::findTargets(v3Global.rootp());
|
||||
V3Error::abortIfErrors();
|
||||
V3Instrumentation::instrument(v3Global.rootp());
|
||||
}
|
||||
|
||||
// Convert parseref's to varrefs, and other directly post parsing fixups
|
||||
V3LinkParse::linkParse(v3Global.rootp());
|
||||
// Cross-link signal names
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
"hier_params" { FL; return yVLT_HIER_PARAMS; }
|
||||
"hier_workers" { FL; return yVLT_HIER_WORKERS; }
|
||||
"inline" { FL; return yVLT_INLINE; }
|
||||
"instrument" { FL; return yVLT_INSTRUMENT; }
|
||||
"isolate_assignments" { FL; return yVLT_ISOLATE_ASSIGNMENTS; }
|
||||
"lint_off" { FL; return yVLT_LINT_OFF; }
|
||||
"lint_on" { FL; return yVLT_LINT_ON; }
|
||||
|
|
@ -149,6 +150,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
-?"-file" { FL; return yVLT_D_FILE; }
|
||||
-?"-function" { FL; return yVLT_D_FUNCTION; }
|
||||
-?"-hier-dpi" { FL; return yVLT_D_HIER_DPI; }
|
||||
-?"-id" { FL; return yVLT_D_ID; }
|
||||
-?"-instance" { FL; return yVLT_D_INSTANCE; }
|
||||
-?"-levels" { FL; return yVLT_D_LEVELS; }
|
||||
-?"-lines" { FL; return yVLT_D_LINES; }
|
||||
-?"-match" { FL; return yVLT_D_MATCH; }
|
||||
|
|
@ -157,6 +160,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
-?"-mtask" { FL; return yVLT_D_MTASK; }
|
||||
-?"-rule" { FL; return yVLT_D_RULE; }
|
||||
-?"-scope" { FL; return yVLT_D_SCOPE; }
|
||||
-?"-target" { FL; return yVLT_D_TARGET; }
|
||||
-?"-task" { FL; return yVLT_D_TASK; }
|
||||
-?"-var" { FL; return yVLT_D_VAR; }
|
||||
-?"-workers" { FL; return yVLT_D_WORKERS; }
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
|||
%token<fl> yVLT_HIER_PARAMS "hier_params"
|
||||
%token<fl> yVLT_HIER_WORKERS "hier_workers"
|
||||
%token<fl> yVLT_INLINE "inline"
|
||||
%token<fl> yVLT_INSTRUMENT "instrument"
|
||||
%token<fl> yVLT_ISOLATE_ASSIGNMENTS "isolate_assignments"
|
||||
%token<fl> yVLT_LINT_OFF "lint_off"
|
||||
%token<fl> yVLT_LINT_ON "lint_on"
|
||||
|
|
@ -276,6 +277,8 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
|||
%token<fl> yVLT_D_FILE "--file"
|
||||
%token<fl> yVLT_D_FUNCTION "--function"
|
||||
%token<fl> yVLT_D_HIER_DPI "--hier-dpi"
|
||||
%token<fl> yVLT_D_ID "--id"
|
||||
%token<fl> yVLT_D_INSTANCE "--instance"
|
||||
%token<fl> yVLT_D_LEVELS "--levels"
|
||||
%token<fl> yVLT_D_LINES "--lines"
|
||||
%token<fl> yVLT_D_MATCH "--match"
|
||||
|
|
@ -284,6 +287,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
|||
%token<fl> yVLT_D_MTASK "--mtask"
|
||||
%token<fl> yVLT_D_RULE "--rule"
|
||||
%token<fl> yVLT_D_SCOPE "--scope"
|
||||
%token<fl> yVLT_D_TARGET "--target"
|
||||
%token<fl> yVLT_D_TASK "--task"
|
||||
%token<fl> yVLT_D_VAR "--var"
|
||||
%token<fl> yVLT_D_WORKERS "--workers"
|
||||
|
|
@ -7995,6 +7999,8 @@ vltItem:
|
|||
{ /* Historical, now has no effect */ }
|
||||
| vltInlineFront vltDModuleE vltDFTaskE
|
||||
{ V3Control::addInline($<fl>1, *$2, *$3, $1); }
|
||||
| yVLT_INSTRUMENT yVLT_D_MODEL yaSTRING yVLT_D_ID yaINTNUM yVLT_D_TARGET yaSTRING
|
||||
{ V3Control::addInstrumentationConfigs($<fl>1, *$3, $5->toSInt(), *$7); }
|
||||
| yVLT_COVERAGE_BLOCK_OFF vltDFile
|
||||
{ V3Control::addCoverageBlockOff(*$2, 0); }
|
||||
| yVLT_COVERAGE_BLOCK_OFF vltDFile yVLT_D_LINES yaINTNUM
|
||||
|
|
|
|||
Loading…
Reference in New Issue