misc: Clean up and complete the gem5<->SystemC-TLM bridge [1/10]
authorChristian Menard <Christian.Menard@tu-dresden.de>
Fri, 10 Feb 2017 00:15:30 +0000 (19:15 -0500)
committerChristian Menard <Christian.Menard@tu-dresden.de>
Fri, 10 Feb 2017 00:15:30 +0000 (19:15 -0500)
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:
 * Restructure the existing sources in preparation of the addition of the
 * new
   Master Port.
 * Refractor names to allow for distinction of the slave and master port.
 * Replace the Makefile by a SConstruct.

Testing Done: The examples provided in util/tlm (now
util/tlm/examples/slave_port) still compile and run error free.

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

Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
28 files changed:
configs/common/MemConfig.py
util/tlm/Makefile [deleted file]
util/tlm/examples/slave_port/SConstruct [new file with mode: 0644]
util/tlm/examples/slave_port/main.cc [new file with mode: 0644]
util/tlm/examples/slave_port/run_gem5.sh [new file with mode: 0644]
util/tlm/examples/slave_port/sc_target.cc [new file with mode: 0644]
util/tlm/examples/slave_port/sc_target.hh [new file with mode: 0644]
util/tlm/examples/slave_port/tgen.cfg [new file with mode: 0644]
util/tlm/examples/slave_port/tlm.py [new file with mode: 0644]
util/tlm/examples/slave_port/tlm_elastic.py [new file with mode: 0644]
util/tlm/main.cc [deleted file]
util/tlm/run_gem5.sh [deleted file]
util/tlm/sc_ext.cc
util/tlm/sc_ext.hh
util/tlm/sc_mm.cc
util/tlm/sc_mm.hh
util/tlm/sc_peq.hh [new file with mode: 0644]
util/tlm/sc_port.cc [deleted file]
util/tlm/sc_port.hh [deleted file]
util/tlm/sc_slave_port.cc [new file with mode: 0644]
util/tlm/sc_slave_port.hh [new file with mode: 0644]
util/tlm/sc_target.cc [deleted file]
util/tlm/sc_target.hh [deleted file]
util/tlm/sim_control.cc [new file with mode: 0644]
util/tlm/sim_control.hh [new file with mode: 0644]
util/tlm/tgen.cfg [deleted file]
util/tlm/tlm.py [deleted file]
util/tlm/tlm_elastic.py [deleted file]

index 71e3bf460c0d4f3466d1a67a62ac6e239179b84f..2cfa25e5858588f7fce4867fc72ab31c3c93b1f3 100644 (file)
@@ -163,7 +163,7 @@ def config_mem(options, system):
 
     if options.tlm_memory:
         system.external_memory = m5.objects.ExternalSlave(
-            port_type="tlm",
+            port_type="tlm_slave",
             port_data=options.tlm_memory,
             port=system.membus.master,
             addr_ranges=system.mem_ranges)
