vcd.cc revision 13245
113245Sgabeblack@google.com/* 213245Sgabeblack@google.com * Copyright 2018 Google, Inc. 313245Sgabeblack@google.com * 413245Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 513245Sgabeblack@google.com * modification, are permitted provided that the following conditions are 613245Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 713245Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 813245Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 913245Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1013245Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1113245Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1213245Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1313245Sgabeblack@google.com * this software without specific prior written permission. 1413245Sgabeblack@google.com * 1513245Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1613245Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1713245Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1813245Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1913245Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2013245Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2113245Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2213245Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2313245Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2413245Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2513245Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2613245Sgabeblack@google.com * 2713245Sgabeblack@google.com * Authors: Gabe Black 2813245Sgabeblack@google.com */ 2913245Sgabeblack@google.com 3013245Sgabeblack@google.com#include "systemc/utils/vcd.hh" 3113245Sgabeblack@google.com 3213245Sgabeblack@google.com#include <ctime> 3313245Sgabeblack@google.com#include <iomanip> 3413245Sgabeblack@google.com 3513245Sgabeblack@google.com#include "base/bitfield.hh" 3613245Sgabeblack@google.com#include "base/cprintf.hh" 3713245Sgabeblack@google.com#include "base/logging.hh" 3813245Sgabeblack@google.com#include "systemc/core/scheduler.hh" 3913245Sgabeblack@google.com#include "systemc/ext/core/sc_event.hh" 4013245Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 4113245Sgabeblack@google.com#include "systemc/ext/core/sc_time.hh" 4213245Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_bv_base.hh" 4313245Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_logic.hh" 4413245Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_lv_base.hh" 4513245Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_fxnum.hh" 4613245Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_fxval.hh" 4713245Sgabeblack@google.com#include "systemc/ext/dt/int/sc_int_base.hh" 4813245Sgabeblack@google.com#include "systemc/ext/dt/int/sc_signed.hh" 4913245Sgabeblack@google.com#include "systemc/ext/dt/int/sc_uint_base.hh" 5013245Sgabeblack@google.com#include "systemc/ext/dt/int/sc_unsigned.hh" 5113245Sgabeblack@google.com#include "systemc/ext/utils/functions.hh" 5213245Sgabeblack@google.com 5313245Sgabeblack@google.comnamespace sc_gem5 5413245Sgabeblack@google.com{ 5513245Sgabeblack@google.com 5613245Sgabeblack@google.comnamespace 5713245Sgabeblack@google.com{ 5813245Sgabeblack@google.com 5913245Sgabeblack@google.comstd::string 6013245Sgabeblack@google.comcleanName(std::string name) 6113245Sgabeblack@google.com{ 6213245Sgabeblack@google.com for (int i = 0; i < name.length(); i++) { 6313245Sgabeblack@google.com if (name[i] == '[') 6413245Sgabeblack@google.com name[i] = '('; 6513245Sgabeblack@google.com else if (name[i] == ']') 6613245Sgabeblack@google.com name[i] = ')'; 6713245Sgabeblack@google.com } 6813245Sgabeblack@google.com return name; 6913245Sgabeblack@google.com} 7013245Sgabeblack@google.com 7113245Sgabeblack@google.com} // anonymous namespace 7213245Sgabeblack@google.com 7313245Sgabeblack@google.comclass VcdTraceValBase : public TraceValBase 7413245Sgabeblack@google.com{ 7513245Sgabeblack@google.com protected: 7613245Sgabeblack@google.com std::string _vcdName; 7713245Sgabeblack@google.com 7813245Sgabeblack@google.com const char * 7913245Sgabeblack@google.com stripLeadingBits(const char *orig) 8013245Sgabeblack@google.com { 8113245Sgabeblack@google.com const char first = orig[0]; 8213245Sgabeblack@google.com 8313245Sgabeblack@google.com if (first != 'z' && first != 'x' && first != '0') 8413245Sgabeblack@google.com return orig; 8513245Sgabeblack@google.com 8613245Sgabeblack@google.com const char *res = orig; 8713245Sgabeblack@google.com while (*++res == first) {} 8813245Sgabeblack@google.com 8913245Sgabeblack@google.com if (first != '0' || *res != '1') 9013245Sgabeblack@google.com res--; 9113245Sgabeblack@google.com 9213245Sgabeblack@google.com return res; 9313245Sgabeblack@google.com } 9413245Sgabeblack@google.com 9513245Sgabeblack@google.com char 9613245Sgabeblack@google.com scLogicToVcdState(char in) 9713245Sgabeblack@google.com { 9813245Sgabeblack@google.com switch (in) { 9913245Sgabeblack@google.com case 'U': 10013245Sgabeblack@google.com case 'X': 10113245Sgabeblack@google.com case 'W': 10213245Sgabeblack@google.com case 'D': 10313245Sgabeblack@google.com return 'x'; 10413245Sgabeblack@google.com case '0': 10513245Sgabeblack@google.com case 'L': 10613245Sgabeblack@google.com return '0'; 10713245Sgabeblack@google.com case '1': 10813245Sgabeblack@google.com case 'H': 10913245Sgabeblack@google.com return '1'; 11013245Sgabeblack@google.com case 'Z': 11113245Sgabeblack@google.com return 'z'; 11213245Sgabeblack@google.com default: 11313245Sgabeblack@google.com return '?'; 11413245Sgabeblack@google.com } 11513245Sgabeblack@google.com } 11613245Sgabeblack@google.com 11713245Sgabeblack@google.com void 11813245Sgabeblack@google.com printVal(std::ostream &os, const std::string &rep) 11913245Sgabeblack@google.com { 12013245Sgabeblack@google.com switch (width()) { 12113245Sgabeblack@google.com case 0: 12213245Sgabeblack@google.com return; 12313245Sgabeblack@google.com case 1: 12413245Sgabeblack@google.com os << rep << vcdName() << std::endl;; 12513245Sgabeblack@google.com return; 12613245Sgabeblack@google.com default: 12713245Sgabeblack@google.com os << "b" << stripLeadingBits(rep.c_str()) << " " << 12813245Sgabeblack@google.com vcdName() << std::endl; 12913245Sgabeblack@google.com return; 13013245Sgabeblack@google.com } 13113245Sgabeblack@google.com } 13213245Sgabeblack@google.com 13313245Sgabeblack@google.com public: 13413245Sgabeblack@google.com VcdTraceValBase(int width) : TraceValBase(width) {} 13513245Sgabeblack@google.com ~VcdTraceValBase() {} 13613245Sgabeblack@google.com 13713245Sgabeblack@google.com void vcdName(const std::string &vcd_name) { _vcdName = vcd_name; } 13813245Sgabeblack@google.com const std::string &vcdName() { return _vcdName; } 13913245Sgabeblack@google.com virtual std::string vcdType() { return "wire"; } 14013245Sgabeblack@google.com 14113245Sgabeblack@google.com virtual void output(std::ostream &os) = 0; 14213245Sgabeblack@google.com}; 14313245Sgabeblack@google.com 14413245Sgabeblack@google.comvoid 14513245Sgabeblack@google.comVcdTraceScope::addValue(const std::string &name, VcdTraceValBase *value) 14613245Sgabeblack@google.com{ 14713245Sgabeblack@google.com size_t pos = name.find_first_of('.'); 14813245Sgabeblack@google.com if (pos == std::string::npos) { 14913245Sgabeblack@google.com values.emplace_back(name, value); 15013245Sgabeblack@google.com } else { 15113245Sgabeblack@google.com std::string sname = name.substr(0, pos); 15213245Sgabeblack@google.com auto it = scopes.find(sname); 15313245Sgabeblack@google.com if (it == scopes.end()) 15413245Sgabeblack@google.com it = scopes.emplace(sname, new VcdTraceScope).first; 15513245Sgabeblack@google.com it->second->addValue(name.substr(pos + 1), value); 15613245Sgabeblack@google.com } 15713245Sgabeblack@google.com} 15813245Sgabeblack@google.com 15913245Sgabeblack@google.comvoid 16013245Sgabeblack@google.comVcdTraceScope::output(const std::string &name, std::ostream &os) 16113245Sgabeblack@google.com{ 16213245Sgabeblack@google.com os << "$scope module " << name << " $end" << std::endl; 16313245Sgabeblack@google.com 16413245Sgabeblack@google.com for (auto &p: values) { 16513245Sgabeblack@google.com const std::string &name = p.first; 16613245Sgabeblack@google.com VcdTraceValBase *value = p.second; 16713245Sgabeblack@google.com 16813245Sgabeblack@google.com int w = value->width(); 16913245Sgabeblack@google.com if (w <= 0) { 17013245Sgabeblack@google.com std::string msg = csprintf("'%s' has 0 bits", name); 17113245Sgabeblack@google.com // The typo in this error message is intentional to match the 17213245Sgabeblack@google.com // Accellera output. 17313245Sgabeblack@google.com SC_REPORT_ERROR("(E710) object cannot not be traced", msg.c_str()); 17413245Sgabeblack@google.com return; 17513245Sgabeblack@google.com } 17613245Sgabeblack@google.com 17713245Sgabeblack@google.com std::string clean_name = cleanName(name); 17813245Sgabeblack@google.com if (w == 1) { 17913245Sgabeblack@google.com ccprintf(os, "$var %s % 3d %s %s $end\n", 18013245Sgabeblack@google.com value->vcdType(), w, value->vcdName(), clean_name); 18113245Sgabeblack@google.com } else { 18213245Sgabeblack@google.com ccprintf(os, "$var %s % 3d %s %s [%d:0] $end\n", 18313245Sgabeblack@google.com value->vcdType(), w, value->vcdName(), clean_name, w - 1); 18413245Sgabeblack@google.com } 18513245Sgabeblack@google.com } 18613245Sgabeblack@google.com 18713245Sgabeblack@google.com for (auto &p: scopes) 18813245Sgabeblack@google.com p.second->output(p.first, os); 18913245Sgabeblack@google.com 19013245Sgabeblack@google.com os << "$upscope $end" << std::endl; 19113245Sgabeblack@google.com} 19213245Sgabeblack@google.com 19313245Sgabeblack@google.comtemplate <typename T> 19413245Sgabeblack@google.comclass VcdTraceVal : public TraceVal<T, VcdTraceValBase> 19513245Sgabeblack@google.com{ 19613245Sgabeblack@google.com public: 19713245Sgabeblack@google.com typedef T TracedType; 19813245Sgabeblack@google.com 19913245Sgabeblack@google.com VcdTraceVal(const T* t, const std::string &vcd_name, int width) : 20013245Sgabeblack@google.com TraceVal<T, VcdTraceValBase>(t, width) 20113245Sgabeblack@google.com { 20213245Sgabeblack@google.com this->vcdName(vcd_name); 20313245Sgabeblack@google.com } 20413245Sgabeblack@google.com}; 20513245Sgabeblack@google.com 20613245Sgabeblack@google.comstd::string 20713245Sgabeblack@google.comVcdTraceFile::nextSignalName() 20813245Sgabeblack@google.com{ 20913245Sgabeblack@google.com std::string name(_nextName); 21013245Sgabeblack@google.com 21113245Sgabeblack@google.com bool carry = false; 21213245Sgabeblack@google.com int pos = NextNameChars - 1; 21313245Sgabeblack@google.com do { 21413245Sgabeblack@google.com carry = (_nextName[pos] == 'z'); 21513245Sgabeblack@google.com if (carry) 21613245Sgabeblack@google.com _nextName[pos--] = 'a'; 21713245Sgabeblack@google.com else 21813245Sgabeblack@google.com _nextName[pos--]++; 21913245Sgabeblack@google.com } while (carry && pos >= 0); 22013245Sgabeblack@google.com 22113245Sgabeblack@google.com return name; 22213245Sgabeblack@google.com} 22313245Sgabeblack@google.com 22413245Sgabeblack@google.comvoid 22513245Sgabeblack@google.comVcdTraceFile::initialize() 22613245Sgabeblack@google.com{ 22713245Sgabeblack@google.com finalizeTime(); 22813245Sgabeblack@google.com 22913245Sgabeblack@google.com // Date. 23013245Sgabeblack@google.com stream() << "$date" << std::endl; 23113245Sgabeblack@google.com time_t long_time; 23213245Sgabeblack@google.com time(&long_time); 23313245Sgabeblack@google.com struct tm *p_tm = localtime(&long_time); 23413245Sgabeblack@google.com stream() << std::put_time(p_tm, " %b %d, %Y %H:%M:%S\n"); 23513245Sgabeblack@google.com stream() << "$end" << std::endl << std::endl; 23613245Sgabeblack@google.com 23713245Sgabeblack@google.com // Version. 23813245Sgabeblack@google.com stream() << "$version" << std::endl; 23913245Sgabeblack@google.com stream() << " " << ::sc_core::sc_version() << std::endl; 24013245Sgabeblack@google.com stream() << "$end" << std::endl << std::endl; 24113245Sgabeblack@google.com 24213245Sgabeblack@google.com // Timescale. 24313245Sgabeblack@google.com stream() << "$timescale" << std::endl; 24413245Sgabeblack@google.com stream() << " " << ::sc_core::sc_time::from_value(timeUnitTicks) << 24513245Sgabeblack@google.com std::endl; 24613245Sgabeblack@google.com stream() << "$end" << std::endl << std::endl; 24713245Sgabeblack@google.com 24813245Sgabeblack@google.com for (auto tv: traceVals) 24913245Sgabeblack@google.com tv->finalize(); 25013245Sgabeblack@google.com 25113245Sgabeblack@google.com topScope.output("SystemC", stream()); 25213245Sgabeblack@google.com 25313245Sgabeblack@google.com stream() << "$enddefinitions $end" << std::endl << std::endl; 25413245Sgabeblack@google.com 25513245Sgabeblack@google.com Tick now = scheduler.getCurTick(); 25613245Sgabeblack@google.com 25713245Sgabeblack@google.com std::string timedump_comment = 25813245Sgabeblack@google.com csprintf("All initial values are dumped below at time " 25913245Sgabeblack@google.com "%g sec = %g timescale units.", 26013245Sgabeblack@google.com static_cast<double>(now) / SimClock::Float::s, 26113245Sgabeblack@google.com static_cast<double>(now / timeUnitTicks)); 26213245Sgabeblack@google.com writeComment(timedump_comment); 26313245Sgabeblack@google.com 26413245Sgabeblack@google.com lastPrintedTime = now / timeUnitTicks; 26513245Sgabeblack@google.com 26613245Sgabeblack@google.com stream() << "$dumpvars" << std::endl; 26713245Sgabeblack@google.com for (auto tv: traceVals) 26813245Sgabeblack@google.com tv->output(stream()); 26913245Sgabeblack@google.com stream() << "$end" << std::endl << std::endl; 27013245Sgabeblack@google.com 27113245Sgabeblack@google.com initialized = true; 27213245Sgabeblack@google.com} 27313245Sgabeblack@google.com 27413245Sgabeblack@google.comVcdTraceFile::~VcdTraceFile() 27513245Sgabeblack@google.com{ 27613245Sgabeblack@google.com for (auto tv: traceVals) 27713245Sgabeblack@google.com delete tv; 27813245Sgabeblack@google.com traceVals.clear(); 27913245Sgabeblack@google.com 28013245Sgabeblack@google.com if (timeUnitTicks) 28113245Sgabeblack@google.com ccprintf(stream(), "#%u\n", scheduler.getCurTick() / timeUnitTicks); 28213245Sgabeblack@google.com} 28313245Sgabeblack@google.com 28413245Sgabeblack@google.comvoid 28513245Sgabeblack@google.comVcdTraceFile::trace(bool delta) 28613245Sgabeblack@google.com{ 28713245Sgabeblack@google.com if (!delta) 28813245Sgabeblack@google.com deltasAtNow = 0; 28913245Sgabeblack@google.com 29013245Sgabeblack@google.com uint64_t deltaOffset = deltasAtNow; 29113245Sgabeblack@google.com 29213245Sgabeblack@google.com if (delta) 29313245Sgabeblack@google.com deltaOffset = deltasAtNow++; 29413245Sgabeblack@google.com 29513245Sgabeblack@google.com if (_traceDeltas != delta) 29613245Sgabeblack@google.com return; 29713245Sgabeblack@google.com 29813245Sgabeblack@google.com if (!initialized) { 29913245Sgabeblack@google.com initialize(); 30013245Sgabeblack@google.com return; 30113245Sgabeblack@google.com } 30213245Sgabeblack@google.com 30313245Sgabeblack@google.com Tick now = scheduler.getCurTick() / timeUnitTicks + deltaOffset; 30413245Sgabeblack@google.com 30513245Sgabeblack@google.com if (now <= lastPrintedTime) { 30613245Sgabeblack@google.com // TODO warn about reversed time? 30713245Sgabeblack@google.com return; 30813245Sgabeblack@google.com } 30913245Sgabeblack@google.com 31013245Sgabeblack@google.com bool time_printed = false; 31113245Sgabeblack@google.com for (auto tv: traceVals) { 31213245Sgabeblack@google.com if (tv->check()) { 31313245Sgabeblack@google.com if (!time_printed) { 31413245Sgabeblack@google.com lastPrintedTime = now; 31513245Sgabeblack@google.com ccprintf(stream(), "#%u\n", now); 31613245Sgabeblack@google.com time_printed = true; 31713245Sgabeblack@google.com } 31813245Sgabeblack@google.com 31913245Sgabeblack@google.com tv->output(stream()); 32013245Sgabeblack@google.com } 32113245Sgabeblack@google.com } 32213245Sgabeblack@google.com if (time_printed) 32313245Sgabeblack@google.com stream() << std::endl; 32413245Sgabeblack@google.com} 32513245Sgabeblack@google.com 32613245Sgabeblack@google.comclass VcdTraceValBool : public VcdTraceVal<bool> 32713245Sgabeblack@google.com{ 32813245Sgabeblack@google.com public: 32913245Sgabeblack@google.com using VcdTraceVal<bool>::VcdTraceVal; 33013245Sgabeblack@google.com 33113245Sgabeblack@google.com void 33213245Sgabeblack@google.com output(std::ostream &os) override 33313245Sgabeblack@google.com { 33413245Sgabeblack@google.com printVal(os, this->value() ? "1" : "0"); 33513245Sgabeblack@google.com } 33613245Sgabeblack@google.com}; 33713245Sgabeblack@google.com 33813245Sgabeblack@google.comvoid 33913245Sgabeblack@google.comVcdTraceFile::addTraceVal(const bool *v, const std::string &name) 34013245Sgabeblack@google.com{ 34113245Sgabeblack@google.com addNewTraceVal<VcdTraceValBool>(v, name); 34213245Sgabeblack@google.com} 34313245Sgabeblack@google.com 34413245Sgabeblack@google.comtemplate <typename T> 34513245Sgabeblack@google.comclass VcdTraceValFloat : public VcdTraceVal<T> 34613245Sgabeblack@google.com{ 34713245Sgabeblack@google.com public: 34813245Sgabeblack@google.com using VcdTraceVal<T>::VcdTraceVal; 34913245Sgabeblack@google.com 35013245Sgabeblack@google.com std::string vcdType() override { return "real"; } 35113245Sgabeblack@google.com 35213245Sgabeblack@google.com void 35313245Sgabeblack@google.com output(std::ostream &os) override 35413245Sgabeblack@google.com { 35513245Sgabeblack@google.com ccprintf(os, "r%.16g %s\n", this->value(), this->vcdName()); 35613245Sgabeblack@google.com } 35713245Sgabeblack@google.com}; 35813245Sgabeblack@google.com 35913245Sgabeblack@google.comvoid 36013245Sgabeblack@google.comVcdTraceFile::addTraceVal(const float *v, const std::string &name) 36113245Sgabeblack@google.com{ 36213245Sgabeblack@google.com addNewTraceVal<VcdTraceValFloat<float>>(v, name); 36313245Sgabeblack@google.com} 36413245Sgabeblack@google.comvoid 36513245Sgabeblack@google.comVcdTraceFile::addTraceVal(const double *v, const std::string &name) 36613245Sgabeblack@google.com{ 36713245Sgabeblack@google.com addNewTraceVal<VcdTraceValFloat<double>>(v, name); 36813245Sgabeblack@google.com} 36913245Sgabeblack@google.com 37013245Sgabeblack@google.comclass VcdTraceValScLogic : public VcdTraceVal<sc_dt::sc_logic> 37113245Sgabeblack@google.com{ 37213245Sgabeblack@google.com public: 37313245Sgabeblack@google.com using VcdTraceVal<sc_dt::sc_logic>::VcdTraceVal; 37413245Sgabeblack@google.com 37513245Sgabeblack@google.com void 37613245Sgabeblack@google.com output(std::ostream &os) override 37713245Sgabeblack@google.com { 37813245Sgabeblack@google.com char str[2] = { 37913245Sgabeblack@google.com scLogicToVcdState(value().to_char()), 38013245Sgabeblack@google.com '\0' 38113245Sgabeblack@google.com }; 38213245Sgabeblack@google.com printVal(os, str); 38313245Sgabeblack@google.com } 38413245Sgabeblack@google.com}; 38513245Sgabeblack@google.com 38613245Sgabeblack@google.comvoid 38713245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_logic *v, const std::string &name) 38813245Sgabeblack@google.com{ 38913245Sgabeblack@google.com addNewTraceVal<VcdTraceValScLogic>(v, name); 39013245Sgabeblack@google.com} 39113245Sgabeblack@google.com 39213245Sgabeblack@google.comtemplate <typename T> 39313245Sgabeblack@google.comclass VcdTraceValFinite : public VcdTraceVal<T> 39413245Sgabeblack@google.com{ 39513245Sgabeblack@google.com public: 39613245Sgabeblack@google.com using VcdTraceVal<T>::VcdTraceVal; 39713245Sgabeblack@google.com 39813245Sgabeblack@google.com void 39913245Sgabeblack@google.com finalize() override 40013245Sgabeblack@google.com { 40113245Sgabeblack@google.com VcdTraceVal<T>::finalize(); 40213245Sgabeblack@google.com this->_width = this->value().length(); 40313245Sgabeblack@google.com } 40413245Sgabeblack@google.com 40513245Sgabeblack@google.com void 40613245Sgabeblack@google.com output(std::ostream &os) override 40713245Sgabeblack@google.com { 40813245Sgabeblack@google.com std::string str; 40913245Sgabeblack@google.com const int w = this->width(); 41013245Sgabeblack@google.com 41113245Sgabeblack@google.com str.reserve(w); 41213245Sgabeblack@google.com for (int i = w - 1; i >= 0; i--) 41313245Sgabeblack@google.com str += this->value()[i].to_bool() ? '1' : '0'; 41413245Sgabeblack@google.com 41513245Sgabeblack@google.com this->printVal(os, str); 41613245Sgabeblack@google.com } 41713245Sgabeblack@google.com}; 41813245Sgabeblack@google.com 41913245Sgabeblack@google.comvoid 42013245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_int_base *v, 42113245Sgabeblack@google.com const std::string &name) 42213245Sgabeblack@google.com{ 42313245Sgabeblack@google.com addNewTraceVal<VcdTraceValFinite<sc_dt::sc_int_base>>(v, name); 42413245Sgabeblack@google.com} 42513245Sgabeblack@google.comvoid 42613245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_uint_base *v, 42713245Sgabeblack@google.com const std::string &name) 42813245Sgabeblack@google.com{ 42913245Sgabeblack@google.com addNewTraceVal<VcdTraceValFinite<sc_dt::sc_uint_base>>(v, name); 43013245Sgabeblack@google.com} 43113245Sgabeblack@google.com 43213245Sgabeblack@google.comvoid 43313245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_signed *v, const std::string &name) 43413245Sgabeblack@google.com{ 43513245Sgabeblack@google.com addNewTraceVal<VcdTraceValFinite<sc_dt::sc_signed>>(v, name); 43613245Sgabeblack@google.com} 43713245Sgabeblack@google.comvoid 43813245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_unsigned *v, 43913245Sgabeblack@google.com const std::string &name) 44013245Sgabeblack@google.com{ 44113245Sgabeblack@google.com addNewTraceVal<VcdTraceValFinite<sc_dt::sc_unsigned>>(v, name); 44213245Sgabeblack@google.com} 44313245Sgabeblack@google.com 44413245Sgabeblack@google.comtemplate <typename T> 44513245Sgabeblack@google.comclass VcdTraceValLogic : public VcdTraceVal<T> 44613245Sgabeblack@google.com{ 44713245Sgabeblack@google.com public: 44813245Sgabeblack@google.com using VcdTraceVal<T>::VcdTraceVal; 44913245Sgabeblack@google.com 45013245Sgabeblack@google.com void 45113245Sgabeblack@google.com finalize() override 45213245Sgabeblack@google.com { 45313245Sgabeblack@google.com VcdTraceVal<T>::finalize(); 45413245Sgabeblack@google.com this->_width = this->value().length(); 45513245Sgabeblack@google.com } 45613245Sgabeblack@google.com 45713245Sgabeblack@google.com void 45813245Sgabeblack@google.com output(std::ostream &os) override 45913245Sgabeblack@google.com { 46013245Sgabeblack@google.com this->printVal(os, this->value().to_string()); 46113245Sgabeblack@google.com } 46213245Sgabeblack@google.com}; 46313245Sgabeblack@google.com 46413245Sgabeblack@google.comvoid 46513245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_bv_base *v, const std::string &name) 46613245Sgabeblack@google.com{ 46713245Sgabeblack@google.com addNewTraceVal<VcdTraceValLogic<::sc_dt::sc_bv_base>>(v, name); 46813245Sgabeblack@google.com} 46913245Sgabeblack@google.comvoid 47013245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_lv_base *v, const std::string &name) 47113245Sgabeblack@google.com{ 47213245Sgabeblack@google.com addNewTraceVal<VcdTraceValLogic<::sc_dt::sc_lv_base>>(v, name); 47313245Sgabeblack@google.com} 47413245Sgabeblack@google.com 47513245Sgabeblack@google.comtemplate <typename T> 47613245Sgabeblack@google.comclass VcdTraceValFxval : public VcdTraceVal<T> 47713245Sgabeblack@google.com{ 47813245Sgabeblack@google.com public: 47913245Sgabeblack@google.com using VcdTraceVal<T>::VcdTraceVal; 48013245Sgabeblack@google.com 48113245Sgabeblack@google.com std::string vcdType() override { return "real"; } 48213245Sgabeblack@google.com 48313245Sgabeblack@google.com void 48413245Sgabeblack@google.com output(std::ostream &os) override 48513245Sgabeblack@google.com { 48613245Sgabeblack@google.com ccprintf(os, "r%.16g %s\n", 48713245Sgabeblack@google.com this->value().to_double(), this->vcdName()); 48813245Sgabeblack@google.com } 48913245Sgabeblack@google.com}; 49013245Sgabeblack@google.com 49113245Sgabeblack@google.comvoid 49213245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_fxval *v, const std::string &name) 49313245Sgabeblack@google.com{ 49413245Sgabeblack@google.com addNewTraceVal<VcdTraceValFxval<sc_dt::sc_fxval>>(v, name); 49513245Sgabeblack@google.com} 49613245Sgabeblack@google.comvoid 49713245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_fxval_fast *v, 49813245Sgabeblack@google.com const std::string &name) 49913245Sgabeblack@google.com{ 50013245Sgabeblack@google.com addNewTraceVal<VcdTraceValFxval<sc_dt::sc_fxval_fast>>(v, name); 50113245Sgabeblack@google.com} 50213245Sgabeblack@google.com 50313245Sgabeblack@google.comtemplate <typename T> 50413245Sgabeblack@google.comclass VcdTraceValFxnum : public VcdTraceVal<T> 50513245Sgabeblack@google.com{ 50613245Sgabeblack@google.com public: 50713245Sgabeblack@google.com using VcdTraceVal<T>::VcdTraceVal; 50813245Sgabeblack@google.com 50913245Sgabeblack@google.com void 51013245Sgabeblack@google.com output(std::ostream &os) override 51113245Sgabeblack@google.com { 51213245Sgabeblack@google.com std::string str; 51313245Sgabeblack@google.com const int w = this->width(); 51413245Sgabeblack@google.com 51513245Sgabeblack@google.com str.reserve(w); 51613245Sgabeblack@google.com for (int i = w - 1; i >= 0; i--) 51713245Sgabeblack@google.com str += this->value()[i] ? '1' : '0'; 51813245Sgabeblack@google.com 51913245Sgabeblack@google.com this->printVal(os, str); 52013245Sgabeblack@google.com } 52113245Sgabeblack@google.com}; 52213245Sgabeblack@google.com 52313245Sgabeblack@google.comvoid 52413245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_fxnum *v, const std::string &name) 52513245Sgabeblack@google.com{ 52613245Sgabeblack@google.com addNewTraceVal<VcdTraceValFxnum<::sc_dt::sc_fxnum>>(v, name); 52713245Sgabeblack@google.com} 52813245Sgabeblack@google.comvoid 52913245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::sc_fxnum_fast *v, 53013245Sgabeblack@google.com const std::string &name) 53113245Sgabeblack@google.com{ 53213245Sgabeblack@google.com addNewTraceVal<VcdTraceValFxnum<::sc_dt::sc_fxnum_fast>>(v, name); 53313245Sgabeblack@google.com} 53413245Sgabeblack@google.com 53513245Sgabeblack@google.comclass VcdTraceValEvent : public VcdTraceVal<::sc_core::sc_event> 53613245Sgabeblack@google.com{ 53713245Sgabeblack@google.com public: 53813245Sgabeblack@google.com using VcdTraceVal<::sc_core::sc_event>::VcdTraceVal; 53913245Sgabeblack@google.com 54013245Sgabeblack@google.com std::string vcdType() override { return "event"; } 54113245Sgabeblack@google.com 54213245Sgabeblack@google.com void 54313245Sgabeblack@google.com output(std::ostream &os) override 54413245Sgabeblack@google.com { 54513245Sgabeblack@google.com if (value()) 54613245Sgabeblack@google.com printVal(os, "1"); 54713245Sgabeblack@google.com else 54813245Sgabeblack@google.com os << std::endl; 54913245Sgabeblack@google.com } 55013245Sgabeblack@google.com}; 55113245Sgabeblack@google.com 55213245Sgabeblack@google.comvoid 55313245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_core::sc_event *v, const std::string &name) 55413245Sgabeblack@google.com{ 55513245Sgabeblack@google.com addNewTraceVal<VcdTraceValEvent>(v, name); 55613245Sgabeblack@google.com} 55713245Sgabeblack@google.com 55813245Sgabeblack@google.comclass VcdTraceValTime : public VcdTraceVal<::sc_core::sc_time> 55913245Sgabeblack@google.com{ 56013245Sgabeblack@google.com private: 56113245Sgabeblack@google.com static const int TimeWidth = 64; 56213245Sgabeblack@google.com 56313245Sgabeblack@google.com public: 56413245Sgabeblack@google.com using VcdTraceVal<::sc_core::sc_time>::VcdTraceVal; 56513245Sgabeblack@google.com 56613245Sgabeblack@google.com std::string vcdType() override { return "time"; } 56713245Sgabeblack@google.com 56813245Sgabeblack@google.com void 56913245Sgabeblack@google.com finalize() override 57013245Sgabeblack@google.com { 57113245Sgabeblack@google.com VcdTraceVal<::sc_core::sc_time>::finalize(); 57213245Sgabeblack@google.com _width = TimeWidth; 57313245Sgabeblack@google.com } 57413245Sgabeblack@google.com 57513245Sgabeblack@google.com void 57613245Sgabeblack@google.com output(std::ostream &os) override 57713245Sgabeblack@google.com { 57813245Sgabeblack@google.com char str[TimeWidth + 1]; 57913245Sgabeblack@google.com str[TimeWidth] = '\0'; 58013245Sgabeblack@google.com 58113245Sgabeblack@google.com const uint64_t val = value().value(); 58213245Sgabeblack@google.com for (int i = 0; i < TimeWidth; i++) 58313245Sgabeblack@google.com str[i] = ::bits(val, TimeWidth - i - 1) ? '1' : '0'; 58413245Sgabeblack@google.com 58513245Sgabeblack@google.com printVal(os, str); 58613245Sgabeblack@google.com } 58713245Sgabeblack@google.com}; 58813245Sgabeblack@google.comvoid 58913245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_core::sc_time *v, const std::string &name) 59013245Sgabeblack@google.com{ 59113245Sgabeblack@google.com addNewTraceVal<VcdTraceValTime>(v, name); 59213245Sgabeblack@google.com} 59313245Sgabeblack@google.com 59413245Sgabeblack@google.comtemplate <typename T> 59513245Sgabeblack@google.comclass VcdTraceValInt : public VcdTraceVal<T> 59613245Sgabeblack@google.com{ 59713245Sgabeblack@google.com public: 59813245Sgabeblack@google.com using VcdTraceVal<T>::VcdTraceVal; 59913245Sgabeblack@google.com 60013245Sgabeblack@google.com void 60113245Sgabeblack@google.com output(std::ostream &os) override 60213245Sgabeblack@google.com { 60313245Sgabeblack@google.com const int w = this->width(); 60413245Sgabeblack@google.com char str[w + 1]; 60513245Sgabeblack@google.com str[w] = '\0'; 60613245Sgabeblack@google.com 60713245Sgabeblack@google.com const uint64_t val = 60813245Sgabeblack@google.com static_cast<uint64_t>(this->value()) & ::mask(sizeof(T) * 8); 60913245Sgabeblack@google.com 61013245Sgabeblack@google.com if (::mask(w) < val) { 61113245Sgabeblack@google.com for (int i = 0; i < w; i++) 61213245Sgabeblack@google.com str[i] = 'x'; 61313245Sgabeblack@google.com } else { 61413245Sgabeblack@google.com for (int i = 0; i < w; i++) 61513245Sgabeblack@google.com str[i] = ::bits(val, w - i - 1) ? '1' : '0'; 61613245Sgabeblack@google.com } 61713245Sgabeblack@google.com 61813245Sgabeblack@google.com this->printVal(os, str); 61913245Sgabeblack@google.com } 62013245Sgabeblack@google.com}; 62113245Sgabeblack@google.com 62213245Sgabeblack@google.comvoid 62313245Sgabeblack@google.comVcdTraceFile::addTraceVal(const unsigned char *v, const std::string &name, 62413245Sgabeblack@google.com int width) 62513245Sgabeblack@google.com{ 62613245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<unsigned char>>(v, name, width); 62713245Sgabeblack@google.com} 62813245Sgabeblack@google.comvoid 62913245Sgabeblack@google.comVcdTraceFile::addTraceVal(const char *v, const std::string &name, int width) 63013245Sgabeblack@google.com{ 63113245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<char>>(v, name, width); 63213245Sgabeblack@google.com} 63313245Sgabeblack@google.comvoid 63413245Sgabeblack@google.comVcdTraceFile::addTraceVal(const unsigned short *v, const std::string &name, 63513245Sgabeblack@google.com int width) 63613245Sgabeblack@google.com{ 63713245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<unsigned short>>(v, name, width); 63813245Sgabeblack@google.com} 63913245Sgabeblack@google.comvoid 64013245Sgabeblack@google.comVcdTraceFile::addTraceVal(const short *v, const std::string &name, int width) 64113245Sgabeblack@google.com{ 64213245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<short>>(v, name, width); 64313245Sgabeblack@google.com} 64413245Sgabeblack@google.comvoid 64513245Sgabeblack@google.comVcdTraceFile::addTraceVal(const unsigned int *v, const std::string &name, 64613245Sgabeblack@google.com int width) 64713245Sgabeblack@google.com{ 64813245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<unsigned int>>(v, name, width); 64913245Sgabeblack@google.com} 65013245Sgabeblack@google.comvoid 65113245Sgabeblack@google.comVcdTraceFile::addTraceVal(const int *v, const std::string &name, int width) 65213245Sgabeblack@google.com{ 65313245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<int>>(v, name, width); 65413245Sgabeblack@google.com} 65513245Sgabeblack@google.comvoid 65613245Sgabeblack@google.comVcdTraceFile::addTraceVal(const unsigned long *v, const std::string &name, 65713245Sgabeblack@google.com int width) 65813245Sgabeblack@google.com{ 65913245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<unsigned long>>(v, name, width); 66013245Sgabeblack@google.com} 66113245Sgabeblack@google.comvoid 66213245Sgabeblack@google.comVcdTraceFile::addTraceVal(const long *v, const std::string &name, int width) 66313245Sgabeblack@google.com{ 66413245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<long>>(v, name, width); 66513245Sgabeblack@google.com} 66613245Sgabeblack@google.com 66713245Sgabeblack@google.comvoid 66813245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::int64 *v, const std::string &name, 66913245Sgabeblack@google.com int width) 67013245Sgabeblack@google.com{ 67113245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<sc_dt::int64>>(v, name, width); 67213245Sgabeblack@google.com} 67313245Sgabeblack@google.comvoid 67413245Sgabeblack@google.comVcdTraceFile::addTraceVal(const sc_dt::uint64 *v, const std::string &name, 67513245Sgabeblack@google.com int width) 67613245Sgabeblack@google.com{ 67713245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<sc_dt::uint64>>(v, name, width); 67813245Sgabeblack@google.com} 67913245Sgabeblack@google.com 68013245Sgabeblack@google.comvoid 68113245Sgabeblack@google.comVcdTraceFile::addTraceVal(const unsigned int *v, const std::string &name, 68213245Sgabeblack@google.com const char **literals) 68313245Sgabeblack@google.com{ 68413245Sgabeblack@google.com uint64_t count = 0; 68513245Sgabeblack@google.com while (*literals++) 68613245Sgabeblack@google.com count++; 68713245Sgabeblack@google.com 68813245Sgabeblack@google.com int bits = 0; 68913245Sgabeblack@google.com while (count >> bits) 69013245Sgabeblack@google.com bits++; 69113245Sgabeblack@google.com 69213245Sgabeblack@google.com addNewTraceVal<VcdTraceValInt<unsigned int>>(v, name, bits); 69313245Sgabeblack@google.com} 69413245Sgabeblack@google.com 69513245Sgabeblack@google.comvoid 69613245Sgabeblack@google.comVcdTraceFile::writeComment(const std::string &comment) 69713245Sgabeblack@google.com{ 69813245Sgabeblack@google.com stream() << "$comment" << std::endl; 69913245Sgabeblack@google.com stream() << comment << std::endl; 70013245Sgabeblack@google.com stream() << "$end" << std::endl << std::endl; 70113245Sgabeblack@google.com} 70213245Sgabeblack@google.com 70313245Sgabeblack@google.com} // namespace sc_gem5 704