diff options
Diffstat (limited to 'src/models')
-rw-r--r-- | src/models/lt_bus.h | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/src/models/lt_bus.h b/src/models/lt_bus.h index 9ae66b0..bab1866 100644 --- a/src/models/lt_bus.h +++ b/src/models/lt_bus.h @@ -45,6 +45,48 @@ struct range { }; template <typename Module> +class tlm_initiator_socket_tagged : public tlm::tlm_initiator_socket<>, + public tlm::tlm_bw_transport_if<> { + using cb_invalidate_direct_mem_ptr = void (Module::*)(std::size_t, + sc_dt::uint64, + sc_dt::uint64); + + public: + explicit tlm_initiator_socket_tagged(const char* name, + std::size_t id, + Module* mod, + cb_invalidate_direct_mem_ptr i) + : tlm_initiator_socket<>{name}, + m_mod{mod}, + m_id{id}, + m_invalidate_direct_mem_ptr{i} { + bind(*static_cast<tlm::tlm_bw_transport_if<>*>(this)); + } + + private: + // -- TLM_BW_TRANSPORT_IF ---------------------------------------------------- + + virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start, + sc_dt::uint64 end) override { + (m_mod->*m_invalidate_direct_mem_ptr)(m_id, start, end); + } + + virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload&, + tlm::tlm_phase&, + sc_core::sc_time&) override { + std::fprintf( + stderr, "tlm_initiator_socket_tagged: nb_transport_bw not supported\n"); + std::abort(); + } + + // -- MEMBER ----------------------------------------------------------------- + + std::size_t m_id{0}; + Module* m_mod{nullptr}; + cb_invalidate_direct_mem_ptr m_invalidate_direct_mem_ptr{nullptr}; +}; + +template <typename Module> class tlm_target_socket_tagged : public tlm::tlm_target_socket<>, public tlm::tlm_fw_transport_if<> { using cb_b_transport = void (Module::*)(std::size_t, @@ -107,11 +149,11 @@ class tlm_target_socket_tagged : public tlm::tlm_target_socket<>, cb_transport_dbg m_transport_dbg{nullptr}; }; -class lt_bus : public sc_core::sc_module, public tlm::tlm_bw_transport_if<> { +class lt_bus : public sc_core::sc_module { using target_socket = tlm_target_socket_tagged<lt_bus>; using target_socket_ptr = std::unique_ptr<target_socket>; - using initiator_socket = tlm::tlm_initiator_socket<>; + using initiator_socket = tlm_initiator_socket_tagged<lt_bus>; using initiator_socket_ptr = std::unique_ptr<initiator_socket>; public: @@ -125,7 +167,7 @@ class lt_bus : public sc_core::sc_module, public tlm::tlm_bw_transport_if<> { const std::string name = "init" + std::to_string(id); { // Add current module on top of module stack for tlm sockets. - scoped_push_hierarchy g(*this); + scoped_push_hierarchy h(*this); // Add new target socket to connect BUS INITIATOR. m_initiators.push_back(std::make_unique<target_socket>( @@ -161,15 +203,15 @@ class lt_bus : public sc_core::sc_module, public tlm::tlm_bw_transport_if<> { const std::string name = "target" + std::to_string(id); { // Add current module on top of module stack for tlm sockets. - scoped_push_hierarchy g(*this); + scoped_push_hierarchy h(*this); // Add new initiator socket to connect BUS TARGET. - m_targets.push_back(std::make_unique<initiator_socket>(name.c_str())); + m_targets.push_back(std::make_unique<initiator_socket>( + name.c_str(), id, this, <_bus::invalidate_direct_mem_ptr)); } // Bind sockets. auto& init = m_targets.back(); - init->bind(*this); init->bind(target); // Insert new mapping, id is equal to idx into socket vector. @@ -179,16 +221,19 @@ class lt_bus : public sc_core::sc_module, public tlm::tlm_bw_transport_if<> { private: // -- TLM_BW_TRANSPORT_IF ---------------------------------------------------- - virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload&, - tlm::tlm_phase&, - sc_core::sc_time&) override { - std::fprintf(stderr, "lt_bus: nb_transport_bw not supported\n"); - std::abort(); - } - - virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start, - sc_dt::uint64 end) override { - assert(false); + void invalidate_direct_mem_ptr(std::size_t id, + sc_dt::uint64 start, + sc_dt::uint64 end) { + for (const auto& map : m_mappings) { + if (map.idx != id) { + continue; + } + const sc_dt::uint64 s = map.addr.start + start; + const sc_dt::uint64 e = map.addr.start + end; + for (auto& sock : m_initiators) { + (*sock)->invalidate_direct_mem_ptr(s, e); + } + } } // -- TLM_FW_TRANSPORT_IF ---------------------------------------------------- |