ParaNut SystemC Model
A SystemC Model of the ParaNut architecture
base.h
Go to the documentation of this file.
1 /************************************************************************
2 *
3  This file is part of the ParaNut project.
4 
5  Copyright (C) 2010-2022 Alexander Bahle <alexander.bahle@hs-augsburg.de>
6  Gundolf Kiefer <gundolf.kiefer@hs-augsburg.de>
7  Christian H. Meyer <christian.meyer@hs-augsburg.de>
8  Hochschule Augsburg, University of Applied Sciences
9 
10  Description:
11  This module contains various types, constants and helper functions
12  for the SystemC model of ParaNut.
13 
14  Redistribution and use in source and binary forms, with or without modification,
15  are permitted provided that the following conditions are met:
16 
17  1. Redistributions of source code must retain the above copyright notice, this
18  list of conditions and the following disclaimer.
19 
20  2. Redistributions in binary form must reproduce the above copyright notice,
21  this list of conditions and the following disclaimer in the documentation and/or
22  other materials provided with the distribution.
23 
24  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 
35  *************************************************************************/
36 
53 
54 #ifndef _BASE_
55 #define _BASE_
56 
62 
63 
64 #include <systemc.h>
65 #include <sstream>
66 
67 // Print useful information during HLS. The tool analyses the source code once without the
68 // __SYNTHESIS__ define set and once with the define set. This printed info helps to discern the two.
69 // Uses #warning, because Vivado HLS does not print #info messages
70 #ifndef SIMBUILD
71 #ifdef __SYNTHESIS__
72 #warning "INFO: __SYNTHESIS__ is set! This is just a ParaNut debug info."
73 #else
74 #warning "INFO: __SYNTHESIS__ is not set! This is just a ParaNut debug info."
75 #endif
76 #endif
77 
81 
87 #define PN_BIG_ENDIAN 0
88 
91 
92 
96 
101 extern int pn_cfg_vcd_level;
102 
110 extern int pn_cfg_insn_trace;
111 
116 extern bool pn_cfg_disable_cache;
117 
125 extern bool pn_cfg_debug_mode;
126 
129 
130 
134 
136 #define KB 1024
138 #define MB (1024 * 1024)
140 #define GB (1024 * 1024 * 1024)
141 
143 typedef unsigned char TByte;
145 typedef unsigned short THalfWord;
147 typedef unsigned TWord;
149 typedef unsigned long long TDWord;
150 
152 #define MIN(A, B) ((A) < (B) ? (A) : (B))
154 #define MAX(A, B) ((A) > (B) ? (A) : (B))
156 #define NUM_BITS(A) ((int)(ceil(log2 (A))))
158 #define C(MEMBER) (MEMBER == t.MEMBER)
160 #define C_ARR(MEMBER, NUM) ({ bool ret = 1; for (int n = 0; n < NUM; ++n) if (!C(MEMBER[n])) ret = 0; ret; })
161 
162 
164 #define XLEN 32
165 
168 
169 
173 
178 extern bool pn_trace_verbose;
179 
180 
193 #ifndef __SYNTHESIS__
194 std::string pn_GetTraceName (sc_object *obj, const char *name, int dim, int arg1, int arg2);
195 #else
196 std::string pn_GetTraceName (...) {
197  return "\0";
198 }
199 #endif
200 
207 #define PN_TRACE(TF, OBJ) \
208  { \
209  if (TF) sc_trace (TF, OBJ, pn_GetTraceName (&(OBJ), #OBJ, 0, 0, 0)); \
210  if (!TF || pn_trace_verbose) cout << " " #OBJ " = '" << (OBJ).name () << "'\n"; \
211  }
212 
220 #define PN_TRACE_BUS(TF, OBJ, N_MAX) \
221  { \
222  for (int n = 0; n < N_MAX; n++) { \
223  if (TF) sc_trace (TF, (OBJ)[n], pn_GetTraceName (&(OBJ)[n], #OBJ, 1, n, 0)); \
224  if (!TF || pn_trace_verbose) \
225  cout << " " #OBJ "[" << n << "] = '" << (OBJ)[n].name () << "'\n"; \
226  } \
227  }
228 
237 #define PN_TRACE_BUS_BUS(TF, OBJ, N_MAX, K_MAX) \
238  { \
239  for (int n = 0; n < N_MAX; n++) \
240  for (int k = 0; k < K_MAX; k++) { \
241  if (TF) sc_trace (TF, (OBJ)[n][k], pn_GetTraceName (&(OBJ)[n][k], #OBJ, 2, n, k)); \
242  if (!TF || pn_trace_verbose) \
243  cout << " " #OBJ "[" << n << "][" << k << "] = '" << (OBJ)[n][k].name () << "'\n"; \
244  } \
245  }
246 
255 #define PN_TRACE_R(TF, OBJ, MEMBER, STR) \
256  { \
257  if (TF) sc_trace (TF, (OBJ).MEMBER, STR + "."#MEMBER); \
258  }
259 
270 #define PN_TRACE_R_BUS(TF, OBJ, MEMBER, STR, N_MAX) \
271  { \
272  std::stringstream ss; \
273  for (int n = 0; n < N_MAX; n++) { \
274  ss << n; \
275  if (TF) sc_trace (TF, (OBJ).MEMBER[n], STR + "."#MEMBER"(" + ss.str().c_str() + ")"); \
276  } \
277  }
278 
290 #define PN_TRACE_R_BUS_BUS(TF, OBJ, MEMBER, STR, N_MAX, K_MAX) \
291  { \
292  std::stringstream ss_n, ss_k; \
293  for (int n = 0; n < N_MAX; n++) { \
294  for (int k = 0; k < K_MAX; k++) { \
295  ss_n << n; \
296  ss_k << k; \
297  if (TF) sc_trace (TF, (OBJ).MEMBER[n][k], STR + "."#MEMBER"(" + ss_n.str().c_str() + ")(" + ss_k.str().c_str() + ")"); \
298  } \
299  } \
300  }
301 
304 
305 
309 
313 extern sc_trace_file *pn_trace_file;
314 
322 char *pn_TbPrintf (const char *format, ...);
334 void pn_TbAssert (bool cond, const char *msg, const char *filename, const int line);
345 void pn_TbInfo (const char *msg, const char *filename, const int line);
356 void pn_TbWarning (const char *msg, const char *filename, const int line);
368 void pn_TbError (const char *msg, const char *filename, const int line);
369 
370 
371 #ifndef __SYNTHESIS__
377 #define PN_ASSERT(COND) pn_TbAssert (COND, NULL, __FILE__, __LINE__)
387 #define PN_ASSERTF(COND, FMT) pn_TbAssert (COND, pn_TbPrintf FMT, __FILE__, __LINE__)
396 #define PN_ASSERTM(COND, MSG) pn_TbAssert (COND, MSG, __FILE__, __LINE__)
397 
403 #define PN_INFO(MSG) pn_TbInfo (MSG, __FILE__, __LINE__)
411 #define PN_INFOF(FMT) pn_TbInfo (pn_TbPrintf FMT, __FILE__, __LINE__)
412 
418 #define PN_WARNING(MSG) pn_TbWarning (MSG, __FILE__, __LINE__)
426 #define PN_WARNINGF(FMT) pn_TbWarning (pn_TbPrintf FMT, __FILE__, __LINE__)
427 
433 #define PN_ERROR(MSG) pn_TbError (MSG, __FILE__, __LINE__)
441 #define PN_ERRORF(FMT) pn_TbError (pn_TbPrintf FMT, __FILE__, __LINE__)
442 
443 
448 static struct {
449  template <typename T> operator sc_core::sc_signal_inout_if<T> & () const {
450  return *(new sc_core::sc_signal<T> (sc_core::sc_gen_unique_name ("vh_open")));
451  }
452 
453 } const vh_open = {};
454 
462 template <typename T>
463 sc_core::sc_signal_in_if<T> const &vh_const (T const &v) // keep the name consistent with vh_open
464 {
465  // Yes, this is an (elaboration-time) memory leak. You can avoid it with some extra effort
466  sc_core::sc_signal<T> *sig_p =
467  new sc_core::sc_signal<T> (sc_core::sc_gen_unique_name ("vh_const"));
468  sig_p->write (v);
469  return *sig_p;
470 }
471 
472 #else // #ifdef __SYNTHESIS__
473 #define PN_ASSERT(COND)
474 #define PN_ASSERTF(COND, FMT)
475 #define PN_ASSERTM(COND, MSG)
476 
477 #define PN_INFO(MSG)
478 #define PN_INFOF(FMT)
479 
480 #define PN_WARNING(MSG)
481 #define PN_WARNINGF(FMT)
482 
483 #define PN_ERROR(MSG)
484 #define PN_ERRORF(FMT)
485 #endif // #ifndef __SYNTHESIS__
486 
487 
497 char *pn_DisAss (TWord insn);
498 
501 
502 
506 
508 class CEventDef {
509 public:
511  const char *name;
513  bool is_timed;
514 };
515 
516 
518 class CPerfMon {
519 public:
521  CPerfMon () { Init (0, NULL); }
523  CPerfMon (int events, CEventDef *ev_tab) { Init (events, ev_tab); }
525  ~CPerfMon () { Done (); }
526 
528  void Init (int events, CEventDef *ev_tab);
530  void Done ();
531 
533  void Reset ();
535  void Count (int ev_no);
536 
538  void Display (const char *name = NULL);
539 
540 protected:
542  int events_;
548  double *time_tab_,
553 
555  double last_stamp_;
557  int last_no_;
558 };
559 
560 
561 // ***** CPerfMonCPU *****
564 
566 #ifndef __SYNTHESIS__
567 class CPerfMonCPU : public CPerfMon {
568 public:
570  CPerfMonCPU () { Init (); }
572  void Init ();
573 
575  void Count (EEventsCPU ev_no) { CPerfMon::Count ((int)ev_no); }
576 };
577 #else
578 class CPerfMonCPU {
579 public:
580  CPerfMonCPU () {}
581 
582  void Display () { /* nothing */
583  }
584  void Count (EEventsCPU ev_no) { /* nothing */
585  }
586 };
587 #endif
588 
591 
592 #ifdef __SC_TOOL__
593 #define PN_CLOCK_TRIGGERED(method_name) SC_CTHREAD(method_name, clk.pos());
594 #else
595 #define PN_CLOCK_TRIGGERED(method_name) SC_METHOD(method_name) sensitive << clk.pos();
596 #endif
598 #endif
Event definition class.
Definition: base.h:508
bool is_timed
0 - event is just counted, 1 - event is timed.
Definition: base.h:513
const char * name
Event name for displaying.
Definition: base.h:511
CPU performance monitor class.
Definition: base.h:567
void Count(EEventsCPU ev_no)
Call CPerfMon::Count() after casting EEventsCPU to int.
Definition: base.h:575
void Init()
Call CPerfMon::Init() for EEventsCPU events and event definitions.
Definition: base.cpp:332
CPerfMonCPU()
Default constructor for EEventsCPU events and event definitions.
Definition: base.h:570
Performance monitor class.
Definition: base.h:518
int * count_tab_
Event counter table.
Definition: base.h:546
double * min_tab_
Event minimal time table.
Definition: base.h:550
CPerfMon(int events, CEventDef *ev_tab)
Constructor for supplying number of events and event definition(s).
Definition: base.h:523
void Count(int ev_no)
Count an event at current simulation time.
Definition: base.cpp:268
double * max_tab_
Event maximum time table.
Definition: base.h:552
~CPerfMon()
Destructor.
Definition: base.h:525
void Done()
Free reserved memory for performance monitoring.
Definition: base.cpp:248
void Display(const char *name=NULL)
Display the collected performance information.
Definition: base.cpp:299
double last_stamp_
Time stamp of last event.
Definition: base.h:555
int last_no_
Event number of last event.
Definition: base.h:557
CEventDef * ev_tab_
Pointer to event definition(s).
Definition: base.h:544
double * time_tab_
Event total time table.
Definition: base.h:548
CPerfMon()
Default constructor, 0 events and no event definitions.
Definition: base.h:521
void Reset()
Reset performance monitor (counted events/times, not number of events and event definition(s)).
Definition: base.cpp:258
void Init(int events, CEventDef *ev_tab)
Init performance monitor for supplied number of events and event definition(s).
Definition: base.cpp:237
int events_
Number of events this performance monitor monitors.
Definition: base.h:542
void pn_TbWarning(const char *msg, const char *filename, const int line)
Testbench warning helper.
Definition: base.cpp:118
unsigned TWord
Word type (32 Bit).
Definition: base.h:147
bool pn_cfg_disable_cache
Cache enable override.
Definition: base.cpp:48
void pn_TbInfo(const char *msg, const char *filename, const int line)
Testbench information helper.
Definition: base.cpp:112
int pn_cfg_insn_trace
Internal simulation instruction trace level.
Definition: base.cpp:47
unsigned short THalfWord
Half word type (16 Bit).
Definition: base.h:145
unsigned long long TDWord
Double word type (64 Bit).
Definition: base.h:149
void pn_TbError(const char *msg, const char *filename, const int line)
Testbench error helper.
Definition: base.cpp:124
char * pn_TbPrintf(const char *format,...)
Testbench printf helper.
Definition: base.cpp:89
int pn_cfg_vcd_level
VCD trace level.
Definition: base.cpp:46
char * pn_DisAss(TWord insn)
Dissassemble RISC-V instructions to C string.
Definition: base.cpp:135
std::string pn_GetTraceName(sc_object *obj, const char *name, int dim, int arg1, int arg2)
Generates and returns a trace file compatible string.
Definition: base.cpp:58
bool pn_trace_verbose
Output verbose tracing information.
Definition: base.cpp:55
void pn_TbAssert(bool cond, const char *msg, const char *filename, const int line)
Testbench assert helper.
Definition: base.cpp:99
sc_trace_file * pn_trace_file
ParaNut trace file pointer.
Definition: base.cpp:86
bool pn_cfg_debug_mode
Interactive debug mode enable.
Definition: base.cpp:49
unsigned char TByte
Byte type (8 Bit).
Definition: base.h:143
sc_core::sc_signal_in_if< T > const & vh_const(T const &v)
vvh_const type/struct (vhdl constant value equivalent)
Definition: base.h:463
EEventsCPU
CPU performance monitor events enum.
Definition: base.h:563
@ EV_JUMP
Definition: base.h:563
@ EV_ALU
Definition: base.h:563
@ EV_LOAD
Definition: base.h:563
@ EV_STORE
Definition: base.h:563
@ EV_OTHER
Definition: base.h:563
@ EV_IFETCH
Definition: base.h:563