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>
This commit is contained in:
Christian Menard 2017-02-09 19:15:41 -05:00
parent ccd9210e1a
commit 03f740664b
16 changed files with 511 additions and 116 deletions

View 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");

View 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

View 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");

View 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 \

View 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

View file

@ -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);
}
}

View file

@ -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

View 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

View file

@ -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

View file

@ -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
{
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);
}
};
void
SCSlavePort::registerPortHandler()
SCSlavePort::bindToTransactor(Gem5SlaveTransactor* transactor)
{
ExternalSlave::registerHandler("tlm_slave", new SlavePortHandler);
sc_assert(this->transactor == nullptr);
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)
{
// Create and register a new SystemC slave port
auto* port = new SCSlavePort(name, port_data, owner);
control.registerSlavePort(port_data, port);
return port;
}
}

View file

@ -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__

View 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);
}
}

View 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();
};

View file

@ -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

View file

@ -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);
}
}

View file

@ -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