diff --git a/util/tlm/Makefile b/util/tlm/Makefile
deleted file mode 100644 (file)
index 1fda3b1..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (c) 2015, University of Kaiserslautern
-# 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
-
-
-ARCH = ARM
-VARIANT = opt
-#VARIANT = debug
-
-SYSTEMC_INC = /opt/systemc/include
-SYSTEMC_LIB = /opt/systemc/lib-linux64
-
-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
-
-LIBS = -lgem5_$(VARIANT) -lsystemc
-
-ALL = gem5.$(VARIANT).sc
-
-all: $(ALL)
-
-.cc.o:
-       $(CXX) $(CXXFLAGS) -c -o $@ $<
-
-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
-
-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)
-
-clean:
-       $(RM) $(ALL)
-       $(RM) *.o
-       $(RM) -r m5out
diff --git a/util/tlm/examples/slave_port/SConstruct b/util/tlm/examples/slave_port/SConstruct
new file mode 100644 (file)
index 0000000..8ca9959
--- /dev/null
@@ -0,0 +1,77 @@
+#!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
+# 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
+
+import os
+
+gem5_arch = 'ARM'
+gem5_variant = 'opt'
+#gem5_variant = 'debug'
+
+gem5_root = '#../../../..'
+
+target = 'gem5.' + gem5_variant + '.sc'
+
+env = Environment()
+
+# 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']
+
+# search for SystemC
+env.ParseConfig('pkg-config --cflags --libs systemc')
+
+# add include dirs
+env.Append(CPPPATH=[gem5_root + '/build/' + gem5_arch,
+                    gem5_root + '/util/systemc',
+                    gem5_root + '/util/tlm'])
+
+env.Append(LIBS=['gem5_' + gem5_variant])
+env.Append(LIBPATH=[gem5_root + '/build/' + gem5_arch])
+
+env.Append(CXXFLAGS=['-std=c++11',
+                     '-DSC_INCLUDE_DYNAMIC_PROCESSES',
+                     '-DTRACING_ON'])
+
+if gem5_variant == 'debug':
+    env.Append(CXXFLAGS=['-g', '-DDEBUG'])
+
+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']
+
+src_tlm     = Glob(gem5_root + '/util/tlm/*.cc')
+src_main    = Glob('*.cc')
+
+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 (file)
index 0000000..256a99d
--- /dev/null
@@ -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/examples/slave_port/run_gem5.sh b/util/tlm/examples/slave_port/run_gem5.sh
new file mode 100644 (file)
index 0000000..a4a0b80
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Copyright (c) 2015, University of Kaiserslautern
+# 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
+
+# Color Definition:
+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 \
+--tlm-memory=memory                                         \
+--cpu-type=timing                                           \
+--num-cpu=1                                                 \
+--mem-type=SimpleMemory                                     \
+--mem-size=512MB                                            \
+--mem-channels=1                                            \
+--caches --l2cache                                          \
+--machine-type=VExpress_EMM                                 \
+--dtb-filename=vexpress.aarch32.ll_20131205.0-gem5.1cpu.dtb \
+--kernel=vmlinux.aarch32.ll_20131205.0-gem5
+
+echo -e "\n${BGre}Run gem5 ${RCol}\n"
+
+time ./gem5.opt.sc m5out/config.ini -o 2147483648 
diff --git a/util/tlm/examples/slave_port/sc_target.cc b/util/tlm/examples/slave_port/sc_target.cc
new file mode 100644 (file)
index 0000000..c44a271
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2015, University of Kaiserslautern
+ * 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
+ */
+
+#include "sc_target.hh"
+
+using namespace sc_core;
+using namespace std;
+
+Target::Target(sc_core::sc_module_name name,
+    bool debug,
+    unsigned long long int size,
+    unsigned int offset) :
+    socket("socket"),
+    transaction_in_progress(0),
+    response_in_progress(false),
+    next_response_pending(0),
+    end_req_pending(0),
+    m_peq(this, &Target::peq_cb),
+    debug(debug),
+    size(size),
+    offset(offset)
+{
+    /* Register tlm transport functions */
+    socket.register_b_transport(this, &Target::b_transport);
+    socket.register_transport_dbg(this, &Target::transport_dbg);
+    socket.register_nb_transport_fw(this, &Target::nb_transport_fw);
+
+
+    /* allocate storage memory */
+    mem = new unsigned char[size];
+
+    SC_METHOD(execute_transaction_process);
+    sensitive << target_done_event;
+    dont_initialize();
+}
+
+void
+Target::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay)
+{
+    /* Execute the read or write commands */
+    execute_transaction(trans);
+}
+
+unsigned int
+Target::transport_dbg(tlm::tlm_generic_payload& trans)
+{
+    tlm::tlm_command cmd = trans.get_command();
+    sc_dt::uint64    adr = trans.get_address() - offset;
+    unsigned char*   ptr = trans.get_data_ptr();
+    unsigned int     len = trans.get_data_length();
+
+    unsigned char *mem_array_ptr = mem + adr;
+
+    /* Load / Store the access: */
+    if ( cmd == tlm::TLM_READ_COMMAND ) {
+        if (debug) {
+            SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND");
+        }
+        std::memcpy(ptr, mem_array_ptr, len);
+    } else if ( cmd == tlm::TLM_WRITE_COMMAND ) {
+        if (debug) {
+            SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND");
+        }
+        std::memcpy(mem_array_ptr, ptr, len);
+    }
+
+    return len;
+}
+
+
+/* TLM-2 non-blocking transport method */
+tlm::tlm_sync_enum Target::nb_transport_fw(tlm::tlm_generic_payload& trans,
+                                           tlm::tlm_phase& phase,
+                                           sc_time& delay)
+{
+    /* Queue the transaction until the annotated time has elapsed */
+    m_peq.notify(trans, phase, delay);
+    return tlm::TLM_ACCEPTED;
+}
+
+void
+Target::peq_cb(tlm::tlm_generic_payload& trans,
+               const tlm::tlm_phase& phase)
+{
+    sc_time delay;
+
+    if (phase == tlm::BEGIN_REQ) {
+        if (debug) SC_REPORT_INFO("target", "tlm::BEGIN_REQ");
+
+        /* Increment the transaction reference count */
+        trans.acquire();
+
+        if ( !transaction_in_progress ) {
+            send_end_req(trans);
+        } else {
+            /* Put back-pressure on initiator by deferring END_REQ until
+             * pipeline is clear */
+            end_req_pending = &trans;
+        }
+    } else if (phase == tlm::END_RESP) {
+        /* On receiving END_RESP, the target can release the transaction and
+         * allow other pending transactions to proceed */
+        if (!response_in_progress) {
+            SC_REPORT_FATAL("TLM-2", "Illegal transaction phase END_RESP"
+                            "received by target");
+        }
+
+        transaction_in_progress = 0;
+
+        /* Target itself is now clear to issue the next BEGIN_RESP */
+        response_in_progress = false;
+        if (next_response_pending) {
+            send_response( *next_response_pending );
+            next_response_pending = 0;
+        }
+
+        /* ... and to unblock the initiator by issuing END_REQ */
+        if (end_req_pending) {
+            send_end_req( *end_req_pending );
+            end_req_pending = 0;
+        }
+
+    } else /* tlm::END_REQ or tlm::BEGIN_RESP */ {
+            SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by"
+                            "target");
+    }
+}
+
+void
+Target::send_end_req(tlm::tlm_generic_payload& trans)
+{
+    tlm::tlm_phase bw_phase;
+    sc_time delay;
+
+    /* Queue the acceptance and the response with the appropriate latency */
+    bw_phase = tlm::END_REQ;
+    delay = sc_time(10.0, SC_NS); // Accept delay
+
+    tlm::tlm_sync_enum status;
+    status = socket->nb_transport_bw(trans, bw_phase, delay);
+
+    /* Ignore return value;
+     * initiator cannot terminate transaction at this point
+     * Queue internal event to mark beginning of response: */
+    delay = delay + sc_time(40.0, SC_NS); // Latency
+    target_done_event.notify(delay);
+
+    assert(transaction_in_progress == 0);
+    transaction_in_progress = &trans;
+}
+
+void
+Target::execute_transaction_process()
+{
+    /* Execute the read or write commands */
+    execute_transaction( *transaction_in_progress );
+
+    /* Target must honor BEGIN_RESP/END_RESP exclusion rule; i.e. must not
+     * send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ */
+    if (response_in_progress) {
+        /* Target allows only two transactions in-flight */
+        if (next_response_pending) {
+            SC_REPORT_FATAL("TLM-2", "Attempt to have two pending responses"
+                            "in target");
+        }
+        next_response_pending = transaction_in_progress;
+    } else {
+        send_response( *transaction_in_progress );
+    }
+}
+
+void
+Target::execute_transaction(tlm::tlm_generic_payload& trans)
+{
+    tlm::tlm_command cmd = trans.get_command();
+    sc_dt::uint64    adr = trans.get_address() - offset;
+    unsigned char*   ptr = trans.get_data_ptr();
+    unsigned int     len = trans.get_data_length();
+    unsigned char*   byt = trans.get_byte_enable_ptr();
+    unsigned int     wid = trans.get_streaming_width();
+
+    if ( byt != 0 ) {
+        cout << "Byte Error" << endl;
+        trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
+        return;
+    }
+
+    //if ( len > 4 || wid < len ) {
+    //    cout << "Burst Error len=" << len << " wid=" << wid << endl;
+    //    trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
+    //    return;
+    //}
+
+    unsigned char *mem_array_ptr = mem + adr;
+
+    /* Load / Store the access: */
+    if ( cmd == tlm::TLM_READ_COMMAND ) {
+        if (debug) {
+            SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND");
+        }
+        std::memcpy(ptr, mem_array_ptr, len);
+    } else if ( cmd == tlm::TLM_WRITE_COMMAND ) {
+        if (debug) {
+            SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND");
+        }
+        std::memcpy(mem_array_ptr, ptr, len);
+    }
+
+    trans.set_response_status( tlm::TLM_OK_RESPONSE );
+}
+
+void
+Target::send_response(tlm::tlm_generic_payload& trans)
+{
+    tlm::tlm_sync_enum status;
+    tlm::tlm_phase bw_phase;
+    sc_time delay;
+
+    response_in_progress = true;
+    bw_phase = tlm::BEGIN_RESP;
+    delay = sc_time(10.0, SC_NS);
+    status = socket->nb_transport_bw( trans, bw_phase, delay );
+
+    if (status == tlm::TLM_UPDATED) {
+        /* The timing annotation must be honored */
+        m_peq.notify(trans, bw_phase, delay);
+    } else if (status == tlm::TLM_COMPLETED) {
+        /* The initiator has terminated the transaction */
+        transaction_in_progress = 0;
+        response_in_progress = false;
+    }
+    trans.release();
+}
diff --git a/util/tlm/examples/slave_port/sc_target.hh b/util/tlm/examples/slave_port/sc_target.hh
new file mode 100644 (file)
index 0000000..7a2d075
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015, University of Kaiserslautern
+ * 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
+ */
+
+#ifndef __SIM_SC_TARGET_HH__
+#define __SIM_SC_TARGET_HH__
+
+#include <tlm_utils/peq_with_cb_and_phase.h>
+#include <tlm_utils/simple_target_socket.h>
+
+#include <iostream>
+#include <systemc>
+#include <tlm>
+
+using namespace sc_core;
+using namespace std;
+
+struct Target: sc_module
+{
+    /** TLM interface socket: */
+    tlm_utils::simple_target_socket<Target> socket;
+
+    /** TLM related member variables: */
+    tlm::tlm_generic_payload*  transaction_in_progress;
+    sc_event                   target_done_event;
+    bool                       response_in_progress;
+    bool                       debug;
+    tlm::tlm_generic_payload*  next_response_pending;
+    tlm::tlm_generic_payload*  end_req_pending;
+    tlm_utils::peq_with_cb_and_phase<Target> m_peq;
+
+    /** Storage, may be implemented with a map for large devices */
+    unsigned char *mem;
+
+    Target(sc_core::sc_module_name name,
+        bool debug,
+        unsigned long long int size,
+        unsigned int offset);
+    SC_HAS_PROCESS(Target);
+
+    /** TLM interface functions */
+    virtual void b_transport(tlm::tlm_generic_payload& trans,
+                             sc_time& delay);
+    virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
+    virtual tlm::tlm_sync_enum nb_transport_fw(
+                tlm::tlm_generic_payload& trans,
+                tlm::tlm_phase& phase,
+                sc_time& delay);
+
+    /** Callback of Payload Event Queue: */
+    void peq_cb(tlm::tlm_generic_payload& trans,
+                const tlm::tlm_phase& phase);
+
+    /** Helping function common to b_transport and nb_transport */
+    void execute_transaction(tlm::tlm_generic_payload& trans);
+
+    /** Helping functions and processes: */
+    void send_end_req(tlm::tlm_generic_payload& trans);
+    void send_response(tlm::tlm_generic_payload& trans);
+
+    /** Method process that runs on target_done_event */
+    void execute_transaction_process();
+
+    /** Helping Variables **/
+    unsigned long long int size;
+    unsigned offset;
+};
+
+#endif //__SIM_SC_TARGET_HH__
+
diff --git a/util/tlm/examples/slave_port/tgen.cfg b/util/tlm/examples/slave_port/tgen.cfg
new file mode 100644 (file)
index 0000000..e341d85
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright (c) 2015, University of Kaiserslautern
+# 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
+
+
+# This format supports comments using the '#' symbol as the leading
+# character of the line
+#
+# The file format contains [STATE]+ [INIT] [TRANSITION]+ in any order,
+# where the states are the nodes in the graph, init describes what
+# state to start in, and transition describes the edges of the graph.
+#
+# STATE <id> <duration (ticks)> <type>
+#
+# State IDLE idles
+#
+# States LINEAR and RANDOM have additional <percent reads> <start addr>
+# <end addr> <access size (bytes)> <min period (ticks)> <max period (ticks)>
+# <data limit (bytes)>
+#
+# State TRACE plays back a pre-recorded trace once
+#
+# Addresses are expressed as decimal numbers. The period in the linear
+# and random state is from a uniform random distribution over the
+# interval. If a specific value is desired, then the min and max can
+# be set to the same value.
+STATE 0 1000000 LINEAR 50 0 256 4 5000 5000 64
+INIT 0
+TRANSITION 0 0 1
diff --git a/util/tlm/examples/slave_port/tlm.py b/util/tlm/examples/slave_port/tlm.py
new file mode 100644 (file)
index 0000000..9d6b26d
--- /dev/null
@@ -0,0 +1,78 @@
+# Copyright (c) 2015, University of Kaiserslautern
+# 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
+
+import m5
+from m5.objects import *
+
+# This configuration shows a simple setup of a TrafficGen (CPU) and an
+# external TLM port for SystemC co-simulation
+#
+# Base System Architecture:
+# +-------------+  +-----+    ^
+# | System Port |  | CPU |    |
+# +-------+-----+  +--+--+    |
+#         |           |       | gem5 World
+#         |      +----+       | (see this file)
+#         |      |            |
+# +-------v------v-------+    |
+# |        Membus        |    v
+# +----------------+-----+    External Port (see sc_slave_port.*)
+#                  |          ^
+#              +---v---+      | TLM World
+#              |  TLM  |      | (see sc_target.*)
+#              +-------+      v
+#
+
+# Create a system with a Crossbar and a TrafficGenerator as CPU:
+system = System()
+system.membus = IOXBar(width = 16)
+system.physmem = SimpleMemory() # This must be instanciated, even if not needed
+system.cpu = TrafficGen(config_file = "tgen.cfg")
+system.clk_domain = SrcClockDomain(clock = '1.5GHz',
+    voltage_domain = VoltageDomain(voltage = '1V'))
+
+# Create a external TLM port:
+system.tlm = ExternalSlave()
+system.tlm.addr_ranges = [AddrRange('512MB')]
+system.tlm.port_type = "tlm_slave"
+system.tlm.port_data = "memory"
+
+# Route the connections:
+system.cpu.port = system.membus.slave
+system.system_port = system.membus.slave
+system.membus.master = system.tlm.port
+
+# Start the simulation:
+root = Root(full_system = False, system = system)
+root.system.mem_mode = 'timing'
+m5.instantiate()
+m5.simulate() #Simulation time specified later on commandline
diff --git a/util/tlm/examples/slave_port/tlm_elastic.py b/util/tlm/examples/slave_port/tlm_elastic.py
new file mode 100644 (file)
index 0000000..3de0670
--- /dev/null
@@ -0,0 +1,123 @@
+# Copyright (c) 2016, University of Kaiserslautern
+# 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
+
+import m5
+import optparse
+
+from m5.objects import *
+from m5.util import addToPath, fatal
+
+addToPath('../../configs/common/')
+
+from Caches import *
+
+# This configuration shows a simple setup of a Elastic Trace Player (eTraceCPU)
+# and an external TLM port for SystemC co-simulation.
+#
+# We assume a DRAM size of 512MB and L1 cache sizes of 32KB.
+#
+# Base System Architecture:
+#
+#                  +-----------+       ^
+# +-------------+  | eTraceCPU |       |
+# | System Port |  +-----+-----+       |
+# +------+------+  | $D1 | $I1 |       |
+#        |         +--+--+--+--+       |
+#        |            |     |          | gem5 World
+#        |            |     |          | (see this file)
+#        |            |     |          |
+# +------v------------v-----v--+       |
+# |           Membus           |       v
+# +----------------+-----------+       External Port (see sc_port.*)
+#                  |                   ^
+#              +---v---+               | TLM World
+#              |  TLM  |               | (see sc_target.*)
+#              +-------+               v
+#
+#
+# Create a system with a Crossbar and an Elastic Trace Player as CPU:
+
+# Setup System:
+system = System(cpu=TraceCPU(cpu_id=0),
+                mem_mode='timing',
+                mem_ranges = [AddrRange('512MB')],
+                cache_line_size = 64)
+
+# Create a top-level voltage domain:
+system.voltage_domain = VoltageDomain()
+
+# Create a source clock for the system. This is used as the clock period for
+# xbar and memory:
+system.clk_domain = SrcClockDomain(clock =  '1GHz',
+        voltage_domain = system.voltage_domain)
+
+# Create a CPU voltage domain:
+system.cpu_voltage_domain = VoltageDomain()
+
+# Create a separate clock domain for the CPUs. In case of Trace CPUs this clock
+# is actually used only by the caches connected to the CPU:
+system.cpu_clk_domain = SrcClockDomain(clock = '1GHz',
+        voltage_domain = system.cpu_voltage_domain)
+
+# Setup CPU and its L1 caches:
+system.cpu.createInterruptController()
+system.cpu.icache = L1_ICache(size="32kB")
+system.cpu.dcache = L1_DCache(size="32kB")
+system.cpu.icache.cpu_side = system.cpu.icache_port
+system.cpu.dcache.cpu_side = system.cpu.dcache_port
+
+# Assign input trace files to the eTraceCPU:
+system.cpu.instTraceFile="system.cpu.traceListener.inst.gz"
+system.cpu.dataTraceFile="system.cpu.traceListener.data.gz"
+
+# Setting up L1 BUS:
+system.membus = IOXBar(width = 16)
+system.physmem = SimpleMemory() # This must be instantiated, even if not needed
+
+# Create a external TLM port:
+system.tlm = ExternalSlave()
+system.tlm.addr_ranges = [AddrRange('512MB')]
+system.tlm.port_type = "tlm"
+system.tlm.port_data = "memory"
+
+# Connect everything:
+system.membus = SystemXBar()
+system.system_port = system.membus.slave
+system.cpu.icache.mem_side = system.membus.slave
+system.cpu.dcache.mem_side = system.membus.slave
+system.membus.master = system.tlm.port
+
+# Start the simulation:
+root = Root(full_system = False, system = system)
+root.system.mem_mode = 'timing'
+m5.instantiate()
+m5.simulate() #Simulation time specified later on commandline
diff --git a/util/tlm/main.cc b/util/tlm/main.cc
deleted file mode 100644 (file)
index bf442e0..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (c) 2015, University of Kaiserslautern
- * 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
- *          Abdul Mutaal Ahmad
- */
-
-/**
- * @file
- *
- *  Example top level file for SystemC-TLM integration with C++-only
- *  instantiation.
- *
- */
-
-#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 "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 "stats.hh"
-
-// Defining global string variable decalred in stats.hh
-std::string filename;
-
-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::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_)
-{
-    SC_THREAD(run);
-
-    std::string prog_name(argv[0]);
-    unsigned int arg_ptr = 1;
-
-    if (argc == 1) {
-        usage(prog_name);
-    }
-
-    cxxConfigInit();
-    Gem5SystemC::registerSCPorts();
-
-    Trace::setDebugLogger(&logger);
-
-    Gem5SystemC::setTickFrequency();
-    sc_core::sc_set_time_resolution(1, sc_core::SC_PS);
-
-    Gem5SystemC::Module::setupEventQueues(*this);
-    initSignals();
-
-    Stats::initSimStats();
-    Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
-
-    Trace::enable();
-
-    sim_end = 0;
-    debug = false;
-    offset = 0;
-
-    const std::string config_file(argv[arg_ptr]);
-
-    CxxConfigFileBase *conf = new CxxIniFile();
-
-    if (!conf->load(config_file.c_str())) {
-        std::cerr << "Can't open config file: " << config_file << '\n';
-        std::exit(EXIT_FAILURE);
-    }
-    arg_ptr++;
-
-    config_manager = new CxxConfigManager(*conf);
-
-    try {
-        while (arg_ptr < argc) {
-            std::string option(argv[arg_ptr]);
-            arg_ptr++;
-            unsigned num_args = argc - arg_ptr;
-
-            if (option == "-p") {
-                if (num_args < 3) {
-                    usage(prog_name);
-                }
-
-                config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1],
-                argv[arg_ptr + 2]);
-                arg_ptr += 3;
-            } else if (option == "-v") {
-                std::vector<std::string> values;
-
-                if (num_args < 3) {
-                    usage(prog_name);
-                }
-                tokenize(values, argv[2], ',');
-                config_manager->setParamVector(argv[arg_ptr],
-                                               argv[arg_ptr],
-                                               values);
-                arg_ptr += 3;
-            } else if (option == "-d") {
-                if (num_args < 1) {
-                    usage(prog_name);
-                }
-                if (argv[arg_ptr][0] == '-') {
-                    clearDebugFlag(argv[arg_ptr] + 1);
-                } else {
-                    setDebugFlag(argv[arg_ptr]);
-                }
-                arg_ptr++;
-            } else if (option == "-e") {
-                if (num_args < 1) {
-                    usage(prog_name);
-                }
-                std::istringstream(argv[arg_ptr]) >> sim_end;
-                arg_ptr++;
-            } else if (option == "-D") {
-                debug = true;
-            } else if (option == "-o") {
-                if (num_args < 1) {
-                    usage(prog_name);
-                }
-                std::istringstream(argv[arg_ptr]) >> offset;
-                arg_ptr++;
-                /* code */
-            } else {
-                usage(prog_name);
-            }
-        }
-    } catch (CxxConfigManager::Exception &e) {
-        std::cerr << e.name << ": " << e.message << "\n";
-        std::exit(EXIT_FAILURE);
-    }
-
-    CxxConfig::statsEnable();
-    getEventQueue(0)->dump();
-
-    try {
-        config_manager->instantiate();
-    } catch (CxxConfigManager::Exception &e) {
-        std::cerr << "Config problem in sim object "
-                  << e.name << ": " << e.message << "\n";
-        std::exit(EXIT_FAILURE);
-    }
-}
-
-void
-SimControl::before_end_of_elaboration()
-{
-    try {
-        config_manager->initState();
-        config_manager->startup();
-    } catch (CxxConfigManager::Exception &e) {
-        std::cerr << "Config problem in sim object "
-            << e.name << ": " << e.message << "\n";
-        std::exit(EXIT_FAILURE);
-    }
-}
-
-void
-SimControl::run()
-{
-    GlobalSimLoopExitEvent *exit_event = NULL;
-
-    if (sim_end == 0) {
-        exit_event = simulate();
-    } else {
-        exit_event = simulate(sim_end);
-    }
-
-    std::cerr << "Exit at tick " << curTick()
-              << ", cause: " << exit_event->getCause() << '\n';
-
-    getEventQueue(0)->dump();
-
-#if TRY_CLEAN_DELETE
-    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/run_gem5.sh b/util/tlm/run_gem5.sh
deleted file mode 100644 (file)
index c50391e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2015, University of Kaiserslautern
-# 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
-
-# Color Definition:
-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        \
---tlm-memory=memory                                         \
---cpu-type=timing                                           \
---num-cpu=1                                                 \
---mem-type=SimpleMemory                                     \
---mem-size=512MB                                            \
---mem-channels=1                                            \
---caches --l2cache                                          \
---machine-type=VExpress_EMM                                 \
---dtb-filename=vexpress.aarch32.ll_20131205.0-gem5.1cpu.dtb \
---kernel=vmlinux.aarch32.ll_20131205.0-gem5
-
-echo -e "\n${BGre}Run gem5 ${RCol}\n"
-
-time ./gem5.opt.sc m5out/config.ini -o 2147483648 
index ce7417e49425e3f7e52f68d6283adda1ee85a01f..db0c36f03f2f39c4c20927adeabaa0b0e15ec457 100644 (file)
@@ -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
  *
  * 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;
 }
