forked from github/verilator
WIP - Add verilator_replay utility
This commit is contained in:
parent
18e837336a
commit
2c25c25379
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,6 +29,7 @@ internals.txt
|
||||
verilator.txt
|
||||
verilator_bin*
|
||||
verilator_coverage_bin*
|
||||
verilator_replay_bin*
|
||||
verilator.pc
|
||||
verilator-config.cmake
|
||||
verilator-config-version.cmake
|
||||
|
22
Vt_case_reducer_replay_mock.cpp
Normal file
22
Vt_case_reducer_replay_mock.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
// TODO -- will be generated by verilator_replay -- DO NOT PUSH UPSTREAM
|
||||
#include "Vt_case_reducer.h"
|
||||
#include "verilated_replay.h"
|
||||
|
||||
void VerilatedReplay::createMod() {
|
||||
m_modp = new Vt_case_reducer;
|
||||
// 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<Vt_case_reducer*>(m_modp)->eval();
|
||||
}
|
||||
|
||||
void VerilatedReplay::trace() {
|
||||
// TODO -- need VerilatedFstC, etc.
|
||||
//reinterpret_cast<Vt_case_reducer*>(m_modp)->trace();
|
||||
}
|
||||
|
||||
void VerilatedReplay::final() {
|
||||
reinterpret_cast<Vt_case_reducer*>(m_modp)->final();
|
||||
}
|
169
include/verilated_replay.cpp
Normal file
169
include/verilated_replay.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
// -*- 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 functions for replay tool
|
||||
///
|
||||
/// See verilator_replay
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
#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"
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
m_time = fstReaderGetStartTime(m_fstp);
|
||||
// TODO -- use FST timescale
|
||||
m_simTime = m_time;
|
||||
|
||||
// TODO -- this is not right, just testing
|
||||
fstReaderSetFacProcessMaskAll(m_fstp);
|
||||
|
||||
createMod();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VerilatedReplay::~VerilatedReplay() {
|
||||
fstReaderClose(m_fstp);
|
||||
delete(m_modp);
|
||||
}
|
||||
|
||||
//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) {
|
||||
// if (signalName == (*it)->reference) {
|
||||
// VerilatedReplaySignal* signalp = new VerilatedReplaySignal;
|
||||
// signalp->dutSignal = dutSignal;
|
||||
// signalp->bits = bits;
|
||||
// signalp->hash = (*it)->hash;
|
||||
//
|
||||
// if ((*it)->size != bits) {
|
||||
// VL_PRINTF("Error size mismatch on %s: trace=%d design=%d\n",
|
||||
// signalName.c_str(), (*it)->size, bits);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// if ((*it)->type != VCD_VAR_REG && (*it)->type != VCD_VAR_WIRE) {
|
||||
// VL_PRINTF("Error unsupported signal type on %s\n", signalName.c_str());
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// m_inputs.push_back(signalp);
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
// VL_PRINTF("Error finding signal (%s)\n", signalName.c_str());
|
||||
// return -1;
|
||||
//}
|
||||
//
|
||||
//void VerilatedReplay::copySignal(uint8_t* signal, VCDValue* valuep) {
|
||||
// VCDValueType type = valuep->get_type();
|
||||
// switch(type) {
|
||||
// case VCD_SCALAR: {
|
||||
// copySignalBit(signal, 0, valuep->get_value_bit());
|
||||
// break;
|
||||
// }
|
||||
// case VCD_VECTOR: {
|
||||
// VCDBitVector* bitVector = valuep->get_value_vector();
|
||||
// unsigned length = bitVector->size();
|
||||
// for (int i = 0; i < length; ++i) {
|
||||
// copySignalBit(signal, i, bitVector->at(length - i - 1));
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// default: {
|
||||
// VL_PRINTF("Error unsupported VCD value type");
|
||||
// exit(-1);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void VerilatedReplay::copySignalBit(uint8_t* signal, unsigned offset, VCDBit bit) {
|
||||
// unsigned byte = offset / 8;
|
||||
// unsigned byteOffset = offset % 8;
|
||||
// // TODO - more efficient byte copying
|
||||
// signal[byte] &= ~(0x1 << byteOffset);
|
||||
// // TODO - x's and z's?
|
||||
// signal[byte] |= (bit == VCD_1 ? 0x1 : 0x0) << byteOffset;
|
||||
//}
|
||||
|
||||
int VerilatedReplay::replay() {
|
||||
// TODO -- lockless ring buffer for separate reader/replay threads
|
||||
// TODO -- should I be using fstReaderIterBlocks instead? (only one CB)
|
||||
// It appears that 0 is the error return code
|
||||
if (fstReaderIterBlocks2(m_fstp, &VerilatedReplay::fstCallback,
|
||||
&VerilatedReplay::fstCallbackVarlen, this, NULL) == 0) {
|
||||
VL_PRINTF("Error iterating FST\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// One final eval + trace since we only eval on time changes
|
||||
eval();
|
||||
trace();
|
||||
final();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VerilatedReplay::fstCb(uint64_t time, fstHandle facidx,
|
||||
const unsigned char* valuep, uint32_t len) {
|
||||
// Watch for new time steps and eval before we start working on the new time
|
||||
if (m_time != time) {
|
||||
eval();
|
||||
trace();
|
||||
m_time = time;
|
||||
// TODO -- use FST timescale
|
||||
m_simTime = m_time;
|
||||
}
|
||||
|
||||
VL_PRINTF("%lu %u %s\n", time, facidx, valuep);
|
||||
}
|
||||
|
||||
void VerilatedReplay::fstCallbackVarlen(void* userDatap, uint64_t time, fstHandle facidx,
|
||||
const unsigned char* valuep, uint32_t len) {
|
||||
reinterpret_cast<VerilatedReplay*>(userDatap)->fstCb(time, facidx, valuep, len);
|
||||
}
|
||||
|
||||
void VerilatedReplay::fstCallback(void* userDatap, uint64_t time, fstHandle facidx,
|
||||
const unsigned char* valuep) {
|
||||
// Cribbed from fstminer.c in the gtkwave repo
|
||||
uint32_t len;
|
||||
|
||||
if(valuep) {
|
||||
len = strlen((const char *)valuep);
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
fstCallbackVarlen(userDatap, time, facidx, valuep, len);
|
||||
}
|
60
include/verilated_replay.h
Normal file
60
include/verilated_replay.h
Normal file
@ -0,0 +1,60 @@
|
||||
// -*- 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 replay tool
|
||||
///
|
||||
/// See verilator_replay
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
|
||||
#ifndef _VERILATED_REPLAY_H_
|
||||
#define _VERILATED_REPLAY_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilated.h"
|
||||
#include "gtkwave/fstapi.h"
|
||||
#include <string>
|
||||
|
||||
class VerilatedReplay {
|
||||
private:
|
||||
void createMod();
|
||||
void eval();
|
||||
void trace();
|
||||
void final();
|
||||
void fstCb(uint64_t time, fstHandle facidx, const unsigned char* value,
|
||||
uint32_t len);
|
||||
static void fstCallback(void* userData, uint64_t time, fstHandle facidx,
|
||||
const unsigned char* value);
|
||||
static void fstCallbackVarlen(void* userData, uint64_t time, fstHandle facidx,
|
||||
const unsigned char* value, uint32_t len);
|
||||
|
||||
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 replay();
|
||||
};
|
||||
|
||||
#endif // Guard
|
76
include/verilated_replay_main.cpp
Normal file
76
include/verilated_replay_main.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
// -*- 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: Main used by verilator_replay
|
||||
///
|
||||
/// This utility will replay trace files onto a verilated design.
|
||||
/// It is inteded to be used in conjunction with verilator_replay.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
|
||||
#include "verilated_replay.h"
|
||||
|
||||
double simTime = 0;
|
||||
double sc_time_stamp() {
|
||||
return simTime;
|
||||
}
|
||||
|
||||
// TODO -- should we make eval, final and trace(?) part of VerilatedModule?
|
||||
// TODO -- generate this part
|
||||
//#include "Vt_case_reducer.h"
|
||||
//Vt_case_reducer* dutp = NULL;
|
||||
//VerilatedVcdC* tfp = NULL;
|
||||
//void VerilatedReplay::eval() {
|
||||
// dutp->eval();
|
||||
//}
|
||||
//
|
||||
//void VerilatedReplay::trace() {
|
||||
//#if VM_TRACE
|
||||
// if (tfp) tfp->dump(simTime);
|
||||
//#endif // VM_TRACE
|
||||
//}
|
||||
//
|
||||
//void VerilatedReplay::final() {
|
||||
// dutp->final();
|
||||
//}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// TODO -- actual arg parsing
|
||||
std::string fstFilename(argv[1]);
|
||||
VL_PRINTF("FST = %s\n", fstFilename.c_str());
|
||||
|
||||
VerilatedReplay replay(fstFilename, simTime);
|
||||
if (replay.init()) exit(-1);
|
||||
|
||||
//#if VM_TRACE
|
||||
// Verilated::traceEverOn(true);
|
||||
// tfp = new VerilatedFstC;
|
||||
// dutp->trace(tfp, 99);
|
||||
// tfp->open("replay.fst");
|
||||
// if (tfp) tfp->dump(simTime);
|
||||
//#endif // VM_TRACE
|
||||
|
||||
if (replay.replay()) exit(-1);
|
||||
|
||||
//#if VM_TRACE
|
||||
// if (tfp) tfp->close();
|
||||
//#endif // VM_TRACE
|
||||
|
||||
return 0;
|
||||
}
|
@ -64,7 +64,7 @@ else
|
||||
$(MAKE) -C obj_opt TGT=../$@ -f ../Makefile_obj
|
||||
endif
|
||||
|
||||
dbg: ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
|
||||
dbg: ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg ../bin/verilator_replay_bin_dbg
|
||||
../bin/verilator_bin_dbg: obj_dbg ../bin prefiles
|
||||
$(MAKE) -C obj_dbg -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
|
||||
$(MAKE) -C obj_dbg TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
|
||||
@ -73,6 +73,9 @@ dbg: ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
|
||||
$(MAKE) -C obj_dbg TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj serial_vlcov
|
||||
$(MAKE) -C obj_dbg TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj
|
||||
|
||||
../bin/verilator_replay_bin_dbg: obj_dbg ../bin prefiles
|
||||
$(MAKE) -C obj_dbg TGT=../$@ VL_DEBUG=1 VL_VLREPLAY=1 -f ../Makefile_obj
|
||||
|
||||
prefiles::
|
||||
prefiles:: config_rev.h
|
||||
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
|
||||
|
@ -256,14 +256,28 @@ NC_OBJS += \
|
||||
VLCOV_OBJS = \
|
||||
VlcMain.o \
|
||||
|
||||
# verilator_replay
|
||||
VLREPLAY_OBJS = \
|
||||
V3Error.o \
|
||||
VlrOptions.o \
|
||||
VlrGenerator.o \
|
||||
VlrMain.o \
|
||||
|
||||
#### Linking
|
||||
|
||||
ifeq ($(VL_VLCOV),)
|
||||
PREDEP_H = V3Ast__gen_classes.h
|
||||
OBJS += $(RAW_OBJS) $(NC_OBJS)
|
||||
else
|
||||
ifneq ($(VL_VLCOV),)
|
||||
PREDEP_H =
|
||||
OBJS += $(VLCOV_OBJS)
|
||||
else ifneq ($(VL_VLREPLAY),)
|
||||
PREDEP_H =
|
||||
OBJS += $(VLREPLAY_OBJS)
|
||||
# TODO -- do we already search for this in configure?
|
||||
LIBS += -lz
|
||||
# TODO -- do this for verilator_coverage as well
|
||||
CXXFLAGS += -D_V3ERROR_NO_GLOBAL_=1
|
||||
else
|
||||
PREDEP_H = V3Ast__gen_classes.h
|
||||
OBJS += $(RAW_OBJS) $(NC_OBJS)
|
||||
endif
|
||||
|
||||
V3__CONCAT.cpp: $(addsuffix .cpp, $(basename $(RAW_OBJS)))
|
||||
|
47
src/VlrGenerator.cpp
Normal file
47
src/VlrGenerator.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "VlrGenerator.h"
|
||||
#include "V3Error.h"
|
||||
#include "gtkwave/fstapi.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"
|
||||
|
||||
void VlrGenerator::getFstIO() {
|
||||
void* fst = fstReaderOpen(opts().fst());
|
||||
const char* scope = "";
|
||||
string targetScope;
|
||||
if (m_opts.scope()) targetScope = string(m_opts.scope());
|
||||
|
||||
while (struct fstHier* hier = fstReaderIterateHier(fst)) {
|
||||
if (hier->htyp == FST_HT_SCOPE) {
|
||||
scope = fstReaderPushScope(fst, hier->u.scope.name, NULL);
|
||||
if (targetScope.empty()) targetScope = string(scope);
|
||||
UINFO(3, "SCOPE "<<scope<<endl);
|
||||
} else if (hier->htyp == FST_HT_UPSCOPE) {
|
||||
scope = fstReaderPopScope(fst);
|
||||
UINFO(3, "UPSCOPE "<<scope<<endl);
|
||||
} else if (hier->htyp == FST_HT_VAR) {
|
||||
if (string(scope) == targetScope) {
|
||||
string varName = string(scope) + "." + string(hier->u.var.name);
|
||||
switch (hier->u.var.direction) {
|
||||
case FST_VD_INPUT:
|
||||
UINFO(3, "VAR input "<<hier->u.var.name<<endl);
|
||||
m_inputs.push_back(varName);
|
||||
break;
|
||||
case FST_VD_OUTPUT:
|
||||
UINFO(3, "VAR output "<<hier->u.var.name<<endl);
|
||||
m_outputs.push_back(varName);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VlrGenerator::emitVltCode() {
|
||||
}
|
45
src/VlrGenerator.h
Normal file
45
src/VlrGenerator.h
Normal file
@ -0,0 +1,45 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: verilator_replay: Replay code generator
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 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.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _VLRGENERATOR_H_
|
||||
#define _VLRGENERATOR_H_ 1
|
||||
|
||||
#include "VlrOptions.h"
|
||||
#include <list>
|
||||
|
||||
class VlrGenerator {
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VlrGenerator() {}
|
||||
~VlrGenerator() {}
|
||||
|
||||
// METHODS
|
||||
VlrOptions& opts() { return m_opts; }
|
||||
void getFstIO();
|
||||
void emitVltCode();
|
||||
private:
|
||||
typedef std::list<std::string> StrList;
|
||||
|
||||
VlrOptions m_opts;
|
||||
StrList m_inputs;
|
||||
StrList m_outputs;
|
||||
};
|
||||
|
||||
#endif // guard
|
43
src/VlrMain.cpp
Normal file
43
src/VlrMain.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: verilator_replay: main()
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 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.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "VlrGenerator.h"
|
||||
#include "V3Error.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
VlrGenerator gen;
|
||||
|
||||
// Parse command line options
|
||||
gen.opts().parseOptsList(argc-1, argv+1);
|
||||
|
||||
// Read signals from FST or signals file
|
||||
if (gen.opts().fst()) {
|
||||
gen.getFstIO();
|
||||
}
|
||||
// TODO -- manually specified lists
|
||||
// TODO -- check for none of the above
|
||||
|
||||
// Emit replay code
|
||||
if (gen.opts().vlt()) {
|
||||
gen.emitVltCode();
|
||||
}
|
||||
// TODO -- DPI and/or VPI wrappers
|
||||
// TODO -- check no emitters
|
||||
}
|
111
src/VlrOptions.cpp
Normal file
111
src/VlrOptions.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: verilator_replay: Command line options
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 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.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "VlrOptions.h"
|
||||
#include "config_build.h"
|
||||
#include "config_rev.h"
|
||||
#include "V3Error.h"
|
||||
|
||||
void VlrOptions::parseOptsList(int argc, char** argv) {
|
||||
// Parse parameters
|
||||
// Note argc and argv DO NOT INCLUDE the filename in [0]!!!
|
||||
for (int i=0; i<argc; ) {
|
||||
UINFO(9, " Option: "<<argv[i]<<endl);
|
||||
if (argv[i][0]=='-') {
|
||||
const char* sw = argv[i];
|
||||
bool flag = true;
|
||||
// Allow gnu -- switches
|
||||
if (sw[0]=='-' && sw[1]=='-') ++sw;
|
||||
if (0) {} // TODO -- just to avoid the asymetry of one "if"?
|
||||
// Single switches
|
||||
else if (onoff (sw, "-vlt", flag/*ref*/) ) { m_vlt = flag; }
|
||||
//// Parameterized switches
|
||||
else if (!strcmp(sw, "-debug") ) {
|
||||
V3Error::debugDefault(3);
|
||||
}
|
||||
else if (!strcmp(sw, "-debugi") && (i+1)<argc ) {
|
||||
++i;
|
||||
V3Error::debugDefault(atoi(argv[i]));
|
||||
}
|
||||
else if (!strcmp(sw, "-fst") && (i+1)<argc ) {
|
||||
++i;
|
||||
m_fst = argv[i];
|
||||
}
|
||||
else if (!strcmp(sw, "-scope") && (i+1)<argc ) {
|
||||
++i;
|
||||
m_scope = argv[i];
|
||||
}
|
||||
else if (!strcmp(sw, "-V") ) {
|
||||
showVersion(true);
|
||||
exit(0);
|
||||
}
|
||||
else if (!strcmp(sw, "-version") ) {
|
||||
showVersion(false);
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
v3fatal("Invalid option: "<<argv[i]);
|
||||
}
|
||||
++i;
|
||||
} // - options
|
||||
//else if (1) {
|
||||
// addReadFile(argv[i]);
|
||||
// ++i;
|
||||
//}
|
||||
else {
|
||||
v3fatal("Invalid argument: "<<argv[i]);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VlrOptions::showVersion(bool verbose) {
|
||||
cout <<version();
|
||||
cout <<endl;
|
||||
if (!verbose) return;
|
||||
|
||||
cout <<endl;
|
||||
cout << "Copyright 2020 by Todd Strader. Verilator is free software; you can\n";
|
||||
cout << "redistribute it and/or modify the Verilator internals under the terms of\n";
|
||||
cout << "either the GNU Lesser General Public License Version 3 or the Perl Artistic\n";
|
||||
cout << "License Version 2.0.\n";
|
||||
|
||||
cout <<endl;
|
||||
cout << "See https://verilator.org for documentation\n";
|
||||
}
|
||||
|
||||
string VlrOptions::version() {
|
||||
string ver = DTVERSION;
|
||||
ver += " rev "+cvtToStr(DTVERSION_rev);
|
||||
return ver;
|
||||
}
|
||||
|
||||
// TODO -- Shared with Verilator too? Refactor into some common code.
|
||||
bool VlrOptions::onoff(const char* sw, const char* arg, bool& flag) {
|
||||
// if sw==arg, then return true (found it), and flag=true
|
||||
// if sw=="-no-arg", then return true (found it), and flag=false
|
||||
// if sw=="-noarg", then return true (found it), and flag=false
|
||||
// else return false
|
||||
if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash.");
|
||||
if (0==strcmp(sw, arg)) { flag = true; return true; }
|
||||
else if (0==strncmp(sw, "-no", 3) && (0==strcmp(sw+3, arg+1))) { flag = false; return true; }
|
||||
else if (0==strncmp(sw, "-no-", 4) && (0==strcmp(sw+4, arg+1))) { flag = false; return true; }
|
||||
return false;
|
||||
}
|
50
src/VlrOptions.h
Normal file
50
src/VlrOptions.h
Normal file
@ -0,0 +1,50 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: verilator_replay: Command line options
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 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.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _VLROPTIONS_H_
|
||||
#define _VLROPTIONS_H_ 1
|
||||
|
||||
#include <string>
|
||||
|
||||
class VlrOptions {
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VlrOptions():
|
||||
m_fst(NULL), m_scope(NULL), m_vlt(false)
|
||||
{}
|
||||
~VlrOptions() {}
|
||||
|
||||
// METHODS
|
||||
void parseOptsList(int argc, char** argv);
|
||||
|
||||
const char* fst() { return m_fst; }
|
||||
const char* scope() { return m_scope; }
|
||||
bool vlt() { return m_vlt; }
|
||||
private:
|
||||
void showVersion(bool version);
|
||||
std::string version();
|
||||
bool onoff(const char* sw, const char* arg, bool& flag);
|
||||
|
||||
const char* m_fst;
|
||||
const char* m_scope;
|
||||
bool m_vlt;
|
||||
};
|
||||
|
||||
#endif // guard
|
@ -10,6 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--trace-fst"], # TODO -- remove and make independent test
|
||||
);
|
||||
|
||||
execute(
|
||||
|
@ -3,6 +3,9 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2012 by Wilson Snyder.
|
||||
|
||||
// TODO -- don't hijack this test
|
||||
`ifndef REPLAY_HACK
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
@ -64,6 +67,8 @@ module t (/*AUTOARG*/
|
||||
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
||||
module Test
|
||||
(
|
||||
// Inputs
|
||||
|
Loading…
Reference in New Issue
Block a user