misc: Coupling gem5 with SystemC TLM2.0
authorMatthias Jung <jungma@eit.uni-kl.de>
Tue, 4 Aug 2015 04:08:40 +0000 (23:08 -0500)
committerMatthias Jung <jungma@eit.uni-kl.de>
Tue, 4 Aug 2015 04:08:40 +0000 (23:08 -0500)
Transaction Level Modeling (TLM2.0) is widely used in industry for creating
virtual platforms (IEEE 1666 SystemC). This patch contains a standard compliant
implementation of an external gem5 port, that enables the usage of gem5 as a
TLM initiator component in SystemC based virtual platforms. Both TLM coding
paradigms loosely timed (b_transport) and aproximately timed (nb_transport) are
supported.

Compared to the original patch a TLM memory manager was added. Furthermore, the
transaction object was removed and for each TLM payload a PacketPointer that
points to the original gem5 packet is added as an TLM extension.  For event
handling single events are now created.

Committed by: Nilay Vaish <nilay@cs.wisc.edu>

16 files changed:
configs/common/MemConfig.py
configs/common/Options.py
util/tlm/Makefile [new file with mode: 0644]
util/tlm/README [new file with mode: 0644]
util/tlm/main.cc [new file with mode: 0644]
util/tlm/run_gem5.sh [new file with mode: 0644]
util/tlm/sc_ext.cc [new file with mode: 0644]
util/tlm/sc_ext.hh [new file with mode: 0644]
util/tlm/sc_mm.cc [new file with mode: 0644]
util/tlm/sc_mm.hh [new file with mode: 0644]
util/tlm/sc_port.cc [new file with mode: 0644]
util/tlm/sc_port.hh [new file with mode: 0644]
util/tlm/sc_target.cc [new file with mode: 0644]
util/tlm/sc_target.hh [new file with mode: 0644]
util/tlm/tgen.cfg [new file with mode: 0644]
util/tlm/tlm.py [new file with mode: 0644]