+
+}
index cb7411e4460df1c73af076440b3d3fde289343e4..79416f5ce013d0edc14de88d37df771b878e0d52 100644 (file)
@@ -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
  *
  * 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>
 
 #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
index 2a169a37a95741b159cc90bfe3ae0718c2a6773b..f5c07392ce2f696cbc6817af60b30fe912e41a9c 100644 (file)
@@ -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);
 }
+
+}
index 86d9ee11cf0251086ba09b84604f54be34ce0ef2..81316e7f61a93ae8eccd8ac4517edfa9fd5e796a 100644 (file)
  *    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 (file)
index 0000000..386142b
--- /dev/null
@@ -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_port.cc
deleted file mode 100644 (file)
index ab94f73..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 2015, University of Kaiserslautern
- * 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
- *          Abdul Mutaal Ahmad
- */
-
-#include <cctype>
-#include <iomanip>
-#include <sstream>
-
-#include "debug/ExternalPort.hh"
-#include "sc_ext.hh"
-#include "sc_mm.hh"
-#include "sc_port.hh"
-
-namespace Gem5SystemC
-{
-
-/**
- * Instantiate a tlm memory manager that takes care about all the
- * tlm transactions in the system
- */
-MemoryManager mm;
-
-/**
- * Convert a gem5 packet to a TLM payload by copying all the relevant
- * information to a previously allocated tlm payload
- */
-void
-packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans)
-{
-    trans.set_address(packet->getAddr());
-
-    /* Check if this transaction was allocated by mm */
-    sc_assert(trans.has_mm());
-
-    unsigned int size = packet->getSize();
-    unsigned char *data = packet->getPtr<unsigned char>();
-
-    trans.set_data_length(size);
-    trans.set_streaming_width(size);
-    trans.set_data_ptr(data);
-
-    if (packet->isRead()) {
-        trans.set_command(tlm::TLM_READ_COMMAND);
-    }
-    else if (packet->isInvalidate()) {
-        /* Do nothing */
-    } else if (packet->isWrite()) {
-        trans.set_command(tlm::TLM_WRITE_COMMAND);
-    } else {
-        SC_REPORT_FATAL("transactor", "No R/W packet");
-    }
-}
-
-/**
- * Similar to TLM's blocking transport (LT)
- */
-Tick
-sc_transactor::recvAtomic(PacketPtr packet)
-{
-    CAUGHT_UP;
-    SC_REPORT_INFO("transactor", "recvAtomic hasn't been tested much");
-
-    panic_if(packet->cacheResponding(), "Should not see packets where cache "
-             "is responding");
-
-    panic_if(!(packet->isRead() || packet->isWrite()),
-             "Should only see read and writes at TLM memory\n");
-
-
-    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
-
-
-    /* Prepare the transaction */
-    tlm::tlm_generic_payload * trans = mm.allocate();
-    trans->acquire();
-    packet2payload(packet, *trans);
-
-    /* Attach the packet pointer to the TLM transaction to keep track */
-    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");
-    } else if (packet->isRead()) {
-        iSocket->b_transport(*trans, delay);
-    } else if (packet->isInvalidate()) {
-        // do nothing
-    } else if (packet->isWrite()) {
-        iSocket->b_transport(*trans, delay);
-    } else {
-        SC_REPORT_FATAL("transactor", "Typo of request not supported");
-    }
-
-    if (packet->needsResponse()) {
-        packet->makeResponse();
-    }
-
-    trans->release();
-
-    return delay.value();
-}
-
-/**
- * Similar to TLM's debug transport
- */
-void
-sc_transactor::recvFunctional(PacketPtr packet)
-{
-    /* Prepare the transaction */
-    tlm::tlm_generic_payload * trans = mm.allocate();
-    trans->acquire();
-    packet2payload(packet, *trans);
-
-    /* Attach the packet pointer to the TLM transaction to keep track */
-    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");
-    }
-
-    trans->release();
-}
-
-bool
-sc_transactor::recvTimingSnoopResp(PacketPtr packet)
-{
-    /* Snooping should be implemented with tlm_dbg_transport */
-    SC_REPORT_FATAL("transactor","unimplemented func.: recvTimingSnoopResp");
-    return false;
-}
-
-void
-sc_transactor::recvFunctionalSnoop(PacketPtr packet)
-{
-    /* Snooping should be implemented with tlm_dbg_transport */
-    SC_REPORT_FATAL("transactor","unimplemented func.: recvFunctionalSnoop");
-}
-
-/**
- *  Similar to TLM's non-blocking transport (AT)
- */
-bool
-sc_transactor::recvTimingReq(PacketPtr packet)
-{
-    CAUGHT_UP;
-
-    panic_if(packet->cacheResponding(), "Should not see packets where cache "
-             "is responding");
-
-    panic_if(!(packet->isRead() || packet->isWrite()),
-             "Should only see read and writes at TLM memory\n");
-
-
-    /* We should never get a second request after noting that a retry is
-     * required */
-    sc_assert(!needToSendRequestRetry);
-
-    /* Remember if a request comes in while we're blocked so that a retry
-     * can be sent to gem5 */
-    if (blockingRequest) {
-        needToSendRequestRetry = true;
-        return false;
-    }
-
-    /*  NOTE: normal tlm is blocking here. But in our case we return false
-     *  and tell gem5 when a retry can be done. This is the main difference
-     *  in the protocol:
-     *  if (requestInProgress)
-     *  {
-     *      wait(endRequestEvent);
-     *  }
-     *  requestInProgress = trans;
-    */
-
-    /* Prepare the transaction */
-    tlm::tlm_generic_payload * trans = mm.allocate();
-    trans->acquire();
-    packet2payload(packet, *trans);
-
-    /* Attach the packet pointer to the TLM transaction to keep track */
-    gem5Extension* extension = new gem5Extension(packet);
-    trans->set_auto_extension(extension);
-
-    /* Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC
-     * Standard Page 507 for a visualisation of the procedure */
-    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);
-    /* Check returned value: */
-    if (status == tlm::TLM_ACCEPTED) {
-        sc_assert(phase == tlm::BEGIN_REQ);
-        /* Accepted but is now blocking until END_REQ (exclusion rule)*/
-        blockingRequest = trans;
-    } else if (status == tlm::TLM_UPDATED) {
-        /* 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");
-        pe->notify(*trans, phase, delay);
-    } else if (status == tlm::TLM_COMPLETED) {
-        /* Transaction is over nothing has do be done. */
-        sc_assert(phase == tlm::END_RESP);
-        trans->release();
-    }
-
-    return true;
-}
-
-void
-sc_transactor::pec(
-    sc_transactor::payloadEvent<sc_transactor> * pe,
-    tlm::tlm_generic_payload& trans,
-    const tlm::tlm_phase& phase)
-{
-    sc_time delay;
-
-    if (phase == tlm::END_REQ ||
-            &trans == blockingRequest && phase == tlm::BEGIN_RESP) {
-        sc_assert(&trans == blockingRequest);
-        blockingRequest = NULL;
-
-        /* Did another request arrive while blocked, schedule a retry */
-        if (needToSendRequestRetry) {
-            needToSendRequestRetry = false;
-           iSocket.sendRetryReq();
-        }
-    }
-    else if (phase == tlm::BEGIN_RESP)
-    {
-        CAUGHT_UP;
-
-        PacketPtr packet = gem5Extension::getExtension(trans).getPacket();
-
-        sc_assert(!blockingResponse);
-
-        bool need_retry;
-        if (packet->needsResponse()) {
-            packet->makeResponse();
-            need_retry = !iSocket.sendTimingResp(packet);
-        } else {
-            need_retry = false;
-        }
-
-        if (need_retry) {
-            blockingResponse = &trans;
-        } else {
-            if (phase == tlm::BEGIN_RESP) {
-                /* 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);
-                /* Release the transaction with all the extensions */
-                trans.release();
-            }
-        }
-    } else {
-        SC_REPORT_FATAL("transactor", "Invalid protocol phase in pec");
-    }
-    delete pe;
-}
-
-void
-sc_transactor::recvRespRetry()
-{
-    CAUGHT_UP;
-
-    /* Retry a response */
-    sc_assert(blockingResponse);
-
-    tlm::tlm_generic_payload *trans = blockingResponse;
-    blockingResponse = NULL;
-    PacketPtr packet = gem5Extension::getExtension(trans).getPacket();
-
-    bool need_retry = !iSocket.sendTimingResp(packet);
-
-    sc_assert(!need_retry);
-
-    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
-    tlm::tlm_phase phase = tlm::END_RESP;
-    iSocket->nb_transport_fw(*trans, phase, delay);
-    // Release transaction with all the extensions
-    trans->release();
-}
-
-tlm::tlm_sync_enum
-sc_transactor::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");
-    pe->notify(trans, phase, delay);
-    return tlm::TLM_ACCEPTED;
-}
-
-void
-sc_transactor::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_transactor::sc_transactor(const std::string &name_,
-    const std::string &systemc_name,
-    ExternalSlave &owner_) :
-    tlm::tlm_initiator_socket<>(systemc_name.c_str()),
-    ExternalSlave::Port(name_, owner_),
-    iSocket(*this),
-    blockingRequest(NULL),
-    needToSendRequestRetry(false),
-    blockingResponse(NULL)
-{
-    m_export.bind(*this);
-}
-
-class sc_transactorHandler : 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 sc_transactor(name, port_data, owner);
-    }
-};
-
-void
-registerSCPorts()
-{
-    ExternalSlave::registerHandler("tlm", new sc_transactorHandler);
-}
-
-}
diff --git a/util/tlm/sc_port.hh b/util/tlm/sc_port.hh
deleted file mode 100644 (file)
index 374a3cf..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2015, University of Kaiserslautern
- * 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
- */
-
-#ifndef __SIM_SC_TRANSACTOR_HH__
-#define __SIM_SC_TRANSACTOR_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"
-
-namespace Gem5SystemC
-{
-/**
- * Test that gem5 is at the same time as SystemC
- */
-#define CAUGHT_UP do { \
-    assert(curTick() == sc_core::sc_time_stamp().value()); \
-} while (0)
-
-
-class sc_transactor : 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);
-       }
-    };
-
-    /** One instance of pe and the related callback needed */
-    //payloadEvent<sc_transactor> pe;
-    void pec(payloadEvent<sc_transactor> * pe,
-        tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase);
-
-    /**
-     * A transaction after BEGIN_REQ has been sent but before END_REQ, which
-     * is blocking the request channel (Exlusion Rule, see IEEE1666)
-     */
-    tlm::tlm_generic_payload *blockingRequest;
-
-    /**
-     * Did another gem5 request arrive while currently blocked?
-     * This variable is needed when a retry should happen
-     */
-    bool needToSendRequestRetry;
-
-    /**
-     * A response which has been asked to retry by gem5 and so is blocking
-     * the response channel
-     */
-    tlm::tlm_generic_payload *blockingResponse;
-
-  protected:
-    /** The gem5 Port slave interface */
-    Tick recvAtomic(PacketPtr packet);
-    void recvFunctional(PacketPtr packet);
-    bool recvTimingReq(PacketPtr packet);
-    bool recvTimingSnoopResp(PacketPtr packet);
-    void recvRespRetry();
-    void recvFunctionalSnoop(PacketPtr packet);
-
-    /** 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);
-
-    void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
-                                   sc_dt::uint64 end_range);
-
-  public:
-    sc_transactor(const std::string &name_,
-           const std::string &systemc_name,
-           ExternalSlave &owner_);
-};
-
-void registerPort(const std::string &name, Port &port);
-
-void registerSCPorts();
-
-}
-
-#endif // __SIM_SC_PORT_HH__
diff --git a/util/tlm/sc_slave_port.cc b/util/tlm/sc_slave_port.cc
new file mode 100644 (file)
index 0000000..cea0f6d
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * 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
+ *          Abdul Mutaal Ahmad
+ *          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"
+
+namespace Gem5SystemC
+{
+
+/**
+ * Instantiate a tlm memory manager that takes care about all the
+ * tlm transactions in the system
+ */
+MemoryManager mm;
+
+/**
+ * Convert a gem5 packet to a TLM payload by copying all the relevant
+ * information to a previously allocated tlm payload
+ */
+void
+packet2payload(PacketPtr packet, tlm::tlm_generic_payload &trans)
+{
+    trans.set_address(packet->getAddr());
+
+    /* Check if this transaction was allocated by mm */
+    sc_assert(trans.has_mm());
+
+    unsigned int size = packet->getSize();
+    unsigned char *data = packet->getPtr<unsigned char>();
+
+    trans.set_data_length(size);
+    trans.set_streaming_width(size);
+    trans.set_data_ptr(data);
+
+    if (packet->isRead()) {
+        trans.set_command(tlm::TLM_READ_COMMAND);
+    }
+    else if (packet->isInvalidate()) {
+        /* Do nothing */
+    } else if (packet->isWrite()) {
+        trans.set_command(tlm::TLM_WRITE_COMMAND);
+    } else {
+        SC_REPORT_FATAL("SCSlavePort", "No R/W packet");
+    }
+}
+
+/**
+ * Similar to TLM's blocking transport (LT)
+ */
+Tick
+SCSlavePort::recvAtomic(PacketPtr packet)
+{
+    CAUGHT_UP;
+    SC_REPORT_INFO("SCSlavePort", "recvAtomic hasn't been tested much");
+
+    panic_if(packet->cacheResponding(), "Should not see packets where cache "
+             "is responding");
+
+    panic_if(!(packet->isRead() || packet->isWrite()),
+             "Should only see read and writes at TLM memory\n");
+
+
+    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
+
+
+    /* Prepare the transaction */
+    tlm::tlm_generic_payload * trans = mm.allocate();
+    trans->acquire();
+    packet2payload(packet, *trans);
+
+    /* Attach the packet pointer to the TLM transaction to keep track */
+    Gem5Extension* extension = new Gem5Extension(packet);
+    trans->set_auto_extension(extension);
+
+    /* Execute b_transport: */
+    if (packet->cmd == MemCmd::SwapReq) {
+        SC_REPORT_FATAL("SCSlavePort", "SwapReq not supported");
+    } else if (packet->isRead()) {
+        iSocket->b_transport(*trans, delay);
+    } else if (packet->isInvalidate()) {
+        // do nothing
+    } else if (packet->isWrite()) {
+        iSocket->b_transport(*trans, delay);
+    } else {
+        SC_REPORT_FATAL("SCSlavePort", "Typo of request not supported");
+    }
+
+    if (packet->needsResponse()) {
+        packet->makeResponse();
+    }
+
+    trans->release();
+
+    return delay.value();
+}
+
+/**
+ * Similar to TLM's debug transport
+ */
+void
+SCSlavePort::recvFunctional(PacketPtr packet)
+{
+    /* Prepare the transaction */
+    tlm::tlm_generic_payload * trans = mm.allocate();
+    trans->acquire();
+    packet2payload(packet, *trans);
+
+    /* Attach the packet pointer to the TLM transaction to keep track */
+    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("SCSlavePort","debug transport was not completed");
+    }
+
+    trans->release();
+}
+
+bool
+SCSlavePort::recvTimingSnoopResp(PacketPtr packet)
+{
+    /* Snooping should be implemented with tlm_dbg_transport */
+    SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvTimingSnoopResp");
+    return false;
+}
+
+void
+SCSlavePort::recvFunctionalSnoop(PacketPtr packet)
+{
+    /* Snooping should be implemented with tlm_dbg_transport */
+    SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvFunctionalSnoop");
+}
+
+/**
+ *  Similar to TLM's non-blocking transport (AT)
+ */
+bool
+SCSlavePort::recvTimingReq(PacketPtr packet)
+{
+    CAUGHT_UP;
+
+    panic_if(packet->cacheResponding(), "Should not see packets where cache "
+             "is responding");
+
+    panic_if(!(packet->isRead() || packet->isWrite()),
+             "Should only see read and writes at TLM memory\n");
+
+
+    /* We should never get a second request after noting that a retry is
+     * required */
+    sc_assert(!needToSendRequestRetry);
+
+    /* Remember if a request comes in while we're blocked so that a retry
+     * can be sent to gem5 */
+    if (blockingRequest) {
+        needToSendRequestRetry = true;
+        return false;
+    }
+
+    /*  NOTE: normal tlm is blocking here. But in our case we return false
+     *  and tell gem5 when a retry can be done. This is the main difference
+     *  in the protocol:
+     *  if (requestInProgress)
+     *  {
+     *      wait(endRequestEvent);
+     *  }
+     *  requestInProgress = trans;
+    */
+
+    /* Prepare the transaction */
+    tlm::tlm_generic_payload * trans = mm.allocate();
+    trans->acquire();
+    packet2payload(packet, *trans);
+
+    /* Attach the packet pointer to the TLM transaction to keep track */
+    Gem5Extension* extension = new Gem5Extension(packet);
+    trans->set_auto_extension(extension);
+
+    /* Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC
+     * Standard Page 507 for a visualisation of the procedure */
+    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);
+    /* Check returned value: */
+    if (status == tlm::TLM_ACCEPTED) {
+        sc_assert(phase == tlm::BEGIN_REQ);
+        /* Accepted but is now blocking until END_REQ (exclusion rule)*/
+        blockingRequest = trans;
+    } else if (status == tlm::TLM_UPDATED) {
+        /* The Timing annotation must be honored: */
+        sc_assert(phase == tlm::END_REQ || phase == tlm::BEGIN_RESP);
+
+        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. */
+        sc_assert(phase == tlm::END_RESP);
+        trans->release();
+    }
+
+    return true;
+}
+
+void
+SCSlavePort::pec(
+    PayloadEvent<SCSlavePort> * pe,
+    tlm::tlm_generic_payload& trans,
+    const tlm::tlm_phase& phase)
+{
+    sc_time delay;
+
+    if (phase == tlm::END_REQ ||
+            &trans == blockingRequest && phase == tlm::BEGIN_RESP) {
+        sc_assert(&trans == blockingRequest);
+        blockingRequest = NULL;
+
+        /* Did another request arrive while blocked, schedule a retry */
+        if (needToSendRequestRetry) {
+            needToSendRequestRetry = false;
+           iSocket.sendRetryReq();
+        }
+    }
+    else if (phase == tlm::BEGIN_RESP)
+    {
+        CAUGHT_UP;
+
+        PacketPtr packet = Gem5Extension::getExtension(trans).getPacket();
+
+        sc_assert(!blockingResponse);
+
+        bool need_retry;
+        if (packet->needsResponse()) {
+            packet->makeResponse();
+            need_retry = !iSocket.sendTimingResp(packet);
+        } else {
+            need_retry = false;
+        }
+
+        if (need_retry) {
+            blockingResponse = &trans;
+        } else {
+            if (phase == tlm::BEGIN_RESP) {
+                /* 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);
+                /* Release the transaction with all the extensions */
+                trans.release();
+            }
+        }
+    } else {
+        SC_REPORT_FATAL("SCSlavePort", "Invalid protocol phase in pec");
+    }
+    delete pe;
+}
+
+void
+SCSlavePort::recvRespRetry()
+{
+    CAUGHT_UP;
+
+    /* Retry a response */
+    sc_assert(blockingResponse);
+
+    tlm::tlm_generic_payload *trans = blockingResponse;
+    blockingResponse = NULL;
+    PacketPtr packet = Gem5Extension::getExtension(trans).getPacket();
+
+    bool need_retry = !iSocket.sendTimingResp(packet);
+
+    sc_assert(!need_retry);
+
+    sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
+    tlm::tlm_phase phase = tlm::END_RESP;
+    iSocket->nb_transport_fw(*trans, phase, delay);
+    // Release transaction with all the extensions
+    trans->release();
+}
+
+tlm::tlm_sync_enum
+SCSlavePort::nb_transport_bw(tlm::tlm_generic_payload& trans,
+    tlm::tlm_phase& phase,
+    sc_core::sc_time& delay)
+{
+    PayloadEvent<SCSlavePort> * pe;
+    pe = new PayloadEvent<SCSlavePort>(*this, &SCSlavePort::pec, "PE");
+    pe->notify(trans, phase, delay);
+    return tlm::TLM_ACCEPTED;
+}
+
+void
+SCSlavePort::invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+     sc_dt::uint64 end_range)
+{
+    SC_REPORT_FATAL("SCSlavePort", "unimpl. func: invalidate_direct_mem_ptr");
+}
+
+SCSlavePort::SCSlavePort(const std::string &name_,
+    const std::string &systemc_name,
+    ExternalSlave &owner_) :
+    tlm::tlm_initiator_socket<>(systemc_name.c_str()),
+    ExternalSlave::Port(name_, owner_),
+    iSocket(*this),
+    blockingRequest(NULL),
+    needToSendRequestRetry(false),
+    blockingResponse(NULL)
+{
+    m_export.bind(*this);
+}
+
+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()
+{
+    ExternalSlave::registerHandler("tlm_slave", new SlavePortHandler);
+}
+
+}
diff --git a/util/tlm/sc_slave_port.hh b/util/tlm/sc_slave_port.hh
new file mode 100644 (file)
index 0000000..a42532c
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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_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"
+
+namespace Gem5SystemC
+{
+/**
+ * Test that gem5 is at the same time as SystemC
+ */
+#define CAUGHT_UP do { \
+    assert(curTick() == sc_core::sc_time_stamp().value()); \
+} while (0)
+
+/**
+ * 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:
+    SCSlavePort &iSocket;
+
+    /** One instance of pe and the related callback needed */
+    //payloadEvent<SCSlavePort> pe;
+    void pec(PayloadEvent<SCSlavePort> * pe,
+        tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase);
+
+    /**
+     * A transaction after BEGIN_REQ has been sent but before END_REQ, which
+     * is blocking the request channel (Exlusion Rule, see IEEE1666)
+     */
+    tlm::tlm_generic_payload *blockingRequest;
+
+    /**
+     * Did another gem5 request arrive while currently blocked?
+     * This variable is needed when a retry should happen
+     */
+    bool needToSendRequestRetry;
+
+    /**
+     * A response which has been asked to retry by gem5 and so is blocking
+     * the response channel
+     */
+    tlm::tlm_generic_payload *blockingResponse;
+
+  protected:
+    /** The gem5 Port slave interface */
+    Tick recvAtomic(PacketPtr packet);
+    void recvFunctional(PacketPtr packet);
+    bool recvTimingReq(PacketPtr packet);
+    bool recvTimingSnoopResp(PacketPtr packet);
+    void recvRespRetry();
+    void recvFunctionalSnoop(PacketPtr packet);
+
+    /** 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);
+
+    void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+                                   sc_dt::uint64 end_range);
+
+  public:
+    SCSlavePort(const std::string &name_,
+                const std::string &systemc_name,
+                ExternalSlave &owner_);
+
+    static void registerPortHandler();
+
+    friend PayloadEvent<SCSlavePort>;
+};
+
+}
+
+#endif // __SC_SLAVE_PORT_H__
diff --git a/util/tlm/sc_target.cc b/util/tlm/sc_target.cc
deleted file mode 100644 (file)
index bae1de1..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2015, University of Kaiserslautern
- * 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
- */
-
-#include "sc_target.hh"
-
-using namespace sc_core;
-using namespace std;
-
-Target::Target(sc_core::sc_module_name name,
-    bool debug,
-    unsigned long long int size,
-    unsigned int offset) :
-    socket("socket"),
-    transaction_in_progress(0),
-    response_in_progress(false),
-    next_response_pending(0),
-    end_req_pending(0),
-    m_peq(this, &Target::peq_cb),
-    debug(debug),
-    size(size),
-    offset(offset)
-{
-    /* Register tlm transport functions */
-    socket.register_b_transport(this, &Target::b_transport);
-    socket.register_transport_dbg(this, &Target::transport_dbg);
-    socket.register_nb_transport_fw(this, &Target::nb_transport_fw);
-
-
-    /* allocate storage memory */
-    mem = new unsigned char[size];
-
-    SC_METHOD(execute_transaction_process);
-    sensitive << target_done_event;
-    dont_initialize();
-}
-
-void
-Target::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay)
-{
-    /* Execute the read or write commands */
-    execute_transaction(trans);
-}
-
-unsigned int
-Target::transport_dbg(tlm::tlm_generic_payload& trans)
-{
-    tlm::tlm_command cmd = trans.get_command();
-    sc_dt::uint64    adr = trans.get_address() - offset;
-    unsigned char*   ptr = trans.get_data_ptr();
-    unsigned int     len = trans.get_data_length();
-
-    unsigned char *mem_array_ptr = mem + adr;
-
-    /* Load / Store the access: */
-    if ( cmd == tlm::TLM_READ_COMMAND ) {
-        if (debug) {
-            SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND");
-        }
-        std::memcpy(ptr, mem_array_ptr, len);
-    } else if ( cmd == tlm::TLM_WRITE_COMMAND ) {
-        if (debug) {
-            SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND");
-        }
-        std::memcpy(mem_array_ptr, ptr, len);
-    }
-
-    return len;
-}
-
-
-/* TLM-2 non-blocking transport method */
-tlm::tlm_sync_enum Target::nb_transport_fw(tlm::tlm_generic_payload& trans,
-                                           tlm::tlm_phase& phase,
-                                           sc_time& delay)
-{
-    /* Queue the transaction until the annotated time has elapsed */
-    m_peq.notify(trans, phase, delay);
-    return tlm::TLM_ACCEPTED;
-}
-
-void
-Target::peq_cb(tlm::tlm_generic_payload& trans,
-               const tlm::tlm_phase& phase)
-{
-    sc_time delay;
-
-    if (phase == tlm::BEGIN_REQ) {
-        if (debug) SC_REPORT_INFO("target", "tlm::BEGIN_REQ");
-
-        /* Increment the transaction reference count */
-        trans.acquire();
-
-        if ( !transaction_in_progress ) {
-            send_end_req(trans);
-        } else {
-            /* Put back-pressure on initiator by deferring END_REQ until
-             * pipeline is clear */
-            end_req_pending = &trans;
-        }
-    } else if (phase == tlm::END_RESP) {
-        /* On receiving END_RESP, the target can release the transaction and
-         * allow other pending transactions to proceed */
-        if (!response_in_progress) {
-            SC_REPORT_FATAL("TLM-2", "Illegal transaction phase END_RESP"
-                            "received by target");
-        }
-
-        transaction_in_progress = 0;
-
-        /* Target itself is now clear to issue the next BEGIN_RESP */
-        response_in_progress = false;
-        if (next_response_pending) {
-            send_response( *next_response_pending );
-            next_response_pending = 0;
-        }
-
-        /* ... and to unblock the initiator by issuing END_REQ */
-        if (end_req_pending) {
-            send_end_req( *end_req_pending );
-            end_req_pending = 0;
-        }
-
-    } else /* tlm::END_REQ or tlm::BEGIN_RESP */ {
-            SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by"
-                            "target");
-    }
-}
-
-void
-Target::send_end_req(tlm::tlm_generic_payload& trans)
-{
-    tlm::tlm_phase bw_phase;
-    sc_time delay;
-
-    /* Queue the acceptance and the response with the appropriate latency */
-    bw_phase = tlm::END_REQ;
-    delay = sc_time(10, SC_NS); // Accept delay
-
-    tlm::tlm_sync_enum status;
-    status = socket->nb_transport_bw(trans, bw_phase, delay);
-
-    /* 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
-    target_done_event.notify(delay);
-
-    assert(transaction_in_progress == 0);
-    transaction_in_progress = &trans;
-}
-
-void
-Target::execute_transaction_process()
-{
-    /* Execute the read or write commands */
-    execute_transaction( *transaction_in_progress );
-
-    /* Target must honor BEGIN_RESP/END_RESP exclusion rule; i.e. must not
-     * send BEGIN_RESP until receiving previous END_RESP or BEGIN_REQ */
-    if (response_in_progress) {
-        /* Target allows only two transactions in-flight */
-        if (next_response_pending) {
-            SC_REPORT_FATAL("TLM-2", "Attempt to have two pending responses"
-                            "in target");
-        }
-        next_response_pending = transaction_in_progress;
-    } else {
-        send_response( *transaction_in_progress );
-    }
-}
-
-void
-Target::execute_transaction(tlm::tlm_generic_payload& trans)
-{
-    tlm::tlm_command cmd = trans.get_command();
-    sc_dt::uint64    adr = trans.get_address() - offset;
-    unsigned char*   ptr = trans.get_data_ptr();
-    unsigned int     len = trans.get_data_length();
-    unsigned char*   byt = trans.get_byte_enable_ptr();
-    unsigned int     wid = trans.get_streaming_width();
-
-    if ( byt != 0 ) {
-        cout << "Byte Error" << endl;
-        trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE );
-        return;
-    }
-
-    //if ( len > 4 || wid < len ) {
-    //    cout << "Burst Error len=" << len << " wid=" << wid << endl;
-    //    trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE );
-    //    return;
-    //}
-
-    unsigned char *mem_array_ptr = mem + adr;
-
-    /* Load / Store the access: */
-    if ( cmd == tlm::TLM_READ_COMMAND ) {
-        if (debug) {
-            SC_REPORT_INFO("target", "tlm::TLM_READ_COMMAND");
-        }
-        std::memcpy(ptr, mem_array_ptr, len);
-    } else if ( cmd == tlm::TLM_WRITE_COMMAND ) {
-        if (debug) {
-            SC_REPORT_INFO("target", "tlm::TLM_WRITE_COMMAND");
-        }
-        std::memcpy(mem_array_ptr, ptr, len);
-    }
-
-    trans.set_response_status( tlm::TLM_OK_RESPONSE );
-}
-
-void
-Target::send_response(tlm::tlm_generic_payload& trans)
-{
-    tlm::tlm_sync_enum status;
-    tlm::tlm_phase bw_phase;
-    sc_time delay;
-
-    response_in_progress = true;
-    bw_phase = tlm::BEGIN_RESP;
-    delay = sc_time(10, SC_NS);
-    status = socket->nb_transport_bw( trans, bw_phase, delay );
-
-    if (status == tlm::TLM_UPDATED) {
-        /* The timing annotation must be honored */
-        m_peq.notify(trans, bw_phase, delay);
-    } else if (status == tlm::TLM_COMPLETED) {
-        /* The initiator has terminated the transaction */
-        transaction_in_progress = 0;
-        response_in_progress = false;
-    }
-    trans.release();
-}
diff --git a/util/tlm/sc_target.hh b/util/tlm/sc_target.hh
deleted file mode 100644 (file)
index 7a2d075..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2015, University of Kaiserslautern
- * 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
- */
-
-#ifndef __SIM_SC_TARGET_HH__
-#define __SIM_SC_TARGET_HH__
-
-#include <tlm_utils/peq_with_cb_and_phase.h>
-#include <tlm_utils/simple_target_socket.h>
-
-#include <iostream>
-#include <systemc>
-#include <tlm>
-
-using namespace sc_core;
-using namespace std;
-
-struct Target: sc_module
-{
-    /** TLM interface socket: */
-    tlm_utils::simple_target_socket<Target> socket;
-
-    /** TLM related member variables: */
-    tlm::tlm_generic_payload*  transaction_in_progress;
-    sc_event                   target_done_event;
-    bool                       response_in_progress;
-    bool                       debug;
-    tlm::tlm_generic_payload*  next_response_pending;
-    tlm::tlm_generic_payload*  end_req_pending;
-    tlm_utils::peq_with_cb_and_phase<Target> m_peq;
-
-    /** Storage, may be implemented with a map for large devices */
-    unsigned char *mem;
-
-    Target(sc_core::sc_module_name name,
-        bool debug,
-        unsigned long long int size,
-        unsigned int offset);
-    SC_HAS_PROCESS(Target);
-
-    /** TLM interface functions */
-    virtual void b_transport(tlm::tlm_generic_payload& trans,
-                             sc_time& delay);
-    virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
-    virtual tlm::tlm_sync_enum nb_transport_fw(
-                tlm::tlm_generic_payload& trans,
-                tlm::tlm_phase& phase,
-                sc_time& delay);
-
-    /** Callback of Payload Event Queue: */
-    void peq_cb(tlm::tlm_generic_payload& trans,
-                const tlm::tlm_phase& phase);
-
-    /** Helping function common to b_transport and nb_transport */
-    void execute_transaction(tlm::tlm_generic_payload& trans);
-
-    /** Helping functions and processes: */
-    void send_end_req(tlm::tlm_generic_payload& trans);
-    void send_response(tlm::tlm_generic_payload& trans);
-
-    /** Method process that runs on target_done_event */
-    void execute_transaction_process();
-
-    /** Helping Variables **/
-    unsigned long long int size;
-    unsigned offset;
-};
-
-#endif //__SIM_SC_TARGET_HH__
-
diff --git a/util/tlm/sim_control.cc b/util/tlm/sim_control.cc
new file mode 100644 (file)
index 0000000..ef04c6b
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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
+ *          Abdul Mutaal Ahmad
+ *          Christian Menard
+ */
+
+/**
+ * @file
+ *
+ *  Example top level file for SystemC-TLM integration with C++-only
+ *  instantiation.
+ *
+ */
+
+#include <systemc>
+#include <tlm>
+
+#include "sc_slave_port.hh"
+#include "sim/cxx_config_ini.hh"
+#include "sim/init_signals.hh"
+#include "sim/stat_control.hh"
+#include "sim_control.hh"
+#include "stats.hh"
+
+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::exit(EXIT_FAILURE);
+}
+
+SimControl::SimControl(sc_core::sc_module_name name, int argc_, char** argv_)
+  : Gem5SystemC::Module(name),
+    argc(argc_),
+    argv(argv_)
+{
+    SC_THREAD(run);
+
+    std::string prog_name(argv[0]);
+    unsigned int arg_ptr = 1;
+
+    if (argc == 1) {
+        usage(prog_name);
+    }
+
+    cxxConfigInit();
+    Gem5SystemC::SCSlavePort::registerPortHandler();
+
+    Trace::setDebugLogger(&logger);
+
+    Gem5SystemC::setTickFrequency();
+    sc_core::sc_set_time_resolution(1, sc_core::SC_PS);
+
+    Gem5SystemC::Module::setupEventQueues(*this);
+    initSignals();
+
+    Stats::initSimStats();
+    Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
+
+    Trace::enable();
+
+    sim_end = 0;
+    debug = false;
+    offset = 0;
+
+    const std::string config_file(argv[arg_ptr]);
+
+    CxxConfigFileBase *conf = new CxxIniFile();
+
+    if (!conf->load(config_file.c_str())) {
+        std::cerr << "Can't open config file: " << config_file << '\n';
+        std::exit(EXIT_FAILURE);
+    }
+    arg_ptr++;
+
+    config_manager = new CxxConfigManager(*conf);
+
+    try {
+        while (arg_ptr < argc) {
+            std::string option(argv[arg_ptr]);
+            arg_ptr++;
+            unsigned num_args = argc - arg_ptr;
+
+            if (option == "-p") {
+                if (num_args < 3) {
+                    usage(prog_name);
+                }
+
+                config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1],
+                argv[arg_ptr + 2]);
+                arg_ptr += 3;
+            } else if (option == "-v") {
+                std::vector<std::string> values;
+
+                if (num_args < 3) {
+                    usage(prog_name);
+                }
+                tokenize(values, argv[2], ',');
+                config_manager->setParamVector(argv[arg_ptr],
+                                               argv[arg_ptr],
+                                               values);
+                arg_ptr += 3;
+            } else if (option == "-d") {
+                if (num_args < 1) {
+                    usage(prog_name);
+                }
+                if (argv[arg_ptr][0] == '-') {
+                    clearDebugFlag(argv[arg_ptr] + 1);
+                } else {
+                    setDebugFlag(argv[arg_ptr]);
+                }
+                arg_ptr++;
+            } else if (option == "-e") {
+                if (num_args < 1) {
+                    usage(prog_name);
+                }
+                std::istringstream(argv[arg_ptr]) >> sim_end;
+                arg_ptr++;
+            } else if (option == "-D") {
+                debug = true;
+            } else if (option == "-o") {
+                if (num_args < 1) {
+                    usage(prog_name);
+                }
+                std::istringstream(argv[arg_ptr]) >> offset;
+                arg_ptr++;
+                /* code */
+            } else {
+                usage(prog_name);
+            }
+        }
+    } catch (CxxConfigManager::Exception &e) {
+        std::cerr << e.name << ": " << e.message << "\n";
+        std::exit(EXIT_FAILURE);
+    }
+
+    CxxConfig::statsEnable();
+    getEventQueue(0)->dump();
+
+    try {
+        config_manager->instantiate();
+    } catch (CxxConfigManager::Exception &e) {
+        std::cerr << "Config problem in sim object "
+                  << e.name << ": " << e.message << "\n";
+        std::exit(EXIT_FAILURE);
+    }
+}
+
+void
+SimControl::before_end_of_elaboration()
+{
+    try {
+        config_manager->initState();
+        config_manager->startup();
+    } catch (CxxConfigManager::Exception &e) {
+        std::cerr << "Config problem in sim object "
+            << e.name << ": " << e.message << "\n";
+        std::exit(EXIT_FAILURE);
+    }
+}
+
+void
+SimControl::run()
+{
+    GlobalSimLoopExitEvent *exit_event = NULL;
+
+    if (sim_end == 0) {
+        exit_event = simulate();
+    } else {
+        exit_event = simulate(sim_end);
+    }
+
+    std::cerr << "Exit at tick " << curTick()
+              << ", cause: " << exit_event->getCause() << '\n';
+
+    getEventQueue(0)->dump();
+
+#if TRY_CLEAN_DELETE
+    config_manager->deleteObjects();
+#endif
+}
diff --git a/util/tlm/sim_control.hh b/util/tlm/sim_control.hh
new file mode 100644 (file)
index 0000000..52bfa64
--- /dev/null
@@ -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
diff --git a/util/tlm/tgen.cfg b/util/tlm/tgen.cfg
deleted file mode 100644 (file)
index e341d85..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (c) 2015, University of Kaiserslautern
-# 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
-
-
-# This format supports comments using the '#' symbol as the leading
-# character of the line
-#
-# The file format contains [STATE]+ [INIT] [TRANSITION]+ in any order,
-# where the states are the nodes in the graph, init describes what
-# state to start in, and transition describes the edges of the graph.
-#
-# STATE <id> <duration (ticks)> <type>
-#
-# State IDLE idles
-#
-# States LINEAR and RANDOM have additional <percent reads> <start addr>
-# <end addr> <access size (bytes)> <min period (ticks)> <max period (ticks)>
-# <data limit (bytes)>
-#
-# State TRACE plays back a pre-recorded trace once
-#
-# Addresses are expressed as decimal numbers. The period in the linear
-# and random state is from a uniform random distribution over the
-# interval. If a specific value is desired, then the min and max can
-# be set to the same value.
-STATE 0 1000000 LINEAR 50 0 256 4 5000 5000 64
-INIT 0
-TRANSITION 0 0 1
diff --git a/util/tlm/tlm.py b/util/tlm/tlm.py
deleted file mode 100644 (file)
index e9025ab..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (c) 2015, University of Kaiserslautern
-# 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
-
-import m5
-from m5.objects import *
-
-# This configuration shows a simple setup of a TrafficGen (CPU) and an
-# external TLM port for SystemC co-simulation
-#
-# Base System Architecture:
-# +-------------+  +-----+    ^
-# | System Port |  | CPU |    |
-# +-------+-----+  +--+--+    |
-#         |           |       | gem5 World
-#         |      +----+       | (see this file)
-#         |      |            |
-# +-------v------v-------+    |
-# |        Membus        |    v
-# +----------------+-----+    External Port (see sc_port.*)
-#                  |          ^
-#              +---v---+      | TLM World
-#              |  TLM  |      | (see sc_target.*)
-#              +-------+      v
-#
-
-# Create a system with a Crossbar and a TrafficGenerator as CPU:
-system = System()
-system.membus = IOXBar(width = 16)
-system.physmem = SimpleMemory() # This must be instanciated, even if not needed
-system.cpu = TrafficGen(config_file = "tgen.cfg")
-system.clk_domain = SrcClockDomain(clock = '1.5GHz',
-    voltage_domain = VoltageDomain(voltage = '1V'))
-
-# Create a external TLM port:
-system.tlm = ExternalSlave()
-system.tlm.addr_ranges = [AddrRange('512MB')]
-system.tlm.port_type = "tlm"
-system.tlm.port_data = "memory"
-
-# Route the connections:
-system.cpu.port = system.membus.slave
-system.system_port = system.membus.slave
-system.membus.master = system.tlm.port
-
-# Start the simulation:
-root = Root(full_system = False, system = system)
-root.system.mem_mode = 'timing'
-m5.instantiate()
-m5.simulate() #Simulation time specified later on commandline
diff --git a/util/tlm/tlm_elastic.py b/util/tlm/tlm_elastic.py
deleted file mode 100644 (file)
index 3de0670..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (c) 2016, University of Kaiserslautern
-# 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
-
-import m5
-import optparse
-
-from m5.objects import *
-from m5.util import addToPath, fatal
-
-addToPath('../../configs/common/')
-
-from Caches import *
-
-# This configuration shows a simple setup of a Elastic Trace Player (eTraceCPU)
-# and an external TLM port for SystemC co-simulation.
-#
-# We assume a DRAM size of 512MB and L1 cache sizes of 32KB.
-#
-# Base System Architecture:
-#
-#                  +-----------+       ^
-# +-------------+  | eTraceCPU |       |
-# | System Port |  +-----+-----+       |
-# +------+------+  | $D1 | $I1 |       |
-#        |         +--+--+--+--+       |
-#        |            |     |          | gem5 World
-#        |            |     |          | (see this file)
-#        |            |     |          |
-# +------v------------v-----v--+       |
-# |           Membus           |       v
-# +----------------+-----------+       External Port (see sc_port.*)
-#                  |                   ^
-#              +---v---+               | TLM World
-#              |  TLM  |               | (see sc_target.*)
-#              +-------+               v
-#
-#
-# Create a system with a Crossbar and an Elastic Trace Player as CPU:
-
-# Setup System:
-system = System(cpu=TraceCPU(cpu_id=0),
-                mem_mode='timing',
-                mem_ranges = [AddrRange('512MB')],
-                cache_line_size = 64)
-
-# Create a top-level voltage domain:
-system.voltage_domain = VoltageDomain()
-
-# Create a source clock for the system. This is used as the clock period for
-# xbar and memory:
-system.clk_domain = SrcClockDomain(clock =  '1GHz',
-        voltage_domain = system.voltage_domain)
-
-# Create a CPU voltage domain:
-system.cpu_voltage_domain = VoltageDomain()
-
-# Create a separate clock domain for the CPUs. In case of Trace CPUs this clock
-# is actually used only by the caches connected to the CPU:
-system.cpu_clk_domain = SrcClockDomain(clock = '1GHz',
-        voltage_domain = system.cpu_voltage_domain)
-
-# Setup CPU and its L1 caches:
-system.cpu.createInterruptController()
-system.cpu.icache = L1_ICache(size="32kB")
-system.cpu.dcache = L1_DCache(size="32kB")
-system.cpu.icache.cpu_side = system.cpu.icache_port
-system.cpu.dcache.cpu_side = system.cpu.dcache_port
-
-# Assign input trace files to the eTraceCPU:
-system.cpu.instTraceFile="system.cpu.traceListener.inst.gz"
-system.cpu.dataTraceFile="system.cpu.traceListener.data.gz"
-
-# Setting up L1 BUS:
-system.membus = IOXBar(width = 16)
-system.physmem = SimpleMemory() # This must be instantiated, even if not needed
-
-# Create a external TLM port:
-system.tlm = ExternalSlave()
-system.tlm.addr_ranges = [AddrRange('512MB')]
-system.tlm.port_type = "tlm"
-system.tlm.port_data = "memory"
-
-# Connect everything:
-system.membus = SystemXBar()
-system.system_port = system.membus.slave
-system.cpu.icache.mem_side = system.membus.slave
-system.cpu.dcache.mem_side = system.membus.slave
-system.membus.master = system.tlm.port
-
-# Start the simulation:
-root = Root(full_system = False, system = system)
-root.system.mem_mode = 'timing'
-m5.instantiate()
-m5.simulate() #Simulation time specified later on commandline