From: Gabe Black Date: Thu, 14 Mar 2019 12:33:51 +0000 (-0700) Subject: systemc: Templatize the gem5/TLM bridge SimObjects. X-Git-Tag: v19.0.0.0~996 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2a98a994df296f818b05da90ba073d879562da04;p=gem5.git systemc: Templatize the gem5/TLM bridge SimObjects. The C++ side is templated, and there are python versions for each (currently two) width of bridge supported. Change-Id: I4baa9f22d4c87629d45e9e1292eb66c65d25a655 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/17234 Reviewed-by: Gabe Black Maintainer: Gabe Black --- diff --git a/src/systemc/tlm_bridge/TlmBridge.py b/src/systemc/tlm_bridge/TlmBridge.py index d2dff8600..dcc545280 100644 --- a/src/systemc/tlm_bridge/TlmBridge.py +++ b/src/systemc/tlm_bridge/TlmBridge.py @@ -29,9 +29,10 @@ from m5.objects.SystemC import SystemC_ScModule from m5.params import * from m5.proxy import * -class Gem5ToTlmBridge(SystemC_ScModule): - type = 'Gem5ToTlmBridge' - cxx_class = 'sc_gem5::Gem5ToTlmBridge' +class Gem5ToTlmBridgeBase(SystemC_ScModule): + type = 'Gem5ToTlmBridgeBase' + abstract = True + cxx_class = 'sc_gem5::Gem5ToTlmBridgeBase' cxx_header = 'systemc/tlm_bridge/gem5_to_tlm.hh' system = Param.System(Parent.any, "system") @@ -41,12 +42,39 @@ class Gem5ToTlmBridge(SystemC_ScModule): addr_ranges = VectorParam.AddrRange([], 'Addresses served by this port\'s TLM side') -class TlmToGem5Bridge(SystemC_ScModule): - type = 'TlmToGem5Bridge' - cxx_class = 'sc_gem5::TlmToGem5Bridge' +class TlmToGem5BridgeBase(SystemC_ScModule): + type = 'TlmToGem5BridgeBase' + abstract = True + cxx_class = 'sc_gem5::TlmToGem5BridgeBase' cxx_header = 'systemc/tlm_bridge/tlm_to_gem5.hh' system = Param.System(Parent.any, "system") gem5 = MasterPort('gem5 master port') tlm = SlavePort('TLM target socket') + + +class Gem5ToTlmBridge32(Gem5ToTlmBridgeBase): + type = 'Gem5ToTlmBridge32' + cxx_template_params = [ 'unsigned int BITWIDTH' ] + cxx_class = 'sc_gem5::Gem5ToTlmBridge<32>' + cxx_header = 'systemc/tlm_bridge/gem5_to_tlm.hh' + +class Gem5ToTlmBridge64(Gem5ToTlmBridgeBase): + type = 'Gem5ToTlmBridge64' + cxx_template_params = [ 'unsigned int BITWIDTH' ] + cxx_class = 'sc_gem5::Gem5ToTlmBridge<64>' + cxx_header = 'systemc/tlm_bridge/gem5_to_tlm.hh' + + +class TlmToGem5Bridge32(TlmToGem5BridgeBase): + type = 'TlmToGem5Bridge32' + cxx_template_params = [ 'unsigned int BITWIDTH' ] + cxx_class = 'sc_gem5::TlmToGem5Bridge<32>' + cxx_header = 'systemc/tlm_bridge/tlm_to_gem5.hh' + +class TlmToGem5Bridge64(TlmToGem5BridgeBase): + type = 'TlmToGem5Bridge64' + cxx_template_params = [ 'unsigned int BITWIDTH' ] + cxx_class = 'sc_gem5::TlmToGem5Bridge<64>' + cxx_header = 'systemc/tlm_bridge/tlm_to_gem5.hh' diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.cc b/src/systemc/tlm_bridge/gem5_to_tlm.cc index 06ed2abf3..f78c679ee 100644 --- a/src/systemc/tlm_bridge/gem5_to_tlm.cc +++ b/src/systemc/tlm_bridge/gem5_to_tlm.cc @@ -63,6 +63,8 @@ #include "systemc/tlm_bridge/gem5_to_tlm.hh" +#include "params/Gem5ToTlmBridge32.hh" +#include "params/Gem5ToTlmBridge64.hh" #include "sim/system.hh" #include "systemc/tlm_bridge/sc_ext.hh" #include "systemc/tlm_bridge/sc_mm.hh" @@ -106,8 +108,10 @@ packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans) } } +template void -Gem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent *pe, +Gem5ToTlmBridge::pec( + Gem5SystemC::PayloadEvent> *pe, tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase) { sc_core::sc_time delay; @@ -163,8 +167,9 @@ Gem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent *pe, } // Similar to TLM's blocking transport (LT) +template Tick -Gem5ToTlmBridge::recvAtomic(PacketPtr packet) +Gem5ToTlmBridge::recvAtomic(PacketPtr packet) { panic_if(packet->cacheResponding(), "Should not see packets where cache is responding"); @@ -205,8 +210,9 @@ Gem5ToTlmBridge::recvAtomic(PacketPtr packet) return delay.value(); } +template void -Gem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet) +Gem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet) { // Snooping should be implemented with tlm_dbg_transport. SC_REPORT_FATAL("Gem5ToTlmBridge", @@ -214,8 +220,9 @@ Gem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet) } // Similar to TLM's non-blocking transport (AT). +template bool -Gem5ToTlmBridge::recvTimingReq(PacketPtr packet) +Gem5ToTlmBridge::recvTimingReq(PacketPtr packet) { panic_if(packet->cacheResponding(), "Should not see packets where cache is responding"); @@ -309,8 +316,9 @@ Gem5ToTlmBridge::recvTimingReq(PacketPtr packet) return true; } +template bool -Gem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet) +Gem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet) { // Snooping should be implemented with tlm_dbg_transport. SC_REPORT_FATAL("Gem5ToTlmBridge", @@ -318,14 +326,16 @@ Gem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet) return false; } +template bool -Gem5ToTlmBridge::tryTiming(PacketPtr packet) +Gem5ToTlmBridge::tryTiming(PacketPtr packet) { panic("tryTiming(PacketPtr) isn't implemented."); } +template void -Gem5ToTlmBridge::recvRespRetry() +Gem5ToTlmBridge::recvRespRetry() { /* Retry a response */ sc_assert(blockingResponse); @@ -347,8 +357,9 @@ Gem5ToTlmBridge::recvRespRetry() } // Similar to TLM's debug transport. +template void -Gem5ToTlmBridge::recvFunctional(PacketPtr packet) +Gem5ToTlmBridge::recvFunctional(PacketPtr packet) { // Prepare the transaction. tlm::tlm_generic_payload *trans = mm.allocate(); @@ -369,8 +380,9 @@ Gem5ToTlmBridge::recvFunctional(PacketPtr packet) trans->release(); } +template tlm::tlm_sync_enum -Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans, +Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &delay) { auto *pe = new Gem5SystemC::PayloadEvent( @@ -381,9 +393,10 @@ Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans, return tlm::TLM_ACCEPTED; } -Gem5ToTlmBridge::Gem5ToTlmBridge( +template +Gem5ToTlmBridge::Gem5ToTlmBridge( Params *params, const sc_core::sc_module_name &mn) : - sc_core::sc_module(mn), bsp(std::string(name()) + ".gem5", *this), + Gem5ToTlmBridgeBase(mn), bsp(std::string(name()) + ".gem5", *this), socket("tlm_socket"), wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), system(params->system), blockingRequest(nullptr), @@ -392,8 +405,9 @@ Gem5ToTlmBridge::Gem5ToTlmBridge( { } +template ::Port & -Gem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx) +Gem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx) { if (if_name == "gem5") return bsp; @@ -403,8 +417,9 @@ Gem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx) return sc_core::sc_module::gem5_getPort(if_name, idx); } +template void -Gem5ToTlmBridge::before_end_of_elaboration() +Gem5ToTlmBridge::before_end_of_elaboration() { bsp.sendRangeChange(); @@ -414,9 +429,16 @@ Gem5ToTlmBridge::before_end_of_elaboration() } // namespace sc_gem5 -sc_gem5::Gem5ToTlmBridge * -Gem5ToTlmBridgeParams::create() +sc_gem5::Gem5ToTlmBridge<32> * +Gem5ToTlmBridge32Params::create() { - return new sc_gem5::Gem5ToTlmBridge( + return new sc_gem5::Gem5ToTlmBridge<32>( + this, sc_core::sc_module_name(name.c_str())); +} + +sc_gem5::Gem5ToTlmBridge<64> * +Gem5ToTlmBridge64Params::create() +{ + return new sc_gem5::Gem5ToTlmBridge<64>( this, sc_core::sc_module_name(name.c_str())); } diff --git a/src/systemc/tlm_bridge/gem5_to_tlm.hh b/src/systemc/tlm_bridge/gem5_to_tlm.hh index 02deb6add..e36058ac6 100644 --- a/src/systemc/tlm_bridge/gem5_to_tlm.hh +++ b/src/systemc/tlm_bridge/gem5_to_tlm.hh @@ -66,7 +66,7 @@ #include #include "mem/port.hh" -#include "params/Gem5ToTlmBridge.hh" +#include "params/Gem5ToTlmBridgeBase.hh" #include "sim/system.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/ext/core/sc_module_name.hh" @@ -78,13 +78,20 @@ namespace sc_gem5 { -class Gem5ToTlmBridge : public sc_core::sc_module +class Gem5ToTlmBridgeBase : public sc_core::sc_module +{ + protected: + using sc_core::sc_module::sc_module; +}; + +template +class Gem5ToTlmBridge : public Gem5ToTlmBridgeBase { private: class BridgeSlavePort : public SlavePort { protected: - Gem5ToTlmBridge &bridge; + Gem5ToTlmBridge &bridge; AddrRangeList getAddrRanges() const override @@ -119,14 +126,16 @@ class Gem5ToTlmBridge : public sc_core::sc_module void recvRespRetry() override { bridge.recvRespRetry(); } public: - BridgeSlavePort(const std::string &name_, Gem5ToTlmBridge &bridge_) : + BridgeSlavePort(const std::string &name_, + Gem5ToTlmBridge &bridge_) : SlavePort(name_, nullptr), bridge(bridge_) {} }; BridgeSlavePort bsp; - tlm_utils::simple_initiator_socket socket; - sc_gem5::TlmInitiatorWrapper<64> wrapper; + tlm_utils::simple_initiator_socket< + Gem5ToTlmBridge, BITWIDTH> socket; + sc_gem5::TlmInitiatorWrapper wrapper; System *system; @@ -151,7 +160,7 @@ class Gem5ToTlmBridge : public sc_core::sc_module AddrRangeList addrRanges; protected: - void pec(Gem5SystemC::PayloadEvent *pe, + void pec(Gem5SystemC::PayloadEvent> *pe, tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase); // The gem5 port interface. @@ -172,10 +181,10 @@ class Gem5ToTlmBridge : public sc_core::sc_module public: ::Port &gem5_getPort(const std::string &if_name, int idx=-1) override; - typedef Gem5ToTlmBridgeParams Params; + typedef Gem5ToTlmBridgeBaseParams Params; Gem5ToTlmBridge(Params *p, const sc_core::sc_module_name &mn); - tlm_utils::simple_initiator_socket & + tlm_utils::simple_initiator_socket, BITWIDTH> & getSocket() { return socket; diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc b/src/systemc/tlm_bridge/tlm_to_gem5.cc index 9e704901f..4b69286d0 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.cc +++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc @@ -60,14 +60,17 @@ #include "systemc/tlm_bridge/tlm_to_gem5.hh" +#include "params/TlmToGem5Bridge32.hh" +#include "params/TlmToGem5Bridge64.hh" #include "sim/system.hh" #include "systemc/ext/core/sc_module_name.hh" namespace sc_gem5 { +template void -TlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans) +TlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans) { tlm::tlm_phase phase = tlm::END_REQ; auto delay = sc_core::SC_ZERO_TIME; @@ -77,9 +80,10 @@ TlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans) "Unexpected status after sending END_REQ"); } +template void -TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans, - sc_core::sc_time &delay) +TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans, + sc_core::sc_time &delay) { tlm::tlm_phase phase = tlm::BEGIN_RESP; @@ -99,8 +103,9 @@ TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans, } } +template void -TlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans) +TlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans) { sc_assert(!waitForRetry); sc_assert(pendingRequest == nullptr); @@ -136,8 +141,9 @@ TlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans) } } +template void -TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans) +TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans) { sc_assert(responseInProgress); @@ -151,8 +157,9 @@ TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans) } } +template PacketPtr -TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans) +TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans) { MemCmd cmd; @@ -184,14 +191,16 @@ TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans) return pkt; } +template void -TlmToGem5Bridge::destroyPacket(PacketPtr pkt) +TlmToGem5Bridge::destroyPacket(PacketPtr pkt) { delete pkt; } +template void -TlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans) +TlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans) { if (trans.is_response_error()) { std::stringstream ss; @@ -201,9 +210,10 @@ TlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans) } } +template void -TlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans, - const tlm::tlm_phase &phase) +TlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans, + const tlm::tlm_phase &phase) { switch (phase) { case tlm::BEGIN_REQ: @@ -217,8 +227,9 @@ TlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans, } } +template tlm::tlm_sync_enum -TlmToGem5Bridge::nb_transport_fw( +TlmToGem5Bridge::nb_transport_fw( tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &delay) { @@ -242,9 +253,10 @@ TlmToGem5Bridge::nb_transport_fw( return tlm::TLM_ACCEPTED; } +template void -TlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans, - sc_core::sc_time &t) +TlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans, + sc_core::sc_time &t) { Gem5SystemC::Gem5Extension *extension = nullptr; trans.get_extension(extension); @@ -278,8 +290,9 @@ TlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans, trans.set_response_status(tlm::TLM_OK_RESPONSE); } +template unsigned int -TlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans) +TlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans) { Gem5SystemC::Gem5Extension *extension = nullptr; trans.get_extension(extension); @@ -300,15 +313,17 @@ TlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans) return trans.get_data_length(); } +template bool -TlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, - tlm::tlm_dmi &dmi_data) +TlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, + tlm::tlm_dmi &dmi_data) { return false; } +template bool -TlmToGem5Bridge::recvTimingResp(PacketPtr pkt) +TlmToGem5Bridge::recvTimingResp(PacketPtr pkt) { // exclusion rule // We need to Wait for END_RESP before sending next BEGIN_RESP @@ -354,8 +369,9 @@ TlmToGem5Bridge::recvTimingResp(PacketPtr pkt) return true; } +template void -TlmToGem5Bridge::recvReqRetry() +TlmToGem5Bridge::recvReqRetry() { sc_assert(waitForRetry); sc_assert(pendingRequest != nullptr); @@ -373,15 +389,17 @@ TlmToGem5Bridge::recvReqRetry() } } +template void -TlmToGem5Bridge::recvRangeChange() +TlmToGem5Bridge::recvRangeChange() { SC_REPORT_WARNING("TlmToGem5Bridge", "received address range change but ignored it"); } +template ::Port & -TlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx) +TlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx) { if (if_name == "gem5") return bmp; @@ -391,9 +409,10 @@ TlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx) return sc_core::sc_module::gem5_getPort(if_name, idx); } -TlmToGem5Bridge::TlmToGem5Bridge( +template +TlmToGem5Bridge::TlmToGem5Bridge( Params *params, const sc_core::sc_module_name &mn) : - sc_core::sc_module(mn), peq(this, &TlmToGem5Bridge::peq_cb), + TlmToGem5BridgeBase(mn), peq(this, &TlmToGem5Bridge::peq_cb), waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr), needToSendRetry(false), responseInProgress(false), bmp(std::string(name()) + "master", *this), socket("tlm_socket"), @@ -404,8 +423,9 @@ TlmToGem5Bridge::TlmToGem5Bridge( { } +template void -TlmToGem5Bridge::before_end_of_elaboration() +TlmToGem5Bridge::before_end_of_elaboration() { /* * Register the TLM non-blocking interface when using gem5 Timing mode and @@ -418,25 +438,33 @@ TlmToGem5Bridge::before_end_of_elaboration() if (system->isTimingMode()) { SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface"); socket.register_nb_transport_fw( - this, &TlmToGem5Bridge::nb_transport_fw); + this, &TlmToGem5Bridge::nb_transport_fw); } else if (system->isAtomicMode()) { SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface"); socket.register_b_transport( - this, &TlmToGem5Bridge::b_transport); + this, &TlmToGem5Bridge::b_transport); } else { panic("gem5 operates neither in Timing nor in Atomic mode"); } - socket.register_transport_dbg(this, &TlmToGem5Bridge::transport_dbg); + socket.register_transport_dbg( + this, &TlmToGem5Bridge::transport_dbg); sc_core::sc_module::before_end_of_elaboration(); } } // namespace sc_gem5 -sc_gem5::TlmToGem5Bridge * -TlmToGem5BridgeParams::create() +sc_gem5::TlmToGem5Bridge<32> * +TlmToGem5Bridge32Params::create() { - return new sc_gem5::TlmToGem5Bridge( + return new sc_gem5::TlmToGem5Bridge<32>( + this, sc_core::sc_module_name(name.c_str())); +} + +sc_gem5::TlmToGem5Bridge<64> * +TlmToGem5Bridge64Params::create() +{ + return new sc_gem5::TlmToGem5Bridge<64>( this, sc_core::sc_module_name(name.c_str())); } diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.hh b/src/systemc/tlm_bridge/tlm_to_gem5.hh index 1d6fa13d0..d2b15af67 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.hh +++ b/src/systemc/tlm_bridge/tlm_to_gem5.hh @@ -62,7 +62,7 @@ #define __SYSTEMC_TLM_BRIDGE_TLM_TO_GEM5_HH__ #include "mem/port.hh" -#include "params/TlmToGem5Bridge.hh" +#include "params/TlmToGem5BridgeBase.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/ext/core/sc_module_name.hh" #include "systemc/ext/tlm_core/2/generic_payload/gp.hh" @@ -74,7 +74,14 @@ namespace sc_gem5 { -class TlmToGem5Bridge : public sc_core::sc_module +class TlmToGem5BridgeBase : public sc_core::sc_module +{ + protected: + using sc_core::sc_module::sc_module; +}; + +template +class TlmToGem5Bridge : public TlmToGem5BridgeBase { private: struct TlmSenderState : public Packet::SenderState @@ -86,7 +93,7 @@ class TlmToGem5Bridge : public sc_core::sc_module class BridgeMasterPort : public MasterPort { protected: - TlmToGem5Bridge &bridge; + TlmToGem5Bridge &bridge; bool recvTimingResp(PacketPtr pkt) override @@ -97,12 +104,13 @@ class TlmToGem5Bridge : public sc_core::sc_module void recvRangeChange() override { bridge.recvRangeChange(); } public: - BridgeMasterPort(const std::string &name_, TlmToGem5Bridge &bridge_) : + BridgeMasterPort(const std::string &name_, + TlmToGem5Bridge &bridge_) : MasterPort(name_, nullptr), bridge(bridge_) {} }; - tlm_utils::peq_with_cb_and_phase peq; + tlm_utils::peq_with_cb_and_phase> peq; bool waitForRetry; tlm::tlm_generic_payload *pendingRequest; @@ -113,8 +121,9 @@ class TlmToGem5Bridge : public sc_core::sc_module bool responseInProgress; BridgeMasterPort bmp; - tlm_utils::simple_target_socket socket; - sc_gem5::TlmTargetWrapper<64> wrapper; + tlm_utils::simple_target_socket< + TlmToGem5Bridge, BITWIDTH> socket; + sc_gem5::TlmTargetWrapper wrapper; System *system; @@ -151,10 +160,10 @@ class TlmToGem5Bridge : public sc_core::sc_module public: ::Port &gem5_getPort(const std::string &if_name, int idx=-1) override; - typedef TlmToGem5BridgeParams Params; + typedef TlmToGem5BridgeBaseParams Params; TlmToGem5Bridge(Params *p, const sc_core::sc_module_name &mn); - tlm_utils::simple_target_socket & + tlm_utils::simple_target_socket, BITWIDTH> & getSocket() { return socket;