index cf0fb1632cccd6a56730fa15f12ffa3ac2994d71..0191554a7b78a4635d744c05e8787032035c09f9 100644 (file)
@@ -151,6 +151,15 @@ def config_mem(options, system):
     them.
     """
 
+    if options.tlm_memory:
+        system.external_memory = m5.objects.ExternalSlave(
+            port_type="tlm",
+            port_data=options.tlm_memory,
+            port=system.membus.master,
+            addr_ranges=system.mem_ranges)
+        system.kernel_addr_check = False
+        return
+
     if options.external_memory_system:
         system.external_memory = m5.objects.ExternalSlave(
             port_type=options.external_memory_system,
index 35d453d24d379484f219aaac41f33833d2eae0cc..1922f78a656a794b19da8ecd3f0a818581a3edab 100644 (file)
@@ -106,6 +106,8 @@ def addCommonOptions(parser):
     # Cache Options
     parser.add_option("--external-memory-system", type="string",
                       help="use external ports of this port_type for caches")
+    parser.add_option("--tlm-memory", type="string",
+                      help="use external port for SystemC TLM cosimulation")
     parser.add_option("--caches", action="store_true")
     parser.add_option("--l2cache", action="store_true")
     parser.add_option("--fastmem", action="store_true")
diff --git a/util/tlm/Makefile b/util/tlm/Makefile
new file mode 100644 (file)
index 0000000..1fda3b1
--- /dev/null
@@ -0,0 +1,76 @@
+# 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/README b/util/tlm/README
new file mode 100644 (file)
index 0000000..f3cb4fb
--- /dev/null
@@ -0,0 +1,96 @@
+This directory contains a demo of a coupling between gem5 and SystemC-TLM.
+It is based on the gem5-systemc implementation in utils/systemc.
+First a simple example with gem5's traffic generator is shown, later an full
+system example.
+
+Files:
+
+    main.cc                -- demonstration top level
+    sc_port.{cc,hh}        -- transactor that translates beween gem5 and tlm
+    sc_mm.{cc,hh}          -- implementation of a tlm memory manager
+    sc_ext.{cc,hh}         -- a TLM extension that carries the gem5 packet
+    sc_target.{cc,hh}      -- an example TLM LT/AT memory module
+    tlm.py                 -- simple gem5 configuration
+    tgen.cfg               -- configuration file for the traceplayer
+
+Other Files will be used from utils/systemc example:
+
+    sc_logger.{cc,hh},
+    sc_module.{cc,hh},
+    sc_gem5_control.{cc,hh},
+    stats.{cc,hh}
+
+
+I. Traffic Generator Setup
+==========================
+
+To build:
+
+First build a normal gem5 (cxx-config not needed, Python needed).
+Second build gem5 as a library with cxx-config support and (optionally)
+without python.
+
+> cd ../..
+> scons build/ARM/gem5.opt
+> scons --with-cxx-config --without-python build/ARM/libgem5_opt.so
+> cd util/systemc_tlm
+
+Set a proper LD_LIBRARY_PATH e.g. for bash:
+> export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/gem5/build/ARM/"
+
+Then edit the Makefile to set the paths for SystemC and run make
+
+> make
+
+Make a config file for the C++-configured gem5 using normal gem5
+
+> ../../build/ARM/gem5.opt ./tlm.py
+
+The message "fatal: Can't find port handler type 'tlm'" is okay.
+The configuration will be stored in the m5out/ directory
+
+The binary 'gem5.opt.sc', that has been created in the make step,
+can now be used to load in the generated config file from the previous
+normal gem5 run.
+
+Try:
+
+> ./gem5.opt.sc m5out/config.ini -e 1000000
+
+It should run a simulation for 1us.
+
+To see more information what happens inside the TLM module use the -D flag:
+
+> ./gem5.opt.sc m5out/config.ini -e 1000000 -D
+
+To see more information about the port coupling use:
+
+> ./gem5.opt.sc m5out/config.ini -e 1000000 -d ExternalPort
+
+II. Full System Setup
+=====================
+
+Build gem5 as discribed in Section I. Then, make a config file for the
+C++-configured gem5 using normal gem5
+
+> ../../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                              \
+  --disk-image=linux-aarch32-ael.img
+
+The message "fatal: Can't find port handler type 'tlm'" is okay.
+The configuration will be stored in the m5out/ directory
+
+The binary 'gem5.opt.sc' can now be used to load in the generated config
+file from the previous normal gem5 run.
+
+Try:
+
+> ./gem5.opt.sc m5out/config.ini -o 2147483648
+
+The parameter -o specifies the begining of the memory region (0x80000000).
+The system should boot now.
+
+For conveniance a run_gem5.sh file holds all those commands
diff --git a/util/tlm/main.cc b/util/tlm/main.cc
new file mode 100644 (file)
index 0000000..517e4ad
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * 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
+ */
+
+/**
+ * @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"
+
+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::enabled = true;
+
+    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;
+
+    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");
+
+    return EXIT_SUCCESS;
+}
diff --git a/util/tlm/run_gem5.sh b/util/tlm/run_gem5.sh
new file mode 100644 (file)
index 0000000..c50391e
--- /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/sc_ext.cc b/util/tlm/sc_ext.cc
new file mode 100644 (file)
index 0000000..ce7417e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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_ext.hh"
+
+using namespace tlm;
+
+gem5Extension::gem5Extension(PacketPtr packet)
+{
+    Packet = packet;
+}
+
+gem5Extension& gem5Extension::getExtension(const tlm_generic_payload *payload)
+{
+    gem5Extension *result = NULL;
+    payload->get_extension(result);
+    sc_assert(result!=NULL);
+    return *result;
+}
+
+gem5Extension& gem5Extension::getExtension(const tlm_generic_payload &payload)
+{
+    return gem5Extension::getExtension(&payload);
+}
+
+PacketPtr gem5Extension::getPacket()
+{
+    return Packet;
+}
+
+tlm_extension_base* gem5Extension::clone() const
+{
+    return new gem5Extension(Packet);
+}
+
+void gem5Extension::copy_from(const tlm_extension_base& ext)
+{
+    const gem5Extension& cpyFrom = static_cast<const gem5Extension&>(ext);
+    Packet = cpyFrom.Packet;
+}
diff --git a/util/tlm/sc_ext.hh b/util/tlm/sc_ext.hh
new file mode 100644 (file)
index 0000000..cb7411e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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 SC_EXT_H_
+#define SC_EXT_H_
+
+#include <systemc.h>
+#include <tlm.h>
+
+#include <iostream>
+
+#include "mem/packet.hh"
+
+class gem5Extension: public tlm::tlm_extension<gem5Extension>
+{
+  public:
+    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);
+    PacketPtr getPacket();
+
+  private:
+    PacketPtr Packet;
+};
+
+#endif
diff --git a/util/tlm/sc_mm.cc b/util/tlm/sc_mm.cc
new file mode 100644 (file)
index 0000000..509d429
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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:
+ *    Robert Gernhardt
+ *    Matthias Jung
+ */
+
+#include <iostream>
+
+#include "sc_mm.hh"
+
+using namespace std;
+
+MemoryManager::MemoryManager(): numberOfAllocations(0), numberOfFrees(0)
+{
+
+}
+
+MemoryManager::~MemoryManager()
+{
+    for(gp* payload: freePayloads) {
+        delete payload;
+        numberOfFrees++;
+    }
+}
+
+gp*
+MemoryManager::allocate()
+{
+    if(freePayloads.empty()) {
+        numberOfAllocations++;
+        return new gp(this);
+    } else {
+        gp* result = freePayloads.back();
+        freePayloads.pop_back();
+        return result;
+    }
+}
+
+void
+MemoryManager::free(gp* payload)
+{
+    payload->reset(); //clears all extensions
+    freePayloads.push_back(payload);
+}
diff --git a/util/tlm/sc_mm.hh b/util/tlm/sc_mm.hh
new file mode 100644 (file)
index 0000000..86d9ee1
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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:
+ *    Robert Gernhardt
+ *    Matthias Jung
+ */
+
+#ifndef MEMORYMANAGER_H_
+#define MEMORYMANAGER_H_
+
+#include <tlm.h>
+
+#include <vector>
+
+typedef tlm::tlm_generic_payload gp;
+
+class MemoryManager : public tlm::tlm_mm_interface
+{
+  public:
+    MemoryManager();
+    virtual ~MemoryManager();
+    virtual gp* allocate();
+    virtual void free(gp* payload);
+
+  private:
+    unsigned int numberOfAllocations;
+    unsigned int numberOfFrees;
+    std::vector<gp*> freePayloads;
+};
+
+#endif /* MEMORYMANAGER_H_ */
diff --git a/util/tlm/sc_port.cc b/util/tlm/sc_port.cc
new file mode 100644 (file)
index 0000000..c949d3f
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * 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 <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");
+
+    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;
+
+    /* We should never get a second request after noting that a retry is
+     * required */
+    sc_assert(!needToSendRequestRetry);
+
+    /* FIXME screw coherency traffic */
+    if (packet->memInhibitAsserted())
+        return true;
+
+    /* 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
new file mode 100644 (file)
index 0000000..374a3cf
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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_target.cc b/util/tlm/sc_target.cc
new file mode 100644 (file)
index 0000000..69025b3
--- /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, 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
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/tgen.cfg b/util/tlm/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/tlm.py b/util/tlm/tlm.py
new file mode 100644 (file)
index 0000000..e9025ab
--- /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_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