summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorChristian Menard <Christian.Menard@tu-dresden.de>2017-02-09 19:15:41 -0500
committerChristian Menard <Christian.Menard@tu-dresden.de>2017-02-09 19:15:41 -0500
commit03f740664bc8db8890359c9c5ad02df9db478bae (patch)
tree27de717f997634ca22d04200a51b54305244929b /util
parentccd9210e1a1bdce828a13a4ffdf84548ffe61592 (diff)
downloadgem5-03f740664bc8db8890359c9c5ad02df9db478bae.tar.xz
misc: Clean up and complete the gem5<->SystemC-TLM bridge [5/10]
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>
Diffstat (limited to 'util')
-rw-r--r--util/tlm/examples/master_port/main.cc24
-rw-r--r--util/tlm/examples/master_port/tlm.py2
-rw-r--r--util/tlm/examples/slave_port/main.cc27
-rw-r--r--util/tlm/examples/slave_port/run_gem5.sh2
-rw-r--r--util/tlm/examples/slave_port/tlm.py2
-rw-r--r--util/tlm/master_transactor.cc62
-rw-r--r--util/tlm/master_transactor.hh70
-rw-r--r--util/tlm/sc_master_port.cc61
-rw-r--r--util/tlm/sc_master_port.hh32
-rw-r--r--util/tlm/sc_slave_port.cc55
-rw-r--r--util/tlm/sc_slave_port.hh30
-rw-r--r--util/tlm/sim_control.cc53
-rw-r--r--util/tlm/sim_control.hh17
-rw-r--r--util/tlm/sim_control_if.hh56
-rw-r--r--util/tlm/slave_transactor.cc62
-rw-r--r--util/tlm/slave_transactor.hh70
16 files changed, 510 insertions, 115 deletions
diff --git a/util/tlm/examples/master_port/main.cc b/util/tlm/examples/master_port/main.cc
index 588d81156..2fb1caeae 100644
--- a/util/tlm/examples/master_port/main.cc
+++ b/util/tlm/examples/master_port/main.cc
@@ -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");
diff --git a/util/tlm/examples/master_port/tlm.py b/util/tlm/examples/master_port/tlm.py
index 13c4388a9..0b017a6d1 100644
--- a/util/tlm/examples/master_port/tlm.py
+++ b/util/tlm/examples/master_port/tlm.py
@@ -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
diff --git a/util/tlm/examples/slave_port/main.cc b/util/tlm/examples/slave_port/main.cc
index 9f1cadc8d..5f555aa32 100644
--- a/util/tlm/examples/slave_port/main.cc
+++ b/util/tlm/examples/slave_port/main.cc
@@ -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");
diff --git a/util/tlm/examples/slave_port/run_gem5.sh b/util/tlm/examples/slave_port/run_gem5.sh
index a4a0b8021..fd14689b9 100644
--- a/util/tlm/examples/slave_port/run_gem5.sh
+++ b/util/tlm/examples/slave_port/run_gem5.sh
@@ -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 \
diff --git a/util/tlm/examples/slave_port/tlm.py b/util/tlm/examples/slave_port/tlm.py
index 9d6b26db1..ed4db4047 100644
--- a/util/tlm/examples/slave_port/tlm.py
+++ b/util/tlm/examples/slave_port/tlm.py
@@ -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
index 000000000..9e8c2ffec
--- /dev/null
+++ b/util/tlm/master_transactor.cc
@@ -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
index 000000000..242c712e7
--- /dev/null
+++ b/util/tlm/master_transactor.hh
@@ -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
diff --git a/util/tlm/sc_master_port.cc b/util/tlm/sc_master_port.cc
index 06fab51a2..4ab1f51c6 100644
--- a/util/tlm/sc_master_port.cc
+++ b/util/tlm/sc_master_port.cc
@@ -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
diff --git a/util/tlm/sc_master_port.hh b/util/tlm/sc_master_port.hh
index f2ac1580e..5fae9b6b4 100644
--- a/util/tlm/sc_master_port.hh
+++ b/util/tlm/sc_master_port.hh
@@ -36,17 +36,20 @@
#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
diff --git a/util/tlm/sc_slave_port.cc b/util/tlm/sc_slave_port.cc
index 3176de928..cc4218fc0 100644
--- a/util/tlm/sc_slave_port.cc
+++ b/util/tlm/sc_slave_port.cc
@@ -35,14 +35,10 @@
* 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;
}
}
diff --git a/util/tlm/sc_slave_port.hh b/util/tlm/sc_slave_port.hh
index 9e37ff4bb..6f8f6a633 100644
--- a/util/tlm/sc_slave_port.hh
+++ b/util/tlm/sc_slave_port.hh
@@ -37,19 +37,20 @@
#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__
diff --git a/util/tlm/sim_control.cc b/util/tlm/sim_control.cc
index d6bedc80b..f6a3e4ffe 100644
--- a/util/tlm/sim_control.cc
+++ b/util/tlm/sim_control.cc
@@ -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);
+}
+
}
diff --git a/util/tlm/sim_control.hh b/util/tlm/sim_control.hh
index d210d76dd..b411022de 100644
--- a/util/tlm/sim_control.hh
+++ b/util/tlm/sim_control.hh
@@ -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
index 000000000..b65e919d2
--- /dev/null
+++ b/util/tlm/sim_control_if.hh
@@ -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
index 000000000..d181156c6
--- /dev/null
+++ b/util/tlm/slave_transactor.cc
@@ -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
index 000000000..6a9c5e836
--- /dev/null
+++ b/util/tlm/slave_transactor.hh
@@ -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