util: Add some examples for using systemc code within gem5.

These examples have comments inside them that explain what they do.
There's also a README file which explains how to use the examples
generally, and at a high level what each one does.

Change-Id: I223963dc1c190289986b2ee5705910dbcad4a4c9
Reviewed-on: https://gem5-review.googlesource.com/c/13376
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
diff --git a/util/systemc/systemc_within_gem5/README b/util/systemc/systemc_within_gem5/README
new file mode 100644
index 0000000..6c743b9
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/README
@@ -0,0 +1,33 @@
+This directory holds several examples which show how to build and run systemc
+code and models within gem5. To build a particular example, set the EXTRAS
+variable when running scons so that it gets picked up as part of gem5's build.
+For example:
+
+scons build/ARM/gem5.opt \
+          EXTRAS=util/systemc/systemc_within_gem5/systemc_sc_main
+
+Then when running gem5, you can use the config.py in the corresponding
+directory.
+
+build/ARM/gem5.opt util/systemc/systemc_within_gem5/systemc_sc_main/config.py \
+        --word Hello --word World
+
+
+To rebuild gem5 excluding the example code, be sure to clear the EXTRAS
+variable:
+
+scons build/ARM/gem5.opt EXTRAS=
+
+When building your own models, you don't have to use the EXTRAS mechanism and
+can instead put your source files alongside regular gem5 sources.
+
+
+Existing examples:
+
+systemc_sc_main - Run code based on an sc_main function.
+systemc_simple_object - Build systemc objects into a gem5 object hierarchy.
+
+
+Note that these directories all have a systemc_ prefix so that when EXTRAS
+pastes them into the build directory, they won't conflict with any existing
+top level directory.
diff --git a/util/systemc/systemc_within_gem5/systemc_sc_main/SConscript b/util/systemc/systemc_within_gem5/systemc_sc_main/SConscript
new file mode 100644
index 0000000..1fae5c6
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_sc_main/SConscript
@@ -0,0 +1,30 @@
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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: Gabe Black
+
+Import('*')
+
+Source('sc_main.cc')
diff --git a/util/systemc/systemc_within_gem5/systemc_sc_main/config.py b/util/systemc/systemc_within_gem5/systemc_sc_main/config.py
new file mode 100755
index 0000000..5cc80c7
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_sc_main/config.py
@@ -0,0 +1,69 @@
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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: Gabe Black
+
+import argparse
+import m5
+import sys
+
+from m5.objects import SystemC_Kernel, Root
+
+# pylint:disable=unused-variable
+
+# The python version of the systemc kernel acts as an interface to sc_main. The
+# c++ version of the kernel object has a lot of important jobs supporting
+# systemc objects and needs to exist in simulations using systemc.
+kernel = SystemC_Kernel()
+root = Root(full_system=True, systemc_kernel=kernel)
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--word', action="append", default=[],
+        help='Add a word to the list of words to print. Can be repeated.')
+
+args = parser.parse_args()
+
+# Tell gem5 to run the c++ sc_main function. If one isn't defined, gem5 will
+# detect that and report an error. If gem5 isn't finding your sc_main, make
+# sure its signature matches exactly so your compiler doesn't think it's a
+# different function.
+#
+# The arguements passed to this function will be treated as the argv values
+# passed to the c++ sc_main, with the argc value set appropriately.
+kernel.sc_main(*args.word);
+
+# Construct the SimObject hierarchy. Anything sc_main built has already been
+# constructed.
+m5.instantiate(None)
+
+# Run the simulation until something kicks us back to the config file. sc_main
+# will be at the point it first called sc_start and may keep executing as the
+# simulation runs, or it may be completed if it never called sc_start.
+cause = m5.simulate(m5.MaxTick).getCause()
+
+# If sc_main finished, extract what it returned and do something with it.
+result = kernel.sc_main_result()
+if result.code != 0:
+    sys.exit(int(result.code))
diff --git a/util/systemc/systemc_within_gem5/systemc_sc_main/sc_main.cc b/util/systemc/systemc_within_gem5/systemc_sc_main/sc_main.cc
new file mode 100644
index 0000000..13da38c
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_sc_main/sc_main.cc
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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: Gabe Black
+ */
+
+#include <vector>
+
+#include "base/trace.hh"
+
+#include "systemc/ext/systemc"
+
+class Printer : public sc_core::sc_module
+{
+  public:
+    sc_core::sc_in<const char *> input;
+
+    SC_CTOR(Printer)
+    {
+        SC_THREAD(print);
+    }
+
+    void
+    print()
+    {
+        int i = 0;
+        while (true) {
+            wait(input.value_changed_event());
+            DPRINTFN("Word %d: %s\n", i++, input.read());
+        }
+    }
+};
+
+class Feeder : public sc_core::sc_module
+{
+  public:
+    sc_core::sc_in<bool> clk;
+    sc_core::sc_out<const char *> output;
+
+    std::vector<const char *> strings;
+
+    SC_HAS_PROCESS(Feeder);
+    Feeder(sc_core::sc_module_name, std::vector<const char *> _strings) :
+        strings(_strings)
+    {
+        SC_THREAD(feed);
+        sensitive << clk.pos();
+    }
+
+    void
+    feed()
+    {
+        int i = 0;
+        while (true) {
+            wait();
+            if (i >= strings.size())
+                sc_core::sc_stop();
+            else
+                output = strings[i];
+            i++;
+        }
+    }
+};
+
+int
+sc_main(int argc, char *argv[])
+{
+    std::vector<const char *> strings;
+    for (int i = 0; i < argc; i++)
+        strings.push_back(argv[i]);
+
+    sc_core::sc_clock clk;
+    sc_core::sc_buffer<const char *> buf;
+
+    Feeder feeder("feeder", strings);
+    feeder.clk(clk);
+    feeder.output(buf);
+
+    Printer printer("printer");
+    printer.input(buf);
+
+    sc_core::sc_start();
+
+    return 0;
+}
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/SConscript b/util/systemc/systemc_within_gem5/systemc_simple_object/SConscript
new file mode 100644
index 0000000..bd336c6
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/SConscript
@@ -0,0 +1,32 @@
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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: Gabe Black
+
+Import('*')
+
+SimObject('SystemC_Example.py')
+Source('printer.cc')
+Source('feeder.cc')
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/SystemC_Example.py b/util/systemc/systemc_within_gem5/systemc_simple_object/SystemC_Example.py
new file mode 100644
index 0000000..20a6305
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/SystemC_Example.py
@@ -0,0 +1,53 @@
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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: Gabe Black
+
+from m5.params import *
+from m5.SimObject import SimObject
+
+from SystemC import SystemC_ScModule
+
+# This class is a subclass of sc_module, and all the special magic which makes
+# that work is handled in the base classes.
+class SystemC_Printer(SystemC_ScModule):
+    type = 'SystemC_Printer'
+    cxx_class = 'Printer'
+    cxx_header = 'systemc_simple_object/printer.hh'
+    # This parameter will be available in the SystemC_PrinterParams::create
+    # function and can be passed to the c++ object's constructor, used to set
+    # one of its member variables, as a parameter to one of its methods, etc.
+    prefix = Param.String('', 'Prefix for each word')
+
+# This is a standard gem5 SimObject class with no special accomodation for the
+# fact that one of its parameters is a systemc object.
+class Gem5_Feeder(SimObject):
+    type = 'Gem5_Feeder'
+    cxx_class = 'Feeder'
+    cxx_header = 'systemc_simple_object/feeder.hh'
+    # This parameter will be a pointer to an instance of the class above.
+    printer = Param.SystemC_Printer('Printer for our words.')
+    delay = Param.Latency('1ns', 'Time to wait between each word.')
+    strings = VectorParam.String([], 'Words to print.')
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/config.py b/util/systemc/systemc_within_gem5/systemc_simple_object/config.py
new file mode 100755
index 0000000..0340876
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/config.py
@@ -0,0 +1,59 @@
+# Copyright 2018 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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: Gabe Black
+
+from __future__ import print_function
+
+import argparse
+import m5
+import sys
+
+from m5.objects import SystemC_Kernel, Root, SystemC_Printer, Gem5_Feeder
+
+# pylint:disable=unused-variable
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--word', action="append", default=[])
+parser.add_argument('--delay', default='1ns')
+parser.add_argument('--prefix', default='')
+
+args = parser.parse_args()
+
+printer = SystemC_Printer()
+printer.prefix = args.prefix
+
+feeder = Gem5_Feeder()
+feeder.printer = printer
+feeder.delay = args.delay
+feeder.strings = args.word
+
+kernel = SystemC_Kernel(feeder=feeder)
+root = Root(full_system=True, systemc_kernel=kernel)
+
+m5.instantiate(None)
+
+cause = m5.simulate(m5.MaxTick).getCause()
+print(cause)
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/feeder.cc b/util/systemc/systemc_within_gem5/systemc_simple_object/feeder.cc
new file mode 100644
index 0000000..599e1b1
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/feeder.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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: Gabe Black
+ */
+
+#include "params/Gem5_Feeder.hh"
+#include "sim/sim_exit.hh"
+#include "systemc_simple_object/feeder.hh"
+
+Feeder::Feeder(Gem5_FeederParams *params) :
+    SimObject(params), printer(params->printer), delay(params->delay),
+    strings(params->strings), index(0), event(this)
+{
+    // Bind the printer objects "input" port to our sc_buffer. This will let
+    // us feed it values. If some other object was responsible for the
+    // sc_buffer, we could interact with it directly and not have built it
+    // ourselves.
+    //
+    // Alternatively Printer could define a normal c++ method which we could
+    // call to feed it words without involving any systemc specific classes.
+    printer->input(buf);
+}
+
+void
+Feeder::startup()
+{
+    schedule(&event, curTick() + delay);
+}
+
+void
+Feeder::feed()
+{
+    if (index >= strings.size())
+        exitSimLoop("Printed all the words.");
+    else
+        buf.write(strings[index++].c_str());
+
+    schedule(&event, curTick() + delay);
+}
+
+Feeder *
+Gem5_FeederParams::create()
+{
+    return new Feeder(this);
+}
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/feeder.hh b/util/systemc/systemc_within_gem5/systemc_simple_object/feeder.hh
new file mode 100644
index 0000000..9d2cbcb
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/feeder.hh
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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: Gabe Black
+ */
+
+#ifndef __SYSTEMC_SIMPLE_OBJECT_FEEDER_HH__
+#define __SYSTEMC_SIMPLE_OBJECT_FEEDER_HH__
+
+#include <string>
+#include <vector>
+
+#include "sim/eventq.hh"
+#include "sim/sim_object.hh"
+#include "systemc_simple_object/printer.hh"
+
+// The "external" header interface for systemc is in systemc/ext and is what
+// a model which doesn't know anything about gem5 would use. This includes a
+// particular file from those headers, but alternatively we could include
+// systemc/ext/systemc or systemc/ext/systemc.h.
+#include "systemc/ext/channel/sc_buffer.hh"
+
+// This implementation (mostly) just uses standard gem5 mechanisms.
+class Gem5_FeederParams;
+
+class Feeder : public SimObject
+{
+  public:
+    Feeder(Gem5_FeederParams *params);
+
+    void feed();
+
+  private:
+    Printer *printer;
+    Tick delay;
+    std::vector<std::string> strings;
+    int index;
+
+    // SystemC types can be used in gem5 classes, but that should be avoided
+    // except to help interact with systemc objects/models.
+    sc_core::sc_buffer<const char *> buf;
+
+    EventWrapper<Feeder, &Feeder::feed> event;
+
+    void startup() override;
+};
+
+#endif // __SYSTEMC_SIMPLE_OBJECT_PRINTER_HH__
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/printer.cc b/util/systemc/systemc_within_gem5/systemc_simple_object/printer.cc
new file mode 100644
index 0000000..36dd5f7
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/printer.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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: Gabe Black
+ */
+
+#include <vector>
+
+#include "params/SystemC_Printer.hh"
+#include "systemc_simple_object/printer.hh"
+
+// This "create" method bridges the python configuration and the systemc
+// objects. It instantiates the Printer object and sets it up using the
+// parameter values from the config, just like it would for a SimObject. The
+// systemc object could accept those parameters however it likes, for instance
+// through its constructor or by assigning them to a member variable.
+Printer *
+SystemC_PrinterParams::create()
+{
+    Printer *printer = new Printer(name.c_str());
+    printer->prefix = prefix;
+    return printer;
+}
diff --git a/util/systemc/systemc_within_gem5/systemc_simple_object/printer.hh b/util/systemc/systemc_within_gem5/systemc_simple_object/printer.hh
new file mode 100644
index 0000000..832b204
--- /dev/null
+++ b/util/systemc/systemc_within_gem5/systemc_simple_object/printer.hh
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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: Gabe Black
+ */
+
+#ifndef __SYSTEMC_SIMPLE_OBJECT_PRINTER_HH__
+#define __SYSTEMC_SIMPLE_OBJECT_PRINTER_HH__
+
+#include <string>
+
+// This include brings in the gem5 statistics classes and DPRINTF mechanism
+// which is not necessary, but shows that if they're gem5 aware, models can
+// take advantage of these sorts of gem5 mechanisms.
+#include "base/statistics.hh"
+#include "base/trace.hh"
+
+// Include the standard top level "systemc" header. For models which aren't
+// aware of gem5, systemc/ext would be in their include path directly and the
+// include wouldn't need the systemc/ext prefix.
+#include "systemc/ext/systemc"
+
+// This class is a garden variety sc_module, except that it uses DPRINTFN in
+// one of its methods, and maintains a gem5 statistic.
+class Printer : public sc_core::sc_module
+{
+  public:
+    sc_core::sc_in<const char *> input;
+    std::string prefix;
+
+    SC_CTOR(Printer)
+    {
+        SC_THREAD(print);
+    }
+
+    void
+    print()
+    {
+        int i = 0;
+        while (true) {
+            wait(input.value_changed_event());
+
+            // DPRINTFN works as expected here because sc_objects have a name()
+            // method which DPRINTFN relies on. Normally name() would come from
+            // a SimObject whose members were in scope, but it doesn't have to.
+            DPRINTFN("Word %d: %s%s\n", i++, prefix, input.read());
+
+            // Manage the gem5 statistic like normal.
+            numWords++;
+        }
+    }
+
+    Stats::Scalar numWords;
+
+    // Gem5 statistics should be set up during the "end_of_elabortion"
+    // callback.
+    void
+    end_of_elaboration() override
+    {
+        numWords
+            .name(std::string(name()) + ".numWords")
+            .desc("number of words printed")
+            ;
+    }
+};
+
+#endif // __SYSTEMC_SIMPLE_OBJECT_PRINTER_HH__