1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //=============================================================================
3 //
4 // Copyright 2001-2021 by Wilson Snyder. This program is free software; you can
5 // redistribute it and/or modify it under the terms of either the GNU
6 // Lesser General Public License Version 3 or the Perl Artistic License
7 // Version 2.0.
8 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
9 //
10 //=============================================================================
11 ///
12 /// \file
13 /// \brief Verilated tracing in VCD format for SystemC header
14 ///
15 /// User wrapper code should use this header when creating VCD SystemC
16 /// traces.
17 ///
18 /// This class is not threadsafe, as the SystemC kernel is not threadsafe.
19 ///
20 //=============================================================================
21 
22 #ifndef VERILATOR_VERILATED_VCD_SC_H_
23 #define VERILATOR_VERILATED_VCD_SC_H_
24 
25 #include "verilatedos.h"
26 #include "verilated_sc.h"
27 #include "verilated_vcd_c.h"
28 
29 //=============================================================================
30 // VerilatedVcdSc
31 ///
32 /// Class representing a Verilator-friendly VCD trace format registered
33 /// with the SystemC simulation kernel, just like a SystemC-documented
34 /// trace format.
35 
36 class VerilatedVcdSc final : sc_trace_file, public VerilatedVcdC {
37     // CONSTRUCTORS
38     VL_UNCOPYABLE(VerilatedVcdSc);
39 
40 public:
41     /// Construct a SC trace object, and register with the SystemC kernel
VerilatedVcdSc()42     VerilatedVcdSc() {
43         sc_get_curr_simcontext()->add_trace_file(this);
44         // We want to avoid a depreciated warning, but still be back compatible.
45         // Turning off the message just for this still results in an
46         // annoying "to turn off" message.
47         const sc_time t1sec{1, SC_SEC};
48         if (t1sec.to_default_time_units() != 0) {
49             const sc_time tunits{1.0 / t1sec.to_default_time_units(), SC_SEC};
50             spTrace()->set_time_unit(tunits.to_string());
51         }
52         spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
53     }
54     /// Destruct, flush, and close the dump
~VerilatedVcdSc()55     virtual ~VerilatedVcdSc() { close(); }
56 
57     // METHODS - for SC kernel
58     // Called by SystemC simulate()
cycle(bool delta_cycle)59     virtual void cycle(bool delta_cycle) {
60         if (!delta_cycle) this->dump(sc_time_stamp().to_double());
61     }
62 
63 private:
64     // METHODS - Fake outs for linker
65 
66 #ifdef NC_SYSTEMC
67     // Cadence Incisive has these as abstract functions so we must create them
set_time_unit(int exponent10_seconds)68     virtual void set_time_unit(int exponent10_seconds) {}  // deprecated
69 #endif
set_time_unit(double v,sc_time_unit tu)70     virtual void set_time_unit(double v, sc_time_unit tu) {}  // LCOV_EXCL_LINE
71 
72 //--------------------------------------------------
73 // SystemC 2.1.v1
74 #define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const std::string& name);
75 #define DECL_TRACE_METHOD_B(tp) \
76     virtual void trace(const tp& object, const std::string& name, int width);
77 
78     virtual void write_comment(const std::string&);
79     virtual void trace(const unsigned int&, const std::string&, const char**);
80 
81     // clang-format off
82     // Formatting matches that of sc_trace.h
83 #if (SYSTEMC_VERSION >= 20171012)
84     DECL_TRACE_METHOD_A( sc_event )
85     DECL_TRACE_METHOD_A( sc_time )
86 #endif
87 
88     DECL_TRACE_METHOD_A( bool )
89     DECL_TRACE_METHOD_A( sc_dt::sc_bit )
90     DECL_TRACE_METHOD_A( sc_dt::sc_logic )
91 
92     DECL_TRACE_METHOD_B( unsigned char )
93     DECL_TRACE_METHOD_B( unsigned short )
94     DECL_TRACE_METHOD_B( unsigned int )
95     DECL_TRACE_METHOD_B( unsigned long )
96 #ifdef SYSTEMC_64BIT_PATCHES
97     DECL_TRACE_METHOD_B( unsigned long long)
98 #endif
99     DECL_TRACE_METHOD_B( char )
100     DECL_TRACE_METHOD_B( short )
101     DECL_TRACE_METHOD_B( int )
102     DECL_TRACE_METHOD_B( long )
103     DECL_TRACE_METHOD_B( sc_dt::int64 )
104     DECL_TRACE_METHOD_B( sc_dt::uint64 )
105 
106     DECL_TRACE_METHOD_A( float )
107     DECL_TRACE_METHOD_A( double )
108     DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
109     DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
110     DECL_TRACE_METHOD_A( sc_dt::sc_signed )
111     DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
112 
113     DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
114     DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
115     DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
116     DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
117 
118     DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
119     DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
120     // clang-format on
121 
122 #undef DECL_TRACE_METHOD_A
123 #undef DECL_TRACE_METHOD_B
124 };
125 
126 #endif  // Guard
127