Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-10-25 17:09:34 -07:00
parent 28c6d82b8b
commit 20ed9e5537
1 changed files with 27 additions and 18 deletions

View File

@ -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;