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