misc: Clean up and complete the gem5<->SystemC-TLM bridge [5/10]
authorChristian Menard <Christian.Menard@tu-dresden.de>
Fri, 10 Feb 2017 00:15:41 +0000 (19:15 -0500)
committerChristian Menard <Christian.Menard@tu-dresden.de>
Fri, 10 Feb 2017 00:15:41 +0000 (19:15 -0500)
Changeset 11798:3a490c57058d
---------------------------
misc: Clean up and complete the gem5<->SystemC-TLM bridge [5/10]

The current TLM bridge only provides a Slave Port that allows the gem5
world to send request to the SystemC world. This patch series refractors
and cleans up the existing code, and adds a Master Port that allows the
SystemC world to send requests to the gem5 world.

This patch:
 * Introduce transactor modules that represent the gem5 ports in the
 * SystemC world.
 * Update the SimControl module and let it keep track of the gem5 ports.

Reviewed at http://reviews.gem5.org/r/3775/

Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
16 files changed:
util/tlm/examples/master_port/main.cc
util/tlm/examples/master_port/tlm.py
util/tlm/examples/slave_port/main.cc
util/tlm/examples/slave_port/run_gem5.sh
util/tlm/examples/slave_port/tlm.py
util/tlm/master_transactor.cc [new file with mode: 0644]
util/tlm/master_transactor.hh [new file with mode: 0644]
util/tlm/sc_master_port.cc
util/tlm/sc_master_port.hh
util/tlm/sc_slave_port.cc
util/tlm/sc_slave_port.hh
util/tlm/sim_control.cc
util/tlm/sim_control.hh
util/tlm/sim_control_if.hh [new file with mode: 0644]
util/tlm/slave_transactor.cc [new file with mode: 0644]
util/tlm/slave_transactor.hh [new file with mode: 0644]

index 588d8115635b5646105584bf15e99492fe987378..2fb1caeae2d10c42b3e69d66f2c43b46ce84c1ba 100644 (file)
@@ -36,8 +36,8 @@
 #include <tlm>
 
 #include "cli_parser.hh"
+#include "master_transactor.hh"
 #include "report_handler.hh"
-#include "sc_master_port.hh"
 #include "sim_control.hh"
 #include "stats.hh"
 #include "traffic_generator.hh"
@@ -50,24 +50,16 @@ sc_main(int argc, char** argv)
 
     sc_core::sc_report_handler::set_handler(reportHandler);
 
-    Gem5SystemC::Gem5SimControl simControl("gem5",
-                                           parser.getConfigFile(),
-                                           parser.getSimulationEnd(),
-                                           parser.getDebugFlags());
+    Gem5SystemC::Gem5SimControl sim_control("gem5",
+                                            parser.getConfigFile(),
+                                            parser.getSimulationEnd(),
+                                            parser.getDebugFlags());
 
     TrafficGenerator trafficGenerator("traffic_generator");
+    Gem5SystemC::Gem5MasterTransactor transactor("transactor", "transactor");
 
-    tlm::tlm_target_socket<>* mem_port =
-      dynamic_cast<tlm::tlm_target_socket<>*>(
-        sc_core::sc_find_object("gem5.memory"));
-
-    if (mem_port) {
-        SC_REPORT_INFO("sc_main", "Port Found");
-        trafficGenerator.socket.bind(*mem_port);
-    } else {
-        SC_REPORT_FATAL("sc_main", "Port Not Found");
-        std::exit(EXIT_FAILURE);
-    }
+    trafficGenerator.socket.bind(transactor.socket);
+    transactor.sim_control.bind(sim_control);
 
     SC_REPORT_INFO("sc_main", "Start of Simulation");
 
