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