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

tagged_initiator_mixin.h 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. #ifndef _SCC_TAGGED_INITIATOR_MIXIN_H__
  17. #define _SCC_TAGGED_INITIATOR_MIXIN_H__
  18. #include "utilities.h"
  19. #include <functional>
  20. #include <sstream>
  21. #include <tlm>
  22. namespace scc {
  23. /**
  24. *
  25. */
  26. template <typename BASE_TYPE, typename TYPES = tlm::tlm_base_protocol_types>
  27. class tagged_initiator_mixin : public BASE_TYPE {
  28. public:
  29. using transaction_type = typename TYPES::tlm_payload_type;
  30. using phase_type = typename TYPES::tlm_phase_type;
  31. using sync_enum_type = tlm::tlm_sync_enum;
  32. using fw_interface_type = tlm::tlm_fw_transport_if<TYPES>;
  33. using bw_interface_type = tlm::tlm_bw_transport_if<TYPES>;
  34. public:
  35. /**
  36. *
  37. */
  38. tagged_initiator_mixin()
  39. : BASE_TYPE(sc_core::sc_gen_unique_name("tagged_initiator_socket"))
  40. , bw_if(this->name()) {
  41. this->m_export.bind(bw_if);
  42. }
  43. /**
  44. *
  45. * @param n
  46. */
  47. explicit tagged_initiator_mixin(const char *n)
  48. : BASE_TYPE(n)
  49. , bw_if(this->name()) {
  50. this->m_export.bind(bw_if);
  51. }
  52. /**
  53. *
  54. * @param cb the callback function
  55. * @param tag the tag to return upon calling
  56. */
  57. void register_nb_transport_bw(
  58. std::function<sync_enum_type(unsigned int, transaction_type &, phase_type &, sc_core::sc_time &)> cb,
  59. unsigned int tag) {
  60. bw_if.set_transport_function(cb, tag);
  61. }
  62. /**
  63. *
  64. * @param cb the callback function
  65. * @param tag the tag to return upon calling
  66. */
  67. void register_invalidate_direct_mem_ptr(std::function<void(unsigned int, sc_dt::uint64, sc_dt::uint64)> cb,
  68. unsigned int tag) {
  69. bw_if.set_invalidate_direct_mem_function(cb, tag);
  70. }
  71. private:
  72. class bw_transport_if : public tlm::tlm_bw_transport_if<TYPES> {
  73. public:
  74. using transport_fct =
  75. std::function<sync_enum_type(unsigned int, transaction_type &, phase_type &, sc_core::sc_time &)>;
  76. using invalidate_dmi_fct = std::function<void(unsigned int, sc_dt::uint64, sc_dt::uint64)>;
  77. bw_transport_if(const std::string &name)
  78. : m_name(name)
  79. , m_transport_ptr(0)
  80. , m_invalidate_direct_mem_ptr(0) {}
  81. void set_transport_function(transport_fct p, unsigned int tag) {
  82. if (m_transport_ptr) {
  83. std::stringstream s;
  84. s << m_name << ": non-blocking callback allready registered";
  85. SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket", s.str().c_str());
  86. } else {
  87. m_transport_ptr = p;
  88. tags[0] = tag;
  89. }
  90. }
  91. void set_invalidate_direct_mem_function(invalidate_dmi_fct p, unsigned int tag) {
  92. if (m_invalidate_direct_mem_ptr) {
  93. std::stringstream s;
  94. s << m_name << ": invalidate DMI callback allready registered";
  95. SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket", s.str().c_str());
  96. } else {
  97. m_invalidate_direct_mem_ptr = p;
  98. tags[1] = tag;
  99. }
  100. }
  101. sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t) {
  102. if (m_transport_ptr) return m_transport_ptr(tag[0], trans, phase, t);
  103. std::stringstream s;
  104. s << m_name << ": no transport callback registered";
  105. SC_REPORT_ERROR("/OSCI_TLM-2/tagged_initiator_mixin", s.str().c_str());
  106. return tlm::TLM_ACCEPTED; ///< unreachable code
  107. }
  108. void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) {
  109. if (m_invalidate_direct_mem_ptr) // forward call
  110. m_invalidate_direct_mem_ptr(tag[1], start_range, end_range);
  111. }
  112. private:
  113. const std::string m_name;
  114. unsigned int tags[2]; // dbg, dmi
  115. transport_fct m_transport_ptr;
  116. invalidate_dmi_fct m_invalidate_direct_mem_ptr;
  117. };
  118. private:
  119. bw_transport_if bw_if;
  120. };
  121. }
  122. #endif //_SCC_TAGGED_INITIATOR_MIXIN_H__