1 // -*- mode: C++; c-file-style: "cc-mode" -*- 2 //============================================================================= 3 // 4 // Code available from: https://verilator.org 5 // 6 // Copyright 2001-2021 by Wilson Snyder. This program is free software; you 7 // can redistribute it and/or modify it under the terms of either the GNU 8 // Lesser General Public License Version 3 or the Perl Artistic License 9 // Version 2.0. 10 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 11 // 12 //============================================================================= 13 /// 14 /// \file 15 /// \brief Verilated tracing in FST format header 16 /// 17 /// User wrapper code should use this header when creating FST traces. 18 /// 19 //============================================================================= 20 21 #ifndef VERILATOR_VERILATED_FST_C_H_ 22 #define VERILATOR_VERILATED_FST_C_H_ 23 24 #include "verilated.h" 25 #include "verilated_trace.h" 26 27 #include "gtkwave/fstapi.h" 28 29 #include <list> 30 #include <map> 31 #include <string> 32 #include <vector> 33 34 //============================================================================= 35 // VerilatedFst 36 // Base class to create a Verilator FST dump 37 // This is an internally used class - see VerilatedFstC for what to call from applications 38 39 class VerilatedFst final : public VerilatedTrace<VerilatedFst> { 40 private: 41 // Give the superclass access to private bits (to avoid virtual functions) 42 friend class VerilatedTrace<VerilatedFst>; 43 44 //========================================================================= 45 // FST specific internals 46 47 void* m_fst; 48 std::map<vluint32_t, fstHandle> m_code2symbol; 49 std::map<int, fstEnumHandle> m_local2fstdtype; 50 std::list<std::string> m_curScope; 51 fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array 52 char* m_strbuf = nullptr; // String buffer long enough to hold maxBits() chars 53 54 // CONSTRUCTORS 55 VL_UNCOPYABLE(VerilatedFst); 56 void declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, 57 fstVarType vartype, bool array, int arraynum, int msb, int lsb); 58 59 protected: 60 //========================================================================= 61 // Implementation of VerilatedTrace interface 62 63 // Implementations of protected virtual methods for VerilatedTrace 64 virtual void emitTimeChange(vluint64_t timeui) override; 65 66 // Hooks called from VerilatedTrace preFullDump()67 virtual bool preFullDump() override { return isOpen(); } preChangeDump()68 virtual bool preChangeDump() override { return isOpen(); } 69 70 // Implementations of duck-typed methods for VerilatedTrace. These are 71 // called from only one place (namely full*) so always inline them. 72 inline void emitBit(vluint32_t code, CData newval); 73 inline void emitCData(vluint32_t code, CData newval, int bits); 74 inline void emitSData(vluint32_t code, SData newval, int bits); 75 inline void emitIData(vluint32_t code, IData newval, int bits); 76 inline void emitQData(vluint32_t code, QData newval, int bits); 77 inline void emitWData(vluint32_t code, const WData* newvalp, int bits); 78 inline void emitDouble(vluint32_t code, double newval); 79 80 public: 81 //========================================================================= 82 // External interface to client code 83 // (All must be threadsafe) 84 85 explicit VerilatedFst(void* fst = nullptr); 86 ~VerilatedFst(); 87 88 // Open the file; call isOpen() to see if errors 89 void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex); 90 // Close the file 91 void close() VL_MT_SAFE_EXCLUDES(m_mutex); 92 // Flush any remaining data to this file 93 void flush() VL_MT_SAFE_EXCLUDES(m_mutex); 94 // Return if file is open isOpen()95 bool isOpen() const VL_MT_SAFE { return m_fst != nullptr; } 96 97 //========================================================================= 98 // Internal interface to Verilator generated code 99 100 // Inside dumping routines, declare a data type 101 void declDTypeEnum(int dtypenum, const char* name, vluint32_t elements, 102 unsigned int minValbits, const char** itemNamesp, const char** itemValuesp); 103 104 // Inside dumping routines, declare a signal 105 void declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, 106 fstVarType vartype, bool array, int arraynum); 107 void declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, 108 fstVarType vartype, bool array, int arraynum, int msb, int lsb); 109 void declQuad(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, 110 fstVarType vartype, bool array, int arraynum, int msb, int lsb); 111 void declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, 112 fstVarType vartype, bool array, int arraynum, int msb, int lsb); 113 void declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, 114 fstVarType vartype, bool array, int arraynum); 115 }; 116 117 #ifndef DOXYGEN 118 // Declare specialization here as it's used in VerilatedFstC just below 119 template <> void VerilatedTrace<VerilatedFst>::dump(vluint64_t timeui); 120 template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const char* unitp); 121 template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const std::string& unit); 122 template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const char* unitp); 123 template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const std::string& unit); 124 #endif 125 126 //============================================================================= 127 // VerilatedFstC 128 /// Create a FST dump file in C standalone (no SystemC) simulations. 129 /// Also derived for use in SystemC simulations. 130 131 class VerilatedFstC VL_NOT_FINAL { 132 VerilatedFst m_sptrace; // Trace file being created 133 134 // CONSTRUCTORS 135 VL_UNCOPYABLE(VerilatedFstC); 136 137 public: 138 /// Construct the dump. Optional argument is ignored. 139 explicit VerilatedFstC(void* filep = nullptr) 140 : m_sptrace{filep} {} 141 /// Destruct, flush, and close the dump ~VerilatedFstC()142 ~VerilatedFstC() { close(); } 143 144 // METHODS - User called 145 146 /// Return if file is open isOpen()147 bool isOpen() const VL_MT_SAFE { return m_sptrace.isOpen(); } 148 /// Open a new FST file open(const char * filename)149 void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); } 150 /// Close dump close()151 void close() VL_MT_SAFE { m_sptrace.close(); } 152 /// Flush dump flush()153 void flush() VL_MT_SAFE { m_sptrace.flush(); } 154 /// Write one cycle of dump data 155 /// Call with the current context's time just after eval'ed, 156 /// e.g. ->dump(contextp->time()) dump(vluint64_t timeui)157 void dump(vluint64_t timeui) { m_sptrace.dump(timeui); } 158 /// Write one cycle of dump data - backward compatible and to reduce 159 /// conversion warnings. It's better to use a vluint64_t time instead. dump(double timestamp)160 void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); } dump(vluint32_t timestamp)161 void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); } dump(int timestamp)162 void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); } 163 164 // METHODS - Internal/backward compatible 165 // \protectedsection 166 167 // Set time units (s/ms, defaults to ns) 168 // Users should not need to call this, as for Verilated models, these 169 // propage from the Verilated default timeunit set_time_unit(const char * unitp)170 void set_time_unit(const char* unitp) VL_MT_SAFE { m_sptrace.set_time_unit(unitp); } set_time_unit(const std::string & unit)171 void set_time_unit(const std::string& unit) VL_MT_SAFE { m_sptrace.set_time_unit(unit); } 172 // Set time resolution (s/ms, defaults to ns) 173 // Users should not need to call this, as for Verilated models, these 174 // propage from the Verilated default timeprecision set_time_resolution(const char * unitp)175 void set_time_resolution(const char* unitp) VL_MT_SAFE { 176 m_sptrace.set_time_resolution(unitp); 177 } set_time_resolution(const std::string & unit)178 void set_time_resolution(const std::string& unit) VL_MT_SAFE { 179 m_sptrace.set_time_resolution(unit); 180 } 181 182 // Internal class access spTrace()183 inline VerilatedFst* spTrace() { return &m_sptrace; }; 184 }; 185 186 #endif // guard 187