MatchLib
nvhls_module.h
1 /*
2  * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
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 #ifndef MATCH_MODULE_H
17 #define MATCH_MODULE_H
18 
19 #ifndef __SYNTHESIS__
20 #include <map>
21 #endif
22 
35 #if defined(ENABLE_SYNC_RESET)
36 #define NVHLS_NEG_RESET_SIGNAL_IS(port) reset_signal_is(port,false)
37 #define NVHLS_POS_RESET_SIGNAL_IS(port) reset_signal_is(port,true)
38 #else // defined(ENABLE_SYNC_RESET)
39 #define NVHLS_NEG_RESET_SIGNAL_IS(port) async_reset_signal_is(port,false)
40 #define NVHLS_POS_RESET_SIGNAL_IS(port) async_reset_signal_is(port,true)
41 #endif // defined(ENABLE_SYNC_RESET)
42 
43 #include <nvhls_trace.h>
44 #include <nvhls_marshaller.h>
45 #include <nvhls_message.h>
46 
56 #if defined(__SYNTHESIS__) && defined(HLS_CATAPULT) && __cplusplus >= 201103L
57 #define nvhls_concat(s1,s2) (std::string(s2)).c_str()
58 #else
59 #define nvhls_concat(s1,s2) (std::string(s1) + "_" + std::string(s2)).c_str()
60 #endif
61 
62 namespace match {
107 class Module : public sc_module, public nvhls_message {
108  public:
109  // Interface in/out
110  sc_in_clk clk;
111  sc_in<bool> rst;
112 #ifndef __SYNTHESIS__
113  sc_attr_base* module_indicator;
114 #endif
115 
116  Module() : sc_module(sc_gen_unique_name("module")), clk("clk"), rst("rst") {
117 #ifndef __SYNTHESIS__
118  module_indicator = new sc_attr_base("match_module");
119  this->add_attribute(*module_indicator);
120 #endif
121  }
122  Module(sc_module_name nm) : sc_module(nm), clk("clk"), rst("rst") {
123 #ifndef __SYNTHESIS__
124  module_indicator = new sc_attr_base("match_module");
125  this->add_attribute(*module_indicator);
126 #endif
127  }
128 
129  ~Module() {
130 #ifndef __SYNTHESIS__
131  delete module_indicator;
132 #endif
133  }
134 
135  protected:
136 
137 #ifndef __SYNTHESIS__
138  /* A map to store simulation stats. Not instantiated for synthesis. */
139  std::map<std::string, uint64> stats_;
140 #endif
141  Tracer tracer_;
142  Flusher EndT; // Note: this variable is excused from following naming
143  // conventions.
144 #ifndef __SYNTHESIS__
145 
146 
147  bool IsModule(sc_object* obj) {
148  if (!obj)
149  return false;
150  else {
151  if(!obj->kind() || !obj->name())
152  return false;
153  else {
154 #ifndef __SYNTHESIS__
155  return (obj->get_attribute("match_module") != 0);
156 #else
157  std::string objName = obj->name();
158  return ((strncmp(obj->kind(), "sc_module", 9) == 0) &&
159  (objName.find("dummyPortManager") == std::string::npos ) &&
160  (objName.find("rocket") == std::string::npos ) &&
161  (objName.find("router") == std::string::npos )
162  );
163 #endif
164  }
165  }
166  }
167  /* Return a vector of children Modules. A wrapper of get_child_objects(). */
168  std::vector<Module*> GetChildren() {
169  std::vector<sc_object*> children = get_child_objects();
170  std::vector<Module*> result;
171 
172  if(children.size() != 0) {
173  for (unsigned i = 0; i < children.size(); i++) {
174  if (IsModule(children[i])) {
175  result.push_back((Module*)(children[i]));
176  }
177  }
178  }
179 
180  return result;
181  }
182 
183 #endif
184 
185  void IncrStat(const std::string& name, unsigned int num = 1) {
186 #ifndef __SYNTHESIS__
187  stats_[name] = stats_[name] + num;
188 #endif
189  }
190 
191  void IncrStatIndexed(const std::string& name, unsigned int idx,
192  unsigned int num = 1) {
193 #ifndef __SYNTHESIS__
194  std::stringstream final_name;
195  final_name << name << "_" << idx;
196  stats_[final_name.str()] = stats_[final_name.str()] + num;
197 #endif
198  }
199 
200  Tracer& T(int l = 0) {
201 #ifdef NOPRINT
202  l = 10;
203 #endif
204 #ifndef __SYNTHESIS__
205  tracer_.SetCurrentLevel(l);
206  tracer_ << sc_time_stamp() << ": ";
207  if (get_parent() != NULL) {
208  if (get_parent()->get_parent() != NULL) {
209  if (get_parent()->get_parent()->get_parent() != NULL) {
210  if (get_parent()->get_parent()->get_parent()->get_parent() != NULL) {
211  if (get_parent()->get_parent()->get_parent()->get_parent()->get_parent() != NULL) {
212  if (strncmp(get_parent()->get_parent()->get_parent()->get_parent()->get_parent()->basename(), "", 1)) {
213  tracer_ << get_parent()->get_parent()->get_parent()->get_parent()->get_parent()->basename() << ".";
214  }
215  }
216 
217  if (strncmp(get_parent()->get_parent()->get_parent()->get_parent()->basename(), "", 1)) {
218  tracer_ << get_parent()->get_parent()->get_parent()->get_parent()->basename() << ".";
219  }
220  }
221 
222  if (strncmp(get_parent()->get_parent()->get_parent()->basename(), "", 1)) {
223  tracer_ << get_parent()->get_parent()->get_parent()->basename() << ".";
224  }
225  }
226 
227  if (strncmp(get_parent()->get_parent()->basename(), "", 1)) {
228  tracer_ << get_parent()->get_parent()->basename() << ".";
229  }
230  }
231 
232  if (strncmp(get_parent()->basename(), "", 1)) {
233  tracer_ << get_parent()->basename() << ".";
234  }
235  }
236  if (strncmp(basename(), "", 1)) {
237  tracer_ << basename() << ": ";
238  }
239 #endif
240  return tracer_;
241  }
242 
243  Tracer& ASSERT(bool cond) {
244 #ifndef __SYNTHESIS__
245  if (!cond) {
246  // Guarantee a print-out.
247  tracer_.SetCurrentLevel(tracer_.GetTraceLevel());
248  tracer_.SetFatal();
249  } else {
250  // Guarantee it won't print out.
251  tracer_.SetCurrentLevel(tracer_.GetTraceLevel() + 1);
252  }
253  tracer_ << "ASSERTION FAILURE: ";
254  tracer_ << sc_time_stamp() << ": ";
255  if (strncmp(name(), "", 1)) {
256  tracer_ << name() << ": ";
257  }
258 #endif
259  return tracer_;
260  }
261 
262  public:
263  void SetTraceLevel(int l) {
264 #ifndef __SYNTHESIS__
265  tracer_.SetTraceLevel(l);
266  std::vector<Module*> children = GetChildren();
267  for (unsigned int i = 0; i < children.size(); i++) {
268  children[i]->SetTraceLevel(l);
269  }
270 #endif
271  }
272 
273  protected:
274  void RecordEvent(const std::string& name, uint64 param = 0) {
275 // Param is ignored fore now.
276 #ifndef __SYNTHESIS__
277  IncrStat(name);
278 #endif
279  }
280 
281  void PrintStats(std::ostream& ofile, unsigned int lvl, Module* aggregator) {
282 #ifndef __SYNTHESIS__
283  for (std::map<std::string, uint64>::iterator it = stats_.begin();
284  it != stats_.end(); it++) {
285  Indent(ofile, lvl);
286  ofile << it->first << ": " << it->second << std::endl;
287  // Add stat into subtotal if necessary.
288  if (aggregator)
289  aggregator->IncrStat(it->first, it->second);
290  }
291 #endif
292  }
293  void Indent(std::ostream& ofile, unsigned int lvl) {
294 #ifndef __SYNTHESIS__
295  for (unsigned int x = 0; x < 2 * lvl; x++) {
296  ofile << " ";
297  }
298 #endif
299  }
300 
301  public:
302  bool HasStats() {
303 #ifndef __SYNTHESIS__
304  return (stats_.size() != 0);
305 #else
306  return false;
307 #endif
308  }
309  bool ChildrenHaveStats() {
310  bool has_stats = false;
311 #ifndef __SYNTHESIS__
312  std::vector<Module*> children = GetChildren();
313  if(children.size() != 0) {
314  for (unsigned int x = 0; x < children.size(); x++) {
315  has_stats |= children[x]->HasStats();
316  if(!has_stats) {
317  has_stats |= children[x]->ChildrenHaveStats();
318  }
319  }
320  }
321 #endif
322  return has_stats;
323  }
324  void DumpStats(std::ostream& ofile, unsigned int lvl, Module* aggregator) {
325 #ifndef __SYNTHESIS__
326  if (!HasStats() && !ChildrenHaveStats()) {
327  return;
328  }
329 
330  Indent(ofile, lvl);
331  ofile << name() << ":" << std::endl;
332  Module* final_aggregator = ChildrenHaveStats() ? NULL : aggregator;
333  if(HasStats())
334  PrintStats(ofile, lvl + 1, final_aggregator);
335 
336  std::vector<Module*> children = GetChildren();
337 
338  if (ChildrenHaveStats()) {
339 
340  for (unsigned int x = 0; x < children.size(); x++) {
341  children[x]->DumpStats(ofile, lvl + 1, this);
342  }
343 
344  if (lvl == 0) {
345  Indent(ofile, 0);
346  ofile << "Totals:" << std::endl;
347  PrintStats(ofile, 1, aggregator);
348  } else {
349  Indent(ofile, lvl + 1);
350  ofile << "Sub-totals (" << name() << "):" << std::endl;
351  PrintStats(ofile, lvl + 2, aggregator);
352  }
353  }
354 #endif
355  }
356  static const unsigned int width = 0;
357  template <unsigned int Size>
358  void Marshall(Marshaller<Size>& m) {
359  }
360 }; // class Module
361 
362 } // namespace match
363 
364 #endif // MATCH_MODULE_H
Tracer class to dump simulation stats to an output stream (stdout by default).
Definition: nvhls_trace.h:91
Matchlib Module class: a wrapper of sc_module with tracing and stats support.
Definition: nvhls_module.h:107