index 13c4388a9abf088daa624474849f13c012189617..0b017a6d11fd628c912ab1169f201aa73199aaad 100644 (file)
@@ -61,7 +61,7 @@ system.clk_domain = SrcClockDomain(clock = '1.5GHz',
 # Create a external TLM port:
 system.tlm = ExternalMaster()
 system.tlm.port_type = "tlm_master"
-system.tlm.port_data = "memory"
+system.tlm.port_data = "transactor"
 
 # Route the connections:
 system.system_port = system.membus.slave
index 9f1cadc8d954393601771b4c5fabf133ab25e2cf..5f555aa32886864fcdff6f2de6b3899b8ba99ad8 100644 (file)
@@ -50,6 +50,7 @@
 #include "report_handler.hh"
 #include "sc_target.hh"
 #include "sim_control.hh"
+#include "slave_transactor.hh"
 #include "stats.hh"
 
 int
@@ -60,31 +61,21 @@ sc_main(int argc, char **argv)
 
     sc_core::sc_report_handler::set_handler(reportHandler);
 
-    Gem5SystemC::Gem5SimControl simControl("gem5",
+    Gem5SystemC::Gem5SimControl sim_control("gem5",
                                            parser.getConfigFile(),
                                            parser.getSimulationEnd(),
                                            parser.getDebugFlags());
-    Target *memory;
 
     unsigned long long int memorySize = 512*1024*1024ULL;
 
-    tlm::tlm_initiator_socket <> *mem_port =
-        dynamic_cast<tlm::tlm_initiator_socket<> *>(
-                    sc_core::sc_find_object("gem5.memory")
-                );
+    Gem5SystemC::Gem5SlaveTransactor transactor("transactor", "transactor");
+    Target memory("memory",
+                  parser.getVerboseFlag(),
+                  memorySize,
+                  parser.getMemoryOffset());
 
-    if (mem_port) {
-        SC_REPORT_INFO("sc_main", "Port Found");
-        memory = new Target("memory",
-                            parser.getVerboseFlag(),
-                            memorySize,
-                            parser.getMemoryOffset());
-
-        memory->socket.bind(*mem_port);
-    } else {
-        SC_REPORT_FATAL("sc_main", "Port Not Found");
-        std::exit(EXIT_FAILURE);
-    }
+    memory.socket.bind(transactor.socket);
+    transactor.sim_control.bind(sim_control);
 
     SC_REPORT_INFO("sc_main", "Start of Simulation");
 
index a4a0b8021d00a8f2c3b392d218721f383e1bcf8f..fd14689b9e15d9a078951d389e376863bcdc7386 100644 (file)
@@ -37,7 +37,7 @@ BGre='\e[1;31m';
 echo -e "\n${BGre}Create gem5 Configuration${RCol}\n"
 
 ../../../../build/ARM/gem5.opt ../../../../configs/example/fs.py \
---tlm-memory=memory                                         \
+--tlm-memory=transactor                                     \
 --cpu-type=timing                                           \
 --num-cpu=1                                                 \
 --mem-type=SimpleMemory                                     \
index 9d6b26db1b491fa8bddc68b7f2b3e8386dcf25c2..ed4db40475fb5ced6c673dcb82ce26ddfbfa978c 100644 (file)
@@ -64,7 +64,7 @@ system.clk_domain = SrcClockDomain(clock = '1.5GHz',
 system.tlm = ExternalSlave()
 system.tlm.addr_ranges = [AddrRange('512MB')]
 system.tlm.port_type = "tlm_slave"
-system.tlm.port_data = "memory"
+system.tlm.port_data = "transactor"
 
 # Route the connections:
 system.cpu.port = system.membus.slave
diff --git a/util/tlm/master_transactor.cc b/util/tlm/master_transactor.cc
new file mode 100644 (file)
index 0000000..9e8c2ff
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Christian Menard
+ */
+
+#include "master_transactor.hh"
+#include "sc_master_port.hh"
+#include "sim_control.hh"
+
+namespace Gem5SystemC
+{
+
+Gem5MasterTransactor::Gem5MasterTransactor(sc_core::sc_module_name name,
+                                           const std::string& portName)
+    : sc_core::sc_module(name),
+      socket(portName.c_str()),
+      sim_control("sim_control"),
+      portName(portName)
+{
+    if (portName.empty()) {
+        SC_REPORT_ERROR(name, "No port name specified!\n");
+    }
+}
+
+void
+Gem5MasterTransactor::before_end_of_elaboration()
+{
+    auto* port = sim_control->getMasterPort(portName);
+
+    port->bindToTransactor(this);
+}
+
+}
diff --git a/util/tlm/master_transactor.hh b/util/tlm/master_transactor.hh
new file mode 100644 (file)
index 0000000..242c712
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Christian Menard
+ */
+
+#ifndef __GEM5_MASTER_TRANSACTOR_HH__
+#define __GEM5_MASTER_TRANSACTOR_HH__
+
+#include <tlm_utils/simple_target_socket.h>
+
+#include <systemc>
+#include <tlm>
+
+#include "sc_master_port.hh"
+#include "sim_control_if.hh"
+
+namespace Gem5SystemC
+{
+
+class Gem5MasterTransactor : public sc_core::sc_module
+{
+  public:
+    // module interface
+    tlm_utils::simple_target_socket<SCMasterPort> socket;
+    sc_core::sc_port<Gem5SimControlInterface> sim_control;
+
+  private:
+    std::string portName;
+
+  public:
+    SC_HAS_PROCESS(Gem5MasterTransactor);
+
+    Gem5MasterTransactor(sc_core::sc_module_name name,
+                         const std::string& portName);
+
+    void before_end_of_elaboration();
+};
+
+}
+
+#endif
index 06fab51a2be681b3229d569a6dd4bed792fb5024..4ab1f51c6206e1bf76121915fd18a4db67fefd32 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <sstream>
 
+#include "master_transactor.hh"
 #include "params/ExternalMaster.hh"
 #include "sc_master_port.hh"
 #include "sim/system.hh"
@@ -81,18 +82,26 @@ SCMasterPort::destroyPacket(PacketPtr pkt)
 SCMasterPort::SCMasterPort(const std::string& name_,
                            const std::string& systemc_name,
                            ExternalMaster& owner_,
-                           Module& module)
+                           Gem5SimControl& simControl)
   : ExternalMaster::Port(name_, owner_),
-    tSocket(systemc_name.c_str()),
     peq(this, &SCMasterPort::peq_cb),
     waitForRetry(false),
     pendingRequest(nullptr),
     needToSendRetry(false),
     responseInProgress(false),
-    module(module)
+    transactor(nullptr),
+    simControl(simControl)
 {
-    auto system =
+    system =
         dynamic_cast<const ExternalMasterParams*>(owner_.params())->system;
+}
+
+void
+SCMasterPort::bindToTransactor(Gem5MasterTransactor* transactor)
+{
+    sc_assert(this->transactor == nullptr);
+
+    this->transactor = transactor;
 
     /*
      * Register the TLM non-blocking interface when using gem5 Timing mode and
@@ -104,16 +113,18 @@ SCMasterPort::SCMasterPort(const std::string& name_,
      */
     if (system->isTimingMode()) {
         SC_REPORT_INFO("SCMasterPort", "register non-blocking interface");
-        tSocket.register_nb_transport_fw(this,
-                                         &SCMasterPort::nb_transport_fw);
+        transactor->socket.register_nb_transport_fw(this,
+                                &SCMasterPort::nb_transport_fw);
     } else if (system->isAtomicMode()) {
         SC_REPORT_INFO("SCMasterPort", "register blocking interface");
-        tSocket.register_b_transport(this, &SCMasterPort::b_transport);
+        transactor->socket.register_b_transport(this,
+                                &SCMasterPort::b_transport);
     } else {
         panic("gem5 operates neither in Timing nor in Atomic mode");
     }
 
-    tSocket.register_transport_dbg(this, &SCMasterPort::transport_dbg);
+    transactor->socket.register_transport_dbg(this,
+                                              &SCMasterPort::transport_dbg);
 }
 
 void
@@ -156,7 +167,7 @@ SCMasterPort::peq_cb(tlm::tlm_generic_payload& trans,
                        const tlm::tlm_phase& phase)
 {
     // catch up with SystemC time
-    module.catchup();
+    simControl.catchup();
     assert(curTick() == sc_core::sc_time_stamp().value());
 
     switch (phase) {
@@ -172,7 +183,7 @@ SCMasterPort::peq_cb(tlm::tlm_generic_payload& trans,
 
     // the functions called above may have scheduled gem5 events
     // -> notify the event loop handler
-    module.notify();
+    simControl.notify();
 }
 
 void
@@ -216,7 +227,7 @@ SCMasterPort::sendEndReq(tlm::tlm_generic_payload& trans)
     tlm::tlm_phase phase = tlm::END_REQ;
     auto delay = sc_core::SC_ZERO_TIME;
 
-    auto status = tSocket->nb_transport_bw(trans, phase, delay);
+    auto status = transactor->socket->nb_transport_bw(trans, phase, delay);
     panic_if(status != tlm::TLM_ACCEPTED,
              "Unexpected status after sending END_REQ");
 }
@@ -300,7 +311,7 @@ SCMasterPort::sendBeginResp(tlm::tlm_generic_payload& trans,
 
     trans.set_response_status(tlm::TLM_OK_RESPONSE);
 
-    auto status = tSocket->nb_transport_bw(trans, phase, delay);
+    auto status = transactor->socket->nb_transport_bw(trans, phase, delay);
 
     if (status == tlm::TLM_COMPLETED ||
         status == tlm::TLM_UPDATED && phase == tlm::END_RESP) {
@@ -336,27 +347,17 @@ SCMasterPort::recvRangeChange()
                       "received address range change but ignored it");
 }
 
-class SCMasterPortHandler : public ExternalMaster::Handler
+ExternalMaster::Port*
+SCMasterPortHandler::getExternalPort(const std::string &name,
+                                     ExternalMaster &owner,
+                                     const std::string &port_data)
 {
-    Module& module;
+    // Create and register a new SystemC master port
+    auto* port = new SCMasterPort(name, port_data, owner, control);
 
-  public:
-    SCMasterPortHandler(Module& module) : module(module) {}
+    control.registerMasterPort(port_data, port);
 
-    ExternalMaster::Port* getExternalPort(const std::string& name,
-                                          ExternalMaster& owner,
-                                          const std::string& port_data)
-    {
-        // This will make a new initiatiator port
-        return new SCMasterPort(name, port_data, owner, module);
-    }
-};
-
-void
-SCMasterPort::registerPortHandler(Module& module)
-{
-    ExternalMaster::registerHandler("tlm_master",
-                                    new SCMasterPortHandler(module));
+    return port;
 }
 
 } // namespace Gem5SystemC
index f2ac1580e7b6e763bf1203937931a1dceedc2998..5fae9b6b4eab9a588a8180b8c752acaa17f4c844 100644 (file)
 #define __SC_MASTER_PORT_HH__
 
 #include <tlm_utils/peq_with_cb_and_phase.h>
-#include <tlm_utils/simple_target_socket.h>
 
+#include <systemc>
 #include <tlm>
 
 #include <mem/external_master.hh>
-#include <sc_module.hh>
 #include <sc_peq.hh>
+#include <sim_control.hh>
 
 namespace Gem5SystemC
 {
 
+// forward declaration
+class Gem5MasterTransactor;
+
 /**
  * This is a gem5 master port that translates TLM transactions to gem5 packets.
  *
@@ -84,11 +87,11 @@ class SCMasterPort : public ExternalMaster::Port
 
     bool responseInProgress;
 
-    // Keep a reference to the gem5 SystemC module
-    Module& module;
+    Gem5MasterTransactor* transactor;
 
-  public:
-    tlm_utils::simple_target_socket<SCMasterPort> tSocket;
+    System* system;
+
+    Gem5SimControl& simControl;
 
   protected:
     // payload event call back
@@ -112,9 +115,9 @@ class SCMasterPort : public ExternalMaster::Port
     SCMasterPort(const std::string& name_,
                  const std::string& systemc_name,
                  ExternalMaster& owner_,
-                 Module& module);
+                 Gem5SimControl& simControl);
 
-    static void registerPortHandler(Module& module);
+    void bindToTransactor(Gem5MasterTransactor* transactor);
 
     friend PayloadEvent<SCMasterPort>;
 
@@ -132,6 +135,19 @@ class SCMasterPort : public ExternalMaster::Port
     void checkTransaction(tlm::tlm_generic_payload& trans);
 };
 
+class SCMasterPortHandler : public ExternalMaster::Handler
+{
+  private:
+    Gem5SimControl& control;
+
+  public:
+    SCMasterPortHandler(Gem5SimControl& control) : control(control) {}
+
+    ExternalMaster::Port *getExternalPort(const std::string &name,
+                                          ExternalMaster &owner,
+                                          const std::string &port_data);
+};
+
 }
 
 #endif
index 3176de928cfaaeb17e1b6acde54f1ec567565954..cc4218fc0720055eefed8753d05d740de8b79a11 100644 (file)
  *          Christian Menard
  */
 
-#include <cctype>
-#include <iomanip>
-#include <sstream>
-
-#include "debug/ExternalPort.hh"
 #include "sc_ext.hh"
 #include "sc_mm.hh"
 #include "sc_slave_port.hh"
+#include "slave_transactor.hh"
 
 namespace Gem5SystemC
 {
@@ -116,11 +112,11 @@ SCSlavePort::recvAtomic(PacketPtr packet)
     if (packet->cmd == MemCmd::SwapReq) {
         SC_REPORT_FATAL("SCSlavePort", "SwapReq not supported");
     } else if (packet->isRead()) {
-        iSocket->b_transport(*trans, delay);
+        transactor->socket->b_transport(*trans, delay);
     } else if (packet->isInvalidate()) {
         // do nothing
     } else if (packet->isWrite()) {
-        iSocket->b_transport(*trans, delay);
+        transactor->socket->b_transport(*trans, delay);
     } else {
         SC_REPORT_FATAL("SCSlavePort", "Typo of request not supported");
     }
@@ -150,7 +146,7 @@ SCSlavePort::recvFunctional(PacketPtr packet)
     trans->set_auto_extension(extension);
 
     /* Execute Debug Transport: */
-    unsigned int bytes = iSocket->transport_dbg(*trans);
+    unsigned int bytes = transactor->socket->transport_dbg(*trans);
     if (bytes != trans->get_data_length()) {
         SC_REPORT_FATAL("SCSlavePort","debug transport was not completed");
     }
@@ -223,7 +219,7 @@ SCSlavePort::recvTimingReq(PacketPtr packet)
     sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
     tlm::tlm_phase phase = tlm::BEGIN_REQ;
     tlm::tlm_sync_enum status;
-    status = iSocket->nb_transport_fw(*trans, phase, delay);
+    status = transactor->socket->nb_transport_fw(*trans, phase, delay);
     /* Check returned value: */
     if (status == tlm::TLM_ACCEPTED) {
         sc_assert(phase == tlm::BEGIN_REQ);
@@ -288,7 +284,7 @@ SCSlavePort::pec(
                 /* Send END_RESP and we're finished: */
                 tlm::tlm_phase fw_phase = tlm::END_RESP;
                 sc_time delay = SC_ZERO_TIME;
-                iSocket->nb_transport_fw(trans, fw_phase, delay);
+                transactor->socket->nb_transport_fw(trans, fw_phase, delay);
                 /* Release the transaction with all the extensions */
                 trans.release();
             }
@@ -317,7 +313,7 @@ SCSlavePort::recvRespRetry()
 
     sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
     tlm::tlm_phase phase = tlm::END_RESP;
-    iSocket->nb_transport_fw(*trans, phase, delay);
+    transactor->socket->nb_transport_fw(*trans, phase, delay);
     // Release transaction with all the extensions
     trans->release();
 }
@@ -337,30 +333,35 @@ SCSlavePort::SCSlavePort(const std::string &name_,
     const std::string &systemc_name,
     ExternalSlave &owner_) :
     ExternalSlave::Port(name_, owner_),
-    iSocket(systemc_name.c_str()),
     blockingRequest(NULL),
     needToSendRequestRetry(false),
-    blockingResponse(NULL)
+    blockingResponse(NULL),
+    transactor(nullptr)
 {
-    iSocket.register_nb_transport_bw(this, &SCSlavePort::nb_transport_bw);
 }
 
-class SlavePortHandler : public ExternalSlave::Handler
+void
+SCSlavePort::bindToTransactor(Gem5SlaveTransactor* transactor)
 {
-  public:
-    ExternalSlave::Port *getExternalPort(const std::string &name,
-        ExternalSlave &owner,
-        const std::string &port_data)
-    {
-        // This will make a new initiatiator port
-        return new SCSlavePort(name, port_data, owner);
-    }
-};
+    sc_assert(this->transactor == nullptr);
 
-void
-SCSlavePort::registerPortHandler()
+    this->transactor = transactor;
+
+    transactor->socket.register_nb_transport_bw(this,
+                                                &SCSlavePort::nb_transport_bw);
+}
+
+ExternalSlave::Port*
+SCSlavePortHandler::getExternalPort(const std::string &name,
+                                    ExternalSlave &owner,
+                                    const std::string &port_data)
 {
-    ExternalSlave::registerHandler("tlm_slave", new SlavePortHandler);
+    // Create and register a new SystemC slave port
+    auto* port = new SCSlavePort(name, port_data, owner);
+
+    control.registerSlavePort(port_data, port);
+
+    return port;
 }
 
 }
index 9e37ff4bb5797f6c6d45c10d90fe169e38a3a81d..6f8f6a6336b11d602c1aa6e4fc749371210b1fd7 100644 (file)
 #ifndef __SC_SLAVE_PORT_HH__
 #define __SC_SLAVE_PORT_HH__
 
-#include <tlm_utils/simple_initiator_socket.h>
-
-#include <map>
 #include <systemc>
 #include <tlm>
 
 #include "mem/external_slave.hh"
 #include "sc_mm.hh"
-#include "sc_module.hh"
 #include "sc_peq.hh"
+#include "sim_control.hh"
 
 namespace Gem5SystemC
 {
+
+// forward declaration
+class Gem5SlaveTransactor;
+
 /**
  * Test that gem5 is at the same time as SystemC
  */
@@ -70,8 +71,6 @@ namespace Gem5SystemC
 class SCSlavePort : public ExternalSlave::Port
 {
   public:
-    tlm_utils::simple_initiator_socket<SCSlavePort> iSocket;
-
     /** One instance of pe and the related callback needed */
     //payloadEvent<SCSlavePort> pe;
     void pec(PayloadEvent<SCSlavePort> * pe,
@@ -104,21 +103,36 @@ class SCSlavePort : public ExternalSlave::Port
     void recvRespRetry();
     void recvFunctionalSnoop(PacketPtr packet);
 
+    Gem5SlaveTransactor* transactor;
+
+  public:
     /** The TLM initiator interface */
     tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
                                        tlm::tlm_phase& phase,
                                        sc_core::sc_time& t);
 
-  public:
     SCSlavePort(const std::string &name_,
                 const std::string &systemc_name,
                 ExternalSlave &owner_);
 
-    static void registerPortHandler();
+    void bindToTransactor(Gem5SlaveTransactor* transactor);
 
     friend PayloadEvent<SCSlavePort>;
 };
 
+class SCSlavePortHandler : public ExternalSlave::Handler
+{
+  private:
+    Gem5SimControl& control;
+
+  public:
+    SCSlavePortHandler(Gem5SimControl& control) : control(control) {}
+
+    ExternalSlave::Port *getExternalPort(const std::string &name,
+                                         ExternalSlave &owner,
+                                         const std::string &port_data);
+};
+
 }
 
 #endif // __SC_SLAVE_PORT_H__
index d6bedc80ba709371a6f9db5a8a7d8da5a207a391..f6a3e4ffe9972c714dc4d7226a20fb5dd67215f5 100644 (file)
@@ -77,8 +77,11 @@ Gem5SimControl::Gem5SimControl(sc_core::sc_module_name name,
     instance = this;
 
     cxxConfigInit();
-    Gem5SystemC::SCSlavePort::registerPortHandler();
-    Gem5SystemC::SCMasterPort::registerPortHandler(*this);
+
+    // register the systemc slave and master port handler
+    ExternalSlave::registerHandler("tlm_slave", new SCSlavePortHandler(*this));
+    ExternalMaster::registerHandler("tlm_master",
+                                    new SCMasterPortHandler(*this));
 
     Trace::setDebugLogger(&logger);
 
@@ -134,7 +137,7 @@ Gem5SimControl::Gem5SimControl(sc_core::sc_module_name name,
 }
 
 void
-Gem5SimControl::before_end_of_elaboration()
+Gem5SimControl::end_of_elaboration()
 {
     try {
         config_manager->initState();
@@ -167,4 +170,48 @@ Gem5SimControl::run()
 #endif
 }
 
+void
+Gem5SimControl::registerSlavePort(const std::string& name, SCSlavePort* port)
+{
+    if (slavePorts.find(name) == slavePorts.end()) {
+        slavePorts[name] = port;
+    } else {
+        std::cerr << "Slave Port " << name << " is already registered!\n";
+        std::exit(EXIT_FAILURE);
+    }
+}
+
+void
+Gem5SimControl::registerMasterPort(const std::string& name, SCMasterPort* port)
+{
+    if (masterPorts.find(name) == masterPorts.end()) {
+        masterPorts[name] = port;
+    } else {
+        std::cerr << "Master Port " << name << " is already registered!\n";
+        std::exit(EXIT_FAILURE);
+    }
+}
+
+SCSlavePort*
+Gem5SimControl::getSlavePort(const std::string& name)
+{
+    if (slavePorts.find(name) == slavePorts.end()) {
+        std::cerr << "Slave Port " << name << " was not found!\n";
+        std::exit(EXIT_FAILURE);
+    }
+
+    return slavePorts.at(name);
+}
+
+SCMasterPort*
+Gem5SimControl::getMasterPort(const std::string& name)
+{
+    if (masterPorts.find(name) == masterPorts.end()) {
+        std::cerr << "Master Port " << name << " was not found!\n";
+        std::exit(EXIT_FAILURE);
+    }
+
+    return masterPorts.at(name);
+}
+
 }
index d210d76dd6237b7006675e4ce556dba043d91cec..b411022de8425c66d780848d49083b54724a1873 100644 (file)
@@ -46,6 +46,7 @@
 #include "sc_module.hh"
 #include "sim/cxx_manager.hh"
 #include "sim/system.hh"
+#include "sim_control_if.hh"
 
 namespace Gem5SystemC
 {
@@ -58,7 +59,7 @@ namespace Gem5SystemC
  * While it is mandatory to have one instance of this class for running a gem5
  * simulation in SystemC, it is not allowed to have multiple instances!
  */
-class Gem5SimControl : public Gem5SystemC::Module
+class Gem5SimControl : public Module, public Gem5SimControlInterface
 {
   protected:
     CxxConfigManager* config_manager;
@@ -66,6 +67,13 @@ class Gem5SimControl : public Gem5SystemC::Module
 
     Tick simulationEnd;
 
+    /*
+     * Keep track of the slave and master ports that are created by gem5
+     * according to the config file.
+     */
+    std::map<const std::string, SCSlavePort*> slavePorts;
+    std::map<const std::string, SCMasterPort*> masterPorts;
+
     /// Pointer to a previously created instance.
     static Gem5SimControl* instance;
 
@@ -90,7 +98,12 @@ class Gem5SimControl : public Gem5SystemC::Module
                    uint64_t simulationEnd,
                    const std::string& gem5DebugFlags);
 
-    void before_end_of_elaboration();
+    void registerSlavePort(const std::string& name, SCSlavePort* port);
+    void registerMasterPort(const std::string& name, SCMasterPort* port);
+    SCSlavePort* getSlavePort(const std::string& name) override;
+    SCMasterPort* getMasterPort(const std::string& name) override;
+
+    void end_of_elaboration();
 
     void run();
 };
diff --git a/util/tlm/sim_control_if.hh b/util/tlm/sim_control_if.hh
new file mode 100644 (file)
index 0000000..b65e919
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017, Dresden University of Technology (TU Dresden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Christian Menard
+ */
+
+#ifndef __SC_SIM_CONTROL_IF_HH__
+#define __SC_SIM_CONTROL_IF_HH__
+
+#include <systemc>
+
+namespace Gem5SystemC
+{
+
+// forward declerations
+class SCSlavePort;
+class SCMasterPort;
+
+class Gem5SimControlInterface : public sc_core::sc_interface
+{
+  public:
+    virtual SCSlavePort* getSlavePort(const std::string& name) = 0;
+    virtual SCMasterPort* getMasterPort(const std::string& name) = 0;
+};
+
+}
+
+#endif
diff --git a/util/tlm/slave_transactor.cc b/util/tlm/slave_transactor.cc
new file mode 100644 (file)
index 0000000..d181156
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Christian Menard
+ */
+
+#include "sc_slave_port.hh"
+#include "sim_control.hh"
+#include "slave_transactor.hh"
+
+namespace Gem5SystemC
+{
+
+Gem5SlaveTransactor::Gem5SlaveTransactor(sc_core::sc_module_name name,
+                                         const std::string& portName)
+    : sc_core::sc_module(name),
+      socket(portName.c_str()),
+      sim_control("sim_control"),
+      portName(portName)
+{
+    if (portName.empty()) {
+        SC_REPORT_ERROR(name, "No port name specified!\n");
+    }
+}
+
+void
+Gem5SlaveTransactor::before_end_of_elaboration()
+{
+    auto* port = sim_control->getSlavePort(portName);
+
+    port->bindToTransactor(this);
+}
+
+}
diff --git a/util/tlm/slave_transactor.hh b/util/tlm/slave_transactor.hh
new file mode 100644 (file)
index 0000000..6a9c5e8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Christian Menard
+ */
+
+#ifndef __GEM5_SLAVE_TRANSACTOR_HH__
+#define __GEM5_SLAVE_TRANSACTOR_HH__
+
+#include <tlm_utils/simple_initiator_socket.h>
+
+#include <systemc>
+#include <tlm>
+
+#include "sc_slave_port.hh"
+#include "sim_control_if.hh"
+
+namespace Gem5SystemC
+{
+
+class Gem5SlaveTransactor : public sc_core::sc_module
+{
+  public:
+    // module interface
+    tlm_utils::simple_initiator_socket<SCSlavePort> socket;
+    sc_core::sc_port<Gem5SimControlInterface> sim_control;
+
+  private:
+    std::string portName;
+
+  public:
+    SC_HAS_PROCESS(Gem5SlaveTransactor);
+
+    Gem5SlaveTransactor(sc_core::sc_module_name name,
+                        const std::string& portName);
+
+    void before_end_of_elaboration();
+};
+
+}
+
+#endif