49 : debug_level(param->get_class_debug_level(
GET_CLASS(*this))), vcd_fp(nullptr), sig_n(0)
60 vcd_fp = fopen(vcd_file_to_parse.c_str(),
"r");
63 THROW_ERROR(
"Unable to open VCD file: " + vcd_file_to_parse);
72 if(selected_signals.empty())
85 size_t n_signals_in_scope = scope.second.size();
102 filtered_signals.clear();
118 while(fscanf(
vcd_fp,
"%255s%n", token, &chars_read) != EOF)
127 THROW_ERROR(
"buffer overflow. read token too long");
130 if(strncmp(
"$end", token, 4) == 0)
150 unsigned int msb = 0;
151 unsigned int lsb = 0;
153 if(fscanf(
vcd_fp,
"%255s %u %255s %255s %14s", type, &size, id_code, ref, tmp) == 5)
157 if(strlen(type) > 256)
159 THROW_ERROR(
"Overflow. Read token too long (type var)");
162 if(strlen(ref) > 256)
164 THROW_ERROR(
"Overflow. Read token too long (name var)");
169 THROW_ERROR(
"Overflow. Read token too long ($end token)");
172 if(strlen(id_code) > 256)
174 THROW_ERROR(
"Overflow. Read token too long (id_code)");
177 if(strncmp(
"real", type, 4) == 0)
186 if(strncmp(
"$end", tmp, 4) != 0)
189 if(sscanf(tmp,
"[%u:%u]", &msb, &lsb) != 2)
191 if(sscanf(tmp,
"[%u]", &lsb) != 1)
202 if((fscanf(
vcd_fp,
"%14s", tmp) != 1) || (strncmp(
"$end", tmp, 4) != 0))
207 else if(sscanf(ref,
"%*[a-zA-Z0-9_][%*s].") == 2)
219 else if(sscanf(ref,
"%255[a-zA-Z0-9_][%14s]", reftmp, tmp) == 2)
223 if(sscanf(tmp,
"%u:%u", &msb, &lsb) != 2)
225 if(sscanf(tmp,
"%u", &lsb) != 1)
275 if(fscanf(
vcd_fp,
" %*s %255s $end ", new_scope) == 1)
278 if(strlen(new_scope) > 256)
296 if(fscanf(
vcd_fp,
" %255s ", token) == 1)
299 if(strlen(token) > 256)
304 if(strncmp(token,
"$end", 4) == 0)
328 std::stack<std::string> scope;
331 bool enddef_found =
false;
335 while(!enddef_found && (fscanf(
vcd_fp,
"%255s%n", keyword, &chars_read) == 1))
343 if(keyword[0] ==
'$')
345 if(strncmp(
"var", (keyword + 1), 3) == 0)
349 else if(strncmp(
"scope", (keyword + 1), 5) == 0)
353 else if(strncmp(
"upscope", (keyword + 1), 7) == 0)
357 else if(strncmp(
"enddefinitions", (keyword + 1), 14) == 0)
378 THROW_ERROR(
"Specified VCD file is not a valid VCD file");
383 THROW_ERROR(
"Missing bits in port vector declaration");
397 if(fscanf(
vcd_fp,
"%255s%n", sym, &chars_read) == 1)
423 if(fscanf(
vcd_fp,
"%255s%n", sym, &chars_read) == 1)
446 unsigned long last_timestep = 0;
448 bool carry_over =
false;
452 while(!feof(
vcd_fp) && (fscanf(
vcd_fp,
"%4099s%n", token, &chars_read) == 1))
454 if(chars_read < 4099)
459 if(strncmp(
"comment", (token + 1), 7) == 0)
467 else if((token[0] ==
'b') || (token[0] ==
'B'))
471 THROW_ERROR(
"can't parse binary value change for signal: " +
STR(token));
474 else if((token[0] ==
'r') || (token[0] ==
'R') || carry_over)
478 THROW_ERROR(
"can't parse real value change for signal: " +
STR(token));
482 else if(token[0] ==
'#')
484 last_timestep = std::stoul(token + 1,
nullptr, 10);
486 else if((token[0] ==
'0') || (token[0] ==
'1') || (token[0] ==
'x') || (token[0] ==
'X') ||
487 (token[0] ==
'z') || (token[0] ==
'Z'))
498 THROW_ERROR(
"Badly placed token in simulation part");
522 const auto& signal_names = scope_it->second;
523 return signal_names.find(name) != signal_names.end();
527 const std::string&
type,
const bool isvect,
const unsigned int msb,
528 const unsigned int lsb)
530 THROW_ASSERT(!scope.empty() && !name.empty(),
"scope = \"" + scope +
"\" name = \"" + name +
"\"");
532 std::pair<std::string, std::string>
key = std::make_pair(scope, name);
539 parse_result.at(scope)[name] = std::list<sig_variation>();
543 THROW_ASSERT(msb == lsb,
"partial vector declaration supported only one bit at a time");
546 if(type != old_sig_info.
type || !old_sig_info.
is_vec)
548 THROW_ERROR(
"type for signal " + scope + name +
" is not consistent");
564 if((info.
lsb != 0) ||
568 "port vector declaration is not consistent for vcd signal: \n" + si.first.first +
569 si.first.second +
"\n");
581 for(
const auto& sn : vcd2sn.second)
584 std::list<sig_variation>& vars =
parse_result.at(sn.first).at(sn.second);
585 vars.emplace_back(0, std::string(siginfo.
msb - siginfo.
lsb + 1,
'x'));
592 THROW_ASSERT(!value.empty(),
"trying to add an empty variation for vcd id " + sig_id +
" at time " +
STR(ts));
593 THROW_ASSERT(!sig_id.empty(),
"adding a variation to unspecified vcd signal");
597 for(
const auto& sn : it->second)
600 std::list<sig_variation>& vars =
parse_result.at(sn.first).at(sn.second);
601 THROW_ASSERT(vars.back().time_stamp <= ts,
"Variations are not being added in time order: id = '" + sig_id +
602 "', ts = " +
STR(vars.back().time_stamp) +
" > " +
STR(ts));
606 std::string new_value;
613 THROW_ASSERT(value.size() == 1,
"variation of a bit is larger than a bit");
614 new_value = std::string(vars.back().value);
616 "vcd id " + sig_id +
" is not assigned to any bit of port" + sn.first +
619 THROW_ASSERT(idx < new_value.size(),
"vcd_id " + sig_id +
" for signal " + sn.first +
621 " is mapped to a bit higher than port size");
622 new_value.at(new_value.size() - idx - 1) = value.front();
632 if((siginfo.
msb - siginfo.
lsb + 1) > value.size())
634 char leading = *new_value.begin();
635 char to_prepend =
'0';
636 if(leading !=
'0' && leading !=
'1')
638 to_prepend = leading;
640 while(new_value.size() < (siginfo.
msb - siginfo.
lsb + 1))
642 new_value.insert(0, 1, to_prepend);
647 if(vars.back().time_stamp == ts)
655 vars.back().value = new_value;
659 vars.back().duration = ts - vars.back().time_stamp;
660 vars.emplace_back(ts, new_value);
vcd_trace_t parse_result
holds the parsed vcd trace during the parsing
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
bool check_filter_list(const std::string &scope_str, const std::string &name)
Checks if a signal is to be monitored.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
vcd_parser(const ParameterConstRef ¶ms)
constructor
std::string vcd_filename
name of the vcd file to parse
std::map< std::pair< std::string, std::string >, vcd_sig_info > scope_and_name_to_sig_info
maps every pair (scope, signal name) to the corresponding sig_info
int vcd_parse_sim()
Parses all lines that occur in the simulation portion of the VCD file.
int vcd_parse_sim_real(char *value, unsigned long timestamp)
Reads the next token from the file and calls the appropriate function.
int vcd_parse_skip_to_end()
Parses specified file until $end keyword is seen, ignoring all text inbetween.
size_t msb
position of the msb of this signal in the vector. valid only if is_vec == true
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
bool check_signals() const
check if the port vectors declarations are consistent
UnorderedMapStd< std::string, UnorderedSetStdStable< std::string > > vcd_filter_t
this is the type used to select which signals have to be filtered during parsing. ...
void vcd_pop_def_scope(std::stack< std::string > &scope)
void vcd_push_def_scope(std::stack< std::string > &scope)
Parses definition $scope keyword line until $end keyword is seen.
unsigned long sig_n
total number of signals in the vcd file
FILE * vcd_fp
file pointer to the vcd file to parse
bool is_vec
true if the vcd_signal is part of a vector
vcd_filter_t filtered_signals
set of signals to select from the vcd file.
UnorderedMapStd< std::string, CustomUnorderedMapStable< std::string, std::list< sig_variation > >> vcd_trace_t
this type is the result of a parse.
int vcd_parse_sim_vector(char *value, unsigned long timestamp)
Reads the next token from the file and calls the appropriate fuction.
size_t lsb
position of the lsb of this signal in the vector. valid only if is_vec == true
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
#define HIERARCHY_SEPARATOR
void vcd_add_signal(const std::string &scope, const std::string &name, const std::string &vcd_id, const std::string &type, const bool isvect, const unsigned int msb, const unsigned int lsb)
insert a signal in the maps needed for selecting the vcd data and for relating it back to HDL and C v...
This class describes all classes used to represent a structural object.
int vcd_parse_def_var(const std::string &scope)
Parses definition $var keyword line until $end keyword is seen.
const int debug_level
Debug Level.
vcd_trace_t parse_vcd(const std::string &vcd_file_to_parse, const vcd_parser::vcd_filter_t &selected_signals)
parses a file selecting only a predefined set of signals.
This file collects some hash functors.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
this class is used to manage the command-line or XML options.
void add_variation(const std::string &id, const std::string &value, unsigned long long ts)
CustomUnorderedMap< std::string, size_t > vcd_id_to_bit
#define PRINT_OUT_MEX(profLevel, curprofLevel, mex)
std::string type
the type of the signal in vcd file
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
std::map< std::string, CustomUnorderedSet< std::pair< std::string, std::string > > > vcd_id_to_scope_and_name
maps every signal id in the vcd to the set of the corresponding pairs (scope, hdl signal name) ...
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...