verilator/include/verilated_replay_common.cpp
2020-01-18 16:17:41 -05:00

84 lines
3.1 KiB
C++

// -*- 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"
#include <iostream>
using namespace std;
// TODO -- can we not do this?
// Include the GTKWave implementation directly
// Ugh, building with verilated_fst_c.cpp, brings this in, let's really not do this
//#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 -- a better way to fatal in either Verilator or in the runtime?
cout<<"Could not open FST: "<<fstName<<endl;
exit(-1);
}
}
void VerilatedReplayCommon::searchFst(const string& targetScope) {
const char* scope = "";
string searchScope(targetScope);
while (fstHier* hierp = fstReaderIterateHier(m_fstp)) {
if (hierp->htyp == FST_HT_SCOPE) {
scope = fstReaderPushScope(m_fstp, hierp->u.scope.name, NULL);
// 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) {
switch (hierp->u.var.direction) {
case FST_VD_INPUT:
m_inputs[hierp->u.var.handle] =
fstVar(hierp, varName);
break;
case FST_VD_OUTPUT:
m_outputs[hierp->u.var.handle] =
fstVar(hierp, varName);
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);
}
}
}
}