PandA-2024.02
vcd_parser.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
37 // include class header
38 #include "vcd_parser.hpp"
39 #include <iostream>
40 // include from ./
41 #include "Parameter.hpp"
42 
43 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
44 #include "hash_helper.hpp"
45 #include "string_manipulation.hpp" // for GET_CLASS
46 #include "structural_objects.hpp"
47 
49  : debug_level(param->get_class_debug_level(GET_CLASS(*this))), vcd_fp(nullptr), sig_n(0)
50 {
51 }
52 
53 vcd_parser::vcd_trace_t vcd_parser::parse_vcd(const std::string& vcd_file_to_parse,
54  const vcd_filter_t& selected_signals)
55 {
56  // ---- initialization ----
57  // open file
58  INDENT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "-->Opening VCD file to parse: " + vcd_file_to_parse);
59  vcd_fp = nullptr;
60  vcd_fp = fopen(vcd_file_to_parse.c_str(), "r");
61  if(vcd_fp == nullptr)
62  {
63  THROW_ERROR("Unable to open VCD file: " + vcd_file_to_parse);
64  }
65  INDENT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "<--Opened VCD file to parse: " + vcd_file_to_parse);
66  // initialize member file name
67  vcd_filename = vcd_file_to_parse;
68 
69  INDENT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "-->Initializing parser");
71  // avoid useless parse
72  if(selected_signals.empty())
73  {
74  return std::move(parse_result);
75  }
76 
77  // initialize signals to select
78  filtered_signals = selected_signals;
79  // reset parsed signals
80  sig_n = 0;
81  // reserve space in hash maps
82  parse_result.reserve(filtered_signals.size());
83  for(const auto& scope : filtered_signals)
84  {
85  size_t n_signals_in_scope = scope.second.size();
86  parse_result[scope.first].reserve(n_signals_in_scope);
87  }
88 
89  INDENT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "<--Initialized parser");
90 
91  // ---- parse ----
92  // parse definitions
93  vcd_parse_def();
94  // parse waveforms
95  vcd_parse_sim();
96  // ---- statistics ----
98  "Number of selected signals: " + STR(scope_and_name_to_sig_info.size()) + "/" + STR(sig_n));
99  // ---- cleanup ----
100  INDENT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "-->Cleaning up VCD parser");
101  fclose(vcd_fp);
102  filtered_signals.clear();
103  vcd_filename.clear();
105  vcd_id_to_scope_and_name.clear();
106  INDENT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "<--Cleaned up VCD parser");
107  return std::move(parse_result);
108 }
109 
114 {
115  char token[256]; /* String value of current token */
116  int chars_read = -1; /* Number of characters scanned in */
117 
118  while(fscanf(vcd_fp, "%255s%n", token, &chars_read) != EOF)
119  {
120  if(chars_read < 0)
121  {
122  continue;
123  }
124 
125  if(chars_read > 256)
126  {
127  THROW_ERROR("buffer overflow. read token too long");
128  }
129 
130  if(strncmp("$end", token, 4) == 0)
131  {
132  return 0;
133  }
134 
135  chars_read = -1;
136  }
137  return -1;
138 }
139 
143 int vcd_parser::vcd_parse_def_var(const std::string& scope)
144 {
145  char type[256]; /* Variable type */
146  unsigned int size; /* Bit width of specified variable */
147  char id_code[256]; /* Unique variable identifier_code */
148  char ref[256]; /* Name of variable in design */
149  char tmp[15]; /* Temporary string holder */
150  unsigned int msb = 0; /* Most significant bit */
151  unsigned int lsb = 0; /* Least significant bit */
152 
153  if(fscanf(vcd_fp, "%255s %u %255s %255s %14s", type, &size, id_code, ref, tmp) == 5)
154  {
155  bool isvect = false; /* check if the signal is a vector */
156  /* Make sure that we have not exceeded array boundaries */
157  if(strlen(type) > 256)
158  {
159  THROW_ERROR("Overflow. Read token too long (type var)");
160  }
161 
162  if(strlen(ref) > 256)
163  {
164  THROW_ERROR("Overflow. Read token too long (name var)");
165  }
166 
167  if(strlen(tmp) > 15)
168  {
169  THROW_ERROR("Overflow. Read token too long ($end token)");
170  }
171 
172  if(strlen(id_code) > 256)
173  {
174  THROW_ERROR("Overflow. Read token too long (id_code)");
175  }
176 
177  if(strncmp("real", type, 4) == 0)
178  {
179  msb = 63;
180  lsb = 0;
181  isvect = true;
182  }
183  else
184  {
185  char reftmp[256]; /* Temporary variable name */
186  if(strncmp("$end", tmp, 4) != 0)
187  {
188  /* A bit select was specified for this signal, get the size */
189  if(sscanf(tmp, "[%u:%u]", &msb, &lsb) != 2)
190  {
191  if(sscanf(tmp, "[%u]", &lsb) != 1)
192  {
193  THROW_ERROR("Unrecognized $var format");
194  }
195  else
196  {
197  msb = lsb;
198  }
199  }
200  isvect = true;
201 
202  if((fscanf(vcd_fp, "%14s", tmp) != 1) || (strncmp("$end", tmp, 4) != 0))
203  {
204  THROW_ERROR("Unrecognized $var format");
205  }
206  }
207  else if(sscanf(ref, "%*[a-zA-Z0-9_][%*s].") == 2)
208  {
209  /* This is a hierarchical reference so we shouldn't modify ref -- quirky behavior from VCS */
210  msb = size - 1;
211  lsb = 0;
212  /* this is the case of signal (like integer) that are defined in the VCD in the same way of bit but they are
213  * arrays */
214  if(msb > 0)
215  {
216  isvect = true;
217  }
218  }
219  else if(sscanf(ref, "%255[a-zA-Z0-9_][%14s]", reftmp, tmp) == 2)
220  {
221  strcpy(ref, reftmp);
222 
223  if(sscanf(tmp, "%u:%u", &msb, &lsb) != 2)
224  {
225  if(sscanf(tmp, "%u", &lsb) != 1)
226  {
227  THROW_ERROR("Unrecognized $var format");
228  }
229  else
230  {
231  msb = lsb;
232  }
233  }
234  isvect = true;
235  }
236  else
237  {
238  msb = size - 1;
239  lsb = 0;
240  /* this is the case of signal (like integer) that are defined in the VCD in the same way of bit but they are
241  * arrays */
242  if(msb > 0)
243  {
244  isvect = true;
245  }
246  }
247  }
248 
249  sig_n++;
250 
251  /* if check fails do nothing: this signal is useless */
252  if(!check_filter_list(scope, ref))
253  {
254  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Filtered SIGNAL: " + scope + ref);
255  return 0;
256  }
257  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "SELECTED SIGNAL: " + scope + ref);
258 
259  vcd_add_signal(scope, ref, id_code, type, isvect, msb, lsb);
260  }
261  else
262  {
263  THROW_ERROR("Unrecognized $var format");
264  }
265  return 0;
266 }
267 
271 void vcd_parser::vcd_push_def_scope(std::stack<std::string>& scope)
272 {
273  char new_scope[256]; /* scope name */
274 
275  if(fscanf(vcd_fp, " %*s %255s $end ", new_scope) == 1)
276  {
277  /* Make sure that we have not exceeded any array boundaries */
278  if(strlen(new_scope) > 256)
279  {
280  THROW_ERROR("Overflow. Read token too long.");
281  }
282  }
283  else
284  {
285  THROW_ERROR("Unrecognized $scope format");
286  }
287  scope.push(scope.top() + new_scope + STR(HIERARCHY_SEPARATOR));
288  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "NEW_SCOPE: " + scope.top());
289  return;
290 }
291 
292 void vcd_parser::vcd_pop_def_scope(std::stack<std::string>& scope)
293 {
294  char token[256];
295 
296  if(fscanf(vcd_fp, " %255s ", token) == 1)
297  {
298  /* Make sure that we have not exceeded any array boundaries */
299  if(strlen(token) > 256)
300  {
301  THROW_ERROR("Overflow. Read token too long");
302  }
303 
304  if(strncmp(token, "$end", 4) == 0)
305  {
306  scope.pop();
307  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "UP_SCOPE: " + scope.top());
308  return;
309  }
310  else
311  {
312  THROW_ERROR("missing $end after $upscope token");
313  }
314  }
315  THROW_ERROR("Unrecognized $upscope format");
316 }
317 
318 /*
319  * Parses all definition information from specified file.
320  */
322 {
323  /*
324  * stack for the scopes. it holds the string representing the current scope,
325  * i. e. the path down through the structural components, using their names
326  * separated by HIERARCHY_SEPARATOR
327  */
328  std::stack<std::string> scope;
329  scope.push("");
330 
331  bool enddef_found = false; /* If set to true, definition section is finished */
332  char keyword[256]; /* Holds keyword value */
333  int chars_read; /* Number of characters scanned in */
334 
335  while(!enddef_found && (fscanf(vcd_fp, "%255s%n", keyword, &chars_read) == 1))
336  {
337  if(chars_read > 256)
338  {
339  THROW_ERROR("Overflow. Read token too long");
340  }
341 
342  /* check the token and chose the right action */
343  if(keyword[0] == '$')
344  {
345  if(strncmp("var", (keyword + 1), 3) == 0)
346  {
347  vcd_parse_def_var(scope.top());
348  }
349  else if(strncmp("scope", (keyword + 1), 5) == 0)
350  {
351  vcd_push_def_scope(scope);
352  }
353  else if(strncmp("upscope", (keyword + 1), 7) == 0)
354  {
355  vcd_pop_def_scope(scope);
356  }
357  else if(strncmp("enddefinitions", (keyword + 1), 14) == 0)
358  {
359  enddef_found = true;
361  {
362  THROW_ERROR("missing $end token in parsed vcd file: " + vcd_filename);
363  }
364  }
365  else if(vcd_parse_skip_to_end())
366  {
367  THROW_ERROR("missing $end token in parsed vcd file: " + vcd_filename);
368  }
369  }
370  else
371  {
372  THROW_ERROR("undefined token '" + STR(keyword) + "' in parsed vcd file: " + vcd_filename);
373  }
374  }
375 
376  if(!enddef_found)
377  {
378  THROW_ERROR("Specified VCD file is not a valid VCD file");
379  }
380 
381  if(!check_signals())
382  {
383  THROW_ERROR("Missing bits in port vector declaration");
384  }
385 
386  return 0;
387 }
388 
392 int vcd_parser::vcd_parse_sim_vector(char* value, unsigned long timestamp)
393 {
394  char sym[256]; /* String value of signal symbol */
395  int chars_read; /* Number of characters scanned in */
396 
397  if(fscanf(vcd_fp, "%255s%n", sym, &chars_read) == 1)
398  {
399  if(chars_read > 256)
400  {
401  THROW_ERROR("Overflow. Read token too long");
402  }
403 
404  /* add variation to signal list -> normal vector */
405  add_variation(sym, value, timestamp);
406  }
407  else
408  {
409  THROW_ERROR("Bad file format");
410  }
411 
412  return 0;
413 }
414 
418 int vcd_parser::vcd_parse_sim_real(char* value, unsigned long timestamp)
419 {
420  char sym[256]; /* String value of signal symbol */
421  int chars_read; /* Number of characters scanned in */
422 
423  if(fscanf(vcd_fp, "%255s%n", sym, &chars_read) == 1)
424  {
425  if(chars_read > 256)
426  {
427  THROW_ERROR("Overflow. Read token too long");
428  }
429 
430  /* add variation to signal list */
431  add_variation(sym, value, timestamp);
432  }
433  else
434  {
435  THROW_ERROR("Bad file format");
436  }
437  return 0;
438 }
439 
444 {
445  char token[4100]; /* Current token from VCD file */
446  unsigned long last_timestep = 0; /* Value of last timestamp from file */
447  int chars_read; /* Number of characters scanned in */
448  bool carry_over = false; /* Specifies if last string was too long */
449 
450  // initialize the waveforms
451  init_variations();
452  while(!feof(vcd_fp) && (fscanf(vcd_fp, "%4099s%n", token, &chars_read) == 1))
453  {
454  if(chars_read < 4099)
455  {
456  if(token[0] == '$')
457  {
458  /* Maybe could be a comment area */
459  if(strncmp("comment", (token + 1), 7) == 0)
460  {
462  {
463  THROW_ERROR("missing $end token in parsed vcd file: " + vcd_filename);
464  }
465  }
466  }
467  else if((token[0] == 'b') || (token[0] == 'B'))
468  {
469  if(vcd_parse_sim_vector((token + 1), last_timestep))
470  {
471  THROW_ERROR("can't parse binary value change for signal: " + STR(token));
472  }
473  }
474  else if((token[0] == 'r') || (token[0] == 'R') || carry_over)
475  {
476  if(vcd_parse_sim_real((token + 1), last_timestep))
477  {
478  THROW_ERROR("can't parse real value change for signal: " + STR(token));
479  }
480  carry_over = false;
481  }
482  else if(token[0] == '#')
483  {
484  last_timestep = std::stoul(token + 1, nullptr, 10);
485  }
486  else if((token[0] == '0') || (token[0] == '1') || (token[0] == 'x') || (token[0] == 'X') ||
487  (token[0] == 'z') || (token[0] == 'Z'))
488  {
489  /* normal signal -> add to vector */
490  char tmp[2];
491  tmp[0] = token[0];
492  tmp[1] = '\0';
493 
494  add_variation(token + 1, tmp, last_timestep);
495  }
496  else
497  {
498  THROW_ERROR("Badly placed token in simulation part");
499  }
500  }
501  else
502  {
503  carry_over = true;
504  }
505  }
506 
507  /* simulation is done correctly */
508  return 0;
509 }
510 
511 bool vcd_parser::check_filter_list(const std::string& scope_str, const std::string& name)
512 {
513  if(filtered_signals.empty())
514  {
515  return false;
516  }
517  const auto scope_it = filtered_signals.find(scope_str);
518  if(scope_it == filtered_signals.end())
519  {
520  return false;
521  }
522  const auto& signal_names = scope_it->second;
523  return signal_names.find(name) != signal_names.end();
524 }
525 
526 void vcd_parser::vcd_add_signal(const std::string& scope, const std::string& name, const std::string& vcd_id,
527  const std::string& type, const bool isvect, const unsigned int msb,
528  const unsigned int lsb)
529 {
530  THROW_ASSERT(!scope.empty() && !name.empty(), "scope = \"" + scope + "\" name = \"" + name + "\"");
531 
532  std::pair<std::string, std::string> key = std::make_pair(scope, name);
533  auto it = scope_and_name_to_sig_info.find(key);
534  if(it == scope_and_name_to_sig_info.end())
535  { // the signal is new
536  scope_and_name_to_sig_info.insert(std::make_pair(key, vcd_sig_info(type, isvect, msb, lsb)));
537  scope_and_name_to_sig_info.at(key).vcd_id_to_bit[vcd_id] = lsb;
538  vcd_id_to_scope_and_name[vcd_id].insert(key);
539  parse_result.at(scope)[name] = std::list<sig_variation>();
540  }
541  else
542  { // some bits of the signal have already been declared
543  THROW_ASSERT(msb == lsb, "partial vector declaration supported only one bit at a time");
544  size_t bit = lsb;
545  vcd_sig_info& old_sig_info = scope_and_name_to_sig_info.at(key);
546  if(type != old_sig_info.type || !old_sig_info.is_vec)
547  {
548  THROW_ERROR("type for signal " + scope + name + " is not consistent");
549  }
550  old_sig_info.lsb = std::min(bit, old_sig_info.lsb);
551  old_sig_info.msb = std::max(bit, old_sig_info.msb);
552  scope_and_name_to_sig_info.at(key).vcd_id_to_bit[vcd_id] = bit;
553  vcd_id_to_scope_and_name[vcd_id].insert(key);
554  }
555 }
556 
558 {
559  for(const auto& si : scope_and_name_to_sig_info)
560  {
561  const vcd_sig_info& info = si.second;
562  if(info.is_vec)
563  {
564  if((info.lsb != 0) ||
565  (info.vcd_id_to_bit.size() > 1 && info.vcd_id_to_bit.size() != (info.msb - info.lsb + 1)))
566  {
568  "port vector declaration is not consistent for vcd signal: \n" + si.first.first +
569  si.first.second + "\n");
570  return false;
571  }
572  }
573  }
574  return true;
575 }
576 
578 {
579  for(const auto& vcd2sn : vcd_id_to_scope_and_name)
580  {
581  for(const auto& sn : vcd2sn.second)
582  {
583  const vcd_sig_info& siginfo = scope_and_name_to_sig_info.at(sn);
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'));
586  }
587  }
588 }
589 
590 void vcd_parser::add_variation(const std::string& sig_id, const std::string& value, unsigned long long ts)
591 {
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");
594  auto it = vcd_id_to_scope_and_name.find(sig_id);
595  if(it != vcd_id_to_scope_and_name.end())
596  {
597  for(const auto& sn : it->second)
598  {
599  const vcd_sig_info& siginfo = scope_and_name_to_sig_info.at(sn);
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));
603  THROW_ASSERT(!siginfo.vcd_id_to_bit.empty(),
604  "signal " + sn.first + STR(HIERARCHY_SEPARATOR) + sn.second + " has no mapped vcd_id");
605  /* prepare the new value for variation to insert */
606  std::string new_value;
607  if(siginfo.vcd_id_to_bit.size() > 1)
608  {
609  /*
610  * the signal is a port vector with a separate id for every bit,
611  * so we must keep all the previous bits and change only the new
612  */
613  THROW_ASSERT(value.size() == 1, "variation of a bit is larger than a bit");
614  new_value = std::string(vars.back().value);
615  THROW_ASSERT(siginfo.vcd_id_to_bit.find(sig_id) != siginfo.vcd_id_to_bit.end(),
616  "vcd id " + sig_id + " is not assigned to any bit of port" + sn.first +
617  STR(HIERARCHY_SEPARATOR) + sn.second);
618  size_t idx = siginfo.vcd_id_to_bit.at(sig_id);
619  THROW_ASSERT(idx < new_value.size(), "vcd_id " + sig_id + " for signal " + sn.first +
620  STR(HIERARCHY_SEPARATOR) + sn.second +
621  " is mapped to a bit higher than port size");
622  new_value.at(new_value.size() - idx - 1) = value.front();
623  }
624  else
625  {
626  /*
627  * the signal can be a bit or a port vector, but in the vcd it
628  * has a single unique tag to represent all the bits
629  */
630  new_value = value;
631  /* check bit extension */
632  if((siginfo.msb - siginfo.lsb + 1) > value.size())
633  {
634  char leading = *new_value.begin();
635  char to_prepend = '0';
636  if(leading != '0' && leading != '1')
637  {
638  to_prepend = leading;
639  }
640  while(new_value.size() < (siginfo.msb - siginfo.lsb + 1))
641  {
642  new_value.insert(0, 1, to_prepend);
643  }
644  }
645  }
646 
647  if(vars.back().time_stamp == ts)
648  {
649  /*
650  * another variation for this signal was already added in this
651  * cycle. this can happen, especially in vcds produced by event
652  * based simulators. in this case the last variation must
653  * override the others
654  */
655  vars.back().value = new_value;
656  }
657  else
658  {
659  vars.back().duration = ts - vars.back().time_stamp;
660  vars.emplace_back(ts, new_value);
661  }
662  }
663  }
664 }
vcd_trace_t parse_result
holds the parsed vcd trace during the parsing
Definition: vcd_parser.hpp:155
#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;.
TVMValue param[3]
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.
Definition: vcd_parser.cpp:511
#define GET_CLASS(obj)
Macro returning the actual type of an object.
vcd_parser(const ParameterConstRef &params)
constructor
Definition: vcd_parser.cpp:48
std::string vcd_filename
name of the vcd file to parse
Definition: vcd_parser.hpp:131
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
Definition: vcd_parser.hpp:160
int vcd_parse_sim()
Parses all lines that occur in the simulation portion of the VCD file.
Definition: vcd_parser.cpp:443
#define min(x, y)
int vcd_parse_sim_real(char *value, unsigned long timestamp)
Reads the next token from the file and calls the appropriate function.
Definition: vcd_parser.cpp:418
int vcd_parse_skip_to_end()
Parses specified file until $end keyword is seen, ignoring all text inbetween.
Definition: vcd_parser.cpp:113
size_t msb
position of the msb of this signal in the vector. valid only if is_vec == true
Definition: vcd_parser.hpp:66
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
int key[32]
Definition: aes.h:67
#define max
Definition: backprop.h:17
void init_variations()
Definition: vcd_parser.cpp:577
bool check_signals() const
check if the port vectors declarations are consistent
Definition: vcd_parser.cpp:557
UnorderedMapStd< std::string, UnorderedSetStdStable< std::string > > vcd_filter_t
this is the type used to select which signals have to be filtered during parsing. ...
Definition: vcd_parser.hpp:101
void vcd_pop_def_scope(std::stack< std::string > &scope)
Definition: vcd_parser.cpp:292
void vcd_push_def_scope(std::stack< std::string > &scope)
Parses definition $scope keyword line until $end keyword is seen.
Definition: vcd_parser.cpp:271
unsigned long sig_n
total number of signals in the vcd file
Definition: vcd_parser.hpp:141
FILE * vcd_fp
file pointer to the vcd file to parse
Definition: vcd_parser.hpp:136
bool is_vec
true if the vcd_signal is part of a vector
Definition: vcd_parser.hpp:64
vcd_filter_t filtered_signals
set of signals to select from the vcd file.
Definition: vcd_parser.hpp:148
UnorderedMapStd< std::string, CustomUnorderedMapStable< std::string, std::list< sig_variation > >> vcd_trace_t
this type is the result of a parse.
Definition: vcd_parser.hpp:109
int vcd_parse_sim_vector(char *value, unsigned long timestamp)
Reads the next token from the file and calls the appropriate fuction.
Definition: vcd_parser.cpp:392
size_t lsb
position of the lsb of this signal in the vector. valid only if is_vec == true
Definition: vcd_parser.hpp:68
#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
Definition: exceptions.hpp:263
#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...
Definition: vcd_parser.cpp:526
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.
Definition: vcd_parser.cpp:143
const int debug_level
Debug Level.
Definition: vcd_parser.hpp:124
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.
Definition: vcd_parser.cpp:53
int vcd_parse_def()
Definition: vcd_parser.cpp:321
This file collects some hash functors.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
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)
Definition: vcd_parser.cpp:590
CustomUnorderedMap< std::string, size_t > vcd_id_to_bit
Definition: vcd_parser.hpp:77
#define PRINT_OUT_MEX(profLevel, curprofLevel, mex)
std::string type
the type of the signal in vcd file
Definition: vcd_parser.hpp:62
#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) ...
Definition: vcd_parser.hpp:165
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:55 for PandA-2024.02 by doxygen 1.8.13