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

configurable_tracer.cpp 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*******************************************************************************
  2. * Copyright (C) 2018, MINRES Technologies GmbH
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * 3. Neither the name of the copyright holder nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. * Contributors:
  31. * eyck@minres.com - initial API and implementation
  32. ******************************************************************************/
  33. #include "scc/configurable_tracer.h"
  34. using namespace scc;
  35. configurable_tracer::configurable_tracer(const std::string &&name, file_type type, bool enable_vcd, bool default_enable)
  36. : tracer(std::move(name), type, enable_vcd)
  37. , cci_originator(this->name())
  38. , cci_broker(cci::cci_get_global_broker(cci_originator))
  39. , default_trace_enable(default_enable)
  40. {
  41. // for(auto* o:sc_core::sc_get_top_level_objects(sc_core::sc_curr_simcontext))
  42. // augment_object_hierarchical(o);
  43. }
  44. scc::configurable_tracer::~configurable_tracer() {
  45. for (auto ptr : params) delete ptr;
  46. }
  47. void configurable_tracer::descend(const sc_core::sc_object *obj) {
  48. if (obj == this) return;
  49. const auto* tr = dynamic_cast<const scc::traceable*>(obj);
  50. auto trace_enable = tr?false:get_trace_enabled(obj, default_trace_enable);
  51. for (auto o : obj->get_child_objects()){
  52. const char *kind = o->kind();
  53. if (strcmp(kind, "sc_signal") == 0) {
  54. if(trace_enable)
  55. try_trace_signal(o);
  56. continue;
  57. } else if (strcmp(kind, "sc_inout") == 0 ||
  58. strcmp(kind, "sc_out") == 0 ||
  59. strcmp(kind, "sc_in") == 0 ||
  60. strcmp(kind, "sc_port") == 0) {
  61. if(trace_enable)
  62. try_trace_port(o);
  63. continue;
  64. } else if (strcmp(kind, "tlm_signal") == 0) {
  65. if(trace_enable)
  66. o->trace(trf);
  67. continue;
  68. } else if (strcmp(kind, "sc_vector") == 0 || strcmp(kind, "sc_export") == 0) {
  69. continue;
  70. } else if (strcmp(kind, "sc_module") == 0) {
  71. const auto* str = dynamic_cast<const scc::traceable*>(o);
  72. if(str && get_trace_enabled(o, default_trace_enable))
  73. str->trace(trf);
  74. descend(o);
  75. } else {
  76. auto obj_trace_enable = get_trace_enabled(o, default_trace_enable);
  77. if (obj_trace_enable)
  78. o->trace(trf);
  79. descend(o);
  80. }
  81. }
  82. }
  83. bool scc::configurable_tracer::get_trace_enabled(const sc_core::sc_object *obj, bool fall_back) {
  84. auto *attr = obj->get_attribute("enableTracing");
  85. if (attr != nullptr && dynamic_cast<const sc_core::sc_attribute<bool> *>(attr) != nullptr) {
  86. const auto *a = dynamic_cast<const sc_core::sc_attribute<bool> *>(attr);
  87. return a->value;
  88. } else {
  89. std::string hier_name{obj->name()};
  90. auto h = cci_broker.get_param_handle(hier_name.append(".enableTracing"));
  91. if (h.is_valid()) return h.get_cci_value().get_bool();
  92. }
  93. return fall_back;
  94. }
  95. void configurable_tracer::augment_object_hierarchical(const sc_core::sc_object *obj) {
  96. if (dynamic_cast<const sc_core::sc_module *>(obj) != nullptr ||
  97. dynamic_cast<const scc::traceable *>(obj) != nullptr) {
  98. auto *attr = obj->get_attribute("enableTracing");
  99. if (attr == nullptr ||
  100. dynamic_cast<const sc_core::sc_attribute<bool> *>(attr) == nullptr) { // check if we have no sc_attribute
  101. std::string hier_name{obj->name()};
  102. hier_name += ".enableTracing";
  103. auto h = cci_broker.get_param_handle(hier_name);
  104. if (!h.is_valid()) // we have no cci_param so create one
  105. params.push_back(new cci::cci_param<bool>(hier_name, default_trace_enable, "", cci::CCI_ABSOLUTE_NAME, cci_originator));
  106. }
  107. for (auto *o : obj->get_child_objects()) augment_object_hierarchical(o);
  108. }
  109. }