gem5 v24.0.0.0
Loading...
Searching...
No Matches
vcd.cc
Go to the documentation of this file.
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "systemc/utils/vcd.hh"
29
30#include <ctime>
31#include <iomanip>
32
33#include "base/bitfield.hh"
34#include "base/cprintf.hh"
35#include "sim/core.hh"
50
51namespace sc_gem5
52{
53
54namespace
55{
56
57std::string
58cleanName(std::string name)
59{
60 for (int i = 0; i < name.length(); i++) {
61 if (name[i] == '[')
62 name[i] = '(';
63 else if (name[i] == ']')
64 name[i] = ')';
65 }
66 return name;
67}
68
69} // anonymous namespace
70
72{
73 protected:
74 std::string _vcdName;
75
76 const char *
77 stripLeadingBits(const char *orig)
78 {
79 const char first = orig[0];
80
81 if (first != 'z' && first != 'x' && first != '0')
82 return orig;
83
84 const char *res = orig;
85 while (*++res == first) {}
86
87 if (first != '0' || *res != '1')
88 res--;
89
90 return res;
91 }
92
93 char
95 {
96 switch (in) {
97 case 'U':
98 case 'X':
99 case 'W':
100 case 'D':
101 return 'x';
102 case '0':
103 case 'L':
104 return '0';
105 case '1':
106 case 'H':
107 return '1';
108 case 'Z':
109 return 'z';
110 default:
111 return '?';
112 }
113 }
114
115 void
116 printVal(std::ostream &os, const std::string &rep)
117 {
118 switch (width()) {
119 case 0:
120 return;
121 case 1:
122 os << rep << vcdName() << std::endl;;
123 return;
124 default:
125 os << "b" << stripLeadingBits(rep.c_str()) << " " <<
126 vcdName() << std::endl;
127 return;
128 }
129 }
130
131 public:
134
135 void vcdName(const std::string &vcd_name) { _vcdName = vcd_name; }
136 const std::string &vcdName() { return _vcdName; }
137 virtual std::string vcdType() { return "wire"; }
138
139 virtual void output(std::ostream &os) = 0;
140};
141
142void
144{
145 size_t pos = name.find_first_of('.');
146 if (pos == std::string::npos) {
147 values.emplace_back(name, value);
148 } else {
149 std::string sname = name.substr(0, pos);
150 auto it = scopes.find(sname);
151 if (it == scopes.end())
152 it = scopes.emplace(sname, new VcdTraceScope).first;
153 it->second->addValue(name.substr(pos + 1), value);
154 }
155}
156
157void
158VcdTraceScope::output(const std::string &name, std::ostream &os)
159{
160 os << "$scope module " << name << " $end" << std::endl;
161
162 for (auto &p: values) {
163 const std::string &name = p.first;
164 VcdTraceValBase *value = p.second;
165
166 int w = value->width();
167 if (w <= 0) {
168 std::string msg = gem5::csprintf("'%s' has 0 bits", name);
169 // The typo in this error message is intentional to match the
170 // Accellera output.
171 SC_REPORT_ERROR("(E710) object cannot not be traced", msg.c_str());
172 return;
173 }
174
175 std::string clean_name = cleanName(name);
176 if (w == 1) {
177 gem5::ccprintf(os, "$var %s % 3d %s %s $end\n",
178 value->vcdType(), w, value->vcdName(), clean_name);
179 } else {
180 gem5::ccprintf(os, "$var %s % 3d %s %s [%d:0] $end\n",
181 value->vcdType(), w, value->vcdName(), clean_name, w - 1);
182 }
183 }
184
185 for (auto &p: scopes)
186 p.second->output(p.first, os);
187
188 os << "$upscope $end" << std::endl;
189}
190
191template <typename T>
192class VcdTraceVal : public TraceVal<T, VcdTraceValBase>
193{
194 public:
195 typedef T TracedType;
196
197 VcdTraceVal(const T* t, const std::string &vcd_name, int width) :
199 {
200 this->vcdName(vcd_name);
201 }
202};
203
204std::string
206{
207 std::string name(_nextName);
208
209 bool carry = false;
210 int pos = NextNameChars - 1;
211 do {
212 carry = (_nextName[pos] == 'z');
213 if (carry)
214 _nextName[pos--] = 'a';
215 else
216 _nextName[pos--]++;
217 } while (carry && pos >= 0);
218
219 return name;
220}
221
222void
224{
225 finalizeTime();
226
227 // Date.
228 stream() << "$date" << std::endl;
229 time_t long_time;
230 time(&long_time);
231 struct tm *p_tm = localtime(&long_time);
232 stream() << std::put_time(p_tm, " %b %d, %Y %H:%M:%S\n");
233 stream() << "$end" << std::endl << std::endl;
234
235 // Version.
236 stream() << "$version" << std::endl;
237 stream() << " " << ::sc_core::sc_version() << std::endl;
238 stream() << "$end" << std::endl << std::endl;
239
240 // Timescale.
241 stream() << "$timescale" << std::endl;
243 std::endl;
244 stream() << "$end" << std::endl << std::endl;
245
246 for (auto tv: traceVals)
247 tv->finalize();
248
249 topScope.output("SystemC", stream());
250
251 stream() << "$enddefinitions $end" << std::endl << std::endl;
252
254
255 std::string timedump_comment =
256 gem5::csprintf("All initial values are dumped below at time "
257 "%g sec = %g timescale units.",
258 static_cast<double>(now) / gem5::sim_clock::as_float::s,
259 static_cast<double>(now / timeUnitTicks));
260 writeComment(timedump_comment);
261
263
264 stream() << "$dumpvars" << std::endl;
265 for (auto tv: traceVals)
266 tv->output(stream());
267 stream() << "$end" << std::endl << std::endl;
268
269 initialized = true;
270}
271
273{
274 for (auto tv: traceVals)
275 delete tv;
276 traceVals.clear();
277
278 if (timeUnitTicks) {
279 gem5::ccprintf(stream(), "#%u\n",
281 }
282}
283
284void
286{
287 if (!delta)
288 deltasAtNow = 0;
289
290 uint64_t deltaOffset = deltasAtNow;
291
292 if (delta)
293 deltaOffset = deltasAtNow++;
294
295 if (_traceDeltas != delta)
296 return;
297
298 if (!initialized) {
299 initialize();
300 return;
301 }
302
303 gem5::Tick now = scheduler.getCurTick() / timeUnitTicks + deltaOffset;
304
305 if (now <= lastPrintedTime) {
306 // TODO warn about reversed time?
307 return;
308 }
309
310 bool time_printed = false;
311 for (auto tv: traceVals) {
312 if (tv->check()) {
313 if (!time_printed) {
314 lastPrintedTime = now;
315 gem5::ccprintf(stream(), "#%u\n", now);
316 time_printed = true;
317 }
318
319 tv->output(stream());
320 }
321 }
322 if (time_printed)
323 stream() << std::endl;
324}
325
326class VcdTraceValBool : public VcdTraceVal<bool>
327{
328 public:
329 using VcdTraceVal<bool>::VcdTraceVal;
330
331 void
332 output(std::ostream &os) override
333 {
334 printVal(os, this->value() ? "1" : "0");
335 }
336};
337
338void
339VcdTraceFile::addTraceVal(const bool *v, const std::string &name)
340{
342}
343
344template <typename T>
346{
347 public:
349
350 std::string vcdType() override { return "real"; }
351
352 void
353 output(std::ostream &os) override
354 {
355 gem5::ccprintf(os, "r%.16g %s\n", this->value(), this->vcdName());
356 }
357};
358
359void
360VcdTraceFile::addTraceVal(const float *v, const std::string &name)
361{
363}
364void
365VcdTraceFile::addTraceVal(const double *v, const std::string &name)
366{
368}
369
370class VcdTraceValScLogic : public VcdTraceVal<sc_dt::sc_logic>
371{
372 public:
374
375 void
376 output(std::ostream &os) override
377 {
378 char str[2] = {
379 scLogicToVcdState(value().to_char()),
380 '\0'
381 };
382 printVal(os, str);
383 }
384};
385
386void
391
392template <typename T>
394{
395 public:
397
398 void
399 finalize() override
400 {
402 this->_width = this->value().length();
403 }
404
405 void
406 output(std::ostream &os) override
407 {
408 std::string str;
409 const int w = this->width();
410
411 str.reserve(w);
412 for (int i = w - 1; i >= 0; i--)
413 str += this->value()[i].to_bool() ? '1' : '0';
414
415 this->printVal(os, str);
416 }
417};
418
419void
425void
431
432void
437void
443
444template <typename T>
446{
447 public:
449
450 void
451 finalize() override
452 {
454 this->_width = this->value().length();
455 }
456
457 void
458 output(std::ostream &os) override
459 {
460 this->printVal(os, this->value().to_string());
461 }
462};
463
464void
469void
474
475template <typename T>
477{
478 public:
480
481 std::string vcdType() override { return "real"; }
482
483 void
484 output(std::ostream &os) override
485 {
486 gem5::ccprintf(os, "r%.16g %s\n",
487 this->value().to_double(), this->vcdName());
488 }
489};
490
491void
496void
502
503template <typename T>
505{
506 public:
508
509 void
510 output(std::ostream &os) override
511 {
512 std::string str;
513 const int w = this->width();
514
515 str.reserve(w);
516 for (int i = w - 1; i >= 0; i--)
517 str += this->value()[i] ? '1' : '0';
518
519 this->printVal(os, str);
520 }
521};
522
523void
528void
534
535class VcdTraceValEvent : public VcdTraceVal<::sc_core::sc_event>
536{
537 public:
539
540 std::string vcdType() override { return "event"; }
541
542 void
543 output(std::ostream &os) override
544 {
545 if (value())
546 printVal(os, "1");
547 else
548 os << std::endl;
549 }
550};
551
552void
557
558class VcdTraceValTime : public VcdTraceVal<::sc_core::sc_time>
559{
560 private:
561 static const int TimeWidth = 64;
562
563 public:
565
566 std::string vcdType() override { return "time"; }
567
568 void
574
575 void
576 output(std::ostream &os) override
577 {
578 char str[TimeWidth + 1];
579 str[TimeWidth] = '\0';
580
581 const uint64_t val = value().value();
582 for (int i = 0; i < TimeWidth; i++)
583 str[i] = gem5::bits(val, TimeWidth - i - 1) ? '1' : '0';
584
585 printVal(os, str);
586 }
587};
588void
593
594template <typename T>
596{
597 public:
599
600 void
601 output(std::ostream &os) override
602 {
603 const int w = this->width();
604 char str[w + 1];
605 str[w] = '\0';
606
607 const uint64_t val =
608 static_cast<uint64_t>(this->value()) & gem5::mask(sizeof(T) * 8);
609
610 if (gem5::mask(w) < val) {
611 for (int i = 0; i < w; i++)
612 str[i] = 'x';
613 } else {
614 for (int i = 0; i < w; i++)
615 str[i] = gem5::bits(val, w - i - 1) ? '1' : '0';
616 }
617
618 this->printVal(os, str);
619 }
620};
621
622void
623VcdTraceFile::addTraceVal(const unsigned char *v, const std::string &name,
624 int width)
625{
627}
628void
629VcdTraceFile::addTraceVal(const char *v, const std::string &name, int width)
630{
632}
633void
634VcdTraceFile::addTraceVal(const unsigned short *v, const std::string &name,
635 int width)
636{
638}
639void
640VcdTraceFile::addTraceVal(const short *v, const std::string &name, int width)
641{
643}
644void
645VcdTraceFile::addTraceVal(const unsigned int *v, const std::string &name,
646 int width)
647{
649}
650void
651VcdTraceFile::addTraceVal(const int *v, const std::string &name, int width)
652{
654}
655void
656VcdTraceFile::addTraceVal(const unsigned long *v, const std::string &name,
657 int width)
658{
660}
661void
662VcdTraceFile::addTraceVal(const long *v, const std::string &name, int width)
663{
665}
666
667void
668VcdTraceFile::addTraceVal(const sc_dt::int64 *v, const std::string &name,
669 int width)
670{
672}
673void
674VcdTraceFile::addTraceVal(const sc_dt::uint64 *v, const std::string &name,
675 int width)
676{
678}
679
680void
681VcdTraceFile::addTraceVal(const unsigned int *v, const std::string &name,
682 const char **literals)
683{
684 uint64_t count = 0;
685 while (*literals++)
686 count++;
687
688 int bits = 0;
689 while (count >> bits)
690 bits++;
691
693}
694
695void
696VcdTraceFile::writeComment(const std::string &comment)
697{
698 stream() << "$comment" << std::endl;
699 stream() << comment << std::endl;
700 stream() << "$end" << std::endl << std::endl;
701}
702
703} // namespace sc_gem5
static sc_time from_value(sc_dt::uint64)
Definition sc_time.cc:210
sc_dt::uint64 value() const
Definition sc_time.cc:115
gem5::Tick getCurTick()
Definition scheduler.hh:243
uint64_t timeUnitTicks
Definition tracefile.hh:195
std::ostream & stream()
Definition tracefile.cc:55
virtual void finalize()
Definition tracefile.hh:58
void writeComment(const std::string &comment) override
Definition vcd.cc:696
void addTraceVal(const bool *v, const std::string &name) override
Definition vcd.cc:339
uint64_t deltasAtNow
Definition vcd.hh:56
char _nextName[NextNameChars+1]
Definition vcd.hh:59
static const int NextNameChars
Definition vcd.hh:58
std::vector< VcdTraceValBase * > traceVals
Definition vcd.hh:65
void addNewTraceVal(const typename TV::TracedType *v, const std::string &name, int width=1)
Definition vcd.hh:83
gem5::Tick lastPrintedTime
Definition vcd.hh:55
std::string nextSignalName()
Definition vcd.cc:205
void trace(bool delta) override
Definition vcd.cc:285
VcdTraceScope topScope
Definition vcd.hh:66
void addValue(const std::string &name, VcdTraceValBase *value)
Definition vcd.cc:143
std::map< std::string, VcdTraceScope * > scopes
Definition vcd.hh:45
std::vector< std::pair< std::string, VcdTraceValBase * > > values
Definition vcd.hh:44
void output(const std::string &name, std::ostream &os)
Definition vcd.cc:158
const char * stripLeadingBits(const char *orig)
Definition vcd.cc:77
char scLogicToVcdState(char in)
Definition vcd.cc:94
VcdTraceValBase(int width)
Definition vcd.cc:132
virtual std::string vcdType()
Definition vcd.cc:137
void printVal(std::ostream &os, const std::string &rep)
Definition vcd.cc:116
void vcdName(const std::string &vcd_name)
Definition vcd.cc:135
const std::string & vcdName()
Definition vcd.cc:136
virtual void output(std::ostream &os)=0
std::string _vcdName
Definition vcd.cc:74
void output(std::ostream &os) override
Definition vcd.cc:332
void output(std::ostream &os) override
Definition vcd.cc:543
std::string vcdType() override
Definition vcd.cc:540
void output(std::ostream &os) override
Definition vcd.cc:406
void finalize() override
Definition vcd.cc:399
void output(std::ostream &os) override
Definition vcd.cc:353
std::string vcdType() override
Definition vcd.cc:350
void output(std::ostream &os) override
Definition vcd.cc:510
void output(std::ostream &os) override
Definition vcd.cc:484
std::string vcdType() override
Definition vcd.cc:481
void output(std::ostream &os) override
Definition vcd.cc:601
void finalize() override
Definition vcd.cc:451
void output(std::ostream &os) override
Definition vcd.cc:458
void output(std::ostream &os) override
Definition vcd.cc:376
std::string vcdType() override
Definition vcd.cc:566
void output(std::ostream &os) override
Definition vcd.cc:576
void finalize() override
Definition vcd.cc:569
static const int TimeWidth
Definition vcd.cc:561
VcdTraceVal(const T *t, const std::string &vcd_name, int width)
Definition vcd.cc:197
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
double s
These variables equal the number of ticks in the unit of time they're named after in a double.
Definition core.cc:51
uint64_t Tick
Tick count type.
Definition types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
const char * sc_version()
Definition functions.cc:44
uint64_t uint64
Definition sc_nbdefs.hh:172
int64_t int64
Definition sc_nbdefs.hh:171
Scheduler scheduler
Definition scheduler.cc:494
#define SC_REPORT_ERROR(msg_type, msg)
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:07 for gem5 by doxygen 1.11.0