scc  2022.4.0
SystemC components library
value_registry.cpp
1 /*******************************************************************************
2  * Copyright 2018-2022 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 
17 #include "value_registry.h"
18 #include <cstring>
19 #include <sstream>
20 #include <string>
21 #include <sysc/datatypes/fx/sc_fxnum.h>
22 #include <sysc/datatypes/fx/sc_fxval.h>
23 #include <unordered_map>
24 
25 using namespace sc_core;
26 namespace scc {
27 
28 auto operator<<(std::ostream& os, const sc_event& evt) -> std::ostream& {
29 #if SYSTEMC_VERSION >= 20181013
30  os << evt.triggered();
31 #endif
32  return os;
33 }
34 
35 #if SC_VERSION_MAJOR <= 2 && SC_VERSION_MINOR <= 3 && SC_VERSION_PATCH < 2
36 #define OVERRIDE
37 #elif defined(NCSC)
38 #define OVERRIDE
39 #else
40 #define OVERRIDE override
41 #endif
42 class SC_API value_registry_impl : public sc_trace_file {
43 public:
44  // Constructor
45  value_registry_impl() = default;
46 
47  auto get_mod4name(const std::string& name) const -> sc_module* {
48  sc_module* mod = nullptr;
49  sc_object* obj = sc_find_object(name.c_str());
50  if(obj)
51  return mod;
52  auto pos = name.length() - 1;
53  do {
54  pos = name.find_last_of('.', pos);
55  mod = dynamic_cast<sc_module*>(sc_find_object(name.substr(0, pos).c_str()));
56  } while(pos > 0 && mod == nullptr);
57  return mod;
58  }
59 #define DECL_TRACE_METHOD_A(tp) \
60  void trace(const tp& object, const std::string& name) OVERRIDE { \
61  if(sc_core::sc_find_object(name.c_str()) != nullptr) { \
62  if(sc_module* mod = get_mod4name(name)) { \
63  sc_get_curr_simcontext()->hierarchy_push(mod); \
64  auto* o = new sc_ref_variable<tp>(name, object); \
65  sc_get_curr_simcontext()->hierarchy_pop(); \
66  holder[name] = o; \
67  } \
68  } \
69  }
70 #define DECL_TRACE_METHOD_B(tp) \
71  void trace(const tp& object, const std::string& name, int width) OVERRIDE { \
72  if(sc_core::sc_find_object(name.c_str()) != nullptr) { \
73  if(sc_module* mod = get_mod4name(name)) { \
74  sc_get_curr_simcontext()->hierarchy_push(mod); \
75  auto* o = new sc_ref_variable_masked<tp>(name, object, width); \
76  sc_get_curr_simcontext()->hierarchy_pop(); \
77  holder[name] = o; \
78  } \
79  } \
80  } \
81  void trace(const tp& object, const std::string& name) { trace(object, name, sizeof(tp) * 8); }
82 
83  void trace(const bool& object, const std::string& name) override {
84  if(sc_core::sc_find_object(name.c_str()) == nullptr) {
85  if(sc_module* mod = get_mod4name(name)) {
86  sc_get_curr_simcontext()->hierarchy_push(mod);
87  auto* o = new sc_ref_variable<bool>(name.substr(strlen(mod->name()) + 1), object);
88  sc_get_curr_simcontext()->hierarchy_pop();
89  holder[name] = o;
90  }
91  }
92  }
93 #if(SYSTEMC_VERSION >= 20171012)
94  DECL_TRACE_METHOD_A(sc_event) // NOLINT
95  DECL_TRACE_METHOD_A(sc_time)
96 #endif
97  DECL_TRACE_METHOD_A(sc_dt::sc_bit)
98  DECL_TRACE_METHOD_A(sc_dt::sc_logic)
99 
100  DECL_TRACE_METHOD_B(unsigned char)
101  DECL_TRACE_METHOD_B(unsigned short)
102  DECL_TRACE_METHOD_B(unsigned int)
103  DECL_TRACE_METHOD_B(unsigned long)
104  DECL_TRACE_METHOD_B(char)
105  DECL_TRACE_METHOD_B(short)
106  DECL_TRACE_METHOD_B(int)
107  DECL_TRACE_METHOD_B(long)
108  DECL_TRACE_METHOD_B(sc_dt::int64)
109  DECL_TRACE_METHOD_B(sc_dt::uint64)
110 
111  DECL_TRACE_METHOD_A(float)
112  DECL_TRACE_METHOD_A(double)
113  DECL_TRACE_METHOD_A(sc_dt::sc_int_base)
114  DECL_TRACE_METHOD_A(sc_dt::sc_uint_base)
115  DECL_TRACE_METHOD_A(sc_dt::sc_signed)
116  DECL_TRACE_METHOD_A(sc_dt::sc_unsigned)
117 
118  DECL_TRACE_METHOD_A(sc_dt::sc_fxval)
119  DECL_TRACE_METHOD_A(sc_dt::sc_fxval_fast)
120  DECL_TRACE_METHOD_A(sc_dt::sc_fxnum)
121  DECL_TRACE_METHOD_A(sc_dt::sc_fxnum_fast)
122 
123  DECL_TRACE_METHOD_A(sc_dt::sc_bv_base)
124  DECL_TRACE_METHOD_A(sc_dt::sc_lv_base)
125 
126 #undef DECL_TRACE_METHOD_A
127 #undef DECL_TRACE_METHOD_B
128 
129  // Trace an enumerated object - where possible output the enumeration
130  // literals in the trace file. Enum literals is a null terminated array
131  // of null terminated char* literal strings.
132  void trace(const unsigned int& object, const std::string& name, const char** enum_literals) override {}
133 
134  // Output a comment to the trace file
135  void write_comment(const std::string& comment) override {}
136 
137  // Set the amount of space before next column
138  // (For most formats this does nothing)
139  // void space( int n );
140 
141  // Also trace transitions between delta cycles if flag is true.
142  // void delta_cycles( bool flag );
143 
144  // Set time unit.
145  void set_time_unit(double v, sc_time_unit tu) override{};
146 
147  // Write trace info for cycle
148  void cycle(bool delta_cycle) override {}
149 
150  // Helper for event tracing
151  auto event_trigger_stamp(const sc_event& event) const -> const sc_dt::uint64& { return dummy; }
152 
153  // Flush results and close file
154  ~value_registry_impl() override {
155  for(auto kv : holder)
156  delete kv.second;
157  }
158 
159  std::unordered_map<std::string, sc_variable_b*> holder;
160 
161  sc_dt::uint64 dummy = 0;
162 #ifdef NCSC
163  void set_time_unit(int exponent10_seconds) override {}
164 #endif
165 };
166 
167 value_registry::value_registry()
168 : tracer_base(sc_core::sc_module_name(sc_core::sc_gen_unique_name("value_registrar", true))) {
169  trf = new value_registry_impl();
170 }
171 
172 scc::value_registry::~value_registry() { delete dynamic_cast<value_registry_impl*>(trf); }
173 
174 auto scc::value_registry::get_names() const -> std::vector<std::string> {
175  auto& holder = dynamic_cast<value_registry_impl*>(trf)->holder;
176  std::vector<std::string> keys;
177  keys.reserve(holder.size());
178  for(auto kv : holder)
179  keys.push_back(kv.first);
180  return keys;
181 }
182 
183 auto scc::value_registry::get_value(std::string name) const -> const sc_variable_b* {
184  auto* reg = dynamic_cast<value_registry_impl*>(trf);
185  auto it = reg->holder.find(name);
186  if(it != reg->holder.end()) {
187  std::cerr << "returning value holder ptr" << std::endl;
188  return it->second;
189  }
190  std::cerr << "returning nullptr" << std::endl;
191  return nullptr;
192 }
193 
194 void scc::value_registry::end_of_elaboration() {
195  for(auto o : sc_get_top_level_objects())
196  descend(o, true);
197 }
198 } // namespace scc
base class for automatic tracer
Definition: tracer_base.h:78
SCC SystemC utilities.
the sc_ref_variable for a particular plain data type. This marks an existing C++ variable as discover...
Definition: sc_variable.h:419