scc  2024.06
SystemC components library
tracer_base.cpp
1 /*******************************************************************************
2  * Copyright 2017, 2018 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 "tracer_base.h"
18 #include "observer.h"
19 #include "sc_variable.h"
20 #include "traceable.h"
21 #include <cstring>
22 #include <systemc>
23 
24 #define SC_TRACE_NS ::scc::
25 
26 using namespace sc_dt;
27 namespace scc {
28 using sc_trace_file = sc_core::sc_trace_file;
29 using sc_object = sc_core::sc_object;
30 
31 template <typename T> inline auto try_trace_obj(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) -> bool {
32  if((types_to_trace & trace_types::PORTS) == trace_types::PORTS) {
33  if(auto const* ptr = dynamic_cast<sc_core::sc_in<T> const*>(object)) {
34  if(auto* if_ptr = ptr->get_interface(0)) {
35  SC_TRACE_NS sc_trace(trace_file, *if_ptr, object->name());
36  return true;
37  }
38  }
39  if(auto const* ptr = dynamic_cast<sc_core::sc_inout<T> const*>(object)) {
40  if(auto* if_ptr = ptr->get_interface(0)) {
41  SC_TRACE_NS sc_trace(trace_file, *if_ptr, object->name());
42  return true;
43  }
44  }
45  }
46  if((types_to_trace & trace_types::SIGNALS) == trace_types::SIGNALS) {
47  if(auto const* ptr = dynamic_cast<sc_core::sc_signal_inout_if<T> const*>(object)) {
48  SC_TRACE_NS sc_trace(trace_file, *ptr, object->name());
49  return true;
50  }
51  }
52  return false;
53 }
54 
55 template <size_t SIZE> struct ForLoop {
56  template <template <size_t> class Func>
57  static bool iterate(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
58  if(ForLoop<SIZE - (SIZE > 128 ? 8 : 1)>::template iterate<Func>(trace_file, object, types_to_trace))
59  return true;
60  else
61  return Func<SIZE>()(trace_file, object, types_to_trace);
62  }
63 };
64 
65 template <> struct ForLoop<1> {
66  template <template <size_t> class Func>
67  static bool iterate(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
68  return Func<1>()(trace_file, object, types_to_trace);
69  }
70 };
71 
72 template <size_t size> struct sc_uint_tester {
73  bool operator()(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
74  return try_trace_obj<sc_uint<size>>(trace_file, object, types_to_trace);
75  }
76 };
77 
78 template <size_t size> struct sc_int_tester {
79  bool operator()(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
80  return try_trace_obj<sc_int<size>>(trace_file, object, types_to_trace);
81  }
82 };
83 
84 template <size_t size> struct sc_biguint_tester {
85  bool operator()(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
86  return try_trace_obj<sc_biguint<size>>(trace_file, object, types_to_trace);
87  }
88 };
89 
90 template <size_t size> struct sc_bigint_tester {
91  bool operator()(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
92  return try_trace_obj<sc_bigint<size>>(trace_file, object, types_to_trace);
93  }
94 };
95 
96 template <size_t size> struct sc_bv_tester {
97  bool operator()(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
98  return try_trace_obj<sc_bv<size>>(trace_file, object, types_to_trace);
99  }
100 };
101 
102 template <size_t size> struct sc_lv_tester {
103  bool operator()(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
104  return try_trace_obj<sc_lv<size>>(trace_file, object, types_to_trace);
105  }
106 };
107 
108 void tracer_base::try_trace(sc_trace_file* trace_file, const sc_object* object, trace_types types_to_trace) {
109  if(try_trace_obj<bool>(trace_file, object, types_to_trace))
110  return;
111 
112  if(try_trace_obj<char>(trace_file, object, types_to_trace))
113  return;
114  if(try_trace_obj<unsigned char>(trace_file, object, types_to_trace))
115  return;
116 
117  if(try_trace_obj<short>(trace_file, object, types_to_trace))
118  return;
119  if(try_trace_obj<unsigned short>(trace_file, object, types_to_trace))
120  return;
121 
122  if(try_trace_obj<int>(trace_file, object, types_to_trace))
123  return;
124  if(try_trace_obj<unsigned int>(trace_file, object, types_to_trace))
125  return;
126 
127  if(try_trace_obj<long>(trace_file, object, types_to_trace))
128  return;
129  if(try_trace_obj<unsigned long>(trace_file, object, types_to_trace))
130  return;
131 
132  if(try_trace_obj<long long>(trace_file, object, types_to_trace))
133  return;
134  if(try_trace_obj<unsigned long long>(trace_file, object, types_to_trace))
135  return;
136 
137  if(try_trace_obj<float>(trace_file, object, types_to_trace))
138  return;
139  if(try_trace_obj<double>(trace_file, object, types_to_trace))
140  return;
141 #if(SYSTEMC_VERSION >= 20171012)
142  if(try_trace_obj<sc_core::sc_time>(trace_file, object, types_to_trace))
143  return;
144 #endif
145  if(try_trace_obj<sc_bit>(trace_file, object, types_to_trace))
146  return;
147  if(try_trace_obj<sc_logic>(trace_file, object, types_to_trace))
148  return;
149 #if defined(FULL_TRACE_TYPE_LIST)
150  if(ForLoop<64>::iterate<sc_uint_tester>(trace_file, object, types_to_trace))
151  return;
152  if(ForLoop<64>::iterate<sc_int_tester>(trace_file, object, types_to_trace))
153  return;
154  if(ForLoop<1024>::iterate<sc_biguint_tester>(trace_file, object, types_to_trace))
155  return;
156  if(ForLoop<1024>::iterate<sc_bigint_tester>(trace_file, object, types_to_trace))
157  return;
158  if(ForLoop<1024>::iterate<sc_bv_tester>(trace_file, object, types_to_trace))
159  return;
160  if(ForLoop<1024>::iterate<sc_lv_tester>(trace_file, object, types_to_trace))
161  return;
162 #else
163  if(ForLoop<31>::iterate<sc_uint_tester>(trace_file, object, types_to_trace))
164  return;
165  if(try_trace_obj<sc_uint<32>>(trace_file, object, types_to_trace))
166  return;
167  if(try_trace_obj<sc_uint<40>>(trace_file, object, types_to_trace))
168  return;
169  if(try_trace_obj<sc_uint<48>>(trace_file, object, types_to_trace))
170  return;
171  if(try_trace_obj<sc_uint<56>>(trace_file, object, types_to_trace))
172  return;
173  if(try_trace_obj<sc_uint<64>>(trace_file, object, types_to_trace))
174  return;
175 
176  if(ForLoop<31>::iterate<sc_int_tester>(trace_file, object, types_to_trace))
177  return;
178  if(try_trace_obj<sc_int<32>>(trace_file, object, types_to_trace))
179  return;
180  if(try_trace_obj<sc_int<40>>(trace_file, object, types_to_trace))
181  return;
182  if(try_trace_obj<sc_int<48>>(trace_file, object, types_to_trace))
183  return;
184  if(try_trace_obj<sc_int<56>>(trace_file, object, types_to_trace))
185  return;
186  if(try_trace_obj<sc_int<64>>(trace_file, object, types_to_trace))
187  return;
188 
189  if(try_trace_obj<sc_biguint<32>>(trace_file, object, types_to_trace))
190  return;
191  if(try_trace_obj<sc_biguint<64>>(trace_file, object, types_to_trace))
192  return;
193  if(try_trace_obj<sc_biguint<128>>(trace_file, object, types_to_trace))
194  return;
195  if(try_trace_obj<sc_biguint<256>>(trace_file, object, types_to_trace))
196  return;
197  if(try_trace_obj<sc_biguint<384>>(trace_file, object, types_to_trace))
198  return;
199  if(try_trace_obj<sc_biguint<512>>(trace_file, object, types_to_trace))
200  return;
201  if(try_trace_obj<sc_biguint<1024>>(trace_file, object, types_to_trace))
202  return;
203 
204  if(try_trace_obj<sc_bigint<32>>(trace_file, object, types_to_trace))
205  return;
206  if(try_trace_obj<sc_bigint<64>>(trace_file, object, types_to_trace))
207  return;
208  if(try_trace_obj<sc_bigint<128>>(trace_file, object, types_to_trace))
209  return;
210  if(try_trace_obj<sc_bigint<256>>(trace_file, object, types_to_trace))
211  return;
212  if(try_trace_obj<sc_bigint<384>>(trace_file, object, types_to_trace))
213  return;
214  if(try_trace_obj<sc_bigint<512>>(trace_file, object, types_to_trace))
215  return;
216  if(try_trace_obj<sc_bigint<1024>>(trace_file, object, types_to_trace))
217  return;
218 
219  if(ForLoop<31>::iterate<sc_bv_tester>(trace_file, object, types_to_trace))
220  return;
221  if(try_trace_obj<sc_bv<32>>(trace_file, object, types_to_trace))
222  return;
223  if(try_trace_obj<sc_bv<40>>(trace_file, object, types_to_trace))
224  return;
225  if(try_trace_obj<sc_bv<48>>(trace_file, object, types_to_trace))
226  return;
227  if(try_trace_obj<sc_bv<56>>(trace_file, object, types_to_trace))
228  return;
229  if(try_trace_obj<sc_bv<64>>(trace_file, object, types_to_trace))
230  return;
231  if(try_trace_obj<sc_bv<128>>(trace_file, object, types_to_trace))
232  return;
233  if(try_trace_obj<sc_bv<256>>(trace_file, object, types_to_trace))
234  return;
235  if(try_trace_obj<sc_bv<384>>(trace_file, object, types_to_trace))
236  return;
237  if(try_trace_obj<sc_bv<512>>(trace_file, object, types_to_trace))
238  return;
239  if(try_trace_obj<sc_bv<1024>>(trace_file, object, types_to_trace))
240  return;
241 
242  if(ForLoop<31>::iterate<sc_lv_tester>(trace_file, object, types_to_trace))
243  return;
244  if(try_trace_obj<sc_lv<32>>(trace_file, object, types_to_trace))
245  return;
246  if(try_trace_obj<sc_lv<40>>(trace_file, object, types_to_trace))
247  return;
248  if(try_trace_obj<sc_lv<48>>(trace_file, object, types_to_trace))
249  return;
250  if(try_trace_obj<sc_lv<56>>(trace_file, object, types_to_trace))
251  return;
252  if(try_trace_obj<sc_lv<64>>(trace_file, object, types_to_trace))
253  return;
254  if(try_trace_obj<sc_lv<128>>(trace_file, object, types_to_trace))
255  return;
256  if(try_trace_obj<sc_lv<256>>(trace_file, object, types_to_trace))
257  return;
258  if(try_trace_obj<sc_lv<384>>(trace_file, object, types_to_trace))
259  return;
260  if(try_trace_obj<sc_lv<512>>(trace_file, object, types_to_trace))
261  return;
262  if(try_trace_obj<sc_lv<1024>>(trace_file, object, types_to_trace))
263  return;
264 #endif
265 }
266 
267 std::string tracer_base::get_name() { return sc_core::sc_gen_unique_name("$$$scc_tracer$$$", true); }
268 
269 void tracer_base::descend(const sc_object* obj, bool trace_all) {
270  if(obj == this)
271  return;
272  const char* kind = obj->kind();
273  if(strcmp(kind, "tlm_signal") == 0) {
274  obj->trace(trf);
275  } else if(strcmp(kind, "sc_vector") == 0) {
276  for(auto o : obj->get_child_objects())
277  descend(o, trace_all);
278  } else if((strcmp(kind, "sc_module") == 0 && trace_all) || dynamic_cast<const traceable*>(obj)) {
279  obj->trace(trf);
280  for(auto o : obj->get_child_objects())
281  descend(o, trace_all);
282  } else if(strcmp(kind, "sc_variable") == 0) {
283  if((types_to_trace & trace_types::VARIABLES) == trace_types::VARIABLES)
284  obj->trace(trf);
285  } else if(const auto* tr = dynamic_cast<const scc::traceable*>(obj)) {
286  if(tr->is_trace_enabled())
287  obj->trace(trf);
288  for(auto o : obj->get_child_objects())
289  descend(o, tr->is_trace_enabled());
290  } else {
291  try_trace(trf, obj, types_to_trace);
292  }
293 }
294 } // namespace scc
interface defining a traceable component
Definition: traceable.h:32
SCC TLM utilities.
trace_types
identifies the various type to be traced
Definition: tracer_base.h:35