A SystemC productivity library for virtual platform development utilizing SCV and TLM2.0 https://www.minres.com/#opensource

utilities.h 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*******************************************************************************
  2. * Copyright 2016, 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. * utilities.h
  18. *
  19. * Created on: Nov 5, 2016
  20. * Author: eyck
  21. */
  22. #ifndef _SYSC_UTILITIES_H_
  23. #define _SYSC_UTILITIES_H_
  24. #include "traceable.h"
  25. #include <memory>
  26. // pragmas to disable the deprecated warnings for SystemC headers
  27. #pragma GCC diagnostic push
  28. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  29. #include <systemc>
  30. #pragma GCC diagnostic pop
  31. #include <locale>
  32. #if __cplusplus < 201402L
  33. namespace std {
  34. template <typename T, typename... Args> std::unique_ptr<T> make_unique(Args &&... args) {
  35. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  36. }
  37. }
  38. #endif
  39. //! macros to simplify constructor lists
  40. #define NAMED(X, ...) X(#X, ##__VA_ARGS__)
  41. #define NAMEDD(X, T, ...) X(std::make_unique<T>(#X, ##__VA_ARGS__))
  42. #define NAMEDC(X, T, I, ...) X(T::create<I>(#X, ##__VA_ARGS__))
  43. //! macros to simplify declaration of members to trace
  44. #define TRACE_VAR(F, X) sc_core::sc_trace(F, X, std::string(this->name()) + "." #X)
  45. #define TRACE_ARR(F, X, I) \
  46. sc_core::sc_trace(F, X[I], (std::string(this->name()) + "." #X "(" + std::to_string(I) + ")").c_str());
  47. #define TRACE_SIG(F, X) sc_core::sc_trace(F, X, X.name())
  48. namespace sc_core {
  49. // needed to be able to use sc_time as signal value
  50. #if SC_VERSION_MAJOR <= 2 && SC_VERSION_MINOR <= 3 && SC_VERSION_PATCH < 2
  51. /**
  52. *
  53. * @param
  54. * @param
  55. * @param
  56. */
  57. void sc_trace(sc_trace_file *, const sc_time &, const std::string &);
  58. /**
  59. *
  60. * @param
  61. * @param
  62. * @param
  63. */
  64. void sc_trace(sc_trace_file *, const sc_time &, const char *);
  65. #endif
  66. /**
  67. * trace function for sc_time
  68. *
  69. * @param the trace file
  70. * @param the data to trace
  71. * @param the hierarchical name of the data
  72. */
  73. template <> void sc_trace(sc_trace_file *, const sc_in<sc_time> &, const std::string &);
  74. /**
  75. * trace function for sc_time
  76. *
  77. * @param the trace file
  78. * @param the port carrying the data to trace
  79. * @param the hierarchical name of the data
  80. */
  81. template <> void sc_trace(sc_trace_file *, const sc_inout<sc_time> &, const std::string &);
  82. }
  83. // user-defined literals for easy time creation
  84. /**
  85. * UDL for second
  86. *
  87. * @param val
  88. * @return
  89. */
  90. inline sc_core::sc_time operator"" _sec(long double val) { return sc_core::sc_time(val, sc_core::SC_SEC); }
  91. /**
  92. * UDL for second
  93. *
  94. * @param val
  95. * @return
  96. */
  97. inline sc_core::sc_time operator"" _sec(unsigned long long val) {
  98. return sc_core::sc_time(double(val), sc_core::SC_SEC);
  99. }
  100. /**
  101. * UDL for millisecond
  102. *
  103. * @param val
  104. * @return
  105. */
  106. inline sc_core::sc_time operator"" _ms(long double val) { return sc_core::sc_time(val, sc_core::SC_MS); }
  107. /**
  108. * UDL for millisecond
  109. *
  110. * @param val
  111. * @return
  112. */
  113. inline sc_core::sc_time operator"" _ms(unsigned long long val) { return sc_core::sc_time(double(val), sc_core::SC_MS); }
  114. /**
  115. * UDL for microsecond
  116. *
  117. * @param val
  118. * @return
  119. */
  120. inline sc_core::sc_time operator"" _us(long double val) { return sc_core::sc_time(val, sc_core::SC_US); }
  121. /**
  122. * UDL for microsecond
  123. *
  124. * @param val
  125. * @return
  126. */
  127. inline sc_core::sc_time operator"" _us(unsigned long long val) { return sc_core::sc_time(double(val), sc_core::SC_US); }
  128. /**
  129. * UDL for nanosecond
  130. *
  131. * @param val
  132. * @return
  133. */
  134. inline sc_core::sc_time operator"" _ns(long double val) { return sc_core::sc_time(val, sc_core::SC_NS); }
  135. /**
  136. * UDL for nanosecond
  137. *
  138. * @param val
  139. * @return
  140. */
  141. inline sc_core::sc_time operator"" _ns(unsigned long long val) { return sc_core::sc_time(double(val), sc_core::SC_NS); }
  142. /**
  143. * UDL for picosecond
  144. *
  145. * @param val
  146. * @return
  147. */
  148. inline sc_core::sc_time operator"" _ps(long double val) { return sc_core::sc_time(val, sc_core::SC_PS); }
  149. /**
  150. * UDL for picosecond
  151. *
  152. * @param val
  153. * @return
  154. */
  155. inline sc_core::sc_time operator"" _ps(unsigned long long val) { return sc_core::sc_time(double(val), sc_core::SC_PS); }
  156. /**
  157. * UDL for femtosecond
  158. *
  159. * @param val
  160. * @return
  161. */
  162. inline sc_core::sc_time operator"" _fs(long double val) { return sc_core::sc_time(val, sc_core::SC_FS); }
  163. /**
  164. * UDL for femtosecond
  165. *
  166. * @param val
  167. * @return
  168. */
  169. inline sc_core::sc_time operator"" _fs(unsigned long long val) { return sc_core::sc_time(double(val), sc_core::SC_FS); }
  170. //! UDL for kilobyte
  171. inline constexpr uint64_t operator"" _kB(unsigned long long val) { return val * 1 << 10; }
  172. //! UDL for megabyte
  173. inline constexpr uint64_t operator"" _MB(unsigned long long val) { return val * 1 << 20; }
  174. //! UDL for gigabyte
  175. inline constexpr uint64_t operator"" _GB(unsigned long long val) { return val * 1 << 30; }
  176. namespace scc {
  177. /**
  178. * case-insensitive string compare
  179. *
  180. * @param a string a
  181. * @param b string b
  182. * @return result of std::equal
  183. */
  184. inline bool icompare(std::string const &a, std::string const &b) {
  185. if (a.length() == b.length()) {
  186. return std::equal(b.begin(), b.end(), a.begin(),
  187. [](unsigned char a, unsigned char b) -> bool { return std::tolower(a) == std::tolower(b); });
  188. } else {
  189. return false;
  190. }
  191. }
  192. /**
  193. * parse a time value from given strings
  194. *
  195. * @param value the string to parse
  196. * @param unit the unit string
  197. * @return the parsed sc_core::sc_time value
  198. */
  199. inline sc_core::sc_time parse_from_string(std::string value, std::string unit) noexcept {
  200. std::string::size_type offs{0};
  201. double t_val = std::stod(value, &offs);
  202. if (offs > 0) {
  203. if (icompare(unit, "fs")) return t_val * 1_fs;
  204. if (icompare(unit, "ps")) return t_val * 1_ps;
  205. if (icompare(unit, "ns")) return t_val * 1_ns;
  206. if (icompare(unit, "us")) return t_val * 1_us;
  207. if (icompare(unit, "ms")) return t_val * 1_ms;
  208. if (icompare(unit, "s")) return t_val * 1_sec;
  209. }
  210. return sc_core::SC_ZERO_TIME;
  211. }
  212. /**
  213. * parse a time value from a given string
  214. *
  215. * @param value the string to parse
  216. * @return the parsed sc_core::sc_time value
  217. */
  218. inline sc_core::sc_time parse_from_string(std::string value) noexcept {
  219. std::string::size_type offs{0};
  220. double t_val = std::stod(value, &offs);
  221. if (offs > 0) {
  222. std::string unit = value.substr(offs);
  223. if (icompare(unit, "fs")) return t_val * 1_fs;
  224. if (icompare(unit, "ps")) return t_val * 1_ps;
  225. if (icompare(unit, "ns")) return t_val * 1_ns;
  226. if (icompare(unit, "us")) return t_val * 1_us;
  227. if (icompare(unit, "ms")) return t_val * 1_ms;
  228. if (icompare(unit, "s")) return t_val * 1_sec;
  229. }
  230. return sc_core::SC_ZERO_TIME;
  231. }
  232. }
  233. #endif /* _SYSC_UTILITIES_H_ */