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 * Authors: Gabe Black 28 */ 29 30#ifndef __SYSTEMC_UTILS_TRACEFILE_HH__ 31#define __SYSTEMC_UTILS_TRACEFILE_HH__ 32 33#include <iostream> 34#include <string> 35#include <vector> 36 37#include "systemc/core/event.hh" 38#include "systemc/ext/channel/sc_signal_in_if.hh" 39#include "systemc/ext/core/sc_event.hh" 40#include "systemc/ext/dt/fx/sc_fxnum.hh" 41#include "systemc/ext/utils/sc_trace_file.hh" 42 43class OutputStream; 44 45namespace sc_gem5 46{ 47 48class TraceValBase 49{ 50 protected: 51 int _width; 52 53 public: 54 TraceValBase(int _width) : _width(_width) {} 55 virtual ~TraceValBase() {} 56 57 int width() { return _width; } 58 59 virtual void finalize() {}; 60 virtual bool check() = 0; 61}; 62 63template <typename T, typename Base=TraceValBase> 64class TraceVal : public Base 65{ 66 private: 67 const T *t; 68 T oldVal; 69 70 public: 71 TraceVal(const T *_t, int _width) : Base(_width), t(_t), oldVal(*t) 72 {} 73 ~TraceVal() {} 74 75 void finalize() override { oldVal = *t; } 76 const T &value() { return oldVal; } 77 78 bool 79 check() override 80 { 81 bool changed = (*t != oldVal); 82 oldVal = *t; 83 return changed; 84 } 85}; 86 87template <typename T, typename Base> 88class TraceVal<::sc_core::sc_signal_in_if<T>, Base> : public Base 89{ 90 private: 91 const ::sc_core::sc_signal_in_if<T> *iface; 92 T oldVal; 93 94 public: 95 TraceVal(const ::sc_core::sc_signal_in_if<T> *_iface, int _width) : 96 Base(_width), iface(_iface), oldVal(iface->read()) 97 {} 98 ~TraceVal() {} 99 100 void finalize() override { oldVal = iface->read(); } 101 const T &value() { return oldVal; } 102 103 bool 104 check() override 105 { 106 T newVal = iface->read(); 107 bool changed = (newVal != oldVal); 108 oldVal = newVal; 109 return changed; 110 } 111}; 112 113template <typename Base> 114class TraceVal<::sc_core::sc_event, Base> : public Base 115{ 116 private: 117 bool triggered; 118 uint64_t oldStamp; 119 const Event *event; 120 121 public: 122 TraceVal(const ::sc_core::sc_event *_event, int _width) : 123 Base(_width), triggered(false), oldStamp(0), 124 event(Event::getFromScEvent(_event)) 125 {} 126 ~TraceVal() {} 127 128 bool value() { return triggered; } 129 void finalize() override { oldStamp = event->triggeredStamp(); } 130 131 bool 132 check() override 133 { 134 uint64_t newStamp = event->triggeredStamp(); 135 triggered = (oldStamp != newStamp); 136 oldStamp = newStamp; 137 return triggered; 138 } 139}; 140 141template <typename T, typename Base> 142class TraceValFxnumBase : public Base 143{ 144 private: 145 const T *t; 146 T oldVal; 147 148 public: 149 TraceValFxnumBase(const T *_t, int _width) : 150 Base(_width), t(_t), 151 oldVal(_t->m_params.type_params(), _t->m_params.enc(), 152 _t->m_params.cast_switch(), 0) 153 {} 154 ~TraceValFxnumBase() {} 155 156 void 157 finalize() override 158 { 159 oldVal = *t; 160 this->_width = t->wl(); 161 } 162 163 const T &value() { return oldVal; } 164 165 bool 166 check() override 167 { 168 bool changed = (*t != oldVal); 169 oldVal = *t; 170 return changed; 171 } 172}; 173 174template <typename Base> 175class TraceVal<::sc_dt::sc_fxnum, Base> : 176 public TraceValFxnumBase<::sc_dt::sc_fxnum, Base> 177{ 178 public: 179 using TraceValFxnumBase<::sc_dt::sc_fxnum, Base>::TraceValFxnumBase; 180 ~TraceVal() {} 181}; 182 183template <typename Base> 184class TraceVal<::sc_dt::sc_fxnum_fast, Base> : 185 public TraceValFxnumBase<::sc_dt::sc_fxnum_fast, Base> 186{ 187 public: 188 using TraceValFxnumBase<::sc_dt::sc_fxnum_fast, Base>::TraceValFxnumBase; 189 ~TraceVal() {} 190}; 191 192class TraceFile : public sc_core::sc_trace_file 193{ 194 protected: 195 OutputStream *_os; 196 uint64_t timeUnitTicks; 197 double timeUnitValue; 198 ::sc_core::sc_time_unit timeUnitUnit; 199 200 bool _traceDeltas; 201 202 TraceFile(const std::string &name); 203 204 std::ostream &stream(); 205 206 public: 207 ~TraceFile(); 208 209 void traceDeltas(bool on) { _traceDeltas = on; } 210 211 void set_time_unit(double, ::sc_core::sc_time_unit) override; 212 void finalizeTime(); 213 214 virtual void trace(bool delta) = 0; 215 216 virtual void addTraceVal(const bool *v, const std::string &name) = 0; 217 virtual void addTraceVal(const float *v, const std::string &name) = 0; 218 virtual void addTraceVal(const double *v, const std::string &name) = 0; 219 220 virtual void addTraceVal(const sc_dt::sc_logic *v, 221 const std::string &name) = 0; 222 virtual void addTraceVal(const sc_dt::sc_int_base *v, 223 const std::string &name) = 0; 224 virtual void addTraceVal(const sc_dt::sc_uint_base *v, 225 const std::string &name) = 0; 226 virtual void addTraceVal(const sc_dt::sc_signed *v, 227 const std::string &name) = 0; 228 virtual void addTraceVal(const sc_dt::sc_unsigned *v, 229 const std::string &name) = 0; 230 virtual void addTraceVal(const sc_dt::sc_bv_base *v, 231 const std::string &name) = 0; 232 virtual void addTraceVal(const sc_dt::sc_lv_base *v, 233 const std::string &name) = 0; 234 virtual void addTraceVal(const sc_dt::sc_fxval *v, 235 const std::string &name) = 0; 236 virtual void addTraceVal(const sc_dt::sc_fxval_fast *v, 237 const std::string &name) = 0; 238 virtual void addTraceVal(const sc_dt::sc_fxnum *v, 239 const std::string &name) = 0; 240 virtual void addTraceVal(const sc_dt::sc_fxnum_fast *v, 241 const std::string &name) = 0; 242 243 virtual void addTraceVal(const sc_core::sc_event *v, 244 const std::string &name) = 0; 245 virtual void addTraceVal(const sc_core::sc_time *v, 246 const std::string &name) = 0; 247 248 virtual void addTraceVal(const unsigned char *v, 249 const std::string &name, int width) = 0; 250 virtual void addTraceVal(const char *v, const std::string &name, 251 int width) = 0; 252 virtual void addTraceVal(const unsigned short *v, 253 const std::string &name, int width) = 0; 254 virtual void addTraceVal(const short *v, const std::string &name, 255 int width) = 0; 256 virtual void addTraceVal(const unsigned int *v, 257 const std::string &name, int width) = 0; 258 virtual void addTraceVal(const int *v, const std::string &name, 259 int width) = 0; 260 virtual void addTraceVal(const unsigned long *v, 261 const std::string &name, int width) = 0; 262 virtual void addTraceVal(const long *v, const std::string &name, 263 int width) = 0; 264 265 virtual void addTraceVal(const sc_dt::int64 *v, 266 const std::string &name, int width) = 0; 267 virtual void addTraceVal(const sc_dt::uint64 *v, 268 const std::string &name, int width) = 0; 269 270 virtual void addTraceVal(const unsigned int *, 271 const std::string &name, 272 const char **literals) = 0; 273 274 virtual void writeComment(const std::string &comment) = 0; 275}; 276 277} // namespace sc_gem5 278 279#endif // __SYSTEMC_UTILS_TRACEFILE_HH__ 280