blob: a274d19fb4990f1d3edb86da83222ea5edbafad4 [file] [log] [blame]
<!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/parameters/">
<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="/intro">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="/search">Search</a>
</li>
</ul>
</div>
</nav>
<main>
<div class="sidenav-top">
<img src="/assets/img/gem5ColorLong.gif" height="80">
</div>
<div class="sidenav">
<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>
<!-- 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="introdution">
</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 " 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 active" 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="/intro">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">
<!-- <h1>Adding parameters to SimObjects and more events</h1> -->
<dl>
<dt>authors</dt>
<dd>Jason Lowe-Power</dd>
</dl>
<h1 id="adding-parameters-to-simobjects-and-more-events">Adding parameters to SimObjects and more events</h1>
<p>One of the most powerful parts of gem5’s Python interface is the ability
to pass parameters from Python to the C++ objects in gem5. In this
chapter, we will explore some of the kinds of parameters for SimObjects
and how to use them building off of the simple <code class="highlighter-rouge">HelloObject</code> from the
previous chapters &lt;events-chapter&gt;.</p>
<h2 id="simple-parameters">Simple parameters</h2>
<p>First, we will add parameters for the latency and number of times to
fire the event in the <code class="highlighter-rouge">HelloObject</code>. To add a parameter, modify the
<code class="highlighter-rouge">HelloObject</code> class in the SimObject Python file
(<code class="highlighter-rouge">src/learning_gem5/HelloObject.py</code>). Parameters are set by adding new
statements to the Python class that include a <code class="highlighter-rouge">Param</code> type.</p>
<p>For instance, the following code as a parameter <code class="highlighter-rouge">time_to_wait</code> which is
a “Latency” parameter and <code class="highlighter-rouge">number_of_fires</code> which is an integer
parameter.</p>
<p>``` {.sourceCode .python}
class HelloObject(SimObject):
type = ‘HelloObject’
cxx_header = “learning_gem5/hello_object.hh”</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>time_to_wait = Param.Latency("Time before firing the event")
number_of_fires = Param.Int(1, "Number of times to fire the event before "
"goodbye") ```
</code></pre></div></div>
<p><code class="highlighter-rouge">Param.&lt;TypeName&gt;</code> declares a parameter of type <code class="highlighter-rouge">TypeName</code>. Common types
are <code class="highlighter-rouge">Int</code> for integers, <code class="highlighter-rouge">Float</code> for floats, etc. These types act like
regular Python classes.</p>
<p>Each parameter declaration takes one or two parameters. When given two
parameters (like <code class="highlighter-rouge">number_of_fires</code> above), the first parameter is the
<em>default value</em> for the parameter. In this case, if you instantiate a
<code class="highlighter-rouge">HelloObject</code> in your Python config file without specifying any value
for number_of_fires, it will take the default value of 1.</p>
<p>The second parameter to the parameter declaration is a short description
of the parameter. This must be a Python string. If you only specify a
single parameter to the parameter declaration, it is the description (as
for <code class="highlighter-rouge">time_to_wait</code>).</p>
<p>gem5 also supports many complex parameter types that are not just
builtin types. For instance, <code class="highlighter-rouge">time_to_wait</code> is a <code class="highlighter-rouge">Latency</code>. <code class="highlighter-rouge">Latency</code>
takes a value as a time value as a string and converts it into simulator
<strong>ticks</strong>. For instance, with a default tick rate of 1 picosecond
(10\^12 ticks per second or 1 THz), <code class="highlighter-rouge">"1ns"</code> is automatically converted
to 1000. There are other convenience parameters like <code class="highlighter-rouge">Percent</code>,
<code class="highlighter-rouge">Cycles</code>, <code class="highlighter-rouge">MemorySize</code> and many more.</p>
<p>Once you have declared these parameters in the SimObject file, you need
to copy their values to your C++ class in its constructor. The following
code shows the changes to the <code class="highlighter-rouge">HelloObject</code> constructor.</p>
<p>``` {.sourceCode .c++}
HelloObject::HelloObject(HelloObjectParams <em>params) :
SimObject(params),
event(</em>this),
myName(params-&gt;name),
latency(params-&gt;time_to_wait),
timesLeft(params-&gt;number_of_fires)
{
DPRINTF(Hello, “Created the hello object with the name %s\n”, myName);
}</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
Here, we use the parameter's values for the default values of latency
and timesLeft. Additionally, we store the `name` from the parameter
object to use it later in the member variable `myName`. Each `params`
instantiation has a name which comes from the Python config file when it
is instantiated.
However, assigning the name here is just an example of using the params
object. For all SimObjects, there is a `name()` function that always
returns the name. Thus, there is never a need to store the name like
above.
To the HelloObject class declaration, add a member variable for the
name.
``` {.sourceCode .c++}
class HelloObject : public SimObject
{
private:
void processEvent();
EventWrapper&lt;HelloObject, &amp;HelloObject::processEvent&gt; event;
std::string myName;
Tick latency;
int timesLeft;
public:
HelloObject(HelloObjectParams *p);
void startup();
};
</code></pre></div></div>
<p>When we run gem5 with the above, we get the following error:</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 Jan 4 2017 14:46:36
gem5 started Jan 4 2017 14:46:52
gem5 executing on chinook, pid 3422
command line: build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/run_hello.py
Global frequency set at 1000000000000 ticks per second
fatal: hello.time_to_wait without default or user set value
</code></pre></div></div>
<p>This is because the <code class="highlighter-rouge">time_to_wait</code> parameter does not have a default
value. Therefore, we need to update the Python config file
(<code class="highlighter-rouge">run_hello.py</code>) to specify this value.</p>
<p>``` {.sourceCode .python}
root.hello = HelloObject(time_to_wait = ‘2us’)</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
Or, we can specify `time_to_wait` as a member variable. Either option is
exactly the same because the C++ objects are not created until
`m5.instantiate()` is called.
``` {.sourceCode .python}
root.hello = HelloObject()
root.hello.time_to_wait = '2us'
</code></pre></div></div>
<p>The output of this simple script is the following when running the the
<code class="highlighter-rouge">Hello</code> debug flag.</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 Jan 4 2017 14:46:36
gem5 started Jan 4 2017 14:50:08
gem5 executing on chinook, pid 3455
command line: build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/run_hello.py
Global frequency set at 1000000000000 ticks per second
0: hello: Created the hello object with the name hello
Beginning simulation!
info: Entering event queue @ 0. Starting simulation...
2000000: hello: Hello world! Processing the event! 0 left
2000000: hello: Done firing!
Exiting @ tick 18446744073709551615 because simulate() limit reached
</code></pre></div></div>
<p>You can also modify the config script to fire the event multiple times.</p>
<h2 id="other-simobjects-as-parameters">Other SimObjects as parameters</h2>
<p>You can also specify other SimObjects as parameters. To demonstrate
this, we are going to create a new SimObject, <code class="highlighter-rouge">GoodbyeObject</code>. This
object is going to have a simple function that says “Goodbye” to another
SimObject. To make it a little more interesting, the <code class="highlighter-rouge">GoodbyeObject</code> is
going to have a buffer to write the message, and a limited bandwidth to
write the message.</p>
<p>First, declare the SimObject in the SConscript file:</p>
<p>``` {.sourceCode .python}
Import(‘*’)</p>
<p>SimObject(‘HelloObject.py’)
Source(‘hello_object.cc’)
Source(‘goodbye_object.cc’)</p>
<p>DebugFlag(‘Hello’)</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
The new SConscript file can be downloaded
here \&lt;../\_static/scripts/part2/parameters/SConscript\&gt;
Next, you need to declare the new SimObject in a SimObject Python file.
Since the `GoodbyeObject` is highly related to the `HelloObject`, we
will use the same file. You can add the following code to
`HelloObject.py`.
This object has two parameters, both with default values. The first
parameter is the size of a buffer and is a `MemorySize` parameter.
Second is the `write_bandwidth` which specifies the speed to fill the
buffer. Once the buffer is full, the simulation will exit.
``` {.sourceCode .python}
class GoodbyeObject(SimObject):
type = 'GoodbyeObject'
cxx_header = "learning_gem5/goodbye_object.hh"
buffer_size = Param.MemorySize('1kB',
"Size of buffer to fill with goodbye")
write_bandwidth = Param.MemoryBandwidth('100MB/s', "Bandwidth to fill "
"the buffer")
</code></pre></div></div>
<p>The updated <code class="highlighter-rouge">HelloObject.py</code> file can be downloaded
here &lt;../_static/scripts/part2/parameters/HelloObject.py&gt;</p>
<p>Now, we need to implement the <code class="highlighter-rouge">GoodbyeObject</code>.</p>
<p>``` {.sourceCode .c++}
#ifndef <strong>LEARNING_GEM5_GOODBYE_OBJECT_HH</strong>
#define <strong>LEARNING_GEM5_GOODBYE_OBJECT_HH</strong></p>
<p>#include <string></string></p>
<p>#include “params/GoodbyeObject.hh”
#include “sim/sim_object.hh”</p>
<p>class GoodbyeObject : public SimObject
{
private:
void processEvent();</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/**
* Fills the buffer for one iteration. If the buffer isn't full, this
* function will enqueue another event to continue filling.
*/
void fillBuffer();
EventWrapper&lt;GoodbyeObject, &amp;GoodbyeObject::processEvent&gt; event;
/// The bytes processed per tick
float bandwidth;
/// The size of the buffer we are going to fill
int bufferSize;
/// The buffer we are putting our message in
char *buffer;
/// The message to put into the buffer.
std::string message;
/// The amount of the buffer we've used so far.
int bufferUsed;
</code></pre></div></div>
<p>public:
GoodbyeObject(GoodbyeObjectParams *p);
~GoodbyeObject();</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/**
* Called by an outside object. Starts off the events to fill the buffer
* with a goodbye message.
*
* @param name the name of the object we are saying goodbye to.
*/
void sayGoodbye(std::string name); };
</code></pre></div></div>
<p>#endif // <strong>LEARNING_GEM5_GOODBYE_OBJECT_HH</strong></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
``` {.sourceCode .c++}
#include "learning_gem5/goodbye_object.hh"
#include "debug/Hello.hh"
#include "sim/sim_exit.hh"
GoodbyeObject::GoodbyeObject(GoodbyeObjectParams *params) :
SimObject(params), event(*this), bandwidth(params-&gt;write_bandwidth),
bufferSize(params-&gt;buffer_size), buffer(nullptr), bufferUsed(0)
{
buffer = new char[bufferSize];
DPRINTF(Hello, "Created the goodbye object\n");
}
GoodbyeObject::~GoodbyeObject()
{
delete[] buffer;
}
void
GoodbyeObject::processEvent()
{
DPRINTF(Hello, "Processing the event!\n");
fillBuffer();
}
void
GoodbyeObject::sayGoodbye(std::string other_name)
{
DPRINTF(Hello, "Saying goodbye to %s\n", other_name);
message = "Goodbye " + other_name + "!! ";
fillBuffer();
}
void
GoodbyeObject::fillBuffer()
{
// There better be a message
assert(message.length() &gt; 0);
// Copy from the message to the buffer per byte.
int bytes_copied = 0;
for (auto it = message.begin();
it &lt; message.end() &amp;&amp; bufferUsed &lt; bufferSize - 1;
it++, bufferUsed++, bytes_copied++) {
// Copy the character into the buffer
buffer[bufferUsed] = *it;
}
if (bufferUsed &lt; bufferSize - 1) {
// Wait for the next copy for as long as it would have taken
DPRINTF(Hello, "Scheduling another fillBuffer in %d ticks\n",
bandwidth * bytes_copied);
schedule(event, curTick() + bandwidth * bytes_copied);
} else {
DPRINTF(Hello, "Goodbye done copying!\n");
// Be sure to take into account the time for the last bytes
exitSimLoop(buffer, 0, curTick() + bandwidth * bytes_copied);
}
}
GoodbyeObject*
GoodbyeObjectParams::create()
{
return new GoodbyeObject(this);
}
</code></pre></div></div>
<p>The header file can be downloaded
here &lt;../_static/scripts/part2/parameters/goodbye_object.hh&gt; and the
implementation can be downloaded
here &lt;../_static/scripts/part2/parameters/goodbye_object.cc&gt;</p>
<p>The interface to this <code class="highlighter-rouge">GoodbyeObject</code> is simple a function <code class="highlighter-rouge">sayGoodbye</code>
which takes a string as a parameter. When this function is called, the
simulator builds the message and saves it in a member variable. Then, we
begin filling the buffer.</p>
<p>To model the limited bandwidth, each time we write the message to the
buffer, we pause for the latency it takes to write the message. We use a
simple event to model this pause.</p>
<p>Since we used a <code class="highlighter-rouge">MemoryBandwidth</code> parameter in the SimObject
declaration, the <code class="highlighter-rouge">bandwidth</code> variable is automatically converted into
ticks per byte, so calculating the latency is simply the bandwidth times
the bytes we want to write the buffer.</p>
<p>Finally, when the buffer is full, we call the function <code class="highlighter-rouge">exitSimLoop</code>,
which will exit the simulation. This function takes three parameters,
the first is the message to return to the Python config script
(<code class="highlighter-rouge">exit_event.getCause()</code>), the second is the exit code, and the third is
when to exit.</p>
<h3 id="adding-the-goodbyeobject-as-a-parameter-to-the-helloobject">Adding the GoodbyeObject as a parameter to the HelloObject</h3>
<p>First, we will also add a <code class="highlighter-rouge">GoodbyeObject</code> as a parameter to the
<code class="highlighter-rouge">HelloObject</code>. To do this, you simply specify the SimObject class name
as the <code class="highlighter-rouge">TypeName</code> of the <code class="highlighter-rouge">Param</code>. You can have a default, or not, just
like a normal parameter.</p>
<p>``` {.sourceCode .python}
class HelloObject(SimObject):
type = ‘HelloObject’
cxx_header = “learning_gem5/hello_object.hh”</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>time_to_wait = Param.Latency("Time before firing the event")
number_of_fires = Param.Int(1, "Number of times to fire the event before "
"goodbye")
goodbye_object = Param.GoodbyeObject("A goodbye object") ```
</code></pre></div></div>
<p>The updated <code class="highlighter-rouge">HelloObject.py</code> file can be downloaded
here &lt;../_static/scripts/part2/parameters/HelloObject.py&gt;</p>
<p>Second, we will add a reference to a <code class="highlighter-rouge">GoodbyeObject</code> to the
<code class="highlighter-rouge">HelloObject</code> class.</p>
<p>``` {.sourceCode .c++}
class HelloObject : public SimObject
{
private:
void processEvent();</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>EventWrapper&lt;HelloObject, &amp;HelloObject::processEvent&gt; event;
/// Pointer to the corresponding GoodbyeObject. Set via Python
const GoodbyeObject* goodbye;
/// The name of this object in the Python config file
const std::string myName;
/// Latency between calling the event (in ticks)
const Tick latency;
/// Number of times left to fire the event before goodbye
int timesLeft;
</code></pre></div></div>
<p>public:
HelloObject(HelloObjectParams *p);</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>void startup(); }; ```
</code></pre></div></div>
<p>Then, we need to update the constructor and the process event function
of the <code class="highlighter-rouge">HelloObject</code>. We also add a check in the constructor to make
sure the <code class="highlighter-rouge">goodbye</code> pointer is valid. It is possible to pass a null
pointer as a SimObject via the parameters by using the <code class="highlighter-rouge">NULL</code> special
Python SimObject. We should <em>panic</em> when this happens since it is not a
case this object has been coded to accept.</p>
<p>``` {.sourceCode .c++}
#include “learning_gem5/part2/hello_object.hh”</p>
<p>#include “base/misc.hh”
#include “debug/Hello.hh”</p>
<p>HelloObject::HelloObject(HelloObjectParams <em>params) :
SimObject(params),
event(</em>this),
goodbye(params-&gt;goodbye_object),
myName(params-&gt;name),
latency(params-&gt;time_to_wait),
timesLeft(params-&gt;number_of_fires)
{
DPRINTF(Hello, “Created the hello object with the name %s\n”, myName);
panic_if(!goodbye, “HelloObject must have a non-null GoodbyeObject”);
}</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
Once we have processed the number of event specified by the parameter,
we should call the `sayGoodbye` function in the `GoodbyeObject`.
``` {.sourceCode .c++}
void
HelloObject::processEvent()
{
timesLeft--;
DPRINTF(Hello, "Hello world! Processing the event! %d left\n", timesLeft);
if (timesLeft &lt;= 0) {
DPRINTF(Hello, "Done firing!\n");
goodbye.sayGoodbye(myName);
} else {
schedule(event, curTick() + latency);
}
}
</code></pre></div></div>
<p>You can find the updated header file
here &lt;../_static/scripts/part2/parameters/hello_object.hh&gt; and the
implementation file
here &lt;../_static/scripts/part2/parameters/hello_object.cc&gt;.</p>
<h3 id="updating-the-config-script">Updating the config script</h3>
<p>Lastly, we need to add the <code class="highlighter-rouge">GoodbyeObject</code> to the config script. Create
a new config script, <code class="highlighter-rouge">hello_goodbye.py</code> and instantiate both the hello
and the goodbye objects. For instance, one possible script is the
following.</p>
<p>``` {.sourceCode .python}
import m5
from m5.objects import *</p>
<p>root = Root(full_system = False)</p>
<p>root.hello = HelloObject(time_to_wait = ‘2us’, number_of_fires = 5)
root.hello.goodbye_object = GoodbyeObject(buffer_size=’100B’)</p>
<p>m5.instantiate()</p>
<p>print “Beginning simulation!”
exit_event = m5.simulate()
print ‘Exiting @ tick %i because %s’ % (m5.curTick(), exit_event.getCause())
```</p>
<p>You can download this script
here &lt;../_static/scripts/part2/parameters/hello_goodbye.py&gt;</p>
<p>Running this script generates the following output.</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 Jan 4 2017 15:17:14
gem5 started Jan 4 2017 15:18:41
gem5 executing on chinook, pid 3838
command line: build/X86/gem5.opt --debug-flags=Hello configs/learning_gem5/part2/hello_goodbye.py
Global frequency set at 1000000000000 ticks per second
0: hello.goodbye_object: Created the goodbye object
0: hello: Created the hello object
Beginning simulation!
info: Entering event queue @ 0. Starting simulation...
2000000: hello: Hello world! Processing the event! 4 left
4000000: hello: Hello world! Processing the event! 3 left
6000000: hello: Hello world! Processing the event! 2 left
8000000: hello: Hello world! Processing the event! 1 left
10000000: hello: Hello world! Processing the event! 0 left
10000000: hello: Done firing!
10000000: hello.goodbye_object: Saying goodbye to hello
10000000: hello.goodbye_object: Scheduling another fillBuffer in 152592 ticks
10152592: hello.goodbye_object: Processing the event!
10152592: hello.goodbye_object: Scheduling another fillBuffer in 152592 ticks
10305184: hello.goodbye_object: Processing the event!
10305184: hello.goodbye_object: Scheduling another fillBuffer in 152592 ticks
10457776: hello.goodbye_object: Processing the event!
10457776: hello.goodbye_object: Scheduling another fillBuffer in 152592 ticks
10610368: hello.goodbye_object: Processing the event!
10610368: hello.goodbye_object: Scheduling another fillBuffer in 152592 ticks
10762960: hello.goodbye_object: Processing the event!
10762960: hello.goodbye_object: Scheduling another fillBuffer in 152592 ticks
10915552: hello.goodbye_object: Processing the event!
10915552: hello.goodbye_object: Goodbye done copying!
Exiting @ tick 10944163 because Goodbye hello!! Goodbye hello!! Goodbye hello!! Goodbye hello!! Goodbye hello!! Goodbye hello!! Goo
</code></pre></div></div>
<p>You can modify the parameters to these two SimObjects and see how the
overall execution time (Exiting @ tick <strong>10944163</strong>) changes. To run
these tests, you may want to remove the debug flag so there is less
output to the terminal.</p>
<p>In the next chapters, we will create a more complex and more useful
SimObject, culminating with a simple blocking uniprocessor cache
implementation.</p>
</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>
<footer class="page-footer">
<div class="container">
<div class="row">
<div class="col-12 col-sm-4">
<p><a href="/about">About</a></p>
<p><a href="/publications">Publications</a></p>
<p><a href="/contributing">Contributing</a></p>
</div><br>
<div class="col-12 col-sm-4">
<p><a href="/gettingstarted">Documentation</a></p>
<p><a href="#">Source</a></p>
</div><br>
<div class="col-12 col-sm-4">
<p><a href="/help">Help</a></p>
<p><a href="/search">Search</a></p>
<p><a href="#">Mailing Lists</a></p>
</div>
</div>
</div>
</footer>
</html>