read_vcd
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
28c6d82b8b
commit
20ed9e5537
|
|
@ -40,6 +40,11 @@ class VcdValue;
|
||||||
typedef vector<VcdValue> VcdValues;
|
typedef vector<VcdValue> VcdValues;
|
||||||
typedef int64_t VarTime;
|
typedef int64_t VarTime;
|
||||||
|
|
||||||
|
// Very imprecise syntax definition
|
||||||
|
// https://en.wikipedia.org/wiki/Value_change_dump#Structure.2FSyntax
|
||||||
|
// Much better syntax definition
|
||||||
|
// https://web.archive.org/web/20120323132708/http://www.beyondttl.com/vcd.php
|
||||||
|
|
||||||
class VcdReader : public StaState
|
class VcdReader : public StaState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -52,7 +57,6 @@ private:
|
||||||
void parseVar();
|
void parseVar();
|
||||||
void parseScope();
|
void parseScope();
|
||||||
void parseUpscope();
|
void parseUpscope();
|
||||||
void parseDumpvars();
|
|
||||||
void parseVarValues();
|
void parseVarValues();
|
||||||
void makeVarIdMap();
|
void makeVarIdMap();
|
||||||
void appendVarValue(string id,
|
void appendVarValue(string id,
|
||||||
|
|
@ -149,28 +153,33 @@ VcdReader::read(const char *filename)
|
||||||
while (!token.empty()) {
|
while (!token.empty()) {
|
||||||
if (token == "$date")
|
if (token == "$date")
|
||||||
date_ = readStmtString();
|
date_ = readStmtString();
|
||||||
if (token == "$comment")
|
else if (token == "$comment")
|
||||||
comment_ = readStmtString();
|
comment_ = readStmtString();
|
||||||
else if (token == "$version")
|
else if (token == "$version")
|
||||||
version_ = readStmtString();
|
version_ = readStmtString();
|
||||||
else if (token == "$timescale")
|
else if (token == "$timescale")
|
||||||
parseTimescale();
|
parseTimescale();
|
||||||
if (token == "$var")
|
else if (token == "$var")
|
||||||
parseVar();
|
parseVar();
|
||||||
else if (token == "$scope")
|
else if (token == "$scope")
|
||||||
parseScope();
|
parseScope();
|
||||||
else if (token == "$upscope")
|
else if (token == "$upscope")
|
||||||
parseUpscope();
|
parseUpscope();
|
||||||
else if (token == "$dumpvars")
|
|
||||||
parseDumpvars();
|
|
||||||
else if (token == "$enddefinitions") {
|
else if (token == "$enddefinitions") {
|
||||||
// empty body
|
// empty body
|
||||||
readStmtString();
|
readStmtString();
|
||||||
makeVarIdMap();
|
makeVarIdMap();
|
||||||
parseVarValues();
|
|
||||||
}
|
}
|
||||||
|
else if (token == "$dumpall")
|
||||||
|
parseVarValues();
|
||||||
|
else if (token == "$dumpvars")
|
||||||
|
// Initial values.
|
||||||
|
parseVarValues();
|
||||||
|
else if (token[0] == '$')
|
||||||
|
report_->fileError(800, filename_, stmt_line_, "unhandled vcd command.");
|
||||||
|
else
|
||||||
|
parseVarValues();
|
||||||
token = getToken();
|
token = getToken();
|
||||||
|
|
||||||
}
|
}
|
||||||
gzclose(stream_);
|
gzclose(stream_);
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +247,7 @@ VcdReader::parseVar()
|
||||||
// iverilog separates bus base name from bit range.
|
// iverilog separates bus base name from bit range.
|
||||||
if (tokens.size() == 5)
|
if (tokens.size() == 5)
|
||||||
name += tokens[4];
|
name += tokens[4];
|
||||||
|
|
||||||
vars_.push_back(VcdVar(name, type, width, id));
|
vars_.push_back(VcdVar(name, type, width, id));
|
||||||
max_var_name_length_ = std::max(max_var_name_length_, name.size());
|
max_var_name_length_ = std::max(max_var_name_length_, name.size());
|
||||||
max_var_width_ = std::max(max_var_width_, width);
|
max_var_width_ = std::max(max_var_width_, width);
|
||||||
|
|
@ -249,24 +259,25 @@ VcdReader::parseVar()
|
||||||
void
|
void
|
||||||
VcdReader::parseScope()
|
VcdReader::parseScope()
|
||||||
{
|
{
|
||||||
|
readStmtTokens();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VcdReader::parseUpscope()
|
VcdReader::parseUpscope()
|
||||||
{
|
{
|
||||||
}
|
readStmtTokens();
|
||||||
|
|
||||||
void
|
|
||||||
VcdReader::parseDumpvars()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// vars_ grows so the map has to be built after the vars.
|
// vars_ grows so the map has to be built after the vars.
|
||||||
void
|
void
|
||||||
VcdReader::makeVarIdMap()
|
VcdReader::makeVarIdMap()
|
||||||
{
|
{
|
||||||
for (VcdVar &var : vars_)
|
for (VcdVar &var : vars_) {
|
||||||
id_var_map_[var.id()] = &var;
|
const string &id = var.id();
|
||||||
|
// Use the first variable definition which has the highest scope.
|
||||||
|
if (id_var_map_.find(id) == id_var_map_.end())
|
||||||
|
id_var_map_[id] = &var;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -274,10 +285,8 @@ VcdReader::parseVarValues()
|
||||||
{
|
{
|
||||||
string token = getToken();
|
string token = getToken();
|
||||||
while (!token.empty()) {
|
while (!token.empty()) {
|
||||||
if (token[0] == '#') {
|
if (token[0] == '#')
|
||||||
time_ = stoll(token.substr(1));
|
time_ = stoll(token.substr(1));
|
||||||
//printf("time = %lld\n", time_);
|
|
||||||
}
|
|
||||||
else if (token[0] == '0'
|
else if (token[0] == '0'
|
||||||
|| token[0] == '1'
|
|| token[0] == '1'
|
||||||
|| token[0] == 'X'
|
|| token[0] == 'X'
|
||||||
|
|
@ -302,7 +311,6 @@ VcdReader::parseVarValues()
|
||||||
report_->fileError(804, filename_, stmt_line_,
|
report_->fileError(804, filename_, stmt_line_,
|
||||||
"unknown variable %s", id.c_str());
|
"unknown variable %s", id.c_str());
|
||||||
VcdVar *var = var_itr->second;
|
VcdVar *var = var_itr->second;
|
||||||
//printf("%s = %lld\n", var->name().c_str(), bus_value);
|
|
||||||
var->pushBusValue(time_, bus_value);
|
var->pushBusValue(time_, bus_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -417,6 +425,7 @@ VcdReader::reportWaveforms()
|
||||||
printf(" %-*s",
|
printf(" %-*s",
|
||||||
static_cast<int>(max_var_name_length_),
|
static_cast<int>(max_var_name_length_),
|
||||||
var.name().c_str());
|
var.name().c_str());
|
||||||
|
// WRONG - copies vector
|
||||||
VcdValues var_values = var.values();
|
VcdValues var_values = var.values();
|
||||||
if (!var_values.empty()) {
|
if (!var_values.empty()) {
|
||||||
size_t value_index = 0;
|
size_t value_index = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue