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

initiator_mixin.h 4.5KB

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