systemc: Templatize the gem5/TLM bridge SimObjects.
authorGabe Black <gabeblack@google.com>
Thu, 14 Mar 2019 12:33:51 +0000 (05:33 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 29 Mar 2019 22:46:00 +0000 (22:46 +0000)
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 <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/tlm_bridge/TlmBridge.py
src/systemc/tlm_bridge/gem5_to_tlm.cc
src/systemc/tlm_bridge/gem5_to_tlm.hh
src/systemc/tlm_bridge/tlm_to_gem5.cc
src/systemc/tlm_bridge/tlm_to_gem5.hh

index d2dff8600b264a232ee77e36b697af3de2c23975..dcc545280b6b444c369649aaab238c66c2271ba8 100644 (file)
@@ -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'
index 06ed2abf32bed382e7ce2f9b5bccd19e54011782..f78c679ee51329ad873546bc576fa05f2d5403cc 100644 (file)
@@ -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 <unsigned int BITWIDTH>
 void
-Gem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *pe,
+Gem5ToTlmBridge<BITWIDTH>::pec(
+        Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *pe,
         tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase)
 {
     sc_core::sc_time delay;
@@ -163,8 +167,9 @@ Gem5ToTlmBridge::pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *pe,
 }
 
 // Similar to TLM's blocking transport (LT)
+template <unsigned int BITWIDTH>
 Tick
-Gem5ToTlmBridge::recvAtomic(PacketPtr packet)
+Gem5ToTlmBridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-Gem5ToTlmBridge::recvFunctionalSnoop(PacketPtr packet)
+Gem5ToTlmBridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 bool
-Gem5ToTlmBridge::recvTimingReq(PacketPtr packet)
+Gem5ToTlmBridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 bool
-Gem5ToTlmBridge::recvTimingSnoopResp(PacketPtr packet)
+Gem5ToTlmBridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 bool
-Gem5ToTlmBridge::tryTiming(PacketPtr packet)
+Gem5ToTlmBridge<BITWIDTH>::tryTiming(PacketPtr packet)
 {
     panic("tryTiming(PacketPtr) isn't implemented.");
 }
 
+template <unsigned int BITWIDTH>
 void
-Gem5ToTlmBridge::recvRespRetry()
+Gem5ToTlmBridge<BITWIDTH>::recvRespRetry()
 {
     /* Retry a response */
     sc_assert(blockingResponse);
@@ -347,8 +357,9 @@ Gem5ToTlmBridge::recvRespRetry()
 }
 
 // Similar to TLM's debug transport.
+template <unsigned int BITWIDTH>
 void
-Gem5ToTlmBridge::recvFunctional(PacketPtr packet)
+Gem5ToTlmBridge<BITWIDTH>::recvFunctional(PacketPtr packet)
 {
     // Prepare the transaction.
     tlm::tlm_generic_payload *trans = mm.allocate();
@@ -369,8 +380,9 @@ Gem5ToTlmBridge::recvFunctional(PacketPtr packet)
     trans->release();
 }
 
+template <unsigned int BITWIDTH>
 tlm::tlm_sync_enum
-Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans,
+Gem5ToTlmBridge<BITWIDTH>::nb_transport_bw(tlm::tlm_generic_payload &trans,
     tlm::tlm_phase &phase, sc_core::sc_time &delay)
 {
     auto *pe = new Gem5SystemC::PayloadEvent<Gem5ToTlmBridge>(
@@ -381,9 +393,10 @@ Gem5ToTlmBridge::nb_transport_bw(tlm::tlm_generic_payload &trans,
     return tlm::TLM_ACCEPTED;
 }
 
-Gem5ToTlmBridge::Gem5ToTlmBridge(
+template <unsigned int BITWIDTH>
+Gem5ToTlmBridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 ::Port &
-Gem5ToTlmBridge::gem5_getPort(const std::string &if_name, int idx)
+Gem5ToTlmBridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-Gem5ToTlmBridge::before_end_of_elaboration()
+Gem5ToTlmBridge<BITWIDTH>::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()));
 }
index 02deb6add909ad1bde2ddce1458f923b45e00937..e36058ac6a1f0397a6b42586ecce90529bec3a27 100644 (file)
@@ -66,7 +66,7 @@
 #include <string>
 
 #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"
 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 <unsigned int BITWIDTH>
+class Gem5ToTlmBridge : public Gem5ToTlmBridgeBase
 {
   private:
     class BridgeSlavePort : public SlavePort
     {
       protected:
-        Gem5ToTlmBridge &bridge;
+        Gem5ToTlmBridge<BITWIDTH> &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<BITWIDTH> &bridge_) :
             SlavePort(name_, nullptr), bridge(bridge_)
         {}
     };
 
     BridgeSlavePort bsp;
-    tlm_utils::simple_initiator_socket<Gem5ToTlmBridge, 64> socket;
-    sc_gem5::TlmInitiatorWrapper<64> wrapper;
+    tlm_utils::simple_initiator_socket<
+        Gem5ToTlmBridge<BITWIDTH>, BITWIDTH> socket;
+    sc_gem5::TlmInitiatorWrapper<BITWIDTH> wrapper;
 
     System *system;
 
@@ -151,7 +160,7 @@ class Gem5ToTlmBridge : public sc_core::sc_module
     AddrRangeList addrRanges;
 
   protected:
-    void pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge> *pe,
+    void pec(Gem5SystemC::PayloadEvent<Gem5ToTlmBridge<BITWIDTH>> *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<Gem5ToTlmBridge, 64> &
+    tlm_utils::simple_initiator_socket<Gem5ToTlmBridge<BITWIDTH>, BITWIDTH> &
     getSocket()
     {
         return socket;
index 9e704901fbf4b75a6260154fb20a3398f2210a44..4b69286d09be54da4597011fa24626f1d67eb4f7 100644 (file)
 
 #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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans,
-                               sc_core::sc_time &delay)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans)
+TlmToGem5Bridge<BITWIDTH>::handleEndResp(tlm::tlm_generic_payload &trans)
 {
     sc_assert(responseInProgress);
 
@@ -151,8 +157,9 @@ TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans)
     }
 }
 
