Connecting more dots

This commit is contained in:
Todd Strader 2020-01-18 10:51:35 -05:00
parent d8b75fa352
commit 12716bd1e8
6 changed files with 61 additions and 22 deletions

View File

@ -23,14 +23,18 @@
//=========================================================================
#include "verilated_replay.h"
#define QUOTE(x) #x
#define MAKE_HEADER(x) QUOTE(x.h)
#include MAKE_HEADER(VM_PREFIX)
// TODO -- collapse into constructor?
int VerilatedReplay::init(std::string scope) {
int VerilatedReplay::init() {
addSignals();
for (SignalNameMap::iterator it = m_inputNames.begin(); it != m_inputNames.end(); ++it) {
addInputName(it->first);
}
for (SignalNameMap::iterator it = m_outputNames.begin(); it != m_outputNames.end(); ++it) {
addOutputName(it->first);
}
openFst(m_fstName);
search(scope);
searchFst("");
m_time = fstReaderGetStartTime(m_fstp);
// TODO -- use FST timescale
m_simTime = m_time;
@ -39,8 +43,9 @@ int VerilatedReplay::init(std::string scope) {
++it) {
VL_PRINTF("%s = %d\n", it->second.fullName.c_str(), it->first);
fstReaderSetFacProcessMask(m_fstp, it->first);
m_signals[it->first] = FstSignal(it->second.hier.u.var.length,
reinterpret_cast<VM_PREFIX*>(m_modp)->??);
// TODO -- double check the size hasn't changed
m_inputHandles[it->first] = FstSignal(it->second.hier.u.var.length,
m_inputNames[it->second.fullName].signal);
}
createMod();
@ -56,6 +61,14 @@ VerilatedReplay::~VerilatedReplay() {
delete(m_modp);
}
void VerilatedReplay::addInput(const std::string& fullName, vluint8_t* signal, size_t size) {
m_inputNames[fullName] = FstSignal(size, signal);
}
void VerilatedReplay::addOutput(const std::string& fullName, vluint8_t* signal, size_t size) {
m_outputNames[fullName] = FstSignal(size, signal);
}
//int VerilatedReplay::addInput(const std::string& signalName, void* dutSignal, unsigned bits) {
// for (std::vector<VCDSignal*>::iterator it = m_scopep->signals.begin();
// it != m_scopep->signals.end(); ++it) {
@ -174,7 +187,7 @@ void VerilatedReplay::createMod() {
#if VM_TRACE
Verilated::traceEverOn(true);
m_tfp = new VerilatedFstC;
reinterpret_cast<VM_PREFIX*>(m_modp)->trace(m_tfp, 99);
m_modp->trace(m_tfp, 99);
// TODO -- command line parameter
m_tfp->open("replay.fst");
#endif // VM_TRACE
@ -182,15 +195,16 @@ void VerilatedReplay::createMod() {
void VerilatedReplay::eval() {
// TODO -- make eval, trace and final virtual methods of VerilatedModule?
reinterpret_cast<VM_PREFIX*>(m_modp)->eval();
m_modp->eval();
}
void VerilatedReplay::trace() {
#if VM_TRACE
// TODO -- make this optional
if (m_tfp) m_tfp->dump(m_simTime);
#endif // VM_TRACE
}
void VerilatedReplay::final() {
reinterpret_cast<VM_PREFIX*>(m_modp)->final();
m_modp->final();
}

View File

@ -33,15 +33,26 @@
#include <string>
#include <map>
#define QUOTE(x) #x
#define MAKE_HEADER(x) QUOTE(x.h)
#include MAKE_HEADER(VM_PREFIX)
class VerilatedReplay: private VerilatedReplayCommon {
private:
struct FstSignal {
size_t bits;
vluint8_t* signal;
FstSignal() {}
FstSignal(size_t _bits, vluint8_t* _signal):
bits(_bits), signal(_signal) { }
};
typedef std::map<fstHandle, FstSignal> SignalMap;
typedef std::map<fstHandle, FstSignal> SignalHandleMap;
typedef std::map<std::string, FstSignal> SignalNameMap;
void createMod();
void addSignals();
void addInput(const std::string& fullName, vluint8_t* signal, size_t size);
void addOutput(const std::string& fullName, vluint8_t* signal, size_t size);
void eval();
void trace();
void final();
@ -54,16 +65,19 @@ private:
std::string m_fstName;
double& m_simTime;
VerilatedModule* m_modp;
VM_PREFIX* m_modp;
VerilatedFstC* m_tfp;
uint64_t m_time;
SignalMap m_signals;
SignalHandleMap m_inputHandles;
SignalHandleMap m_outputHandles;
SignalNameMap m_inputNames;
SignalNameMap m_outputNames;
public:
VerilatedReplay(const std::string& fstName, double& simTime):
m_fstName(fstName), m_simTime(simTime)
{}
~VerilatedReplay();
int init(std::string scope);
int init();
int replay();
};

View File

@ -53,12 +53,15 @@ void VerilatedReplayCommon::searchFst(const string& targetScope) {
while (fstHier* hierp = fstReaderIterateHier(m_fstp)) {
if (hierp->htyp == FST_HT_SCOPE) {
scope = fstReaderPushScope(m_fstp, hierp->u.scope.name, NULL);
if (searchScope.empty()) searchScope = string(scope);
// Just take the top scope if nothing else has been specified
if (searchScope.empty() && m_inputNames.empty() && m_outputNames.empty())
searchScope = string(scope);
} else if (hierp->htyp == FST_HT_UPSCOPE) {
scope = fstReaderPopScope(m_fstp);
} else if (hierp->htyp == FST_HT_VAR) {
string varName = string(scope) + "." + string(hierp->u.var.name);
if (string(scope) == searchScope) {
string varName = string(scope) + "." + string(hierp->u.var.name);
switch (hierp->u.var.direction) {
case FST_VD_INPUT:
m_inputs[hierp->u.var.handle] =
@ -70,6 +73,10 @@ void VerilatedReplayCommon::searchFst(const string& targetScope) {
break;
default: break;
}
} else if (m_inputNames.find(varName) != m_inputNames.end()) {
m_inputs[hierp->u.var.handle] = fstVar(hierp, varName);
} else if (m_outputNames.find(varName) != m_outputNames.end()) {
m_outputs[hierp->u.var.handle] = fstVar(hierp, varName);
}
}
}

View File

@ -29,6 +29,7 @@
#include "gtkwave/fstapi.h"
#include <string>
#include <map>
#include <unordered_set>
class VerilatedReplayCommon {
public:
@ -46,11 +47,15 @@ protected:
void* m_fstp;
VarMap m_inputs;
VarMap m_outputs;
std::unordered_set<std::string> m_inputNames;
std::unordered_set<std::string> m_outputNames;
public:
VerilatedReplayCommon() {}
~VerilatedReplayCommon() {}
void openFst(const std::string& fstName);
void searchFst(const std::string& targetScope);
void addInputName(const std::string& name) { m_inputNames.insert(name); }
void addOutputName(const std::string& name) { m_outputNames.insert(name); }
};
#endif // Guard

View File

@ -53,12 +53,10 @@ double sc_time_stamp() {
int main(int argc, char** argv) {
// TODO -- actual arg parsing
std::string fstFilename(argv[1]);
std::string scope(argv[2]);
VL_PRINTF("FST = %s\n", fstFilename.c_str());
VL_PRINTF("Scope = %s\n", scope.c_str());
VerilatedReplay replay(fstFilename, simTime);
if (replay.init(scope)) exit(-1);
if (replay.init()) exit(-1);
//#if VM_TRACE
// Verilated::traceEverOn(true);

View File

@ -11,7 +11,7 @@ void VlrGenerator::emitVltCode() {
// TODO -- use V3OutCFile
cout << "#include \"verilated_replay.h\"" << endl;
cout << endl;
cout << "void VerilatedReplay() {" << endl;
cout << "void VerilatedReplay::addSignals() {" << endl;
for (VarMap::iterator it = m_inputs.begin(); it != m_inputs.end(); ++it) {
string sigName(it->second.fullName);
@ -30,8 +30,9 @@ void VlrGenerator::emitVltCode() {
// TODO -- need to be able to specify a new top level
cout << " addInput(\"" << it->second.fullName <<
"\", reinterpret_cast<VM_PREFIX*>(m_modp)->" << sigName <<
", " << it->second.hier.u.var.length << ");" << endl;
"\", &(m_modp->" << sigName <<
"), " << it->second.hier.u.var.length << ");" << endl;
// TODO -- sizof check (FST vs VLT)
}
cout << "}" << endl;
}