summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/tlm/examples/slave_port/SConstruct (renamed from util/tlm/Makefile)85
-rw-r--r--util/tlm/examples/slave_port/main.cc115
-rw-r--r--util/tlm/examples/slave_port/run_gem5.sh (renamed from util/tlm/run_gem5.sh)2
-rw-r--r--util/tlm/examples/slave_port/sc_target.cc (renamed from util/tlm/sc_target.cc)6
-rw-r--r--util/tlm/examples/slave_port/sc_target.hh (renamed from util/tlm/sc_target.hh)0
-rw-r--r--util/tlm/examples/slave_port/tgen.cfg (renamed from util/tlm/tgen.cfg)0
-rw-r--r--util/tlm/examples/slave_port/tlm.py (renamed from util/tlm/tlm.py)4
-rw-r--r--util/tlm/examples/slave_port/tlm_elastic.py (renamed from util/tlm/tlm_elastic.py)0
-rw-r--r--util/tlm/sc_ext.cc27
-rw-r--r--util/tlm/sc_ext.hh21
-rw-r--r--util/tlm/sc_mm.cc5
-rw-r--r--util/tlm/sc_mm.hh11
-rw-r--r--util/tlm/sc_peq.hh102
-rw-r--r--util/tlm/sc_slave_port.cc (renamed from util/tlm/sc_port.cc)72
-rw-r--r--util/tlm/sc_slave_port.hh (renamed from util/tlm/sc_port.hh)97
-rw-r--r--util/tlm/sim_control.cc (renamed from util/tlm/main.cc)157
-rw-r--r--util/tlm/sim_control.hh76
17 files changed, 476 insertions, 304 deletions
diff --git a/util/tlm/Makefile b/util/tlm/examples/slave_port/SConstruct
index 1fda3b113..8ca9959a0 100644
--- a/util/tlm/Makefile
+++ b/util/tlm/examples/slave_port/SConstruct
@@ -1,21 +1,23 @@
-# Copyright (c) 2015, University of Kaiserslautern
+#!python
+
+# 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
@@ -27,50 +29,49 @@
# 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: Matthias Jung
+#
+# Authors: Christian Menard
+
+import os
+
+gem5_arch = 'ARM'
+gem5_variant = 'opt'
+#gem5_variant = 'debug'
+
+gem5_root = '#../../../..'
+target = 'gem5.' + gem5_variant + '.sc'
-ARCH = ARM
-VARIANT = opt
-#VARIANT = debug
+env = Environment()
-SYSTEMC_INC = /opt/systemc/include
-SYSTEMC_LIB = /opt/systemc/lib-linux64
+# Import PKG_CONFIG_PATH from the external environment
+if os.environ.has_key('PKG_CONFIG_PATH'):
+ env['ENV']['PKG_CONFIG_PATH'] = os.environ['PKG_CONFIG_PATH']
-CXXFLAGS = -I../../build/$(ARCH) -L../../build/$(ARCH)
-CXXFLAGS += -I../systemc/
-CXXFLAGS += -I$(SYSTEMC_INC) -L$(SYSTEMC_LIB)
-CXXFLAGS += -std=c++0x
-CXXFLAGS += -g
-CXXFLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DDEBUG -DTRACING_ON
+# search for SystemC
+env.ParseConfig('pkg-config --cflags --libs systemc')
-LIBS = -lgem5_$(VARIANT) -lsystemc
+# add include dirs
+env.Append(CPPPATH=[gem5_root + '/build/' + gem5_arch,
+ gem5_root + '/util/systemc',
+ gem5_root + '/util/tlm'])
-ALL = gem5.$(VARIANT).sc
+env.Append(LIBS=['gem5_' + gem5_variant])
+env.Append(LIBPATH=[gem5_root + '/build/' + gem5_arch])
-all: $(ALL)
+env.Append(CXXFLAGS=['-std=c++11',
+ '-DSC_INCLUDE_DYNAMIC_PROCESSES',
+ '-DTRACING_ON'])
-.cc.o:
- $(CXX) $(CXXFLAGS) -c -o $@ $<
+if gem5_variant == 'debug':
+ env.Append(CXXFLAGS=['-g', '-DDEBUG'])
-sc_gem5_control.o: ../systemc/sc_gem5_control.cc \
- ../systemc/sc_gem5_control.hh
-sc_logger.o: ../systemc/sc_logger.cc ../systemc/sc_logger.hh
-sc_module.o: ../systemc/sc_module.cc ../systemc/sc_module.hh
-sc_mm.o: sc_mm.cc sc_mm.hh
-sc_ext.o: sc_ext.cc sc_ext.hh
-sc_port.o: sc_port.cc sc_port.hh
-sc_target.o: sc_target.cc sc_target.hh
-stats.o: ../systemc/stats.cc ../systemc/stats.hh
-main.o: main.cc ../systemc/sc_logger.hh ../systemc/sc_module.hh \
- ../systemc/stats.hh
+src_systemc = [gem5_root + '/util/systemc/sc_gem5_control.cc',
+ gem5_root + '/util/systemc/sc_logger.cc',
+ gem5_root + '/util/systemc/sc_module.cc',
+ gem5_root + '/util/systemc/stats.cc']
-gem5.$(VARIANT).sc: main.o ../systemc/stats.o ../systemc/sc_gem5_control.o \
- ../systemc/sc_logger.o ../systemc/sc_module.o sc_mm.o sc_ext.o sc_port.o sc_target.o
- $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
+src_tlm = Glob(gem5_root + '/util/tlm/*.cc')
+src_main = Glob('*.cc')
-clean:
- $(RM) $(ALL)
- $(RM) *.o
- $(RM) -r m5out
+main = env.Program(target, src_systemc + src_tlm + src_main)
diff --git a/util/tlm/examples/slave_port/main.cc b/util/tlm/examples/slave_port/main.cc
new file mode 100644
index 000000000..256a99d1b
--- /dev/null
+++ b/util/tlm/examples/slave_port/main.cc
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015, University of Kaiserslautern
+ * 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: Matthias Jung
+ * Christian Menard
+ * Abdul Mutaal Ahmad
+ */
+
+/**
+ * @file
+ *
+ * Example top level file for SystemC-TLM integration with C++-only
+ * instantiation.
+ *
+ */
+
+#include <tlm_utils/simple_target_socket.h>
+
+#include <systemc>
+#include <tlm>
+
+#include "sc_target.hh"
+#include "sim_control.hh"
+#include "stats.hh"
+
+// Defining global string variable decalred in stats.hh
+std::string filename;
+
+void
+reportHandler(const sc_core::sc_report &report,
+ const sc_core::sc_actions &actions)
+{
+ uint64_t systemc_time = report.get_time().value();
+ uint64_t gem5_time = curTick();
+
+ std::cerr << report.get_time();
+
+ if (gem5_time < systemc_time) {
+ std::cerr << " (<) ";
+ } else if (gem5_time > systemc_time) {
+ std::cerr << " (!) ";
+ } else {
+ std::cerr << " (=) ";
+ }
+
+ std::cerr << ": " << report.get_msg_type()
+ << ' ' << report.get_msg() << '\n';
+}
+
+int
+sc_main(int argc, char **argv)
+{
+ sc_core::sc_report_handler::set_handler(reportHandler);
+
+ SimControl sim_control("gem5", argc, argv);
+ Target *memory;
+
+ filename = "m5out/stats-systemc.txt";
+
+ tlm::tlm_initiator_socket <> *mem_port =
+ dynamic_cast<tlm::tlm_initiator_socket<> *>(
+ sc_core::sc_find_object("gem5.memory")
+ );
+
+ if (mem_port) {
+ SC_REPORT_INFO("sc_main", "Port Found");
+ unsigned long long int size = 512*1024*1024ULL;
+ memory = new Target("memory",
+ sim_control.getDebugFlag(),
+ size,
+ sim_control.getOffset());
+
+ memory->socket.bind(*mem_port);
+ } else {
+ SC_REPORT_FATAL("sc_main", "Port Not Found");
+ std::exit(EXIT_FAILURE);
+ }
+
+ sc_core::sc_start();
+
+ SC_REPORT_INFO("sc_main", "End of Simulation");
+
+ CxxConfig::statsDump();
+
+ return EXIT_SUCCESS;
+}
diff --git a/util/tlm/run_gem5.sh b/util/tlm/examples/slave_port/run_gem5.sh
index c50391e69..a4a0b8021 100644
--- a/util/tlm/run_gem5.sh
+++ b/util/tlm/examples/slave_port/run_gem5.sh
@@ -36,7 +36,7 @@ RCol='\e[0m'; # Text Reset
BGre='\e[1;31m';
echo -e "\n${BGre}Create gem5 Configuration${RCol}\n"
-../../build/ARM/gem5.opt ../../configs/example/fs.py \
+../../../../build/ARM/gem5.opt ../../../../configs/example/fs.py \
--tlm-memory=memory \
--cpu-type=timing \
--num-cpu=1 \
diff --git a/util/tlm/sc_target.cc b/util/tlm/examples/slave_port/sc_target.cc
index bae1de126..c44a27149 100644
--- a/util/tlm/sc_target.cc
+++ b/util/tlm/examples/slave_port/sc_target.cc
@@ -165,7 +165,7 @@ Target::send_end_req(tlm::tlm_generic_payload& trans)
/* Queue the acceptance and the response with the appropriate latency */
bw_phase = tlm::END_REQ;
- delay = sc_time(10, SC_NS); // Accept delay
+ delay = sc_time(10.0, SC_NS); // Accept delay
tlm::tlm_sync_enum status;
status = socket->nb_transport_bw(trans, bw_phase, delay);
@@ -173,7 +173,7 @@ Target::send_end_req(tlm::tlm_generic_payload& trans)
/* Ignore return value;
* initiator cannot terminate transaction at this point
* Queue internal event to mark beginning of response: */
- delay = delay + sc_time(40, SC_NS); // Latency
+ delay = delay + sc_time(40.0, SC_NS); // Latency
target_done_event.notify(delay);
assert(transaction_in_progress == 0);
@@ -249,7 +249,7 @@ Target::send_response(tlm::tlm_generic_payload& trans)
response_in_progress = true;
bw_phase = tlm::BEGIN_RESP;
- delay = sc_time(10, SC_NS);
+ delay = sc_time(10.0, SC_NS);
status = socket->nb_transport_bw( trans, bw_phase, delay );
if (status == tlm::TLM_UPDATED) {
diff --git a/util/tlm/sc_target.hh b/util/tlm/examples/slave_port/sc_target.hh
index 7a2d075d9..7a2d075d9 100644
--- a/util/tlm/sc_target.hh
+++ b/util/tlm/examples/slave_port/sc_target.hh
diff --git a/util/tlm/tgen.cfg b/util/tlm/examples/slave_port/tgen.cfg
index e341d8574..e341d8574 100644
--- a/util/tlm/tgen.cfg
+++ b/util/tlm/examples/slave_port/tgen.cfg
diff --git a/util/tlm/tlm.py b/util/tlm/examples/slave_port/tlm.py
index e9025abab..9d6b26db1 100644
--- a/util/tlm/tlm.py
+++ b/util/tlm/examples/slave_port/tlm.py
@@ -45,7 +45,7 @@ from m5.objects import *
# | | |
# +-------v------v-------+ |
# | Membus | v
-# +----------------+-----+ External Port (see sc_port.*)
+# +----------------+-----+ External Port (see sc_slave_port.*)
# | ^
# +---v---+ | TLM World
# | TLM | | (see sc_target.*)
@@ -63,7 +63,7 @@ system.clk_domain = SrcClockDomain(clock = '1.5GHz',
# Create a external TLM port:
system.tlm = ExternalSlave()
system.tlm.addr_ranges = [AddrRange('512MB')]
-system.tlm.port_type = "tlm"
+system.tlm.port_type = "tlm_slave"
system.tlm.port_data = "memory"
# Route the connections:
diff --git a/util/tlm/tlm_elastic.py b/util/tlm/examples/slave_port/tlm_elastic.py
index 3de0670c0..3de0670c0 100644
--- a/util/tlm/tlm_elastic.py
+++ b/util/tlm/examples/slave_port/tlm_elastic.py
diff --git a/util/tlm/sc_ext.cc b/util/tlm/sc_ext.cc
index ce7417e49..db0c36f03 100644
--- a/util/tlm/sc_ext.cc
+++ b/util/tlm/sc_ext.cc
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,42 +32,48 @@
*
* Authors:
* Matthias Jung
+ * Christian Menard
*/
#include "sc_ext.hh"
using namespace tlm;
-gem5Extension::gem5Extension(PacketPtr packet)
+namespace Gem5SystemC
+{
+
+Gem5Extension::Gem5Extension(PacketPtr packet)
{
Packet = packet;
}
-gem5Extension& gem5Extension::getExtension(const tlm_generic_payload *payload)
+Gem5Extension& Gem5Extension::getExtension(const tlm_generic_payload *payload)
{
- gem5Extension *result = NULL;
+ Gem5Extension *result = NULL;
payload->get_extension(result);
sc_assert(result!=NULL);
return *result;
}
-gem5Extension& gem5Extension::getExtension(const tlm_generic_payload &payload)
+Gem5Extension& Gem5Extension::getExtension(const tlm_generic_payload &payload)
{
- return gem5Extension::getExtension(&payload);
+ return Gem5Extension::getExtension(&payload);
}
-PacketPtr gem5Extension::getPacket()
+PacketPtr Gem5Extension::getPacket()
{
return Packet;
}
-tlm_extension_base* gem5Extension::clone() const
+tlm_extension_base* Gem5Extension::clone() const
{
- return new gem5Extension(Packet);
+ return new Gem5Extension(Packet);
}
-void gem5Extension::copy_from(const tlm_extension_base& ext)
+void Gem5Extension::copy_from(const tlm_extension_base& ext)
{
- const gem5Extension& cpyFrom = static_cast<const gem5Extension&>(ext);
+ const Gem5Extension& cpyFrom = static_cast<const Gem5Extension&>(ext);
Packet = cpyFrom.Packet;
}
+
+}
diff --git a/util/tlm/sc_ext.hh b/util/tlm/sc_ext.hh
index cb7411e44..79416f5ce 100644
--- a/util/tlm/sc_ext.hh
+++ b/util/tlm/sc_ext.hh
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,10 +32,11 @@
*
* Authors:
* Matthias Jung
+ * Christian Menard
*/
-#ifndef SC_EXT_H_
-#define SC_EXT_H_
+#ifndef __SC_EXT_HH__
+#define __SC_EXT_HH__
#include <systemc.h>
#include <tlm.h>
@@ -43,20 +45,27 @@
#include "mem/packet.hh"
-class gem5Extension: public tlm::tlm_extension<gem5Extension>
+namespace Gem5SystemC
+{
+
+class Gem5Extension: public tlm::tlm_extension<Gem5Extension>
{
public:
- gem5Extension(PacketPtr packet);
+ Gem5Extension(PacketPtr packet);
virtual tlm_extension_base* clone() const;
virtual void copy_from(const tlm_extension_base& ext);
- static gem5Extension& getExtension(const tlm::tlm_generic_payload *payload);
- static gem5Extension& getExtension(const tlm::tlm_generic_payload &payload);
+ static Gem5Extension&
+ getExtension(const tlm::tlm_generic_payload *payload);
+ static Gem5Extension&
+ getExtension(const tlm::tlm_generic_payload &payload);
PacketPtr getPacket();
private:
PacketPtr Packet;
};
+}
+
#endif
diff --git a/util/tlm/sc_mm.cc b/util/tlm/sc_mm.cc
index 2a169a37a..f5c07392c 100644
--- a/util/tlm/sc_mm.cc
+++ b/util/tlm/sc_mm.cc
@@ -40,6 +40,9 @@
using namespace std;
+namespace Gem5SystemC
+{
+
MemoryManager::MemoryManager(): numberOfAllocations(0), numberOfFrees(0)
{
@@ -72,3 +75,5 @@ MemoryManager::free(gp* payload)
payload->reset(); //clears all extensions
freePayloads.push_back(payload);
}
+
+}
diff --git a/util/tlm/sc_mm.hh b/util/tlm/sc_mm.hh
index 86d9ee11c..81316e7f6 100644
--- a/util/tlm/sc_mm.hh
+++ b/util/tlm/sc_mm.hh
@@ -34,13 +34,16 @@
* Matthias Jung
*/
-#ifndef MEMORYMANAGER_H_
-#define MEMORYMANAGER_H_
+#ifndef __SC_MM_HH__
+#define __SC_MM_HH__
#include <tlm.h>
#include <vector>
+namespace Gem5SystemC
+{
+
typedef tlm::tlm_generic_payload gp;
class MemoryManager : public tlm::tlm_mm_interface
@@ -57,4 +60,6 @@ class MemoryManager : public tlm::tlm_mm_interface
std::vector<gp*> freePayloads;
};
-#endif /* MEMORYMANAGER_H_ */
+}
+
+#endif /* __SC_MM_HH__ */
diff --git a/util/tlm/sc_peq.hh b/util/tlm/sc_peq.hh
new file mode 100644
index 000000000..386142b72
--- /dev/null
+++ b/util/tlm/sc_peq.hh
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015, University of Kaiserslautern
+ * 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: Matthias Jung
+ * Christian Menard
+ */
+
+#ifndef PAYLOAD_EVENT_H_
+#define PAYLOAD_EVENT_H_
+
+// TLM includes
+#include <tlm.h>
+
+// gem5 includes
+#include <sim/eventq.hh>
+
+namespace Gem5SystemC {
+/**
+ * A 'Fake Payload Event Queue', similar to the TLM PEQs. This helps the
+ * transactors to schedule events in gem5.
+ */
+template <typename OWNER>
+class PayloadEvent : public Event
+{
+ public:
+ OWNER& port;
+ const std::string eventName;
+ void (OWNER::*handler)(PayloadEvent<OWNER>* pe,
+ tlm::tlm_generic_payload& trans,
+ const tlm::tlm_phase& phase);
+
+ protected:
+ tlm::tlm_generic_payload* t;
+ tlm::tlm_phase p;
+
+ void process() { (port.*handler)(this, *t, p); }
+
+ public:
+ const std::string name() const { return eventName; }
+
+ PayloadEvent(OWNER& port_,
+ void (OWNER::*handler_)(PayloadEvent<OWNER>* pe,
+ tlm::tlm_generic_payload& trans,
+ const tlm::tlm_phase& phase),
+ const std::string& event_name)
+ : port(port_)
+ , eventName(event_name)
+ , handler(handler_)
+ {
+ }
+
+ /// Schedule an event into gem5
+ void notify(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase,
+ const sc_core::sc_time& delay)
+ {
+ assert(!scheduled());
+
+ t = &trans;
+ p = phase;
+
+ /**
+ * Get time from SystemC as this will always be more up to date
+ * than gem5's
+ */
+ Tick nextEventTick = sc_core::sc_time_stamp().value() + delay.value();
+
+ port.owner.wakeupEventQueue(nextEventTick);
+ port.owner.schedule(this, nextEventTick);
+ }
+};
+}
+
+#endif
diff --git a/util/tlm/sc_port.cc b/util/tlm/sc_slave_port.cc
index ab94f73ca..cea0f6db6 100644
--- a/util/tlm/sc_port.cc
+++ b/util/tlm/sc_slave_port.cc
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,7 @@
*
* Authors: Matthias Jung
* Abdul Mutaal Ahmad
+ * Christian Menard
*/
#include <cctype>
@@ -40,7 +42,7 @@
#include "debug/ExternalPort.hh"
#include "sc_ext.hh"
#include "sc_mm.hh"
-#include "sc_port.hh"
+#include "sc_slave_port.hh"
namespace Gem5SystemC
{
@@ -78,7 +80,7 @@ packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans)
} else if (packet->isWrite()) {
trans.set_command(tlm::TLM_WRITE_COMMAND);
} else {
- SC_REPORT_FATAL("transactor", "No R/W packet");
+ SC_REPORT_FATAL("SCSlavePort", "No R/W packet");
}
}
@@ -86,10 +88,10 @@ packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans)
* Similar to TLM's blocking transport (LT)
*/
Tick
-sc_transactor::recvAtomic(PacketPtr packet)
+SCSlavePort::recvAtomic(PacketPtr packet)
{
CAUGHT_UP;
- SC_REPORT_INFO("transactor", "recvAtomic hasn't been tested much");
+ SC_REPORT_INFO("SCSlavePort", "recvAtomic hasn't been tested much");
panic_if(packet->cacheResponding(), "Should not see packets where cache "
"is responding");
@@ -107,12 +109,12 @@ sc_transactor::recvAtomic(PacketPtr packet)
packet2payload(packet, *trans);
/* Attach the packet pointer to the TLM transaction to keep track */
- gem5Extension* extension = new gem5Extension(packet);
+ Gem5Extension* extension = new Gem5Extension(packet);
trans->set_auto_extension(extension);
/* Execute b_transport: */
if (packet->cmd == MemCmd::SwapReq) {
- SC_REPORT_FATAL("transactor", "SwapReq not supported");
+ SC_REPORT_FATAL("SCSlavePort", "SwapReq not supported");
} else if (packet->isRead()) {
iSocket->b_transport(*trans, delay);
} else if (packet->isInvalidate()) {
@@ -120,7 +122,7 @@ sc_transactor::recvAtomic(PacketPtr packet)
} else if (packet->isWrite()) {
iSocket->b_transport(*trans, delay);
} else {
- SC_REPORT_FATAL("transactor", "Typo of request not supported");
+ SC_REPORT_FATAL("SCSlavePort", "Typo of request not supported");
}
if (packet->needsResponse()) {
@@ -136,7 +138,7 @@ sc_transactor::recvAtomic(PacketPtr packet)
* Similar to TLM's debug transport
*/
void
-sc_transactor::recvFunctional(PacketPtr packet)
+SCSlavePort::recvFunctional(PacketPtr packet)
{
/* Prepare the transaction */
tlm::tlm_generic_payload * trans = mm.allocate();
@@ -144,38 +146,38 @@ sc_transactor::recvFunctional(PacketPtr packet)
packet2payload(packet, *trans);
/* Attach the packet pointer to the TLM transaction to keep track */
- gem5Extension* extension = new gem5Extension(packet);
+ Gem5Extension* extension = new Gem5Extension(packet);
trans->set_auto_extension(extension);
/* Execute Debug Transport: */
unsigned int bytes = iSocket->transport_dbg(*trans);
if (bytes != trans->get_data_length()) {
- SC_REPORT_FATAL("transactor","debug transport was not completed");
+ SC_REPORT_FATAL("SCSlavePort","debug transport was not completed");
}
trans->release();
}
bool
-sc_transactor::recvTimingSnoopResp(PacketPtr packet)
+SCSlavePort::recvTimingSnoopResp(PacketPtr packet)
{
/* Snooping should be implemented with tlm_dbg_transport */
- SC_REPORT_FATAL("transactor","unimplemented func.: recvTimingSnoopResp");
+ SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvTimingSnoopResp");
return false;
}
void
-sc_transactor::recvFunctionalSnoop(PacketPtr packet)
+SCSlavePort::recvFunctionalSnoop(PacketPtr packet)
{
/* Snooping should be implemented with tlm_dbg_transport */
- SC_REPORT_FATAL("transactor","unimplemented func.: recvFunctionalSnoop");
+ SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvFunctionalSnoop");
}
/**
* Similar to TLM's non-blocking transport (AT)
*/
bool
-sc_transactor::recvTimingReq(PacketPtr packet)
+SCSlavePort::recvTimingReq(PacketPtr packet)
{
CAUGHT_UP;
@@ -213,7 +215,7 @@ sc_transactor::recvTimingReq(PacketPtr packet)
packet2payload(packet, *trans);
/* Attach the packet pointer to the TLM transaction to keep track */
- gem5Extension* extension = new gem5Extension(packet);
+ Gem5Extension* extension = new Gem5Extension(packet);
trans->set_auto_extension(extension);
/* Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC
@@ -231,9 +233,9 @@ sc_transactor::recvTimingReq(PacketPtr packet)
/* The Timing annotation must be honored: */
sc_assert(phase == tlm::END_REQ || phase == tlm::BEGIN_RESP);
- payloadEvent<sc_transactor> * pe;
- pe = new payloadEvent<sc_transactor>(*this,
- &sc_transactor::pec, "PEQ");
+ PayloadEvent<SCSlavePort> * pe;
+ pe = new PayloadEvent<SCSlavePort>(*this,
+ &SCSlavePort::pec, "PEQ");
pe->notify(*trans, phase, delay);
} else if (status == tlm::TLM_COMPLETED) {
/* Transaction is over nothing has do be done. */
@@ -245,8 +247,8 @@ sc_transactor::recvTimingReq(PacketPtr packet)
}
void
-sc_transactor::pec(
- sc_transactor::payloadEvent<sc_transactor> * pe,
+SCSlavePort::pec(
+ PayloadEvent<SCSlavePort> * pe,
tlm::tlm_generic_payload& trans,
const tlm::tlm_phase& phase)
{
@@ -267,7 +269,7 @@ sc_transactor::pec(
{
CAUGHT_UP;
- PacketPtr packet = gem5Extension::getExtension(trans).getPacket();
+ PacketPtr packet = Gem5Extension::getExtension(trans).getPacket();
sc_assert(!blockingResponse);
@@ -292,13 +294,13 @@ sc_transactor::pec(
}
}
} else {
- SC_REPORT_FATAL("transactor", "Invalid protocol phase in pec");
+ SC_REPORT_FATAL("SCSlavePort", "Invalid protocol phase in pec");
}
delete pe;
}
void
-sc_transactor::recvRespRetry()
+SCSlavePort::recvRespRetry()
{
CAUGHT_UP;
@@ -307,7 +309,7 @@ sc_transactor::recvRespRetry()
tlm::tlm_generic_payload *trans = blockingResponse;
blockingResponse = NULL;
- PacketPtr packet = gem5Extension::getExtension(trans).getPacket();
+ PacketPtr packet = Gem5Extension::getExtension(trans).getPacket();
bool need_retry = !iSocket.sendTimingResp(packet);
@@ -321,24 +323,24 @@ sc_transactor::recvRespRetry()
}
tlm::tlm_sync_enum
-sc_transactor::nb_transport_bw(tlm::tlm_generic_payload& trans,
+SCSlavePort::nb_transport_bw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay)
{
- payloadEvent<sc_transactor> * pe;
- pe = new payloadEvent<sc_transactor>(*this, &sc_transactor::pec, "PE");
+ PayloadEvent<SCSlavePort> * pe;
+ pe = new PayloadEvent<SCSlavePort>(*this, &SCSlavePort::pec, "PE");
pe->notify(trans, phase, delay);
return tlm::TLM_ACCEPTED;
}
void
-sc_transactor::invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+SCSlavePort::invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
sc_dt::uint64 end_range)
{
- SC_REPORT_FATAL("transactor", "unimpl. func: invalidate_direct_mem_ptr");
+ SC_REPORT_FATAL("SCSlavePort", "unimpl. func: invalidate_direct_mem_ptr");
}
-sc_transactor::sc_transactor(const std::string &name_,
+SCSlavePort::SCSlavePort(const std::string &name_,
const std::string &systemc_name,
ExternalSlave &owner_) :
tlm::tlm_initiator_socket<>(systemc_name.c_str()),
@@ -351,7 +353,7 @@ sc_transactor::sc_transactor(const std::string &name_,
m_export.bind(*this);
}
-class sc_transactorHandler : public ExternalSlave::Handler
+class SlavePortHandler : public ExternalSlave::Handler
{
public:
ExternalSlave::Port *getExternalPort(const std::string &name,
@@ -359,14 +361,14 @@ class sc_transactorHandler : public ExternalSlave::Handler
const std::string &port_data)
{
// This will make a new initiatiator port
- return new sc_transactor(name, port_data, owner);
+ return new SCSlavePort(name, port_data, owner);
}
};
void
-registerSCPorts()
+SCSlavePort::registerPortHandler()
{
- ExternalSlave::registerHandler("tlm", new sc_transactorHandler);
+ ExternalSlave::registerHandler("tlm_slave", new SlavePortHandler);
}
}
diff --git a/util/tlm/sc_port.hh b/util/tlm/sc_slave_port.hh
index 374a3cfc9..a42532cad 100644
--- a/util/tlm/sc_port.hh
+++ b/util/tlm/sc_slave_port.hh
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +31,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Matthias Jung
+ * Christian Menard
*/
-#ifndef __SIM_SC_TRANSACTOR_HH__
-#define __SIM_SC_TRANSACTOR_HH__
+#ifndef __SC_SLAVE_PORT_HH__
+#define __SC_SLAVE_PORT_HH__
#include <tlm_utils/simple_initiator_socket.h>
@@ -44,6 +46,7 @@
#include "mem/external_slave.hh"
#include "sc_mm.hh"
#include "sc_module.hh"
+#include "sc_peq.hh"
namespace Gem5SystemC
{
@@ -54,74 +57,26 @@ namespace Gem5SystemC
assert(curTick() == sc_core::sc_time_stamp().value()); \
} while (0)
-
-class sc_transactor : public tlm::tlm_initiator_socket<>,
+/**
+ * This is a gem5 slave port that translates gem5 packets to TLM transactions.
+ *
+ * Upon receiving a packet (recvAtomic, recvTiningReq, recvFunctional) the port
+ * creates a new TLM payload and initializes it with information from the gem5
+ * packet. The original packet is added as an extension to the TLM payload.
+ * Then the port issues a TLM transaction in the SystemC world. By storing the
+ * original packet as a payload extension, the packet can be restored and send
+ * back to the gem5 world upon receiving a response from the SystemC world.
+ */
+class SCSlavePort : public tlm::tlm_initiator_socket<>,
public tlm::tlm_bw_transport_if<>,
public ExternalSlave::Port
{
public:
- sc_transactor &iSocket;
-
- /**
- * A 'Fake Payload Event Queue', similar to the TLM PEQs. This will help
- * that gem5 behaves like a normal TLM Initiator
- */
- template<typename OWNER>
- class payloadEvent : public Event
- {
- public:
- OWNER &port;
- const std::string eventName;
- void (OWNER::* handler)(payloadEvent<OWNER> * pe,
- tlm::tlm_generic_payload& trans,
- const tlm::tlm_phase &phase);
-
- protected:
- tlm::tlm_generic_payload *t;
- tlm::tlm_phase p;
-
- void process() { (port.*handler)(this,*t, p); }
-
- public:
- const std::string name() const { return eventName; }
-
- payloadEvent(
- OWNER &port_,
- void (OWNER::* handler_)(payloadEvent<OWNER> * pe,
- tlm::tlm_generic_payload& trans,
- const tlm::tlm_phase &phase),
- const std::string &event_name) :
- port(port_),
- eventName(event_name),
- handler(handler_)
- { }
-
- /// Schedule an event into gem5
- void
- notify(tlm::tlm_generic_payload& trans,
- const tlm::tlm_phase &phase,
- const sc_core::sc_time& delay)
- {
- assert(!scheduled());
-
- t = &trans;
- p = phase;
-
- /**
- * Get time from SystemC as this will alway be more up to date
- * than gem5's
- */
- Tick nextEventTick = sc_core::sc_time_stamp().value()
- + delay.value();
-
- port.owner.wakeupEventQueue(nextEventTick);
- port.owner.schedule(this, nextEventTick);
- }
- };
+ SCSlavePort &iSocket;
/** One instance of pe and the related callback needed */
- //payloadEvent<sc_transactor> pe;
- void pec(payloadEvent<sc_transactor> * pe,
+ //payloadEvent<SCSlavePort> pe;
+ void pec(PayloadEvent<SCSlavePort> * pe,
tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase);
/**
@@ -160,15 +115,15 @@ class sc_transactor : public tlm::tlm_initiator_socket<>,
sc_dt::uint64 end_range);
public:
- sc_transactor(const std::string &name_,
- const std::string &systemc_name,
- ExternalSlave &owner_);
-};
+ SCSlavePort(const std::string &name_,
+ const std::string &systemc_name,
+ ExternalSlave &owner_);
-void registerPort(const std::string &name, Port &port);
+ static void registerPortHandler();
-void registerSCPorts();
+ friend PayloadEvent<SCSlavePort>;
+};
}
-#endif // __SIM_SC_PORT_HH__
+#endif // __SC_SLAVE_PORT_H__
diff --git a/util/tlm/main.cc b/util/tlm/sim_control.cc
index bf442e02b..ef04c6bbd 100644
--- a/util/tlm/main.cc
+++ b/util/tlm/sim_control.cc
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, University of Kaiserslautern
+ * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,7 @@
*
* Authors: Matthias Jung
* Abdul Mutaal Ahmad
+ * Christian Menard
*/
/**
@@ -41,87 +43,41 @@
*
*/
-#include <tlm_utils/simple_target_socket.h>
-
-#include <cstdlib>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
#include <systemc>
#include <tlm>
-#include <typeinfo>
-#include "base/statistics.hh"
-#include "base/str.hh"
-#include "base/trace.hh"
-#include "cpu/base.hh"
-#include "sc_logger.hh"
-#include "sc_module.hh"
-#include "sc_port.hh"
-#include "sc_target.hh"
+#include "sc_slave_port.hh"
#include "sim/cxx_config_ini.hh"
-#include "sim/cxx_manager.hh"
#include "sim/init_signals.hh"
-#include "sim/serialize.hh"
-#include "sim/simulate.hh"
#include "sim/stat_control.hh"
-#include "sim/system.hh"
+#include "sim_control.hh"
#include "stats.hh"
-// Defining global string variable decalred in stats.hh
-std::string filename;
-
-void usage(const std::string &prog_name)
+void
+usage(const std::string& prog_name)
{
- std::cerr << "Usage: " << prog_name << (
- " <config_file.ini> [ <option> ]\n\n"
- "OPTIONS:\n"
-
- " -o <offset> -- set memory offset\n"
- " -p <object> <param> <value> -- set a parameter\n"
- " -v <object> <param> <values> -- set a vector parameter from a\n"
- " comma separated values string\n"
- " -d <flag> -- set a debug flag\n"
- " (-<flag> clear a flag)\n"
- " -D -- debug on\n"
- " -e <ticks> -- end of simulation after a \n"
- " given number of ticks\n"
- "\n"
- );
+ std::cerr
+ << "Usage: " << prog_name
+ << (" <config_file.ini> [ <option> ]\n\n"
+ "OPTIONS:\n"
+
+ " -o <offset> -- set memory offset\n"
+ " -p <object> <param> <value> -- set a parameter\n"
+ " -v <object> <param> <values> -- set a vector parameter from a\n"
+ " comma separated values string\n"
+ " -d <flag> -- set a debug flag\n"
+ " (-<flag> clear a flag)\n"
+ " -D -- debug on\n"
+ " -e <ticks> -- end of simulation after a \n"
+ " given number of ticks\n"
+ "\n");
std::exit(EXIT_FAILURE);
}
-class SimControl : public Gem5SystemC::Module
-{
- protected:
- int argc;
- char **argv;
- CxxConfigManager *config_manager;
- Gem5SystemC::Logger logger;
-
- Tick sim_end;
- bool debug;
- unsigned int offset;
-
- public:
- SC_HAS_PROCESS(SimControl);
-
- SimControl(sc_core::sc_module_name name, int argc_, char **argv_);
-
- void before_end_of_elaboration();
-
- bool getDebugFlag() { return debug; }
-
- unsigned int getOffset() { return offset; }
-
- void run();
-};
-
-SimControl::SimControl(sc_core::sc_module_name name,
- int argc_,
- char **argv_) : Gem5SystemC::Module(name),
- argc(argc_),
- argv(argv_)
+SimControl::SimControl(sc_core::sc_module_name name, int argc_, char** argv_)
+ : Gem5SystemC::Module(name),
+ argc(argc_),
+ argv(argv_)
{
SC_THREAD(run);
@@ -133,7 +89,7 @@ SimControl::SimControl(sc_core::sc_module_name name,
}
cxxConfigInit();
- Gem5SystemC::registerSCPorts();
+ Gem5SystemC::SCSlavePort::registerPortHandler();
Trace::setDebugLogger(&logger);
@@ -268,64 +224,3 @@ SimControl::run()
config_manager->deleteObjects();
#endif
}
-
-
-void
-reportHandler(const sc_core::sc_report &report,
- const sc_core::sc_actions &actions)
-{
- uint64_t systemc_time = report.get_time().value();
- uint64_t gem5_time = curTick();
-
- std::cerr << report.get_time();
-
- if (gem5_time < systemc_time) {
- std::cerr << " (<) ";
- } else if (gem5_time > systemc_time) {
- std::cerr << " (!) ";
- } else {
- std::cerr << " (=) ";
- }
-
- std::cerr << ": " << report.get_msg_type()
- << ' ' << report.get_msg() << '\n';
-}
-
-
-int
-sc_main(int argc, char **argv)
-{
- sc_core::sc_report_handler::set_handler(reportHandler);
-
- SimControl sim_control("gem5", argc, argv);
- Target *memory;
-
- filename = "m5out/stats-tlm.txt";
-
- tlm::tlm_initiator_socket <> *mem_port =
- dynamic_cast<tlm::tlm_initiator_socket<> *>(
- sc_core::sc_find_object("gem5.memory")
- );
-
- if (mem_port) {
- SC_REPORT_INFO("sc_main", "Port Found");
- unsigned long long int size = 512*1024*1024ULL;
- memory = new Target("memory",
- sim_control.getDebugFlag(),
- size,
- sim_control.getOffset());
-
- memory->socket.bind(*mem_port);
- } else {
- SC_REPORT_FATAL("sc_main", "Port Not Found");
- std::exit(EXIT_FAILURE);
- }
-
- sc_core::sc_start();
-
- SC_REPORT_INFO("sc_main", "End of Simulation");
-
- CxxConfig::statsDump();
-
- return EXIT_SUCCESS;
-}
diff --git a/util/tlm/sim_control.hh b/util/tlm/sim_control.hh
new file mode 100644
index 000000000..52bfa64d4
--- /dev/null
+++ b/util/tlm/sim_control.hh
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, University of Kaiserslautern
+ * 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: Matthias Jung
+ * Christian Menard
+ */
+
+#ifndef __SC_SIM_CONTROL_HH__
+#define __SC_SIM_CONTROL_HH__
+
+#include <tlm_utils/simple_target_socket.h>
+
+#include <systemc>
+#include <tlm>
+
+#include "sc_logger.hh"
+#include "sc_module.hh"
+#include "sim/cxx_manager.hh"
+#include "sim/system.hh"
+
+class SimControl : public Gem5SystemC::Module
+{
+ protected:
+ int argc;
+ char** argv;
+ CxxConfigManager* config_manager;
+ Gem5SystemC::Logger logger;
+
+ Tick sim_end;
+ bool debug;
+ unsigned int offset;
+
+ public:
+ SC_HAS_PROCESS(SimControl);
+
+ SimControl(sc_core::sc_module_name name, int argc_, char** argv_);
+
+ void before_end_of_elaboration();
+
+ bool getDebugFlag() { return debug; }
+
+ unsigned int getOffset() { return offset; }
+
+ void run();
+};
+
+#endif