+template <unsigned int BITWIDTH>
 PacketPtr
-TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans)
+TlmToGem5Bridge<BITWIDTH>::generatePacket(tlm::tlm_generic_payload &trans)
 {
     MemCmd cmd;
 
@@ -184,14 +191,16 @@ TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans)
     return pkt;
 }
 
+template <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::destroyPacket(PacketPtr pkt)
+TlmToGem5Bridge<BITWIDTH>::destroyPacket(PacketPtr pkt)
 {
     delete pkt;
 }
 
+template <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans,
-                        const tlm::tlm_phase &phase)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 tlm::tlm_sync_enum
-TlmToGem5Bridge::nb_transport_fw(
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans,
-                             sc_core::sc_time &t)
+TlmToGem5Bridge<BITWIDTH>::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 BITWIDTH>
 unsigned int
-TlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 bool
-TlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
-                                    tlm::tlm_dmi &dmi_data)
+TlmToGem5Bridge<BITWIDTH>::get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
+                                              tlm::tlm_dmi &dmi_data)
 {
     return false;
 }
 
+template <unsigned int BITWIDTH>
 bool
-TlmToGem5Bridge::recvTimingResp(PacketPtr pkt)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::recvReqRetry()
+TlmToGem5Bridge<BITWIDTH>::recvReqRetry()
 {
     sc_assert(waitForRetry);
     sc_assert(pendingRequest != nullptr);
@@ -373,15 +389,17 @@ TlmToGem5Bridge::recvReqRetry()
     }
 }
 
+template <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::recvRangeChange()
+TlmToGem5Bridge<BITWIDTH>::recvRangeChange()
 {
     SC_REPORT_WARNING("TlmToGem5Bridge",
                       "received address range change but ignored it");
 }
 
+template <unsigned int BITWIDTH>
 ::Port &
-TlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx)
+TlmToGem5Bridge<BITWIDTH>::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 <unsigned int BITWIDTH>
+TlmToGem5Bridge<BITWIDTH>::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<BITWIDTH>::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 <unsigned int BITWIDTH>
 void
-TlmToGem5Bridge::before_end_of_elaboration()
+TlmToGem5Bridge<BITWIDTH>::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<BITWIDTH>::nb_transport_fw);
     } else if (system->isAtomicMode()) {
         SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface");
         socket.register_b_transport(
-                this, &TlmToGem5Bridge::b_transport);
+                this, &TlmToGem5Bridge<BITWIDTH>::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<BITWIDTH>::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()));
 }
index 1d6fa13d004a9b2704487bea58aff323216b01d2..d2b15af67a9972a5c8de0f7ce9e2a7f41dafeba4 100644 (file)
@@ -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"
 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 <unsigned int BITWIDTH>
+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<BITWIDTH> &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<BITWIDTH> &bridge_) :
             MasterPort(name_, nullptr), bridge(bridge_)
         {}
     };
 
-    tlm_utils::peq_with_cb_and_phase<TlmToGem5Bridge> peq;
+    tlm_utils::peq_with_cb_and_phase<TlmToGem5Bridge<BITWIDTH>> 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<TlmToGem5Bridge, 64> socket;
-    sc_gem5::TlmTargetWrapper<64> wrapper;
+    tlm_utils::simple_target_socket<
+        TlmToGem5Bridge<BITWIDTH>, BITWIDTH> socket;
+    sc_gem5::TlmTargetWrapper<BITWIDTH> 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<TlmToGem5Bridge, 64> &
+    tlm_utils::simple_target_socket<TlmToGem5Bridge<BITWIDTH>, BITWIDTH> &
     getSocket()
     {
         return socket;