Working towards native Verilator replay without verilator_replay

This commit is contained in:
Todd Strader 2020-01-14 18:16:04 -05:00
parent 2c25c25379
commit fdef131113
6 changed files with 167 additions and 24 deletions

View File

@ -23,30 +23,24 @@
//=========================================================================
#include "verilated_replay.h"
// TODO -- can we not do this?
// Include the GTKWave implementation directly
#define FST_CONFIG_INCLUDE "fst_config.h"
#include "gtkwave/fastlz.c"
#include "gtkwave/fstapi.c"
// TODO -- use the system's LZ4 library, not this copy
#include "gtkwave/lz4.c"
#define QUOTE(x) #x
#define MAKE_HEADER(x) QUOTE(x.h)
#include MAKE_HEADER(VM_PREFIX)
// TODO -- collapse into constructor?
int VerilatedReplay::init() {
m_fstp = fstReaderOpen(m_fstName.c_str());
if (!m_fstp) {
// TODO -- Verilator runtime way of tossing a fatal error?, see elsewhere
VL_PRINTF("Could not open FST: %s\n", m_fstName.c_str());
exit(-1);
}
int VerilatedReplay::init(std::string scope) {
openFst(m_fstName);
search(scope);
m_time = fstReaderGetStartTime(m_fstp);
// TODO -- use FST timescale
m_simTime = m_time;
// TODO -- this is not right, just testing
fstReaderSetFacProcessMaskAll(m_fstp);
for (VarList::iterator it = m_inputs.begin(); it != m_inputs.end();
++it) {
VL_PRINTF("%s = %d\n", it->fullName.c_str(),
it->hier.u.var.handle);
fstReaderSetFacProcessMask(m_fstp, it->hier.u.var.handle);
}
createMod();
@ -160,10 +154,29 @@ void VerilatedReplay::fstCallback(void* userDatap, uint64_t time, fstHandle faci
uint32_t len;
if(valuep) {
len = strlen((const char *)valuep);
len = strlen((const char *)valuep);
} else {
len = 0;
len = 0;
}
fstCallbackVarlen(userDatap, time, facidx, valuep, len);
}
void VerilatedReplay::createMod() {
m_modp = new VM_PREFIX;
// TODO -- make VerilatedModule destructor virtual so we can delete from the base class?
}
void VerilatedReplay::eval() {
// TODO -- make eval, trace and final virtual methods of VerilatedModule?
reinterpret_cast<VM_PREFIX*>(m_modp)->eval();
}
void VerilatedReplay::trace() {
// TODO -- need VerilatedFstC, etc.
//reinterpret_cast<VM_PREFIX*>(m_modp)->trace();
}
void VerilatedReplay::final() {
reinterpret_cast<VM_PREFIX*>(m_modp)->final();
}

View File

@ -27,10 +27,11 @@
#define _VERILATED_REPLAY_H_ 1 ///< Header Guard
#include "verilated.h"
#include "verilated_replay_common.h"
#include "gtkwave/fstapi.h"
#include <string>
class VerilatedReplay {
class VerilatedReplay: private VerilatedReplayCommon {
private:
void createMod();
void eval();
@ -46,14 +47,13 @@ private:
std::string m_fstName;
double& m_simTime;
VerilatedModule* m_modp;
void* m_fstp;
uint64_t m_time;
public:
VerilatedReplay(const std::string& fstName, double& simTime):
m_fstName(fstName), m_simTime(simTime)
{}
~VerilatedReplay();
int init();
int init(std::string scope);
int replay();
};

View File

@ -0,0 +1,71 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Todd Strader. 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//=========================================================================
///
/// \file
/// \brief Verilator: Common replay code
///
/// See verilator_replay
///
/// Code available from: http://www.veripool.org/verilator
///
//=========================================================================
#include "verilated_replay_common.h"
using namespace std;
// TODO -- can we not do this?
// Include the GTKWave implementation directly
#define FST_CONFIG_INCLUDE "fst_config.h"
#include "gtkwave/fastlz.c"
#include "gtkwave/fstapi.c"
// TODO -- use the system's LZ4 library, not this copy
#include "gtkwave/lz4.c"
void VerilatedReplayCommon::openFst(const string& fstName) {
m_fstp = fstReaderOpen(fstName.c_str());
if (!m_fstp) {
// TODO -- Verilator runtime way of tossing a fatal error?, see elsewhere
VL_PRINTF("Could not open FST: %s\n", fstName.c_str());
exit(-1);
}
}
void VerilatedReplayCommon::search(string targetScope) {
const char* scope = "";
while (fstHier* hierp = fstReaderIterateHier(m_fstp)) {
if (hierp->htyp == FST_HT_SCOPE) {
scope = fstReaderPushScope(m_fstp, hierp->u.scope.name, NULL);
if (targetScope.empty()) targetScope = string(scope);
} else if (hierp->htyp == FST_HT_UPSCOPE) {
scope = fstReaderPopScope(m_fstp);
} else if (hierp->htyp == FST_HT_VAR) {
if (string(scope) == targetScope) {
string varName = string(scope) + "." + string(hierp->u.var.name);
switch (hierp->u.var.direction) {
case FST_VD_INPUT:
m_inputs.push_back(fstVar(hierp, varName));
break;
case FST_VD_OUTPUT:
m_outputs.push_back(fstVar(hierp, varName));
break;
default: break;
}
}
}
}
}

View File

@ -0,0 +1,56 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Todd Strader. 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//=========================================================================
///
/// \file
/// \brief Verilator: Include for common replay code
///
/// See verilator_replay
///
/// Code available from: http://www.veripool.org/verilator
///
//=========================================================================
#ifndef _VERILATED_REPLAY_COMMON_H_
#define _VERILATED_REPLAY_COMMON_H_ 1 ///< Header Guard
#include "verilated.h"
#include "gtkwave/fstapi.h"
#include <string>
#include <list>
class VerilatedReplayCommon {
public:
struct fstVar {
struct fstHier hier;
std::string fullName;
fstVar(struct fstHier* _hierp, std::string _fullName):
hier(*_hierp), fullName(_fullName) {}
};
typedef std::list<const fstVar> VarList;
protected:
void* m_fstp;
VarList m_inputs;
VarList m_outputs;
public:
VerilatedReplayCommon() {}
~VerilatedReplayCommon() {}
void openFst(const std::string& fstName);
void search(std::string targetScope);
VarList& inputs() { return m_inputs; }
VarList& outputs() { return m_outputs; }
};
#endif // Guard

View File

@ -53,10 +53,12 @@ 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()) exit(-1);
if (replay.init(scope)) exit(-1);
//#if VM_TRACE
// Verilated::traceEverOn(true);

View File

@ -10,6 +10,7 @@
// TODO -- use the system's LZ4 library, not this copy
#include "gtkwave/lz4.c"
// TODO -- use verilator_replay_common.h instead
void VlrGenerator::getFstIO() {
void* fst = fstReaderOpen(opts().fst());
const char* scope = "";