| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta http-equiv="x-ua-compatible" content="ie=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| |
| <title>gem5</title> |
| |
| <!-- SITE FAVICON --> |
| <link rel="shortcut icon" type="image/gif" href="/assets/img/gem5ColorVert.gif"/> |
| |
| <link rel="canonical" href="http://localhost:4000/helloobject/"> |
| <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700,800,600' rel='stylesheet' type='text/css'> |
| <link href='https://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'> |
| |
| <!-- FAVICON --> |
| <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> |
| |
| <!-- BOOTSTRAP --> |
| <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> |
| |
| <!-- CUSTOM CSS --> |
| <link rel="stylesheet" href="/css/main.css"> |
| </head> |
| |
| |
| <body> |
| <nav class="navbar navbar-expand-md navbar-light bg-light"> |
| <a class="navbar-brand" href="/"> |
| <img src="/assets/img/gem5ColorLong.gif" alt="gem5" height=45px> |
| </a> |
| <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> |
| <span class="navbar-toggler-icon"></span> |
| </button> |
| <div class="collapse navbar-collapse" id="navbarNavDropdown"> |
| <ul class="navbar-nav ml-auto"> |
| <li class="nav-item "> |
| <a class="nav-link" href="/">Home</a> |
| </li> |
| |
| <li class="nav-item dropdown "> |
| <a class="nav-link dropdown-toggle" href="/about" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
| About |
| </a> |
| <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> |
| <a class="dropdown-item" href="/about">About</a> |
| <a class="dropdown-item" href="/publications">Publications</a> |
| <a class="dropdown-item" href="/governance">Governance</a> |
| </div> |
| </li> |
| |
| <li class="nav-item dropdown active"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
| Documentation |
| </a> |
| <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> |
| <!-- Pull navigation from _data/documentation.yml --> |
| |
| <a class="dropdown-item" href="/introduction">Introduction</a> |
| |
| <a class="dropdown-item" href="/building">Getting Started</a> |
| |
| <a class="dropdown-item" href="/environment">Modifying/Extending</a> |
| |
| <a class="dropdown-item" href="/MSIintro">Modeling Cache Coherence with Ruby</a> |
| |
| </div> |
| </li> |
| |
| <li class="nav-item "> |
| <a class="nav-link" href="/contributing">Contributing</a> |
| </li> |
| |
| <li class="nav-item "> |
| <a class="nav-link" href="/blog">Blog</a> |
| </li> |
| |
| <li class="nav-item "> |
| <a class="nav-link" href="/search">Search</a> |
| </li> |
| </ul> |
| </div> |
| </nav> |
| |
| <main> |
| <div class="sidenav-top"> |
| <a href="/"><img src="/assets/img/gem5ColorLong.gif" height="80"></a> |
| <div class="search"> |
| <form action="/search" method="get"> |
| <!-- <label for="search-box"><i class="fa fa-search"></i></label> --> |
| <input type="text" name="query"> |
| <button type="submit" name="submit"><i class="fa fa-search"></i></button> |
| </form> |
| </div> |
| </div> |
| <div class="sidenav"> |
| <!-- Pull navigation from _data/documentation.yml --> |
| |
| <a class="item" href="/introduction" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Introduction |
| </a> |
| <div class="collapse " id="introduction"> |
| |
| </div> |
| |
| <a class="item" data-toggle="collapse" href="#pt1" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Getting Started |
| </a> |
| <div class="collapse " id="pt1"> |
| |
| <a class="subitem " href="/building">Building gem5</a> |
| |
| <a class="subitem " href="/simple_config">Creating a simple configuration script</a> |
| |
| <a class="subitem " href="/cache_config">Adding cache to configuration script</a> |
| |
| <a class="subitem " href="/gem5_stats">Understanding gem5 statistics and output</a> |
| |
| <a class="subitem " href="/example_configs">Using the default configuration scripts</a> |
| |
| </div> |
| |
| <a class="item" data-toggle="collapse" href="#pt2" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Modifying/Extending |
| </a> |
| <div class="collapse show" id="pt2"> |
| |
| <a class="subitem " href="/environment">Setting up your development environment</a> |
| |
| <a class="subitem active" href="/helloobject">Creating a very simple SimObject</a> |
| |
| <a class="subitem " href="/debugging">Debugging gem5</a> |
| |
| <a class="subitem " href="/events">Event-driven programming</a> |
| |
| <a class="subitem " href="/parameters">Adding parameters to SimObjects and more events</a> |
| |
| <a class="subitem " href="/memoryobject">Creating SimObjects in the memory system</a> |
| |
| <a class="subitem " href="/simplecache">Creating a simple cache object</a> |
| |
| </div> |
| |
| <a class="item" data-toggle="collapse" href="#pt3" role="button" aria-expanded="false" aria-controls="collapseExample"> |
| Modeling Cache Coherence with Ruby |
| </a> |
| <div class="collapse " id="pt3"> |
| |
| <a class="subitem " href="/MSIintro">Introduction to Ruby</a> |
| |
| <a class="subitem " href="/cache-intro">MSI example cache protocol</a> |
| |
| <a class="subitem " href="/cache-declarations">Declaring a state machine</a> |
| |
| <a class="subitem " href="/cache-in-ports">In port code blocks</a> |
| |
| <a class="subitem " href="/cache-actions">Action code blocks</a> |
| |
| <a class="subitem " href="/cache-transitions">Transition code blocks</a> |
| |
| <a class="subitem " href="/directory">MSI Directory implementation</a> |
| |
| <a class="subitem " href="/MSIbuilding">Compiling a SLICC protocol</a> |
| |
| <a class="subitem " href="/configuration">Configuring a simple Ruby system</a> |
| |
| <a class="subitem " href="/running">Running the simple Ruby system</a> |
| |
| <a class="subitem " href="/MSIdebugging">Debugging SLICC Protocols</a> |
| |
| <a class="subitem " href="/simple-MI_example">Configuring for a standard protocol</a> |
| |
| </div> |
| |
| </div> |
| |
| <div class="container" id="doc-container"> |
| <div class="edit"><a href="https://github.com/gem5/new-website/tree/master/_pages/documentation/part2/helloobject.md">Edit this page</a></div> |
| <dl> |
| <dt>authors</dt> |
| <dd>Jason Lowe-Power</dd> |
| </dl> |
| |
| <h1 id="creating-a-very-simple-simobject">Creating a <em>very</em> simple SimObject</h1> |
| |
| <p>Almost all objects in gem5 inherit from the base SimObject type. |
| SimObjects export the main interfaces to all objects in gem5. SimObjects |
| are wrapped <code class="highlighter-rouge">C++</code> objects that are accessible from the <code class="highlighter-rouge">Python</code> |
| configuration scripts.</p> |
| |
| <p>SimObjects can have many parameters, which are set via the <code class="highlighter-rouge">Python</code> |
| configuration files. In addition to simple parameters like integers and |
| floating point numbers, they can also have other SimObjects as |
| parameters. This allows you to create complex system hierarchies, like |
| real machines.</p> |
| |
| <p>In this chapter, we will walk through creating a simple “HelloWorld” |
| SimObject. The goal is to introduce you to how SimObjects are created |
| and the required boilerplate code for all SimObjects. We will also |
| create a simple <code class="highlighter-rouge">Python</code> configuration script which instantiates our |
| SimObject.</p> |
| |
| <p>In the next few chapters, we will take this simple SimObject and expand |
| on it to include <a href="debugging-chapter">debugging support</a>, <a href="events-chapter">dynamic |
| events</a>, and <a href="parameters-chapter">parameters</a>.</p> |
| |
| <blockquote> |
| <p><strong>Using git branches</strong></p> |
| |
| <p>It is common to use a new git branch for each new feature you add to |
| gem5.</p> |
| |
| <p>The first step when adding a new feature or modifying something in |
| gem5, is to create a new branch to store your changes. Details on git |
| branches can be found in the Git book_.</p> |
| |
| <p><code class="highlighter-rouge">{.sourceCode .sh} |
| git checkout -b hello-simobject |
| </code></p> |
| </blockquote> |
| |
| <h2 id="step-1-create-a-python-class-for-your-new-simobject">Step 1: Create a Python class for your new SimObject</h2> |
| |
| <p>Each SimObject has a Python class which is associated with it. This |
| Python class describes the parameters of your SimObject that can be |
| controlled from the Python configuration files. For our simple |
| SimObject, we are just going to start out with no parameters. Thus, we |
| simply need to declare a new class for our SimObject and set it’s name |
| and the C++ header that will define the C++ class for the SimObject.</p> |
| |
| <p>We can create a file, HelloObject.py, in <code class="highlighter-rouge">src/learning_gem5</code></p> |
| |
| <p>``` {.sourceCode .python} |
| from m5.params import * |
| from m5.SimObject import SimObject</p> |
| |
| <p>class HelloObject(SimObject): |
| type = ‘HelloObject’ |
| cxx_header = “learning_gem5/hello_object.hh”</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| You can find the complete file |
| here \<../\_static/scripts/part2/helloobject/HelloObject.py\>. |
| |
| It is not required that the `type` be the same as the name of the class, |
| but it is convention. The `type` is the C++ class that you are wrapping |
| with this Python SimObject. Only in special circumstances should the |
| `type` and the class name be different. |
| |
| The `cxx_header` is the file that contains the declaration of the class |
| used as the `type` parameter. Again, the convention is to use the name |
| of the SimObject with all lowercase and underscores, but this is only |
| convention. You can specify any header file here. |
| |
| Step 2: Implement your SimObject in C++ |
| --------------------------------------- |
| |
| Next, we need to create `hello_object.hh` and `hello_object.cc` which |
| will implement the hello object. |
| |
| We'll start with the header file for our `C++` object. By convention, |
| gem5 wraps all header files in `#ifndef/#endif` with the name of the |
| file and the directory its in so there are no circular includes. |
| |
| The only thing we need to do in the file is to declare our class. Since |
| `HelloObject` is a SimObject, it must inherit from the C++ SimObject |
| class. Most of the time, your SimObject's parent will be a subclass of |
| SimObject, not SimObject itself. |
| |
| The SimObject class specifies many virtual functions. However, none of |
| these functions are pure virtual, so in the simplest case, there is no |
| need to implement any functions except for the constructor. |
| |
| The constructor for all SimObjects assumes it will take a parameter |
| object. This parameter object is automatically created by the build |
| system and is based on the `Python` class for the SimObject, like the |
| one we created above. The name for this parameter type is generated |
| automatically from the name of your object. For our "HelloObject" the |
| parameter type's name is "HelloObject\**Params*\*". |
| |
| The code required for our simple header file is listed below. |
| |
| ``` {.sourceCode .c++} |
| #ifndef __LEARNING_GEM5_HELLO_OBJECT_HH__ |
| #define __LEARNING_GEM5_HELLO_OBJECT_HH__ |
| |
| #include "params/HelloObject.hh" |
| #include "sim/sim_object.hh" |
| |
| class HelloObject : public SimObject |
| { |
| public: |
| HelloObject(HelloObjectParams *p); |
| }; |
| |
| #endif // __LEARNING_GEM5_HELLO_OBJECT_HH__ |
| </code></pre></div></div> |
| |
| <p>You can find the complete file |
| here <../_static/scripts/part2/helloobject/hello_object.hh>.</p> |
| |
| <p>Next, we need to implement <em>two</em> functions in the <code class="highlighter-rouge">.cc</code> file, not just |
| one. The first function, is the constructor for the <code class="highlighter-rouge">HelloObject</code>. Here |
| we simply pass the parameter object to the SimObject parent and print |
| “Hello world!”</p> |
| |
| <p>Normally, you would <strong>never</strong> use <code class="highlighter-rouge">std::cout</code> in gem5. Instead, you |
| should use debug flags. In the <a href="debugging-chapter">next chapter</a>, we |
| will modify this to use debug flags instead. However, for now, we’ll |
| simply use <code class="highlighter-rouge">std::cout</code> because it is simple.</p> |
| |
| <p>``` {.sourceCode .c++} |
| #include “learning_gem5/hello_object.hh”</p> |
| |
| <p>#include <iostream></iostream></p> |
| |
| <p>HelloObject::HelloObject(HelloObjectParams *params) : |
| SimObject(params) |
| { |
| std::cout « “Hello World! From a SimObject!” « std::endl; |
| }</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| There is another function that we have to implement as well for the |
| SimObject to be complete. We must implement one function for the |
| parameter type that is implicitly created from the SimObject `Python` |
| declaration, namely, the `create` function. This function simply returns |
| a new instantiation of the SimObject. Usually this function is very |
| simple (as below). |
| |
| ``` {.sourceCode .c++} |
| HelloObject* |
| HelloObjectParams::create() |
| { |
| return new HelloObject(this); |
| } |
| </code></pre></div></div> |
| |
| <p>You can find the complete file |
| here <../_static/scripts/part2/helloobject/hello_object.cc>.</p> |
| |
| <p>If you forget to add the create function for your SimObject, you will |
| get a linker error when you compile. It will look something like the |
| following.</p> |
| |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>build/X86/python/m5/internal/param_HelloObject_wrap.o: In function `_wrap_HelloObjectParams_create': |
| /local.chinook/gem5/gem5-tutorial/gem5/build/X86/python/m5/internal/param_HelloObject_wrap.cc:3096: undefined reference to `HelloObjectParams::create()' |
| collect2: error: ld returned 1 exit status |
| scons: *** [build/X86/gem5.opt] Error 1 |
| scons: building terminated because of errors. |
| </code></pre></div></div> |
| |
| <p>This <code class="highlighter-rouge">undefined reference to `HelloObjectParams::create()'</code> means |
| you need to implement the create function for your SimObject.</p> |
| |
| <h2 id="step-3-register-the-simobject-and-c-file">Step 3: Register the SimObject and C++ file</h2> |
| |
| <p>In order for the <code class="highlighter-rouge">C++</code> file to be compiled and the <code class="highlighter-rouge">Python</code> file to be |
| parsed we need to tell the build system about these files. gem5 uses |
| SCons as the build system, so you simply have to create a SConscript |
| file in the directory with the code for the SimObject. If there is |
| already a SConscript file for that directory, simply add the following |
| declarations to that file.</p> |
| |
| <p>This file is simply a normal <code class="highlighter-rouge">Python</code> file, so you can write any |
| <code class="highlighter-rouge">Python</code> code you want in this file. Some of the scripting can become |
| quite complicated. gem5 leverages this to automatically create code for |
| SimObjects and to compile the domain-specific languages like SLICC and |
| the ISA language.</p> |
| |
| <p>In the SConscript file, there are a number of functions automatically |
| defined after you import them. See the section on that…</p> |
| |
| <p>To get your new SimObject to compile, you simply need to create a new |
| file with the name “SConscript” in the <code class="highlighter-rouge">src/learning_gem5</code> directory. In |
| this file, you have to declare the SimObject and the <code class="highlighter-rouge">.cc</code> file. Below |
| is the required code.</p> |
| |
| <p>``` {.sourceCode .python} |
| Import(‘*’)</p> |
| |
| <p>SimObject(‘HelloObject.py’) |
| Source(‘hello_object.cc’)</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| You can find the complete file |
| here \<../\_static/scripts/part2/helloobject/SConscript\>. |
| |
| Step 4: (Re)-build gem5 |
| ----------------------- |
| |
| To compile and link your new files you simply need to recompile gem5. |
| The below example assumes you are using the x86 ISA, but nothing in our |
| object requires an ISA so, this will work with any of gem5's ISAs. |
| |
| ``` {.sourceCode .sh} |
| scons build/X86/gem5.opt |
| </code></pre></div></div> |
| |
| <h2 id="step-5-create-the-config-scripts-to-use-your-new-simobject">Step 5: Create the config scripts to use your new SimObject</h2> |
| |
| <p>Now that you have implemented a SimObject, and it has been compiled into |
| gem5, you need to create or modify a <code class="highlighter-rouge">Python</code> config file to instantiate |
| your object. Since your object is very simple a system object is not |
| required! CPUs are not needed, or caches, or anything, except a <code class="highlighter-rouge">Root</code> |
| object. All gem5 instances require a <code class="highlighter-rouge">Root</code> object.</p> |
| |
| <p>Walking through creating a <em>very</em> simple configuration script, first, |
| import m5 and all of the objects you have compiled.</p> |
| |
| <p>``` {.sourceCode .python} |
| import m5 |
| from m5.objects import *</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| Next, you have to instantiate the `Root` object, as required by all gem5 |
| instances. |
| |
| ``` {.sourceCode .python} |
| root = Root(full_system = False) |
| </code></pre></div></div> |
| |
| <p>Now, you can instantiate the <code class="highlighter-rouge">HelloObject</code> you created. All you need to |
| do is call the <code class="highlighter-rouge">Python</code> “constructor”. Later, we will look at how to |
| specify parameters via the <code class="highlighter-rouge">Python</code> constructor. In addition to creating |
| an instantiation of your object, you need to make sure that it is a |
| child of the root object. Only SimObjects that are children of the |
| <code class="highlighter-rouge">Root</code> object are instantiated in <code class="highlighter-rouge">C++</code>.</p> |
| |
| <p>``` {.sourceCode .python} |
| root.hello = HelloObject()</p> |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> |
| Finally, you need to call `instantiate` on the `m5` module and actually |
| run the simulation! |
| |
| ``` {.sourceCode .python} |
| m5.instantiate() |
| |
| print("Beginning simulation!") |
| exit_event = m5.simulate() |
| print('Exiting @ tick {} because {}' |
| .format(m5.curTick(), exit_event.getCause())) |
| </code></pre></div></div> |
| |
| <p>You can find the complete file |
| here <../_static/scripts/part2/helloobject/run_hello.py>.</p> |
| |
| <p>The output should look something like the following</p> |
| |
| <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem5 Simulator System. http://gem5.org |
| gem5 is copyrighted software; use the --copyright option for details. |
| |
| gem5 compiled May 4 2016 11:37:41 |
| gem5 started May 4 2016 11:44:28 |
| gem5 executing on mustardseed.cs.wisc.edu, pid 22480 |
| command line: build/X86/gem5.opt configs/learning_gem5/run_hello.py |
| |
| Global frequency set at 1000000000000 ticks per second |
| Hello World! From a SimObject! |
| Beginning simulation! |
| info: Entering event queue @ 0. Starting simulation... |
| Exiting @ tick 18446744073709551615 because simulate() limit reached |
| </code></pre></div></div> |
| |
| <p>Congrats! You have written your first SimObject. In the next chapters, |
| we will extend this SimObject and explore what you can do with |
| SimObjects.</p> |
| |
| <br> |
| |
| <!-- RETRIVE PREVIOUS PAGE LINK --> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <!-- RETRIEVE NEXT PAGE LINK --> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <div class="navbuttons"> |
| |
| <a href="/environment"><button type="button" class="btn btn-outline-primary">PREVIOUS</button></a> |
| |
| |
| |
| <a href="/debugging"><button type="button" class="btn btn-outline-primary">NEXT</button></a> |
| |
| </div> |
| </div> |
| |
| </main> |
| |
| |
| <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> |
| <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> |
| |
| <script> |
| // When the user scrolls down 20px from the top of the document, show the button |
| window.onscroll = function() {scrollFunction()}; |
| |
| function scrollFunction() { |
| if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 20) { |
| document.getElementById("myBtn").style.display = "block"; |
| } else { |
| document.getElementById("myBtn").style.display = "none"; |
| } |
| } |
| |
| // When the user clicks on the button, scroll to the top of the document |
| function topFunction() { |
| document.body.scrollTop = 0; |
| document.documentElement.scrollTop = 0; |
| } |
| </script> |
| |
| </body> |
| |
| |
| </html> |