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:
parent
ccd9210e1a
commit
03f740664b
16 changed files with 511 additions and 116 deletions
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
62
util/tlm/master_transactor.cc
Normal file
62
util/tlm/master_transactor.cc
Normal 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);
|
||||
}
|
||||
|
||||
}
|
70
util/tlm/master_transactor.hh
Normal file
70
util/tlm/master_transactor.hh
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
56
util/tlm/sim_control_if.hh
Normal file
56
util/tlm/sim_control_if.hh
Normal 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
|
62
util/tlm/slave_transactor.cc
Normal file
62
util/tlm/slave_transactor.cc
Normal 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);
|
||||
}
|
||||
|
||||
}
|
70
util/tlm/slave_transactor.hh
Normal file
70
util/tlm/slave_transactor.hh
Normal 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
|
Loading…
Reference in a new issue